Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.com.git
blog/2025/08/18/feature-matrix/build.sh
#!/usr/bin/env bash
-java -jar /tmp/keenwrite.jar \
+keenwrite.bin \
-i index.Rmd \
-o index.xhtml \
blog/2025/08/18/feature-matrix/head.html
<meta name="keywords" content="markdown, text, editor, software">
<meta name="robots" content="index, follow">
-<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self' 'unsafe-inline';">
+<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self';">
<link rel="stylesheet" href="/styles/base.css">
-<style>
+<style type="text/css">
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-Regular.ttf') format('truetype');
+ font-weight: 400; /* Regular */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-Italic.ttf') format('truetype');
+ font-weight: 400; /* Regular */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-Medium.ttf') format('truetype');
+ font-weight: 500; /* Medium */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-MediumItalic.ttf') format('truetype');
+ font-weight: 500; /* Medium */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-SemiBold.ttf') format('truetype');
+ font-weight: 600; /* SemiBold */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-SemiBoldItalic.ttf') format('truetype');
+ font-weight: 600; /* SemiBold */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-Bold.ttf') format('truetype');
+ font-weight: 700; /* Bold */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-BoldItalic.ttf') format('truetype');
+ font-weight: 700; /* Bold */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-ExtraBold.ttf') format('truetype');
+ font-weight: 800; /* ExtraBold */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-ExtraBoldItalic.ttf') format('truetype');
+ font-weight: 800; /* ExtraBold */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-Black.ttf') format('truetype');
+ font-weight: 900; /* Black */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Playfair Display';
+ src: url('/fonts/PlayfairDisplay-BlackItalic.ttf') format('truetype');
+ font-weight: 900; /* Black */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato-Thin.ttf') format('truetype');
+ font-weight: 100; /* Thin */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato-ThinItalic.ttf') format('truetype');
+ font-weight: 100; /* Thin */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato-Light.ttf') format('truetype');
+ font-weight: 300; /* Light */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato-LightItalic.ttf') format('truetype');
+ font-weight: 300; /* Light */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato-Regular.ttf') format('truetype');
+ font-weight: 400; /* Regular */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato-Italic.ttf') format('truetype');
+ font-weight: 400; /* Regular */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato-Bold.ttf') format('truetype');
+ font-weight: 700; /* Bold */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato-BoldItalic.ttf') format('truetype');
+ font-weight: 700; /* Bold */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato-Black.ttf') format('truetype');
+ font-weight: 900; /* Black */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('/fonts/Lato-BlackItalic.ttf') format('truetype');
+ font-weight: 900; /* Black */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'FiraCode';
+ src: url('/fonts/FiraCode-Light.ttf') format('truetype');
+ font-weight: 300; /* Light */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'FiraCode';
+ src: url('/fonts/FiraCode-Regular.ttf') format('truetype');
+ font-weight: 400; /* Regular */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'FiraCode';
+ src: url('/fonts/FiraCode-Medium.ttf') format('truetype');
+ font-weight: 500; /* Medium */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'FiraCode';
+ src: url('/fonts/FiraCode-SemiBold.ttf') format('truetype');
+ font-weight: 600; /* SemiBold */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'FiraCode';
+ src: url('/fonts/FiraCode-Bold.ttf') format('truetype');
+ font-weight: 700; /* Bold */
+ font-style: normal;
+ font-display: swap;
+}
+
+body {
+ font-family: 'Literata Book', serif;
+ line-height: 1.4;
+}
+
h1, h2, h3, table {
- font-family: sans-serif;
+ font-family: 'Lato', sans-serif;
+}
+
+pre, code {
+ font-family: 'FiraCode', monospace;
+ color: #9CDE9F;
+}
+
+pre {
+ padding-left: 2em;
+ word-wrap: normal;
+}
+
+code {
+ white-space: nowrap;
+}
+
+pre code {
+ white-space: pre;
}
blog/2025/08/18/feature-matrix/index.Rmd
-# Markdown
+# Text format feature matrix
::: byline
-Dave Jarvis, Aug 25, 2025
+Dave Jarvis — `r# format(Sys.time(), "%B %d, %Y")`
:::
The purpose of this page is to help dispel the notion that Markdown is inferior
to other text formats for technical documentation. Rather, they each have their
-own strengths and weaknesses. The table provides an objective way to evaluate
+own strengths and weaknesses. The matrix provides an objective way to evaluate
formats for specific needs. Keep in mind that tools such as pandoc can do a
terrific job at converting between formats.
The **Language, R** row denotes that the format supports the R programming
-language.
+language. We could list additional languages, such as Python and Ruby, but
+the list is extensive.
### Variables, interpolated
At time of writing, Mermaid diagrams produce scalable vector graphics (SVG)
that cannot be rendered by numerous vector graphics drawing programs and
-libraries. Mermaid uses `<foreignObject>` to leverage features found in web
-browsers, which was a poor technical choice in my opinion. Both PlantUML and
-GraphViz can produce equally complex, yet standards-compliant SVG documents.
+libraries outside of a web browser environment. Mermaid uses `<foreignObject>`
+to leverage features found in browsers, which was a poor technical choice in my
+opinion. Both PlantUML and GraphViz can produce equally complex, yet
+standards-compliant SVG documents.
To render Mermaid diagrams in AsciiDoc, a headless browser extension must be
The **Captions, consistency** row notes whether the syntax for captions is
consistent across elements being captioned. KeenWrite supports a double-colon
-syntax for captions, where the caption comes after the element being captioned.
-Consider the following text:
+syntax for captions, where the caption comes after the element being captioned
+is separated by a mandatory blank line. Consider the following text:
``` markdown
```
-The blank lines before each caption are mandatory. Sample output:
+Sample output:
![document captions](captions.png)
Chapters and sections are automatically named based on the title text by
-converting the title to lowercase and replacing spaces with hyphens.
+converting the title to lowercase and replacing spaces with hyphens. To wit:
``` md
The **Metadata, external** row indicates whether document metadata (such as
author, book title, publication year) can exist in an external file, allowing
-it to be reused across separate chapter files. In many cases, it is possible to
-concatenate the metadata source to the top of the chapter to process. If the
-system can apply metadata to documents without extra tooling, it is marked as a
+it to be reused in other contexts. For arbitrarily defined variables, if the
+system can inject them into documents without extra tooling, it is marked as
`Y`.
-
### Curls quotation marks, comprehensive
determine how to format single quotation marks, double quotes, contractions,
and mark primes. Systems must pass KeenQuote's test suite using naturally
-entered quotation marks (i.e., \" and \') to be marked as a `Y`.
+entered quotation marks (i.e., \" and \') to be marked as `Y`.
### Collate chapters
The **Collate chapters** row describes whether individual document files---in
the same directory---can be combined into a single work using built-in tooling
without requiring them to reference each other. This approach, where a program
handles the collation (e.g., via a command-line utility), simplifies the
-process and avoids a maintenance burden when adding or removing chapters. File
+process and avoids a maintenance burden when adding or removing chapters. File
systems are well-suited for grouping files. For example:
(how the writing appears), and is therefore unsupported by KeenWrite.
-**Text, underline** is also unsupported by KeenWrite. Historically,
-underlining was developed to compensate for shortcomings in early typewriter
-technology. Namely, a lack of bold or italics. If users ache for that newsstand
-tabloid feel, they'll need to look elsewhere.
+**Text, underline** is also unsupported by KeenWrite. Historically, underlining
+was developed to compensate for shortcomings in early typewriter technology.
+Namely, a lack of bold or italics. If users ache for that newsstand tabloid
+feel, they'll need to look elsewhere.
# Diagram code blocks
evolved in email, mailing lists, Usenet newsgroups, and elsewhere. His original
goal was to make a text format that could be easily converted to HTML while
-remaining human-readable. So one writes `*emphasis*` instead of
-`<em>emphasis</em>`. Gruber released a specification alongside a script that
-converts a Markdown document into valid HTML.
+remaining human-readable. Instead of `<em>emphasis</em>`, we write
+`*emphasis*`. Gruber released a specification alongside a script that converts
+a Markdown document into valid HTML.
The format gained popularity among developers, leading to its adoption for project README files, which significantly boosted its widespread use.
blog/2025/08/18/feature-matrix/index.html
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en" xmlns="http://www.w3.org/1999/xhtml"><head xmlns=""><meta content="width=device-width, initial-scale=1.0" name="viewport"/>
-<meta content="cross-platform, open-source desktop editor" name="description"/>
-<meta content="markdown, text, editor, software" name="keywords"/>
-<meta content="index, follow" name="robots"/>
-<meta content="default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self' 'unsafe-inline';" http-equiv="Content-Security-Policy"/>
-<link href="/styles/base.css" rel="stylesheet"/>
-<style>
-h1, h2, h3, table {
- font-family: sans-serif;
-}
-
-img {
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-
-table {
- margin: 0 auto;
- border-collapse: collapse;
-}
-
-thead {
- background-color: #126d95;
- position: sticky;
- top: 0px;
-}
-
-th, td {
- padding: 0 0.5em;
-}
-
-th {
- padding-top: .25em;
- padding-bottom: .25em;
-}
-
-thead th:not(:first-child) {
- writing-mode: vertical-rl;
- transform: rotate(180deg);
- white-space: normal;
- text-align: start;
- max-height: 11.5em;
- max-width: 5em;
- overflow-wrap: break-word;
- word-break: break-word;
-}
-
-/* Force cell A1 to shrink so date falls to second line. */
-thead th:first-child {
- white-space: normal;
- overflow-wrap: break-word;
- word-break: break-word;
- padding-left: 5em;
- padding-right: 5em;
- text-align: center;
- max-width: 5em;
- box-sizing: border-box;
-}
-
-tbody td:not(:first-child) {
- text-align: center;
-}
-
-tbody tr:nth-child(even) {
- background-color: rgba(0, 0, 0, .25);
-}
-
-tbody tr:last-child td {
- font-weight: bold;
- border-top: 1px solid;
-}
-
-div.byline {
- font-size: 10pt;
-}
-</style>
-<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta content="1754" name="count"/><title>Text format feature matrix</title></head><body><h1 id="markdown">Markdown</h1>
-<div class="byline">
-<p>Dave Jarvis, Aug 25, 2025</p>
-</div>
-<p>Markdown is a versatile plain text document format. The following documents
-were written using (or converted to) CommonMark and pandoc’s fenced div syntax,
-then typeset using <a href="https://wiki.contextgarden.net">ConTeXt</a>:</p>
-<ul>
-<li><a href="https://impacts.to/downloads/lowres/impacts.pdf">Impacts</a></li>
-<li><a href="pdf/autónoma.pdf">autónoma</a> (first page intentionally blank)</li>
-<li><a href="pdf/software-design.pdf">Software Design</a></li>
-<li><a href="pdf/jekyll-hyde.pdf">Dr. Jekyll and Mr. Hyde</a></li>
-<li><a href="pdf/last-will-and-testament.pdf">Last Will and Testament</a></li>
-</ul>
-<p>The purpose of this page is to help dispel the notion that Markdown is inferior
-to other text formats for technical documentation. Rather, they each have their
-own strengths and weaknesses. The table provides an objective way to evaluate
-formats for specific needs. Keep in mind that tools such as pandoc can do a
-terrific job at converting between formats.</p>
-<p>Full disclosure: I developed KeenWrite, a desktop Markdown editor and
-command-line application. While the feature matrix is fairly comprehensive, if
-you spot a critical omission, <a href="/contact.shtml">contact me</a>.</p>
-<p>The <a href="matrix.ods">downloadable</a> feature matrix is an unweighted comparison of
-various plain text systems:</p>
-<p>
-</p><table>
-<thead>
-<tr><th align="left">Feature matrix 24-AUG-2025</th><th align="left">KeenWrite</th><th align="left">KeenWrite / ConTeXt</th><th align="left">KeenWrite / ConTeXt / R Markdown</th><th align="left">AsciiDoc</th><th align="left">AsciiDoc / extensions</th><th align="left">reStructuredText</th><th align="left">Sphinx</th><th align="left">pandoc</th><th align="left">pandoc / LaTeX</th><th align="left">pandoc / extensions / LaTeX</th><th align="left">pandoc / extensions / LaTeX</th><th align="left">pandoc / extensions / LaTeX / knitr</th></tr>
-</thead>
-<tbody>
-<tr><td align="left">Turing complete</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Language, R</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td></tr>
-<tr><td align="left">Data plots, inline</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td></tr>
-<tr><td align="left">Tables</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Tables, nested</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Math, SVG</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Math, KaTeX (HTML)</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Math, MathJax (HTML)</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Math, PDF</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Variables (attributes)</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Variables, interpolated</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Diagrams, text-based</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Diagrams, variables, interoplated</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Diagrams, Mermaid, raster, PDF</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Diagrams, Mermaid, vector, PDF</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Diagrams, Mermaid, HTML</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Images</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Images, dimensions</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Captions, table</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Captions, image</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Captions, equation</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Captions, code block</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Captions, consistency</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Cross-references, section</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Cross-references, table</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Cross-references, figure</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Cross-references, equation</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Cross-references, custom</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Bibliographic references (citations)</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Metadata</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Metadata, external</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Metadata, editor-integrated</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Content, external</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Content, conditional</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td></tr>
-<tr><td align="left">JSON parsing</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td></tr>
-<tr><td align="left">Export, plain text</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Export, XHTML</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Export, PDF</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Export, PDF, Knuth–Plass</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Custom containers (annotations, roles)</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Interface, command-line</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Interface, graphical (with preview)</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Curls quotation marks, natural</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Curls quotation marks, contextual</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Curls quotation marks, comprehensive</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Collate chapters</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Content / presentation separation</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Widespread syntax knowledge</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Community support</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Unicode</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Accessible HTML</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Glossary generator</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Footnotes</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Endnotes</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, colour</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, underline</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Text, overline</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Text, ligatures</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, hyperlink</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, superscripts</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, subscripts</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, strikethrough</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, strong</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, emphasis</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, monospace</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, inline nesting</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, inline styling</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, quotation blocks</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, quotation blocks, nested</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, description lists</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, code blocks</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, code blocks, language</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, dashes, en --</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, dashes, em ---</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, ellipses …</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, arrows -&gt; =&gt; &lt;= &lt;-</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Text, (C) (R) (TM)</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
-<tr><td align="left">Text, entities, numeric</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, entities, named</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Text, non-breaking spaces</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
-<tr><td align="left">Total</td><td align="left">50</td><td align="left">59</td><td align="left">63</td><td align="left">48</td><td align="left">59</td><td align="left">40</td><td align="left">51</td><td align="left">36</td><td align="left">42</td><td align="left">53</td><td align="left">53</td><td align="left">57</td></tr>
-</tbody>
-</table>
-<p/>
-<h2 id="breakdown">Breakdown</h2>
-<p>This section clarifies select features from the matrix.</p>
-<h3 id="turing-complete">Turing complete</h3>
-<p>The <strong>Turing complete</strong> row indicates whether the format may contain executable
-instructions for general computation. For technical documentation, dynamic
-functionality to retrieve information helps avoid publishing outdated
-information by single sourcing data.</p>
-<h3 id="language-r">Language, R</h3>
-<p>The <strong>Language, R</strong> row denotes that the format supports the R programming
-language.</p>
-<h3 id="variables-interpolated">Variables, interpolated</h3>
-<p>The <strong>Variables, interpolated</strong> row indicates that a variable value may
-reference variable names. When the output document is created, the references
-are replaced with the actual value, recursively, before embedding into the
-output document. For example:</p>
-<pre><code class="language-yaml">protagonist:
- name:
- given: Ada
- surname: Lovelace
- full: {{protagonist.name.given}} {{protagonist.name.surname}}
-</code></pre>
-<p>Here, <code>{{protagonist.name.full}}</code> resolves to “Ada Lovelace”.</p>
-<h3 id="diagrams-text-based">Diagrams, text-based</h3>
-<p>The <strong>Diagrams, text-based</strong> row declares whether the format allows
-marking up instructions for drawing a diagram, technical or otherwise.</p>
-<h3 id="diagrams-variables-interpolated">Diagrams, variables, interpolated</h3>
-<p>The <strong>Diagrams, variables, interpolated</strong> row means embedding interpolated
-variables into diagrams. For example, a genealogy diagram could include family
-names from an externally defined character sheet:</p>
-<pre><code>``` diagram-blockdiag
-blockdiag {
- orientation = portrait
-
- group {
- {{protagonist.mother.name.given}}
- {{protagonist.father.name.given}}
- }
- {{protagonist.name.given}}
-
- {{protagonist.mother.name.given}} -&gt; {{protagonist.name.given}}
- {{protagonist.father.name.given}} -&gt; {{protagonist.name.given}}
-}
-```
-</code></pre>
-<h3 id="diagrams-mermaid">Diagrams, Mermaid</h3>
-<p>The <strong>Diagrams, Mermaid</strong> rows signify various aspects of exporting diagrams
-coded using the text-based Mermaid syntax.</p>
-<ul>
-<li><strong>Raster</strong> -- Diagrams render as pixel-based images.</li>
-<li><strong>Vector</strong> -- Diagrams convert to SVG-compliant images.</li>
-</ul>
-<p>At time of writing, Mermaid diagrams produce scalable vector graphics (SVG)
-that cannot be rendered by numerous vector graphics drawing programs and
-libraries. Mermaid uses <code>&lt;foreignObject&gt;</code> to leverage features found in web
-browsers, which was a poor technical choice in my opinion. Both PlantUML and
-GraphViz can produce equally complex, yet standards-compliant SVG documents.</p>
-<p>To render Mermaid diagrams in AsciiDoc, a headless browser extension must be
-installed. AsciiDoctor launches the browser to draw the diagram. While this is
-a pragmatic solution, it has drawbacks.</p>
-<h3 id="images-dimensions">Images, dimensions</h3>
-<p>The <strong>Images, dimensions</strong> row captures the ability to resize images in the
-output document. Setting image dimensions in documents is mixing presentation
-logic with content; however, converting documents into HTML often leaves no
-solution because CSS cannot target specific images (without classes or IDs).</p>
-<p>A pandoc extension to CommonMark allows specifying image dimensions:</p>
-<pre><code class="language-md">![kitten](kitten.jpg){width=300}
-![kitten](kitten.jpg){#id .class width=300}
-</code></pre>
-<p>Similarly, fenced code blocks support attributes:</p>
-<pre><code>``` diagram-plantuml { width=400px }
-```
-</code></pre>
-<p>In ConTeXt, figures can be resized by name using a macro:</p>
-<pre><code class="language-tex">\defineexternalfigure[filename.ext][width=..., height=...]
-</code></pre>
-<h3 id="captions-consistency">Captions, consistency</h3>
-<p>The <strong>Captions, consistency</strong> row notes whether the syntax for captions is
-consistent across elements being captioned. KeenWrite supports a double-colon
-syntax for captions, where the caption comes after the element being captioned.
-Consider the following text:</p>
-<pre><code class="language-markdown">| Header | Header |
-|--------|--------|
-| Value | Value |
-
-:: Table caption
-
-![alt text](logo.svg)
-
-:: Image caption
-
-$$E=mc^2$$
-
-:: Equation caption
-</code></pre>
-<p>The blank lines before each caption are mandatory. Sample output:</p>
-<p><img alt="document captions" src="captions.png"/></p>
-<p>This syntax provided by KeenWrite is a CommonMark extension and diverges
-slightly from pandoc.</p>
-<h3 id="cross-references">Cross-references</h3>
-<p>The <strong>Cross-references</strong> rows refer to built-in directives for referencing
-items in the document. If the cross-reference syntax for a text format requires
-a specific typesetting system, it is marked as <code>N</code>. If the syntax is
-independent of a typesetting system, but requires an external typesetter to
-produce linked cross-reference, it is marked as <code>Y</code>.</p>
-<p>Many formats have a fixed set of cross-references. Beyond figures, tables,
-equations, and sections are algorithms, musical scores, lyrics, source
-listings, and more. If users can add and refer to their own cross-reference
-labels, including internationalized ones, the <strong>Cross-references, custom</strong>
-row is marked with a <code>Y</code>.</p>
-<p>Existing Markdown implementations have fairly similar syntaxes for
-cross-references and citations. KeenWrite uses a cross-reference syntax that is
-based on pandoc’s crossref package.</p>
-<ul>
-<li><code>{@label:id}</code> -- Defines an anchor for user-defined identifier.</li>
-<li><code>[@label:id]</code> -- Inserts a hyperlink to the associated identifier.</li>
-</ul>
-<p>The identifiers must be unique.</p>
-<p>Chapters and sections are automatically named based on the title text by
-converting the title to lowercase and replacing spaces with hyphens.</p>
-<pre><code class="language-md"># Chapter name
-
-[@tbl:table-name] in [@sec:chapter-name] lists famous characters.
-
-:: Table name {#tbl:table-name}
-</code></pre>
-<h3 id="metadata-external">Metadata, external</h3>
-<p>The <strong>Metadata, external</strong> row indicates whether document metadata (such as
-author, book title, publication year) can exist in an external file, allowing
-it to be reused across separate chapter files. In many cases, it is possible to
-concatenate the metadata source to the top of the chapter to process. If the
-system can apply metadata to documents without extra tooling, it is marked as a
-<code>Y</code>.</p>
-<h3 id="curls-quotation-marks-comprehensive">Curls quotation marks, comprehensive</h3>
-<p>The <strong>Curls quotations marks, comprehensive</strong> row describes systems that
-properly format quotation marks. Phrases such as “fish ’n’ chips,” “’Bout that
-time I says, ‘Boys! I been thinkin’ ’bout th’ Universe,’” or quotations that
-span multiple paragraphs must be curled.</p>
-<p>KeenWrite integrates KeenQuotes, a natural language parsing library that can
-determine how to format single quotation marks, double quotes, contractions,
-and mark primes. Systems must pass KeenQuote’s test suite using naturally
-entered quotation marks (i.e., " and ') to be marked as a <code>Y</code>.</p>
-<h3 id="collate-chapters">Collate chapters</h3>
-<p>The <strong>Collate chapters</strong> row describes whether individual document files---in
-the same directory---can be combined into a single work using built-in tooling
-without requiring them to reference each other. This approach, where a program
-handles the collation (e.g., via a command-line utility), simplifies the
-process and avoids a maintenance burden when adding or removing chapters. File
-systems are well-suited for grouping files. For example:</p>
-<pre><code class="language-bash">keenwrite.bin \
- --all \
- --chapters="1-12,15,19-" \
- -i chapter-01.md \
- -o user-guide.pdf ...
-</code></pre>
-<h3 id="text">Text</h3>
-<p>The <strong>Text</strong> rows refer to built-in directives. If the syntax does not offer
-built-in functionality, it is marked as <code>N</code>, regardless of whether extensions
-support it.</p>
-<p>Note that <strong>Text, colour</strong> mixes content (what is written) and presentation
-(how the writing appears), and is therefore unsupported by KeenWrite.</p>
-<p><strong>Text, underline</strong> is also unsupported by KeenWrite. Historically,
-underlining was developed to compensate for shortcomings in early typewriter
-technology. Namely, a lack of bold or italics. If users ache for that newsstand
-tabloid feel, they’ll need to look elsewhere.</p>
-<h1 id="diagram-code-blocks">Diagram code blocks</h1>
-<p>KeenWrite distinguishes between diagrams and source code listings by prefixing
-diagrams with a <code>diagram-</code> prefix, such as:</p>
-<pre><code>``` diagram-plantuml
-@startuml
-Alice -&gt; Bob: Hello
-@enduml
-```
-</code></pre>
-<p>This has a few benefits. First, it allows rendering diagram types using a
-service without having to codify all possible diagram types. Second, when a new
-type of diagram is added, it’s available immediately without needing to upgrade
-the text editor. Third, it clearly distinguishes between a code block to be
-rendered visually and one to be listed as verbatim source code.</p>
-<p>Typically, source code is presented in code blocks that include the language
-name so that syntax highlighting can be applied:</p>
-<pre><code>``` c
-main() {
- printf( "hello, world" );
-}
-```
-</code></pre>
-<p>GitHub created a <em>de facto</em> standard that prevents parsers from dynamically
-distinguishing between a diagram to render and source code to list. The
-following fenced code block could be either a source code listing or a pie
-chart:</p>
-<pre><code>``` mermaid
-pie
- title Turkish Empire Proportions, 1789
- "Asia" : 66
- "Africa" : 20
- "Europe" : 14
-```
-</code></pre>
-<p>While <code>mermaid-lang</code> could help, it creates a special case that needs to be
-programmed into Markdown parsers. KeenWrite’s <code>diagram-</code> prefix side-steps the
-issue while keeping true to the human-readability nature of Markdown. For this
-reason, using <code>mermaid</code> alone for a fenced code block will list the code.</p>
-<h1 id="history">History</h1>
-<p>John Gruber created Markdown based on decades of syntax conventions that had
-evolved in email, mailing lists, Usenet newsgroups, and elsewhere. His original
-goal was to make a text format that could be easily converted to HTML while
-remaining human-readable. So one writes <code>*emphasis*</code> instead of
-<code>&lt;em&gt;emphasis&lt;/em&gt;</code>. Gruber released a specification alongside a script that
-converts a Markdown document into valid HTML.</p>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html lang="en" xmlns="http://www.w3.org/1999/xhtml"><head><meta content="width=device-width, initial-scale=1.0" name="viewport"/><meta content="cross-platform, open-source desktop editor" name="description"/><meta content="markdown, text, editor, software" name="keywords"/><meta content="index, follow" name="robots"/><meta content="default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self';" http-equiv="Content-Security-Policy"/><link href="/styles/base.css" rel="stylesheet"/><style type="text/css">
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(‘/fonts/PlayfairDisplay-Regular.ttf') format(‘truetype’);
+ font-weight: 400; /* Regular */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(’/fonts/PlayfairDisplay-Italic.ttf') format(‘truetype’);
+ font-weight: 400; /* Regular */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(‘/fonts/PlayfairDisplay-Medium.ttf') format(‘truetype’);
+ font-weight: 500; /* Medium */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(’/fonts/PlayfairDisplay-MediumItalic.ttf') format(‘truetype’);
+ font-weight: 500; /* Medium */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(‘/fonts/PlayfairDisplay-SemiBold.ttf') format(‘truetype’);
+ font-weight: 600; /* SemiBold */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(’/fonts/PlayfairDisplay-SemiBoldItalic.ttf') format(‘truetype’);
+ font-weight: 600; /* SemiBold */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(‘/fonts/PlayfairDisplay-Bold.ttf') format(‘truetype’);
+ font-weight: 700; /* Bold */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(’/fonts/PlayfairDisplay-BoldItalic.ttf') format(‘truetype’);
+ font-weight: 700; /* Bold */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(‘/fonts/PlayfairDisplay-ExtraBold.ttf') format(‘truetype’);
+ font-weight: 800; /* ExtraBold */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(’/fonts/PlayfairDisplay-ExtraBoldItalic.ttf') format(‘truetype’);
+ font-weight: 800; /* ExtraBold */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(‘/fonts/PlayfairDisplay-Black.ttf') format(‘truetype’);
+ font-weight: 900; /* Black */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Playfair Display’;
+ src: url(’/fonts/PlayfairDisplay-BlackItalic.ttf') format(‘truetype’);
+ font-weight: 900; /* Black */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Lato’;
+ src: url(‘/fonts/Lato-Thin.ttf') format(‘truetype’);
+ font-weight: 100; /* Thin */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Lato’;
+ src: url(’/fonts/Lato-ThinItalic.ttf') format(‘truetype’);
+ font-weight: 100; /* Thin */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Lato’;
+ src: url(‘/fonts/Lato-Light.ttf') format(‘truetype’);
+ font-weight: 300; /* Light */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Lato’;
+ src: url(’/fonts/Lato-LightItalic.ttf') format(‘truetype’);
+ font-weight: 300; /* Light */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Lato’;
+ src: url(‘/fonts/Lato-Regular.ttf') format(‘truetype’);
+ font-weight: 400; /* Regular */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Lato’;
+ src: url(’/fonts/Lato-Italic.ttf') format(‘truetype’);
+ font-weight: 400; /* Regular */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Lato’;
+ src: url(‘/fonts/Lato-Bold.ttf') format(‘truetype’);
+ font-weight: 700; /* Bold */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Lato’;
+ src: url(’/fonts/Lato-BoldItalic.ttf') format(‘truetype’);
+ font-weight: 700; /* Bold */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Lato’;
+ src: url(‘/fonts/Lato-Black.ttf') format(‘truetype’);
+ font-weight: 900; /* Black */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘Lato’;
+ src: url(’/fonts/Lato-BlackItalic.ttf') format(‘truetype’);
+ font-weight: 900; /* Black */
+ font-style: italic;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘FiraCode’;
+ src: url(‘/fonts/FiraCode-Light.ttf') format(‘truetype’);
+ font-weight: 300; /* Light */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘FiraCode’;
+ src: url(’/fonts/FiraCode-Regular.ttf') format(‘truetype’);
+ font-weight: 400; /* Regular */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘FiraCode’;
+ src: url(‘/fonts/FiraCode-Medium.ttf') format(‘truetype’);
+ font-weight: 500; /* Medium */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘FiraCode’;
+ src: url(’/fonts/FiraCode-SemiBold.ttf') format(‘truetype’);
+ font-weight: 600; /* SemiBold */
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: ‘FiraCode’;
+ src: url(‘/fonts/FiraCode-Bold.ttf’) format(‘truetype’);
+ font-weight: 700; /* Bold */
+ font-style: normal;
+ font-display: swap;
+}
+
+body {
+ font-family: ‘Literata Book’, serif;
+ line-height: 1.4;
+}
+
+h1, h2, h3, table {
+ font-family: ‘Lato’, sans-serif;
+}
+
+pre, code {
+ font-family: ‘FiraCode’, monospace;
+ color: #9CDE9F;
+}
+
+pre {
+ padding-left: 2em;
+ word-wrap: normal;
+}
+
+code {
+ white-space: nowrap;
+}
+
+pre code {
+ white-space: pre;
+}
+
+img {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table {
+ margin: 0 auto;
+ border-collapse: collapse;
+}
+
+thead {
+ background-color: #126d95;
+ position: sticky;
+ top: 0px;
+}
+
+th, td {
+ padding: 0 0.5em;
+}
+
+th {
+ padding-top: .25em;
+ padding-bottom: .25em;
+}
+
+thead th:not(:first-child) {
+ writing-mode: vertical-rl;
+ transform: rotate(180deg);
+ white-space: normal;
+ text-align: start;
+ max-height: 11.5em;
+ max-width: 5em;
+ overflow-wrap: break-word;
+ word-break: break-word;
+}
+
+/* Force cell A1 to shrink so date falls to second line. */
+thead th:first-child {
+ white-space: normal;
+ overflow-wrap: break-word;
+ word-break: break-word;
+ padding-left: 5em;
+ padding-right: 5em;
+ text-align: center;
+ max-width: 5em;
+ box-sizing: border-box;
+}
+
+tbody td:not(:first-child) {
+ text-align: center;
+}
+
+tbody tr:nth-child(even) {
+ background-color: rgba(0, 0, 0, .25);
+}
+
+tbody tr:last-child td {
+ font-weight: bold;
+ border-top: 1px solid;
+}
+
+div.byline {
+ font-size: 10pt;
+}
+</style><meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/><meta content="2399" name="count"/><title>Text format feature matrix</title></head><body><h1 id="text-format-feature-matrix">Text format feature matrix</h1>
+<div class="byline">
+<p>Dave Jarvis — August 26, 2025</p>
+</div>
+<p>Markdown is a versatile plain text document format. The following documents
+were written using (or converted to) CommonMark and pandoc’s fenced div syntax,
+then typeset using <a href="https://wiki.contextgarden.net">ConTeXt</a>:</p>
+<ul>
+<li><a href="https://impacts.to/downloads/lowres/impacts.pdf">Impacts</a></li>
+<li><a href="pdf/autónoma.pdf">autónoma</a> (first page intentionally blank)</li>
+<li><a href="pdf/software-design.pdf">Software Design</a></li>
+<li><a href="pdf/jekyll-hyde.pdf">Dr. Jekyll and Mr. Hyde</a></li>
+<li><a href="pdf/last-will-and-testament.pdf">Last Will and Testament</a></li>
+</ul>
+<p>The purpose of this page is to help dispel the notion that Markdown is inferior
+to other text formats for technical documentation. Rather, they each have their
+own strengths and weaknesses. The matrix provides an objective way to evaluate
+formats for specific needs. Keep in mind that tools such as pandoc can do a
+terrific job at converting between formats.</p>
+<p>Full disclosure: I developed KeenWrite, a desktop Markdown editor and
+command-line application. While the feature matrix is fairly comprehensive, if
+you spot a critical omission, <a href="/contact.shtml">contact me</a>.</p>
+<p>The <a href="matrix.ods">downloadable</a> feature matrix is an unweighted comparison of
+various plain text systems:</p>
+<p>
+</p><table>
+<thead>
+<tr><th align="left">Feature matrix 26-AUG-2025</th><th align="left">KeenWrite</th><th align="left">KeenWrite / ConTeXt</th><th align="left">KeenWrite / ConTeXt / R Markdown</th><th align="left">AsciiDoc</th><th align="left">AsciiDoc / extensions</th><th align="left">reStructuredText</th><th align="left">Sphinx</th><th align="left">pandoc</th><th align="left">pandoc / LaTeX</th><th align="left">pandoc / extensions / LaTeX</th><th align="left">pandoc / extensions / LaTeX</th><th align="left">pandoc / extensions / LaTeX / knitr</th></tr>
+</thead>
+<tbody>
+<tr><td align="left">Turing complete</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Language, R</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td></tr>
+<tr><td align="left">Data plots, inline</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td></tr>
+<tr><td align="left">Tables</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Tables, nested</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Math, SVG</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Math, KaTeX (HTML)</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Math, MathJax (HTML)</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Math, PDF</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Variables (attributes)</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Variables, interpolated</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Diagrams, text-based</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Diagrams, variables, interoplated</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Diagrams, Mermaid, raster, PDF</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Diagrams, Mermaid, vector, PDF</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Diagrams, Mermaid, HTML</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Images</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Images, dimensions</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Captions, table</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Captions, image</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Captions, equation</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Captions, code block</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Captions, consistency</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Cross-references, section</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Cross-references, table</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Cross-references, figure</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Cross-references, equation</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Cross-references, custom</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Bibliographic references (citations)</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Metadata</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Metadata, external</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Metadata, editor-integrated</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Content, external</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Content, conditional</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td></tr>
+<tr><td align="left">JSON parsing</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td></tr>
+<tr><td align="left">Export, plain text</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Export, XHTML</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Export, PDF</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Export, PDF, Knuth–Plass</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Custom containers (annotations, roles)</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Interface, command-line</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Interface, graphical (with preview)</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Curls quotation marks, natural</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Curls quotation marks, contextual</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Curls quotation marks, comprehensive</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Collate chapters</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Content / presentation separation</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Widespread syntax knowledge</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Community support</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Unicode</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Accessible HTML</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Glossary generator</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Footnotes</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Endnotes</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, colour</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, underline</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Text, overline</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Text, ligatures</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, hyperlink</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, superscripts</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, subscripts</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, strikethrough</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, strong</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, emphasis</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, monospace</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, inline nesting</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, inline styling</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, quotation blocks</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, quotation blocks, nested</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, description lists</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, code blocks</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, code blocks, language</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, dashes, en --</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, dashes, em ---</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, ellipses …</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, arrows -&gt; =&gt; &lt;= &lt;-</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Text, (C) (R) (TM)</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td></tr>
+<tr><td align="left">Text, entities, numeric</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, entities, named</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Text, non-breaking spaces</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">N</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td><td align="left">Y</td></tr>
+<tr><td align="left">Total</td><td align="left">50</td><td align="left">59</td><td align="left">63</td><td align="left">48</td><td align="left">57</td><td align="left">40</td><td align="left">51</td><td align="left">36</td><td align="left">42</td><td align="left">53</td><td align="left">53</td><td align="left">57</td></tr>
+</tbody>
+</table>
+<p/>
+<h2 id="breakdown">Breakdown</h2>
+<p>This section clarifies select features from the matrix.</p>
+<h3 id="turing-complete">Turing complete</h3>
+<p>The <strong>Turing complete</strong> row indicates whether the format may contain executable
+instructions for general computation. For technical documentation, dynamic
+functionality to retrieve information helps avoid publishing outdated
+information by single sourcing data.</p>
+<h3 id="language-r">Language, R</h3>
+<p>The <strong>Language, R</strong> row denotes that the format supports the R programming
+language. We could list additional languages, such as Python and Ruby, but
+the list is extensive.</p>
+<h3 id="variables-interpolated">Variables, interpolated</h3>
+<p>The <strong>Variables, interpolated</strong> row indicates that a variable value may
+reference variable names. When the output document is created, the references
+are replaced with the actual value, recursively, before embedding into the
+output document. For example:</p>
+<pre><code class="language-yaml">protagonist:
+ name:
+ given: Ada
+ surname: Lovelace
+ full: {{protagonist.name.given}} {{protagonist.name.surname}}
+</code></pre>
+<p>Here, <code>{{protagonist.name.full}}</code> resolves to “Ada Lovelace”.</p>
+<h3 id="diagrams-text-based">Diagrams, text-based</h3>
+<p>The <strong>Diagrams, text-based</strong> row declares whether the format allows
+marking up instructions for drawing a diagram, technical or otherwise.</p>
+<h3 id="diagrams-variables-interpolated">Diagrams, variables, interpolated</h3>
+<p>The <strong>Diagrams, variables, interpolated</strong> row means embedding interpolated
+variables into diagrams. For example, a genealogy diagram could include family
+names from an externally defined character sheet:</p>
+<pre><code>``` diagram-blockdiag
+blockdiag {
+ orientation = portrait
+
+ group {
+ {{protagonist.mother.name.given}}
+ {{protagonist.father.name.given}}
+ }
+ {{protagonist.name.given}}
+
+ {{protagonist.mother.name.given}} -&gt; {{protagonist.name.given}}
+ {{protagonist.father.name.given}} -&gt; {{protagonist.name.given}}
+}
+```
+</code></pre>
+<h3 id="diagrams-mermaid">Diagrams, Mermaid</h3>
+<p>The <strong>Diagrams, Mermaid</strong> rows signify various aspects of exporting diagrams
+coded using the text-based Mermaid syntax.</p>
+<ul>
+<li><strong>Raster</strong> -- Diagrams render as pixel-based images.</li>
+<li><strong>Vector</strong> -- Diagrams convert to SVG-compliant images.</li>
+</ul>
+<p>At time of writing, Mermaid diagrams produce scalable vector graphics (SVG)
+that cannot be rendered by numerous vector graphics drawing programs and
+libraries outside of a web browser environment. Mermaid uses <code>&lt;foreignObject&gt;</code>
+to leverage features found in browsers, which was a poor technical choice in my
+opinion. Both PlantUML and GraphViz can produce equally complex, yet
+standards-compliant SVG documents.</p>
+<p>To render Mermaid diagrams in AsciiDoc, a headless browser extension must be
+installed. AsciiDoctor launches the browser to draw the diagram. While this is
+a pragmatic solution, it has drawbacks.</p>
+<h3 id="images-dimensions">Images, dimensions</h3>
+<p>The <strong>Images, dimensions</strong> row captures the ability to resize images in the
+output document. Setting image dimensions in documents is mixing presentation
+logic with content; however, converting documents into HTML often leaves no
+solution because CSS cannot target specific images (without classes or IDs).</p>
+<p>A pandoc extension to CommonMark allows specifying image dimensions:</p>
+<pre><code class="language-md">![kitten](kitten.jpg){width=300}
+![kitten](kitten.jpg){#id .class width=300}
+</code></pre>
+<p>Similarly, fenced code blocks support attributes:</p>
+<pre><code>``` diagram-plantuml { width=400px }
+```
+</code></pre>
+<p>In ConTeXt, figures can be resized by name using a macro:</p>
+<pre><code class="language-tex">\defineexternalfigure[filename.ext][width=..., height=...]
+</code></pre>
+<h3 id="captions-consistency">Captions, consistency</h3>
+<p>The <strong>Captions, consistency</strong> row notes whether the syntax for captions is
+consistent across elements being captioned. KeenWrite supports a double-colon
+syntax for captions, where the caption comes after the element being captioned
+is separated by a mandatory blank line. Consider the following text:</p>
+<pre><code class="language-markdown">| Header | Header |
+|--------|--------|
+| Value | Value |
+
+:: Table caption
+
+![alt text](logo.svg)
+
+:: Image caption
+
+$$E=mc^2$$
+
+:: Equation caption
+</code></pre>
+<p>Sample output:</p>
+<p><img alt="document captions" src="captions.png"/></p>
+<p>This syntax provided by KeenWrite is a CommonMark extension and diverges
+slightly from pandoc.</p>
+<h3 id="cross-references">Cross-references</h3>
+<p>The <strong>Cross-references</strong> rows refer to built-in directives for referencing
+items in the document. If the cross-reference syntax for a text format requires
+a specific typesetting system, it is marked as <code>N</code>. If the syntax is
+independent of a typesetting system, but requires an external typesetter to
+produce linked cross-reference, it is marked as <code>Y</code>.</p>
+<p>Many formats have a fixed set of cross-references. Beyond figures, tables,
+equations, and sections are algorithms, musical scores, lyrics, source
+listings, and more. If users can add and refer to their own cross-reference
+labels, including internationalized ones, the <strong>Cross-references, custom</strong>
+row is marked with a <code>Y</code>.</p>
+<p>Existing Markdown implementations have fairly similar syntaxes for
+cross-references and citations. KeenWrite uses a cross-reference syntax that is
+based on pandoc’s crossref package.</p>
+<ul>
+<li><code>{@label:id}</code> -- Defines an anchor for user-defined identifier.</li>
+<li><code>[@label:id]</code> -- Inserts a hyperlink to the associated identifier.</li>
+</ul>
+<p>The identifiers must be unique.</p>
+<p>Chapters and sections are automatically named based on the title text by
+converting the title to lowercase and replacing spaces with hyphens. To wit:</p>
+<pre><code class="language-md"># Chapter name
+
+[@tbl:table-name] in [@sec:chapter-name] lists famous characters.
+
+:: Table name {#tbl:table-name}
+</code></pre>
+<h3 id="metadata-external">Metadata, external</h3>
+<p>The <strong>Metadata, external</strong> row indicates whether document metadata (such as
+author, book title, publication year) can exist in an external file, allowing
+it to be reused in other contexts. For arbitrarily defined variables, if the
+system can inject them into documents without extra tooling, it is marked as
+<code>Y</code>.</p>
+<h3 id="curls-quotation-marks-comprehensive">Curls quotation marks, comprehensive</h3>
+<p>The <strong>Curls quotations marks, comprehensive</strong> row describes systems that
+properly format quotation marks. Phrases such as “fish ’n’ chips,” “’Bout that
+time I says, ‘Boys! I been thinkin’ ’bout th’ Universe,’” or quotations that
+span multiple paragraphs must be curled.</p>
+<p>KeenWrite integrates KeenQuotes, a natural language parsing library that can
+determine how to format single quotation marks, double quotes, contractions,
+and mark primes. Systems must pass KeenQuote’s test suite using naturally
+entered quotation marks (i.e., " and ') to be marked as <code>Y</code>.</p>
+<h3 id="collate-chapters">Collate chapters</h3>
+<p>The <strong>Collate chapters</strong> row describes whether individual document files---in
+the same directory---can be combined into a single work using built-in tooling
+without requiring them to reference each other. This approach, where a program
+handles the collation (e.g., via a command-line utility), simplifies the
+process and avoids a maintenance burden when adding or removing chapters. File
+systems are well-suited for grouping files. For example:</p>
+<pre><code class="language-bash">keenwrite.bin \
+ --all \
+ --chapters="1-12,15,19-" \
+ -i chapter-01.md \
+ -o user-guide.pdf ...
+</code></pre>
+<h3 id="text">Text</h3>
+<p>The <strong>Text</strong> rows refer to built-in directives. If the syntax does not offer
+built-in functionality, it is marked as <code>N</code>, regardless of whether extensions
+support it.</p>
+<p>Note that <strong>Text, colour</strong> mixes content (what is written) and presentation
+(how the writing appears), and is therefore unsupported by KeenWrite.</p>
+<p><strong>Text, underline</strong> is also unsupported by KeenWrite. Historically, underlining
+was developed to compensate for shortcomings in early typewriter technology.
+Namely, a lack of bold or italics. If users ache for that newsstand tabloid
+feel, they’ll need to look elsewhere.</p>
+<h1 id="diagram-code-blocks">Diagram code blocks</h1>
+<p>KeenWrite distinguishes between diagrams and source code listings by prefixing
+diagrams with a <code>diagram-</code> prefix, such as:</p>
+<pre><code>``` diagram-plantuml
+@startuml
+Alice -&gt; Bob: Hello
+@enduml
+```
+</code></pre>
+<p>This has a few benefits. First, it allows rendering diagram types using a
+service without having to codify all possible diagram types. Second, when a new
+type of diagram is added, it’s available immediately without needing to upgrade
+the text editor. Third, it clearly distinguishes between a code block to be
+rendered visually and one to be listed as verbatim source code.</p>
+<p>Typically, source code is presented in code blocks that include the language
+name so that syntax highlighting can be applied:</p>
+<pre><code>``` c
+main() {
+ printf( "hello, world" );
+}
+```
+</code></pre>
+<p>GitHub created a <em>de facto</em> standard that prevents parsers from dynamically
+distinguishing between a diagram to render and source code to list. The
+following fenced code block could be either a source code listing or a pie
+chart:</p>
+<pre><code>``` mermaid
+pie
+ title Turkish Empire Proportions, 1789
+ "Asia" : 66
+ "Africa" : 20
+ "Europe" : 14
+```
+</code></pre>
+<p>While <code>mermaid-lang</code> could help, it creates a special case that needs to be
+programmed into Markdown parsers. KeenWrite’s <code>diagram-</code> prefix side-steps the
+issue while keeping true to the human-readability nature of Markdown. For this
+reason, using <code>mermaid</code> alone for a fenced code block will list the code.</p>
+<h1 id="history">History</h1>
+<p>John Gruber created Markdown based on decades of syntax conventions that had
+evolved in email, mailing lists, Usenet newsgroups, and elsewhere. His original
+goal was to make a text format that could be easily converted to HTML while
+remaining human-readable. Instead of <code>&lt;em&gt;emphasis&lt;/em&gt;</code>, we write
+<code>*emphasis*</code>. Gruber released a specification alongside a script that converts
+a Markdown document into valid HTML.</p>
<p>The format gained popularity among developers, leading to its adoption for project README files, which significantly boosted its widespread use.</p>
<p>However, specification ambiguities resulted in conversion software interpreting edge cases differently. This fragmentation prompted John MacFarlane to spearhead CommonMark, a Markdown standard aimed to eliminate ambiguities.</p>
blog/2025/08/18/feature-matrix/matrix.csv
-Feature matrix 24-AUG-2025,KeenWrite,KeenWrite / ConTeXt,KeenWrite / ConTeXt / R Markdown,AsciiDoc,AsciiDoc / extensions,reStructuredText,Sphinx,pandoc,pandoc / LaTeX,pandoc / extensions / LaTeX,pandoc / extensions / LaTeX,pandoc / extensions / LaTeX / knitr
+Feature matrix 26-AUG-2025,KeenWrite,KeenWrite / ConTeXt,KeenWrite / ConTeXt / R Markdown,AsciiDoc,AsciiDoc / extensions,reStructuredText,Sphinx,pandoc,pandoc / LaTeX,pandoc / extensions / LaTeX,pandoc / extensions / LaTeX,pandoc / extensions / LaTeX / knitr
Turing complete,N,Y,Y,N,Y,N,N,N,Y,Y,Y,Y
"Language, R",N,N,Y,N,N,N,N,N,N,N,N,Y
"Cross-references, table",Y,Y,Y,Y,Y,Y,Y,N,N,Y,Y,Y
"Cross-references, figure",Y,Y,Y,Y,Y,Y,Y,N,N,Y,Y,Y
-"Cross-references, equation",Y,Y,Y,N,Y,Y,Y,N,N,Y,Y,Y
-"Cross-references, custom",N,Y,Y,N,Y,N,N,N,N,N,N,N
+"Cross-references, equation",Y,Y,Y,N,N,Y,Y,N,N,Y,Y,Y
+"Cross-references, custom",N,Y,Y,N,N,N,N,N,N,N,N,N
Bibliographic references (citations),N,N,N,Y,Y,Y,Y,N,N,Y,Y,Y
Metadata,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y
"Text, entities, named",Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y,Y
"Text, non-breaking spaces",N,N,N,N,N,N,N,Y,Y,Y,Y,Y
-Total,50,59,63,48,59,40,51,36,42,53,53,57
+Total,50,59,63,48,57,40,51,36,42,53,53,57
fonts/FiraCode-Bold.ttf
Binary files differ
fonts/FiraCode-Light.ttf
Binary files differ
fonts/FiraCode-Medium.ttf
Binary files differ
fonts/FiraCode-Regular.ttf
Binary files differ
fonts/FiraCode-SemiBold.ttf
Binary files differ
fonts/Lato-Black.ttf
Binary files differ
fonts/Lato-BlackItalic.ttf
Binary files differ
fonts/Lato-Bold.ttf
Binary files differ
fonts/Lato-BoldItalic.ttf
Binary files differ
fonts/Lato-Italic.ttf
Binary files differ
fonts/Lato-Light.ttf
Binary files differ
fonts/Lato-LightItalic.ttf
Binary files differ
fonts/Lato-Regular.ttf
Binary files differ
fonts/Lato-Thin.ttf
Binary files differ
fonts/Lato-ThinItalic.ttf
Binary files differ
fonts/PlayfairDisplay-Black.ttf
Binary files differ
fonts/PlayfairDisplay-BlackItalic.ttf
Binary files differ
fonts/PlayfairDisplay-Bold.ttf
Binary files differ
fonts/PlayfairDisplay-BoldItalic.ttf
Binary files differ
fonts/PlayfairDisplay-ExtraBold.ttf
Binary files differ
fonts/PlayfairDisplay-ExtraBoldItalic.ttf
Binary files differ
fonts/PlayfairDisplay-Italic.ttf
Binary files differ
fonts/PlayfairDisplay-Medium.ttf
Binary files differ
fonts/PlayfairDisplay-MediumItalic.ttf
Binary files differ
fonts/PlayfairDisplay-Regular.ttf
Binary files differ
fonts/PlayfairDisplay-SemiBold.ttf
Binary files differ
fonts/PlayfairDisplay-SemiBoldItalic.ttf
Binary files differ

Adds fonts, updates styles, tweaks content

Author Dave Jarvis <email>
Date 2025-08-26 13:41:56 GMT-0700
Commit 815c049a618ec732b11a65c03e8a83939cd2e452
Parent 05ae63b
Delta 904 lines added, 432 lines removed, 472-line increase