From 76bc77ea6eb72458ea19ab7e4803af66865533c7 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Sat, 27 Aug 2022 03:00:50 +0000
Subject: CTAN sync 202208270300

---
 macros/generic/markdown/markdown.dtx | 2592 +++++++++++++++++++++++++++-------
 1 file changed, 2103 insertions(+), 489 deletions(-)

(limited to 'macros/generic/markdown/markdown.dtx')

diff --git a/macros/generic/markdown/markdown.dtx b/macros/generic/markdown/markdown.dtx
index 0434cf5be6..ec13dced2c 100644
--- a/macros/generic/markdown/markdown.dtx
+++ b/macros/generic/markdown/markdown.dtx
@@ -806,6 +806,21 @@ abbr {
       }%
     },
   },
+  jekyllDataRenderers = {
+    author = {%
+      \gdef\ltd@title@author{#1}%
+      \hypersetup{pdfauthor={#1}}%
+    },
+    title = {%
+      \gdef\ltd@title@title{#1}%
+      \gdef\ltd@title@subtitle{}%
+      \hypersetup{pdftitle={#1}}%
+    },
+    date = {\gdef\ltd@title@date{#1}},
+    email = {\gdef\ltd@title@email{#1}},
+    revision = {\gdef\ltd@title@revision{#1}},
+    url = {\gdef\ltd@title@url{#1}},
+  }
 }
 \renewcommand\markdownLaTeXRendererDirectOrIndirectLink[4]{%
   #1\footnote{See \url{#3}.}}
@@ -838,27 +853,6 @@ abbr {
     dlEnd = {\end{optionlist}},
   }
 }
-\ExplSyntaxOn
-\keys_define:nn
-  { markdown/jekyllData }
-  {
-    author   .code:n =
-      {
-        \gdef\ltd@title@author   { #1 }
-        \hypersetup{ pdfauthor = { #1 } }
-      },
-    title    .code:n =
-      {
-        \gdef\ltd@title@title    { #1 }
-        \gdef\ltd@title@subtitle {    }
-        \hypersetup{ pdftitle  = { #1 } }
-      },
-    date     .code:n = { \gdef\ltd@title@date     { #1 } },
-    email    .code:n = { \gdef\ltd@title@email    { #1 } },
-    revision .code:n = { \gdef\ltd@title@revision { #1 } },
-    url      .code:n = { \gdef\ltd@title@url      { #1 } },
-  }
-\ExplSyntaxOff
 %</latex-themes-witiko-markdown-techdoc>
 %<*manual>
 
@@ -1258,13 +1252,10 @@ local md5 = require("md5")
 %     <#sec:latexyamlmetadata>, and also in the default renderer prototype
 %     for attribute identifiers.
 %
-% \pkg{expl3}
+% \pkg{soulutf8}
 %
-%:    A package that enables the expl3 language from the \LaTeX3 kernel in
-%     \TeX{} Live${}\leq{}2019$. It is used in the default renderer prototypes
-%     for links (see Section <#sec:latexlinks>), \acro{yaml} metadata (see
-%     Section <#sec:latexyamlmetadata>), and in the implementation of
-%     \LaTeX{} themes (see Section <#sec:latexthemesimplementation>).
+%:    A package that is used in the default renderer prototype for
+%     strike-throughs.
 %
 % \end{markdown}
 %  \begin{macrocode}
@@ -2184,7 +2175,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionCacheDir{cache}
+\setupmarkdown[cacheDir = cache]
 \starttext
 \startmarkdown
 Hello *world*!
@@ -2389,8 +2380,11 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionFinalizeCache{true}
-\def\markdownOptionFrozenCacheFileName{cache.tex}
+\setupmarkdown
+  [
+    finalizeCache = yes,
+    frozenCacheFileName = cache.tex,
+  ]
 \starttext
 \startmarkdown
 Hello *world*!
@@ -2410,8 +2404,11 @@ Next, create a new text document `frozen-document.tex` with the following
 content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionFrozenCache{true}
-\def\markdownOptionFrozenCacheFileName{cache.tex}
+\setupmarkdown
+  [
+    frozenCache = yes,
+    frozenCacheFileName = cache.tex,
+  ]
 \starttext
 \startmarkdown
 Hi *world*!
@@ -2631,7 +2628,7 @@ A paragraph.
 > A quote.
 \stopmarkdown
 
-\def\markdownOptionBlankBeforeBlockquote{true}
+\setupmarkdown[blankBeforeBlockquote = yes]
 \startmarkdown
 A paragraph.
 > Not a quote.
@@ -2866,7 +2863,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ```` tex
 \usemodule[t][markdown]
-\def\markdownOptionFencedCode{true}
+\setupmarkdown[fencedCode = yes]
 \starttext
 
 \startmarkdown
@@ -2876,7 +2873,7 @@ A code fence.
 ```
 \stopmarkdown
 
-\def\markdownOptionBlankBeforeCodeFence{true}
+\setupmarkdown[blankBeforeCodeFence = yes]
 \startmarkdown
 A paragraph.
 ```
@@ -3110,7 +3107,7 @@ A heading.
 ==========
 \stopmarkdown
 
-\def\markdownOptionBlankBeforeHeading{true}
+\setupmarkdown[blankBeforeHeading = yes]
 \startmarkdown
 A paragraph.
 Not a heading.
@@ -3335,7 +3332,7 @@ following content:
 > block quote.
 \stopmarkdown
 
-\def\markdownOptionBreakableBlockquotes{true}
+\setupmarkdown[breakableBlockquotes = yes]
 \startmarkdown
 > A block quote.
 
@@ -3751,7 +3748,7 @@ following content:
 ``This is no longer a code span.''
 \stopmarkdown
 
-\def\markdownOptionCodeSpans{false}
+\setupmarkdown[codeSpans = no]
 \startmarkdown
 ``This is a quote.''
 ``This is another quote.''
@@ -3912,7 +3909,7 @@ This is a *transcluded markdown document*.
 Create also a text document named `document.tex` with the following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionContentBlocks{true}
+\setupmarkdown[contentBlocks = yes]
 \definetyping [ConTeXt]
 \setuptyping  [ConTeXt] [option=TEX]
 \starttext
@@ -4071,8 +4068,11 @@ This is a *transcluded markdown document*.
 Create also a text document named `document.tex` with the following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionContentBlocks{true}
-\def\markdownOptionContentBlocksLanguageMap{language-map.json}
+\setupmarkdown
+  [
+    contentBlocks = yes,
+    contentBlocksLanguageMap = language-map.json,
+  ]
 \definetyping [ConTeXt]
 \setuptyping  [ConTeXt] [option=TEX]
 \starttext
@@ -4207,7 +4207,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionDefinitionLists{true}
+\setupmarkdown[definitionLists = yes]
 \starttext
 \startmarkdown
 Term 1
@@ -4446,15 +4446,11 @@ following content:
 ``` tex
 \documentclass{article}
 \usepackage[jekyllData]{markdown}
-\ExplSyntaxOn
-\keys_define:nn
-  { markdown/jekyllData }
-  {
-    name .code:n = { \gdef\name{#1} },
-    age  .code:n = { \gdef\age{#1}  },
-  }
-\ExplSyntaxOff
 \markdownSetup{
+  jekyllDataRenderers = {
+    name = {\gdef\name{#1}},
+    code = {\gdef\age{#1}},
+  },
   renderers = {
     jekyllDataEnd = {\name{} is \age{} years old.},
   }
@@ -4493,6 +4489,106 @@ defaultOptions.expectJekyllData = false
 %</lua,lua-cli>
 %<*manual-options>
 
+#### Option `fancyLists`
+
+`fancyLists` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{fancyLists}{\opt{true}, \opt{false}}
+%
+:    true
+
+     :  Enable the Pandoc fancy list extension:
+
+        ``` md
+        a) first item
+        b) second item
+        c) third item
+        ``````
+
+:    false
+
+     :  Disable the Pandoc fancy list extension.
+
+% \end{markdown}
+% \iffalse
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+```` tex
+\documentclass{article}
+\usepackage{minted}
+\usepackage[fancyLists]{markdown}
+\begin{document}
+\begin{markdown}
+a) first item
+b) second item
+c) third item
+\end{markdown}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex --shell-escape document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> a) first item
+> b) second item
+> c) third item
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+```` tex
+\usemodule[t][markdown]
+\setupmarkdown[fancyLists = yes]
+\starttext
+\startmarkdown
+a) first item
+b) second item
+c) third item
+\stopmarkdown
+\stoptext
+````````
+Next, invoke LuaTeX from the terminal:
+``` sh
+context document.tex
+`````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> a) first item
+> b) second item
+> c) third item
+
+%</manual-options>
+%<*tex>
+% \fi
+%  \begin{macrocode}
+\@@_add_lua_option:nnn
+  { fancyLists }
+  { boolean }
+  { false }
+%    \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli>
+% \fi
+%  \begin{macrocode}
+defaultOptions.fancyLists = false
+%    \end{macrocode}
+% \par
+% \iffalse
+%</lua,lua-cli>
+%<*manual-options>
+
 #### Option `fencedCode`
 
 `fencedCode` (default value: `false`)
@@ -4591,7 +4687,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ```` tex
 \usemodule[t][markdown]
-\def\markdownOptionFencedCode{true}
+\setupmarkdown[fencedCode = yes]
 \definetyping [js]
 \definetyping [html]
 \setuptyping  [html] [option=XML]
@@ -4769,7 +4865,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionFinalizeCache{true}
+\setupmarkdown[finalizeCache = yes]
 \starttext
 \startmarkdown
 Hello *world*!
@@ -4787,7 +4883,7 @@ output file as we requested using the `finalizeCache` option.
 Next, change the content of `document.tex` as follows:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionFrozenCache{true}
+\setupmarkdown[frozenCache = yes]
 \starttext
 \startmarkdown
 Hi *world*!
@@ -4925,7 +5021,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionFootnotes{true}
+\setupmarkdown[footnotes = yes]
 \starttext
 \startmarkdown
 Here is a footnote reference,[^1] and another.[^longnote]
@@ -5181,15 +5277,15 @@ following content:
 \begin{document}
 
 \begin{markdown}
-. Bird
-. McHale
-. Parish
+#. Bird
+#. McHale
+#. Parish
 \end{markdown}
 
 \begin{markdown*}{hashEnumerators}
-. Bird
-. McHale
-. Parish
+#. Bird
+#. McHale
+#. Parish
 \end{markdown*}
 
 \end{document}
@@ -5221,16 +5317,16 @@ following content:
 \starttext
 
 \startmarkdown
-. Bird
-. McHale
-. Parish
+#. Bird
+#. McHale
+#. Parish
 \stopmarkdown
 
-\def\markdownOptionHashEnumerators{true}
+\setupmarkdown[hashEnumerators = yes]
 \startmarkdown
-. Bird
-. McHale
-. Parish
+#. Bird
+#. McHale
+#. Parish
 \stopmarkdown
 
 \stoptext
@@ -5544,7 +5640,7 @@ _There is no <!-- comment --> support._
 _There is no <? HTML instruction ?> support._
 \stopmarkdown
 
-\def\markdownOptionHtml{true}
+\setupmarkdown[html = yes]
 \startmarkdown
 <div>
 *There is block tag support.*
@@ -5763,7 +5859,7 @@ following content:
 $\sqrt{-1}$ *equals* $i$.
 \stopmarkdown
 
-\def\markdownOptionHybrid{true}
+\setupmarkdown[hybrid = yes]
 \startmarkdown
 $\sqrt{-1}$ *equals* $i$.
 \stopmarkdown
@@ -5860,7 +5956,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionInlineFootnotes{true}
+\setupmarkdown[inlineFootnotes = yes]
 \starttext
 \startmarkdown
 Here is an inline note.^[Inlines notes are easier to
@@ -5978,15 +6074,11 @@ following content:
 ``` tex
 \documentclass{article}
 \usepackage[jekyllData]{markdown}
-\ExplSyntaxOn
-\keys_define:nn
-  { markdown/jekyllData }
-  {
-    name .code:n = { \gdef\name{#1} },
-    age  .code:n = { \gdef\age{#1}  },
-  }
-\ExplSyntaxOff
 \markdownSetup{
+  jekyllDataRenderers = {
+    name = {\gdef\name{#1}},
+    code = {\gdef\age{#1}},
+  },
   renderers = {
     jekyllDataEnd = {\name{} is \age{} years old.},
   }
@@ -6017,7 +6109,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionJekyllData{true}
+\setupmarkdown[jekyllData = yes]
 \ExplSyntaxOn
 \keys_define:nn
   { markdown/jekyllData }
@@ -6133,7 +6225,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionPipeTables{true}
+\setupmarkdown[pipeTables = yes]
 \starttext
 \startmarkdown
 | Right | Left | Default | Center |
@@ -6409,14 +6501,9 @@ following content:
 \usemodule[t][markdown]
 \starttext
 
-\def\markdownOptionShiftHeadings{-1}
-\markdownInput{example.md}
-
-\def\markdownOptionShiftHeadings{0}
-\markdownInput{example.md}
-
-\def\markdownOptionShiftHeadings{+1}
-\markdownInput{example.md}
+\inputmarkdown[shiftHeadings = -1]{example.md}
+\inputmarkdown[shiftHeadings =  0]{example.md}
+\inputmarkdown[shiftHeadings = +1]{example.md}
 
 \stoptext
 ````````
@@ -6459,7 +6546,7 @@ defaultOptions.shiftHeadings = 0
 % \fi
 % \begin{markdown}
 %
-% \Valitem[\textasciicircum{} \$]{slice}{the beginning and the end of a slice}
+% \Valitem[\textasciicircum{} \\$]{slice}{the beginning and the end of a slice}
 %
 :    Two space-separated selectors that specify the slice of a document that
      will be processed, whereas the remainder of the document will be ignored.
@@ -6616,17 +6703,12 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionHeaderAttributes{true}
+\setupmarkdown[headerAttributes = yes]
 \starttext
 
-\def\markdownOptionSlice{^ ^act-3}
-\markdownInput{hamlet.md}
-
-\def\markdownOptionSlice{act-1}
-\markdownInput{hamlet.md}
-
-\def\markdownOptionSlice{act-3 act-5}
-\markdownInput{hamlet.md}
+\inputmarkdown[slice = ^ ^act-3]{example.md}
+\inputmarkdown[slice = act-1]{example.md}
+\inputmarkdown[slice = act-3 act-5]{example.md}
 
 \stoptext
 ````````
@@ -6838,7 +6920,7 @@ following content:
 These are just three regular dots ...
 \stopmarkdown
 
-\def\markdownOptionSmartEllipses{true}
+\setupmarkdown[smartEllipses = yes]
 \startmarkdown
 ... and this is a victorian ellipsis.
 \stopmarkdown
@@ -6963,7 +7045,7 @@ The following list respects the numbers specified in the markup:
 5. fifth item
 \stopmarkdown
 
-\def\markdownOptionStartNumber{false}
+\setupmarkdown[startNumber = no]
 \startmarkdown
 The following list respects the numbers specified in the markup:
 
@@ -7013,6 +7095,125 @@ defaultOptions.startNumber = true
 %</lua,lua-cli>
 %<*manual-options>
 
+#### Option `strikeThrough`
+
+`strikeThrough` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{strikeThrough}{\opt{true}, \opt{false}}
+%
+:    true
+
+     :   Enable the Pandoc strike-through syntax extension:
+
+         ``` md
+         This ~~is deleted text.~~
+         ``````
+
+:    false
+
+     :   Disable the Pandoc strike-through syntax extension.
+
+% \end{markdown}
+% \iffalse
+
+##### Plain \TeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+\def\markdownOptionStrikeThrough{true}
+\input soulutf8.sty
+\def\markdownRendererStrikeThrough#1{\st{#1}}
+\markdownBegin
+This is ~~a lunar roving vehicle~~ strike-through text.
+\markdownEnd
+\bye
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+luatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> This is ~~a lunar roving vehicle~~ strike-through text.
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[strikeThrough]{markdown}
+\usepackage{soulutf8}
+\markdownSetup{
+  renderers = {
+    strikeThrough = {\st{#1}},
+  },
+}
+\begin{document}
+\begin{markdown}
+This is ~~a lunar roving vehicle~~ strike-through text.
+\end{markdown}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> This is ~~a lunar roving vehicle~~ strike-through text.
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\usemodule[t][markdown]
+\setupmarkdown[strikeThrough = yes]
+\def\markdownRendererStrikeThrough#1{\overstrikes{#1}}
+\starttext
+\startmarkdown
+This is ~~a lunar roving vehicle~~ strike-through text.
+\stopmarkdown
+\stoptext
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+context document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> This is ~~a lunar roving vehicle~~ strike-through text.
+
+%</manual-options>
+%<*tex>
+% \fi
+%  \begin{macrocode}
+\@@_add_lua_option:nnn
+  { strikeThrough }
+  { boolean }
+  { false }
+%    \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli>
+% \fi
+%  \begin{macrocode}
+defaultOptions.strikeThrough = false
+%    \end{macrocode}
+% \par
+% \iffalse
+%</lua,lua-cli>
+%<*manual-options>
+
 #### Option `stripIndent`
 
 `stripIndent` (default value: `false`)
@@ -7026,7 +7227,7 @@ defaultOptions.startNumber = true
 
      :   Strip the minimal indentation of non-blank lines from all
          lines in a markdown document. Requires that the
-         \Opt{preserveTabs} Lua option is \opt{false}:
+         \Opt{preserveTabs} Lua option is disabled:
 
          ``` tex
          \documentclass{article}
@@ -7091,7 +7292,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionStripIndent{true}
+\setupmarkdown[stripIndent = yes]
 \starttext
     \startmarkdown
         Hello *world*!
@@ -7126,25 +7327,203 @@ defaultOptions.stripIndent = false
 %</lua,lua-cli>
 %<*manual-options>
 
-#### Option `tableCaptions`
+#### Option `subscripts`
 
-`tableCaptions` (default value: `false`)
+`subscripts` (default value: `false`)
 
 % \fi
 % \begin{markdown}
 %
-% \Optitem[false]{tableCaptions}{\opt{true}, \opt{false}}
+% \Optitem[false]{subscripts}{\opt{true}, \opt{false}}
 %
 :    true
 
-     :   Enable the Pandoc `table_captions` syntax extension for
-%        pipe tables (see the \Opt{pipeTables} option).
-%        \iffalse
-         [pipe tables](#pipe-tables).
-%        \fi
+     :   Enable the Pandoc subscript syntax extension:
 
-        ``` md
-        | Right | Left | Default | Center |
+         ``` md
+         H~2~O is a liquid.
+         ``````
+
+:    false
+
+     :   Disable the Pandoc subscript syntax extension.
+
+% \end{markdown}
+% \iffalse
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[subscripts]{markdown}
+\begin{document}
+\begin{markdown}
+H~2~O is a liquid.
+\end{markdown}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> H~2~O is a liquid.
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\usemodule[t][markdown]
+\setupmarkdown[subscripts = yes]
+\starttext
+\startmarkdown
+H~2~O is a liquid.
+\stopmarkdown
+\stoptext
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+context document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> H~2~O is a liquid.
+
+%</manual-options>
+%<*tex>
+% \fi
+%  \begin{macrocode}
+\@@_add_lua_option:nnn
+  { subscripts }
+  { boolean }
+  { false }
+%    \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli>
+% \fi
+%  \begin{macrocode}
+defaultOptions.subscripts = false
+%    \end{macrocode}
+% \par
+% \iffalse
+%</lua,lua-cli>
+%<*manual-options>
+
+#### Option `superscripts`
+
+`superscripts` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{superscripts}{\opt{true}, \opt{false}}
+%
+:    true
+
+     :   Enable the Pandoc superscript syntax extension:
+
+         ``` md
+         2^10^ is 1024.
+         ``````
+
+:    false
+
+     :   Disable the Pandoc superscript syntax extension.
+
+% \end{markdown}
+% \iffalse
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[superscripts]{markdown}
+\begin{document}
+\begin{markdown}
+2^10^ is 1024.
+\end{markdown}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> 2^10^ is 1024.
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\usemodule[t][markdown]
+\setupmarkdown[superscripts = yes]
+\starttext
+\startmarkdown
+2^10^ is 1024.
+\stopmarkdown
+\stoptext
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+context document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> 2^10^ is 1024.
+
+%</manual-options>
+%<*tex>
+% \fi
+%  \begin{macrocode}
+\@@_add_lua_option:nnn
+  { superscripts }
+  { boolean }
+  { false }
+%    \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli>
+% \fi
+%  \begin{macrocode}
+defaultOptions.superscripts = false
+%    \end{macrocode}
+% \par
+% \iffalse
+%</lua,lua-cli>
+%<*manual-options>
+
+#### Option `tableCaptions`
+
+`tableCaptions` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{tableCaptions}{\opt{true}, \opt{false}}
+%
+:    true
+
+     :   Enable the Pandoc `table_captions` syntax extension for
+%        pipe tables (see the \Opt{pipeTables} option).
+%        \iffalse
+         [pipe tables](#pipe-tables).
+%        \fi
+
+        ``` md
+        | Right | Left | Default | Center |
         |------:|:-----|---------|:------:|
         |   12  |  12  |    12   |    12  |
         |  123  |  123 |   123   |   123  |
@@ -7200,8 +7579,11 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionPipeTables{true}
-\def\markdownOptionTableCaptions{true}
+\setupmarkdown
+  [
+    pipeTables = yes,
+    tableCaptions = yes,
+  ]
 \starttext
 \startmarkdown
 | Right | Left | Default | Center |
@@ -7316,7 +7698,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionTaskLists{true}
+\setupmarkdown[taskLists = yes]
 \def\markdownRendererUntickedBox{No}
 \def\markdownRendererHalftickedBox{Maybe}
 \def\markdownRendererTickedBox{Yes}
@@ -7440,7 +7822,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionTexComments{true}
+\setupmarkdown[texComments = yes]
 \starttext
 \startmarkdown
 Hel%  this is a comment
@@ -7694,14 +8076,14 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionHybrid{true}
+\setupmarkdown[hybrid = yes]
 \starttext
 
 \startmarkdown
 This is _emphasized text_ and this is a math subscript: $m\_n$.
 \stopmarkdown
 
-\def\markdownOptionUnderscores{false}
+\setupmarkdown[underscores = yes]
 \startmarkdown
 This is *emphasized text* and this is a math subscript: $m_n$.
 \stopmarkdown
@@ -8316,9 +8698,7 @@ For more information, see the examples for the \Opt{finalizeCache} option.
 % \begin{markdown}
 %
 % The \mref{markdownOptionOutputTempFileName} macro has been deprecated and
-% will be removed in Markdown 3.0.0. To control the filename of the temporary
-% file for Lua output, use the \mref{g_luabridge_error_output_filename_str}
-% macro from the \pkg{lt3luabridge} package.
+% will be removed in Markdown 3.0.0.
 %
 % \end{markdown}
 %  \begin{macrocode}
@@ -8382,20 +8762,6 @@ For more information, see the examples for the \Opt{finalizeCache} option.
 %    \end{macrocode}
 % \begin{markdown}
 %
-% The \mref{markdownOptionOutputDir} macro is also used to set the
-% \mref{g_luabridge_output_dirname_str} macro from the \pkg{lt3luabridge}
-% package.
-%
-% \end{markdown}
-%  \begin{macrocode}
-\str_new:N
-  \g_luabridge_output_dirname_str
-\tl_gset:Nn
-  \g_luabridge_output_dirname_str
-  { \markdownOptionOutputDir }
-%    \end{macrocode}
-% \begin{markdown}
-%
 % Here, we automatically define plain \TeX{} macros for the above plain \TeX{}
 % options.
 %
@@ -8731,7 +9097,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionTaskLists{true}
+\setupmarkdown[taskLists = yes]
 \def\markdownRendererUntickedBox{No}
 \def\markdownRendererTickedBox{Yes}
 \starttext
@@ -9233,9 +9599,9 @@ following text:
 % \begin{markdown}
 
 #### Ellipsis Renderer
- The \mdef{markdownRendererEllipsis} macro replaces any occurance of ASCII
- ellipses in the input text. This macro will only be produced, when the
- \Opt{smartEllipses} option is enabled.  The macro receives no arguments.
+The \mdef{markdownRendererEllipsis} macro replaces any occurance of ASCII
+ellipses in the input text. This macro will only be produced, when the
+\Opt{smartEllipses} option is enabled.  The macro receives no arguments.
 
 % \end{markdown}
 %
@@ -9296,7 +9662,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionSmartEllipses{true}
+\setupmarkdown[smartEllipses = yes]
 \def\markdownRendererEllipsis{\emph{SHAZAM}!}
 \starttext
 \startmarkdown
@@ -9762,7 +10128,7 @@ following content:
 $\sqrt{-1}$ *equals* $i$
 \stopmarkdown
 
-\def\markdownOptionHybrid{true}
+\setupmarkdown[hybrid = yes]
 \startmarkdown
 $\sqrt{-1}$ *equals* $i$
 \stopmarkdown
@@ -10219,7 +10585,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionContentBlocks{true}
+\setupmarkdown[contentBlocks = yes]
 \def\markdownRendererContentBlock#1#2#3#4{%
   This is {\tt #2}, #4.
 }
@@ -10324,7 +10690,7 @@ list is not tight). The macro receives no arguments.
 The \mdef{markdownRendererUlBeginTight} macro represents the beginning of a
 bulleted list that contains no item with several paragraphs of text (the list
 is tight). This macro will only be produced, when the \Opt{tightLists} option
-is `false`. The macro receives no arguments.
+is disabled. The macro receives no arguments.
 
 % \end{markdown}
 %
@@ -10455,7 +10821,7 @@ tight). The macro receives no arguments.
 The \mdef{markdownRendererUlEndTight} macro represents the end of a bulleted
 list that contains no item with several paragraphs of text (the list is
 tight). This macro will only be produced, when the \Opt{tightLists} option is
-`false`. The macro receives no arguments.
+disabled. The macro receives no arguments.
 
 % \end{markdown}
 %
@@ -10602,7 +10968,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionTightLists{true}
+\setupmarkdown[tightLists = yes]
 \starttext
 
 \def\markdownRendererInterblockSeparator{}
@@ -10691,7 +11057,8 @@ following text:
 #### Ordered List Renderers
 The \mdef{markdownRendererOlBegin} macro represents the beginning of an
 ordered list that contains an item with several paragraphs of text (the
-list is not tight). The macro receives no arguments.
+list is not tight). This macro will only be produced, when the \Opt{fancyLists}
+option is disabled. The macro receives no arguments.
 
 % \end{markdown}
 %
@@ -10725,7 +11092,8 @@ list is not tight). The macro receives no arguments.
 The \mdef{markdownRendererOlBeginTight} macro represents the beginning of an
 ordered list that contains no item with several paragraphs of text (the
 list is tight). This macro will only be produced, when the \Opt{tightLists}
-option is `false`. The macro receives no arguments.
+option is enabled and the \Opt{fancyLists} option is disabled. The macro
+receives no arguments.
 
 % \end{markdown}
 %
@@ -10756,9 +11124,84 @@ option is `false`. The macro receives no arguments.
 %
 % \begin{markdown}
 
+The \mdef{markdownRendererFancyOlBegin} macro represents the beginning of a
+fancy ordered list that contains an item with several paragraphs of text (the
+list is not tight). This macro will only be produced, when the \Opt{fancyLists}
+option is enabled. The macro receives two arguments: the style of the list item
+labels (`Decimal`, `LowerRoman`, `UpperRoman`, `LowerAlpha`, and `UpperAlpha`),
+and the style of delimiters between list item labels and texts (`Default`,
+`OneParen`, and `Period`).
+
+% \end{markdown}
+%
+% \iffalse
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+%  \begin{macrocode}
+\def\markdownRendererFancyOlBegin{%
+  \markdownRendererFancyOlBeginPrototype}%
+\ExplSyntaxOn
+\seq_put_right:Nn
+  \g_@@_renderers_seq
+  { fancyOlBegin }
+\prop_put:Nnn
+  \g_@@_renderer_arities_prop
+  { fancyOlBegin }
+  { 2 }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+The \mdef{markdownRendererFancyOlBeginTight} macro represents the beginning of
+a fancy ordered list that contains no item with several paragraphs of text (the
+list is tight). This macro will only be produced, when the \Opt{fancyLists}
+and \Opt{tightLists} options are enabled. The macro receives two arguments: the
+style of the list item labels, and the style of delimiters between list
+item labels and texts. See the \mref{markdownRendererFancyOlBegin} macro for
+the valid style values.
+
+% \end{markdown}
+%
+% \iffalse
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+%  \begin{macrocode}
+\def\markdownRendererFancyOlBeginTight{%
+  \markdownRendererFancyOlBeginTightPrototype}%
+\ExplSyntaxOn
+\seq_put_right:Nn
+  \g_@@_renderers_seq
+  { fancyOlBeginTight }
+\prop_put:Nnn
+  \g_@@_renderer_arities_prop
+  { fancyOlBeginTight }
+  { 2 }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
 The \mdef{markdownRendererOlItem} macro represents an item in an ordered list.
 This macro will only be produced, when the \Opt{startNumber} option is
-`false`.  The macro receives no arguments.
+disabled and the \Opt{fancyLists} option is disabled. The macro receives no
+arguments.
 
 % \end{markdown}
 %
@@ -10790,7 +11233,8 @@ This macro will only be produced, when the \Opt{startNumber} option is
 % \begin{markdown}
 
 The \mdef{markdownRendererOlItemEnd} macro represents the end of an item in
-an ordered list. The macro receives no arguments.
+an ordered list. This macro will only be produced, when the \Opt{fancyLists}
+option is disabled. The macro receives no arguments.
 
 % \end{markdown}
 %
@@ -10823,8 +11267,8 @@ an ordered list. The macro receives no arguments.
 
 The \mdef{markdownRendererOlItemWithNumber} macro represents an item in an
 ordered list.  This macro will only be produced, when the \Opt{startNumber}
-option is enabled.  The macro receives a single numeric argument that
-corresponds to the item number.
+option is enabled and the \Opt{fancyLists} option is disabled.  The macro
+receives a single numeric argument that corresponds to the item number.
 
 % \end{markdown}
 %
@@ -10855,9 +11299,10 @@ corresponds to the item number.
 %
 % \begin{markdown}
 
-The \mdef{markdownRendererOlEnd} macro represents the end of an ordered list
-that contains an item with several paragraphs of text (the list is not
-tight). The macro receives no arguments.
+The \mdef{markdownRendererFancyOlItem} macro represents an item in a fancy
+ordered list. This macro will only be produced, when the \Opt{startNumber}
+option is disabled and the \Opt{fancyLists} option is enabled. The macro receives
+no arguments.
 
 % \end{markdown}
 %
@@ -10867,15 +11312,15 @@ tight). The macro receives no arguments.
 % \fi
 %
 %  \begin{macrocode}
-\def\markdownRendererOlEnd{%
-  \markdownRendererOlEndPrototype}%
+\def\markdownRendererFancyOlItem{%
+  \markdownRendererFancyOlItemPrototype}%
 \ExplSyntaxOn
 \seq_put_right:Nn
   \g_@@_renderers_seq
-  { olEnd }
+  { fancyOlItem }
 \prop_put:Nnn
   \g_@@_renderer_arities_prop
-  { olEnd }
+  { fancyOlItem }
   { 0 }
 \ExplSyntaxOff
 %    \end{macrocode}
@@ -10888,26 +11333,196 @@ tight). The macro receives no arguments.
 %
 % \begin{markdown}
 
-The \mdef{markdownRendererOlEndTight} macro represents the end of an ordered
-list that contains no item with several paragraphs of text (the list is
-tight). This macro will only be produced, when the \Opt{tightLists} option is
-`false`. The macro receives no arguments.
+The \mdef{markdownRendererFancyOlItemEnd} macro represents the end of an item in
+a fancy ordered list. This macro will only be produced, when the \Opt{fancyLists}
+option is enabled. The macro receives no arguments.
 
 % \end{markdown}
 %
 % \iffalse
-
-##### Plain \TeX{} Example {.unnumbered}
-
-Using a text editor, create a text document named `document.tex` with the
-following content:
-``` tex
-\input markdown
-\def\markdownOptionTightLists{true}
-\def\markdownOptionStartNumber{true}
-
-\def\markdownRendererInterblockSeparator{}
-\def\markdownRendererOlBeginTight{ (}
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+%  \begin{macrocode}
+\def\markdownRendererFancyOlItemEnd{%
+  \markdownRendererFancyOlItemEndPrototype}%
+\ExplSyntaxOn
+\seq_put_right:Nn
+  \g_@@_renderers_seq
+  { fancyOlItemEnd }
+\prop_put:Nnn
+  \g_@@_renderer_arities_prop
+  { fancyOlItemEnd }
+  { 0 }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+The \mdef{markdownRendererFancyOlItemWithNumber} macro represents an item in a
+fancy ordered list. This macro will only be produced, when the \Opt{startNumber}
+and \Opt{fancyLists} options are enabled. The macro receives a single numeric
+argument that corresponds to the item number.
+
+% \end{markdown}
+%
+% \iffalse
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+%  \begin{macrocode}
+\def\markdownRendererFancyOlItemWithNumber{%
+  \markdownRendererFancyOlItemWithNumberPrototype}%
+\ExplSyntaxOn
+\seq_put_right:Nn
+  \g_@@_renderers_seq
+  { fancyOlItemWithNumber }
+\prop_put:Nnn
+  \g_@@_renderer_arities_prop
+  { fancyOlItemWithNumber }
+  { 1 }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+The \mdef{markdownRendererOlEnd} macro represents the end of an ordered list
+that contains an item with several paragraphs of text (the list is not
+tight). This macro will only be produced, when the \Opt{fancyLists} option is
+disabled. The macro receives no arguments.
+
+% \end{markdown}
+%
+% \iffalse
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+%  \begin{macrocode}
+\def\markdownRendererOlEnd{%
+  \markdownRendererOlEndPrototype}%
+\ExplSyntaxOn
+\seq_put_right:Nn
+  \g_@@_renderers_seq
+  { olEnd }
+\prop_put:Nnn
+  \g_@@_renderer_arities_prop
+  { olEnd }
+  { 0 }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+The \mdef{markdownRendererOlEndTight} macro represents the end of an ordered
+list that contains no item with several paragraphs of text (the list is
+tight). This macro will only be produced, when the \Opt{tightLists} option is
+enabled and the \Opt{fancyLists} option is disabled. The macro receives no
+arguments.
+
+% \end{markdown}
+%
+% \iffalse
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+%  \begin{macrocode}
+\def\markdownRendererOlEndTight{%
+  \markdownRendererOlEndTightPrototype}%
+\ExplSyntaxOn
+\seq_put_right:Nn
+  \g_@@_renderers_seq
+  { olEndTight }
+\prop_put:Nnn
+  \g_@@_renderer_arities_prop
+  { olEndTight }
+  { 0 }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+The \mdef{markdownRendererFancyOlEnd} macro represents the end of a fancy
+ordered list that contains an item with several paragraphs of text (the list
+is not tight). This macro will only be produced, when the \Opt{fancyLists}
+option is enabled. The macro receives no arguments.
+
+% \end{markdown}
+%
+% \iffalse
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+%  \begin{macrocode}
+\def\markdownRendererFancyOlEnd{%
+  \markdownRendererFancyOlEndPrototype}%
+\ExplSyntaxOn
+\seq_put_right:Nn
+  \g_@@_renderers_seq
+  { fancyOlEnd }
+\prop_put:Nnn
+  \g_@@_renderer_arities_prop
+  { fancyOlEnd }
+  { 0 }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+The \mdef{markdownRendererFancyOlEndTight} macro represents the end of a
+fancy ordered list that contains no item with several paragraphs of text (the
+list is tight). This macro will only be produced, when the \Opt{fancyLists}
+and \Opt{tightLists} options are enabled. The macro receives no arguments.
+
+% \end{markdown}
+%
+% \iffalse
+
+##### Plain \TeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+\def\markdownOptionTightLists{true}
+\def\markdownOptionStartNumber{true}
+
+\def\markdownRendererInterblockSeparator{}
+\def\markdownRendererOlBeginTight{ (}
 \def\markdownRendererOlItemWithNumber#1{%
   \ifnum #1=1\relax
     the first
@@ -11072,8 +11687,11 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionTightLists{true}
-\def\markdownOptionStartNumber{true}
+\setupmarkdown
+  [
+    tightLists = yes,
+    startNumber = yes,
+  ]
 \starttext
 
 \def\markdownRendererInterblockSeparator{}
@@ -11155,15 +11773,15 @@ following text:
 % \fi
 %
 %  \begin{macrocode}
-\def\markdownRendererOlEndTight{%
-  \markdownRendererOlEndTightPrototype}%
+\def\markdownRendererFancyOlEndTight{%
+  \markdownRendererFancyOlEndTightPrototype}%
 \ExplSyntaxOn
 \seq_put_right:Nn
   \g_@@_renderers_seq
-  { olEndTight }
+  { fancyOlEndTight }
 \prop_put:Nnn
   \g_@@_renderer_arities_prop
-  { olEndTight }
+  { fancyOlEndTight }
   { 0 }
 \ExplSyntaxOff
 %    \end{macrocode}
@@ -11216,7 +11834,7 @@ list is not tight). The macro receives no arguments.
 The \mdef{markdownRendererDlBeginTight} macro represents the beginning of a
 definition list that contains an item with several paragraphs of text (the
 list is not tight). This macro will only be produced, when the
-\Opt{tightLists} option is `false`. The macro receives no arguments.
+\Opt{tightLists} option is disabled. The macro receives no arguments.
 
 % \end{markdown}
 %
@@ -11414,7 +12032,7 @@ tight). The macro receives no arguments.
 The \mdef{markdownRendererDlEndTight} macro represents the end of a
 definition list that contains no item with several paragraphs of text (the
 list is tight). This macro will only be produced, when the \Opt{tightLists}
-option is `false`. The macro receives no arguments.
+option is disabled. The macro receives no arguments.
 
 % \end{markdown}
 %
@@ -11648,8 +12266,11 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionDefinitionLists{true}
-\def\markdownOptionTightLists{true}
+\setupmarkdown
+  [
+    definitionLists = yes,
+    tightLists = yes,
+  ]
 \starttext
 
 \def\markdownRendererInterblockSeparator{%
@@ -12670,7 +13291,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionJekyllData{true}
+\setupmarkdown[jekyllData = yes]
 \def\markdownRendererJekyllDataString#1#2{\gdef\name{#2}}
 \def\markdownRendererJekyllDataNumber#1#2{\gdef\age{#2}}
 \def\markdownRendererJekyllDataEnd{%
@@ -13200,7 +13821,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionFootnotes{true}
+\setupmarkdown[footnotes = yes]
 \def\markdownRendererFootnote#1{ (and \lowercase{#1})}
 \starttext
 \startmarkdown
@@ -14001,32 +14622,27 @@ following text:
 %
 % \begin{markdown}
 
-### Token Renderer Prototypes {#texrendererprototypes}
+#### Strike-Through Renderer
+The \mdef{markdownRendererStrikeThrough} macro represents a strike-through span of
+text. The macro receives a single argument that corresponds to the striked-out
+span of text. This macro will only be produced, when the \Opt{strikeThrough}
+option is enabled.
 
 % \end{markdown}
+%
 % \iffalse
 
-By default, token renderers point to package-defined \TeX{} macros, further
-referred to as *prototypes*, which provide useful default definitions.
-
 ##### Plain \TeX{} Example {.unnumbered}
 
 Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \input markdown
-\def\markdownRendererTildePrototype{%
-  Packages can specify token renderer prototypes.%
-}
-\markdownBegin
-~
-\markdownEnd
-
-\def\markdownRendererTilde{%
-  User-defined token renderers take precedence.%
-}
+\def\markdownOptionStrikeThrough{true}
+\input soulutf8.sty
+\def\markdownRendererStrikeThrough#1{\st{#1}}
 \markdownBegin
-~
+This is ~~a lunar roving vehicle~~ strike-through text.
 \markdownEnd
 \bye
 ```````
@@ -14037,9 +14653,7 @@ luatex document.tex
 A PDF document named `document.pdf` should be produced and contain the
 following text:
 
-> Packages can specify token renderer prototypes.
->
-> User-defined token renderers take precedence.
+> This is ~~a lunar roving vehicle~~ strike-through text.
 
 ##### \LaTeX{} Example {.unnumbered}
 
@@ -14047,24 +14661,17 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \documentclass{article}
-\usepackage{markdown}
+\usepackage[strikeThrough]{markdown}
+\usepackage{soulutf8}
 \markdownSetup{
-  rendererPrototypes = {
-    tilde = {Packages can specify token renderer prototypes.},
+  renderers = {
+    strikeThrough = {\st{#1}},
   },
 }
 \begin{document}
 \begin{markdown}
-~
+This is ~~a lunar roving vehicle~~ strike-through text.
 \end{markdown}
-
-\begin{markdown*}{
-  renderers = {
-    tilde = {User-defined token renderers take precedence.},
-  },
-}
-~
-\end{markdown*}
 \end{document}
 ```````
 Next, invoke LuaTeX from the terminal:
@@ -14074,9 +14681,7 @@ lualatex document.tex
 A PDF document named `document.pdf` should be produced and contain the
 following text:
 
-> Packages can specify token renderer prototypes.
->
-> User-defined token renderers take precedence.
+> This is ~~a lunar roving vehicle~~ strike-through text.
 
 ##### \Hologo{ConTeXt} Example {.unnumbered}
 
@@ -14084,19 +14689,11 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownRendererTildePrototype{%
-  Packages can specify token renderer prototypes.%
-}
+\setupmarkdown[strikeThrough = yes]
+\def\markdownRendererStrikeThrough#1{\overstrikes{#1}}
 \starttext
 \startmarkdown
-~
-\stopmarkdown
-
-\def\markdownRendererTilde{%
-  User-defined token renderers take precedence.%
-}
-\startmarkdown
-~
+This is ~~a lunar roving vehicle~~ strike-through text.
 \stopmarkdown
 \stoptext
 ```````
@@ -14107,21 +14704,42 @@ context document.tex
 A PDF document named `document.pdf` should be produced and contain the
 following text:
 
-> Packages can specify token renderer prototypes.
->
-> User-defined token renderers take precedence.
+> This is ~~a lunar roving vehicle~~ strike-through text.
 
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+%  \begin{macrocode}
+\def\markdownRendererStrikeThrough{%
+  \markdownRendererStrikeThroughPrototype}%
+\ExplSyntaxOn
+\seq_put_right:Nn
+  \g_@@_renderers_seq
+  { strikeThrough }
+\prop_put:Nnn
+  \g_@@_renderer_arities_prop
+  { strikeThrough }
+  { 1 }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
 % \fi
 %
 % \begin{markdown}
 
-#### YAML Metadata Renderer Prototypes {#expl3yamlmetadata}
-
-By default, the renderer prototypes for YAML metadata provide a high-level
-interface that can be programmed using the `markdown/jekyllData` key--values
-from the l3keys module of the \LaTeX3 kernel.
+#### Superscript Renderer
+The \mdef{markdownRendererSuperscript} macro represents a superscript span of
+text. The macro receives a single argument that corresponds to the superscript
+span of text. This macro will only be produced, when the \Opt{superscripts}
+option is enabled.
 
 % \end{markdown}
+%
 % \iffalse
 
 ##### Plain \TeX{} Example {.unnumbered}
@@ -14130,22 +14748,10 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \input markdown
-\def\markdownOptionJekyllData{true}
-\ExplSyntaxOn
-\keys_define:nn
-  { markdown/jekyllData }
-  {
-    name .code:n = { \gdef\name{#1} },
-    age  .code:n = { \gdef\age{#1}  },
-  }
-\ExplSyntaxOff
-\def\markdownRendererJekyllDataEnd{%
-  \name{} is \age{} years old.}
+\def\markdownOptionSuperscripts{true}
+\def\markdownRendererSuperscript#1{ taken to the power of #1}
 \markdownBegin
----
-name: Jane Doe
-age:  99
----
+2^10^ is 1024.
 \markdownEnd
 \bye
 ```````
@@ -14156,7 +14762,7 @@ luatex document.tex
 A PDF document named `document.pdf` should be produced and contain the
 following text:
 
-> Jane Doe is 99 years old.
+> 2 taken to the power of 10 is 1024.
 
 ##### \LaTeX{} Example {.unnumbered}
 
@@ -14164,7 +14770,314 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \documentclass{article}
-\usepackage[jekyllData]{markdown}
+\usepackage[superscripts]{markdown}
+\markdownSetup{
+  renderers = {
+    superscript = { taken to the power of #1},
+  },
+}
+\begin{document}
+\begin{markdown}
+2^10^ is 1024.
+\end{markdown}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> 2 taken to the power of 10 is 1024.
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\usemodule[t][markdown]
+\setupmarkdown[superscripts = yes]
+\def\markdownRendererSuperscript#1{ taken to the power of #1}
+\starttext
+\startmarkdown
+2^10^ is 1024.
+\stopmarkdown
+\stoptext
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+context document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> 2 taken to the power of 10 is 1024.
+
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+%  \begin{macrocode}
+\def\markdownRendererSuperscript{%
+  \markdownRendererSuperscriptPrototype}%
+\ExplSyntaxOn
+\seq_put_right:Nn
+  \g_@@_renderers_seq
+  { superscript }
+\prop_put:Nnn
+  \g_@@_renderer_arities_prop
+  { superscript }
+  { 1 }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+#### Subscript Renderer
+The \mdef{markdownRendererSubscript} macro represents a subscript span of
+text. The macro receives a single argument that corresponds to the subscript
+span of text. This macro will only be produced, when the \Opt{subscripts}
+option is enabled.
+
+% \end{markdown}
+%
+% \iffalse
+
+##### Plain \TeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+\def\markdownOptionSubscripts{true}
+\def\markdownRendererSubscript#1{ (#1 moles) and }
+\markdownBegin
+H~2~O is a liquid.
+\markdownEnd
+\bye
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+luatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> H (2 moles) and O is liquid.
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[subscripts]{markdown}
+\markdownSetup{
+  renderers = {
+    subscript = { (#1 moles) and },
+  },
+}
+\begin{document}
+\begin{markdown}
+H~2~O is a liquid.
+\end{markdown}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> H (2 moles) and O is liquid.
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\usemodule[t][markdown]
+\setupmarkdown[subscripts = yes]
+\def\markdownRendererSubscript#1{ (#1 moles) and }
+\starttext
+\startmarkdown
+H~2~O is a liquid.
+\stopmarkdown
+\stoptext
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+context document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> H (2 moles) and O is liquid.
+
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+%  \begin{macrocode}
+\def\markdownRendererSubscript{%
+  \markdownRendererSubscriptPrototype}%
+\ExplSyntaxOn
+\seq_put_right:Nn
+  \g_@@_renderers_seq
+  { subscript }
+\prop_put:Nnn
+  \g_@@_renderer_arities_prop
+  { subscript }
+  { 1 }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+### Token Renderer Prototypes {#texrendererprototypes}
+
+% \end{markdown}
+% \iffalse
+
+By default, token renderers point to package-defined \TeX{} macros, further
+referred to as *prototypes*, which provide useful default definitions.
+
+##### Plain \TeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+\def\markdownRendererTildePrototype{%
+  Packages can specify token renderer prototypes.%
+}
+\markdownBegin
+~
+\markdownEnd
+
+\def\markdownRendererTilde{%
+  User-defined token renderers take precedence.%
+}
+\markdownBegin
+~
+\markdownEnd
+\bye
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+luatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> Packages can specify token renderer prototypes.
+>
+> User-defined token renderers take precedence.
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage{markdown}
+\markdownSetup{
+  rendererPrototypes = {
+    tilde = {Packages can specify token renderer prototypes.},
+  },
+}
+\begin{document}
+\begin{markdown}
+~
+\end{markdown}
+
+\begin{markdown*}{
+  renderers = {
+    tilde = {User-defined token renderers take precedence.},
+  },
+}
+~
+\end{markdown*}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> Packages can specify token renderer prototypes.
+>
+> User-defined token renderers take precedence.
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\usemodule[t][markdown]
+\def\markdownRendererTildePrototype{%
+  Packages can specify token renderer prototypes.%
+}
+\starttext
+\startmarkdown
+~
+\stopmarkdown
+
+\def\markdownRendererTilde{%
+  User-defined token renderers take precedence.%
+}
+\startmarkdown
+~
+\stopmarkdown
+\stoptext
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+context document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> Packages can specify token renderer prototypes.
+>
+> User-defined token renderers take precedence.
+
+% \fi
+%
+% \begin{markdown}
+
+#### YAML Metadata Renderer Prototypes {#expl3yamlmetadata}
+
+By default, the renderer prototypes for YAML metadata provide a high-level
+interface that can be programmed using the `markdown/jekyllData` key--values
+from the l3keys module of the \LaTeX3 kernel.
+
+% \end{markdown}
+% \iffalse
+
+##### Plain \TeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+\def\markdownOptionJekyllData{true}
 \ExplSyntaxOn
 \keys_define:nn
   { markdown/jekyllData }
@@ -14173,7 +15086,37 @@ following content:
     age  .code:n = { \gdef\age{#1}  },
   }
 \ExplSyntaxOff
+\def\markdownRendererJekyllDataEnd{%
+  \name{} is \age{} years old.}
+\markdownBegin
+---
+name: Jane Doe
+age:  99
+---
+\markdownEnd
+\bye
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+luatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> Jane Doe is 99 years old.
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[jekyllData]{markdown}
 \markdownSetup{
+  jekyllDataRenderers = {
+    name = {\gdef\name{#1}},
+    code = {\gdef\age{#1}},
+  },
   renderers = {
     jekyllDataEnd = {\name{} is \age{} years old.},
   }
@@ -14204,7 +15147,7 @@ Using a text editor, create a text document named `document.tex` with the
 following content:
 ``` tex
 \usemodule[t][markdown]
-\def\markdownOptionJekyllData{true}
+\setupmarkdown[jekyllData = yes]
 \ExplSyntaxOn
 \keys_define:nn
   { markdown/jekyllData }
@@ -14416,21 +15359,6 @@ following text:
       }
   }
 %    \end{macrocode}
-% \begin{markdown}
-%
-% \end{markdown}
-%  \begin{macrocode}
-\int_compare:nF
-  { \markdownMode = 3 }
-  {
-    \int_new:N
-      \g_luabridge_method_int
-    \int_gset:Nn
-      \g_luabridge_method_int
-      { \markdownMode }
-  }
-\ExplSyntaxOff
-%    \end{macrocode}
 % \par
 % \begin{markdown}
 %
@@ -14507,11 +15435,11 @@ pdflatex --shell-escape document.tex
 % \begin{markdown}
 %
 % The \LaTeX{} interface provides \LaTeX{} environments for the typesetting of
-% markdown input from within \LaTeX{}, facilities for setting Lua interface
-% options (see Section <#sec:luaoptions>) used during the conversion from
-% markdown to plain \TeX{}, and facilities for changing the way markdown tokens
-% are rendered. The rest of the interface is inherited from the plain \TeX{}
-% interface (see Section <#sec:texinterface>).
+% markdown input from within \LaTeX{}, facilities for setting Lua, plain \TeX,
+% and \LaTeX{} options used during the conversion from markdown to plain
+% \TeX{}, and facilities for changing the way markdown tokens are rendered. The
+% rest of the interface is inherited from the plain \TeX{} interface (see
+% Section <#sec:texinterface>).
 %
 % The \LaTeX{} implementation redefines the plain \TeX{} logging macros (see
 % Section <#sec:texinterfacelogging>) to use the \LaTeX{} \mref{PackageInfo},
@@ -15134,7 +16062,7 @@ following image:
 \pkg{witiko/tilde}
 
 :    A theme that makes tilde (`~`) always typeset the non-breaking space even
-     when the \Opt{hybrid} Lua option is `false`.
+     when the \Opt{hybrid} Lua option is disabled.
 %    ``` tex
 %    \documentclass{article}
 %    \usepackage[theme=witiko/tilde]{markdown}
@@ -15288,7 +16216,7 @@ The following ordered list will be preceded by roman numerals:
 % \begin{markdown}
 %
 % Furthermore, we also define the \meta{key}`=`\meta{value} interface
-% for all option macros recognized by the Lua plain \TeX{} interfaces.
+% for all option macros recognized by the Lua and plain \TeX{} interfaces.
 %
 % \end{markdown}
 %  \begin{macrocode}
@@ -15536,7 +16464,7 @@ The following ordered list will be preceded by roman numerals:
 The \Hologo{ConTeXt} interface provides the same level of functionality as the
 plain \TeX{} interface by using the plain \TeX{} interface behind the scenes.
 Unlike the plain \TeX{} interface, the \Hologo{ConTeXt} interface uses familiar
-\Hologo{ConTeXt} idioms, such as environments.
+\Hologo{ConTeXt} idioms as syntactic sugar.
 
 The \Hologo{ConTeXt} interface accepts the same options as the plain \TeX{}
 interface.
@@ -15551,7 +16479,7 @@ following content:
 $\sqrt{-1}$ *equals* $i$.
 \stopmarkdown
 
-\def\markdownOptionHybrid{true}
+\setupmarkdown[hybrid = yes]
 \startmarkdown
 $\sqrt{-1}$ *equals* $i$.
 \stopmarkdown
@@ -15579,9 +16507,10 @@ texexec --passon=--shell-escape document.tex
 % \fi
 %
 % The \Hologo{ConTeXt} interface provides a start-stop macro pair for the
-% typesetting of markdown input from within \Hologo{ConTeXt}. The rest of the
-% interface is inherited from the plain \TeX{} interface (see Section
-% <#sec:texinterface>).
+% typesetting of markdown input from within \Hologo{ConTeXt} and facilities for
+% setting Lua, plain \TeX, and \Hologo{ConTeXt} options used during the
+% conversion from markdown to plain \TeX{}. The rest of the interface is
+% inherited from the plain \TeX{} interface (see Section <#sec:texinterface>).
 %
 % \end{markdown}
 %  \begin{macrocode}
@@ -15592,6 +16521,21 @@ texexec --passon=--shell-escape document.tex
 % \par
 % \begin{markdown}
 %
+% The \Hologo{ConTeXt} implementation redefines the plain \TeX{} logging macros
+% (see Section <#sec:texinterfacelogging>) to use the \Hologo{ConTeXt}
+% \mref{writestatus} macro.
+%
+% \end{markdown}
+%  \begin{macrocode}
+\def\markdownInfo#1{\writestatus{markdown}{#1.}}%
+\def\markdownWarning#1{\writestatus{markdown\space warn}{#1.}}%
+\def\dospecials{\do\ \do\\\do\{\do\}\do\$\do\&%
+  \do\#\do\^\do\_\do\%\do\~}%
+\input markdown/markdown
+%    \end{macrocode}
+% \par
+% \begin{markdown}
+%
 % The \Hologo{ConTeXt} interface is implemented by the
 % `t-markdown.tex` \Hologo{ConTeXt} module file that can be loaded as follows:
 % ``` tex
@@ -15602,35 +16546,158 @@ texexec --passon=--shell-escape document.tex
 %
 %### Typesetting Markdown
 % The interface exposes the \mdef{startmarkdown} and \mdef{stopmarkdown} macro
-% pair for the typesetting of a markdown document fragment.
+% pair for the typesetting of a markdown document fragment, and defines the
+% \mdef{inputmarkdown} command.
 %
 % \end{markdown}
 %  \begin{macrocode}
 \let\startmarkdown\relax
 \let\stopmarkdown\relax
+\let\inputmarkdown\relax
+%    \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% You may prepend your own code to the \mref{startmarkdown} macro and redefine the
+% \mref{stopmarkdown} macro to produce special effects before and after the
+% markdown block.
+%
+% Note that the \mref{startmarkdown} and \mref{stopmarkdown} macros
+% are subject to the same limitations as the \mref{markdownBegin} and
+% \mref{markdownEnd} macros exposed by the plain \TeX{} interface.
+%
+% The following example \Hologo{ConTeXt} code showcases the usage of the
+% \mref{startmarkdown} and \mref{stopmarkdown} macros:
+% ``` tex
+% \usemodule[t][markdown]
+% \starttext
+% \startmarkdown
+% _Hello_ **world** ...
+% \stopmarkdown
+% \stoptext
+% ```````
+%
+% The \mref{inputmarkdown} macro accepts a single mandatory parameter
+% containing the filename of a markdown document and expands to the result of
+% the conversion of the input markdown document to plain \TeX{}. Unlike the
+% \mref{markdownInput} macro provided by the plain \TeX{} interface, this macro
+% also accepts \Hologo{ConTeXt} interface options (see Section
+% <#sec:contextoptions>) as its optional argument. These options will only
+% influnce this markdown document.
+%
+% The following example \LaTeX{} code showcases the usage of the
+% \mref{markdownInput} macro:
+% ``` tex
+% \usemodule[t][markdown]
+% \starttext
+% % ...
+% \inputmarkdown[smartEllipses]{hello.md}
+% % ...
+% \stoptext
+% ```````
+%
+%### Options {#contextoptions}
+%
+% The \Hologo{ConTeXt} options are represented by a comma-delimited list of
+% \meta{key}`=`\meta{value} pairs. For boolean options, the `=`\meta{value}
+% part is optional, and \meta{key} will be interpreted as \meta{key}`=true`
+% (or, equivalently, \meta{key}`=yes`) if the `=`\meta{value} part has been
+% omitted.
+%
+% \Hologo{ConTeXt} options map directly to the options recognized by the plain
+% \TeX{} interface (see Section <#sec:texoptions>).
+%
+% The \Hologo{ConTeXt} options may be specified when using the
+% \mref{inputmarkdown} macro (see Section <#sec:contextinterface>), or via the
+% \mdef{setupmarkdown} macro. The \mref{setupmarkdown} macro receives the
+% options to set up as its only argument:
+%
+% \end{markdown}
+%  \begin{macrocode}
+\ExplSyntaxOn
+\cs_new:Nn
+  \@@_setup:n
+  {
+    \keys_set:nn
+      { markdown/context-options }
+      { #1 }
+  }
+\long\def\setupmarkdown[#1]
+  {
+    \@@_setup:n
+      { #1 }
+  }
+\ExplSyntaxOff
+%    \end{macrocode}
+% \begin{markdown}
+%
+%#### \Hologo{ConTeXt} Interface Options
+% We define the \meta{key}`=`\meta{value} interface for all option macros
+% recognized by the Lua and plain \TeX{} interfaces.
+%
+% \end{markdown}
+%  \begin{macrocode}
+\ExplSyntaxOn
+\cs_new:Nn \@@_context_define_option_commands_and_keyvals:
+  {
+    \seq_map_inline:Nn
+      \g_@@_option_layers_seq
+      {
+        \seq_map_inline:cn
+          { g_@@_ ##1 _options_seq }
+          {
+              \@@_context_define_option_keyval:nn
+                { ##1 }
+                { ####1 }
+          }
+      }
+  }
+\cs_new:Nn \@@_context_define_option_keyval:nn
+  {
+    \prop_get:cnN
+      { g_@@_ #1 _option_types_prop }
+      { #2 }
+      \l_tmpa_tl
+    \keys_define:nn
+      { markdown/context-options }
+      {
+        #2 .code:n = {
+          \tl_set:Nx
+            \l_tmpa_tl
+            {
+              \str_case:nnF
+                { ##1 }
+                {
+                  { yes } { true }
+                  { no } { false }
+                }
+                { ##1 }
+            }
+          \@@_set_option_value:nV
+            { #2 }
+            \l_tmpa_tl
+        },
+      }
+    \str_if_eq:VVT
+      \l_tmpa_tl
+      \c_@@_option_type_boolean_tl
+      {
+        \keys_define:nn
+          { markdown/context-options }
+          {
+            #2 .default:n = { true },
+          }
+      }
+  }
+\cs_generate_variant:Nn
+  \@@_set_option_value:nn
+  { nV }
+\@@_context_define_option_commands_and_keyvals:
+\ExplSyntaxOff
 %    \end{macrocode}
 % \par
 % \begin{markdown}
 %
-% You may prepend your own code to the \mref{startmarkdown} macro and redefine the
-% \mref{stopmarkdown} macro to produce special effects before and after the
-% markdown block.
-%
-% Note that the \mref{startmarkdown} and \mref{stopmarkdown} macros
-% are subject to the same limitations as the \mref{markdownBegin} and
-% \mref{markdownEnd} macros exposed by the plain \TeX{} interface.
-%
-% The following example \Hologo{ConTeXt} code showcases the usage of the
-% \mref{startmarkdown} and \mref{stopmarkdown} macros:
-% ``` tex
-% \usemodule[t][markdown]
-% \starttext
-% \startmarkdown
-% _Hello_ **world** ...
-% \stopmarkdown
-% \stoptext
-% ```````
-%
 % Implementation {#implementation}
 %================
 %
@@ -15657,7 +16724,7 @@ texexec --passon=--shell-escape document.tex
 %
 % The Lua implementation implements \luamdef{writer} and \luamdef{reader}
 % objects, which provide the conversion from markdown to plain \TeX, and
-% \luamdef{extension} objects, which provide syntax extensions for the
+% \luamdef{extensions} objects, which provide syntax extensions for the
 % \luamref{writer} and \luamref{reader} objects.
 %
 % The Lunamark Lua module implements writers for the conversion to various
@@ -18105,22 +19172,12 @@ function M.writer.new(options)
 % \par
 % \begin{markdown}
 %
-% Make `options.cacheDir` available as \luamdef{writer->cacheDir}, so that it
-% is accessible from extensions.
-%
-% \end{markdown}
-%  \begin{macrocode}
-  self.cacheDir = options.cacheDir
-%    \end{macrocode}
-% \par
-% \begin{markdown}
-%
-% Make `options.hybrid` available as \luamdef{writer->hybrid}, so that it is
+% Make `options` available as \luamdef{writer->options}, so that it is
 % accessible from extensions.
 %
 % \end{markdown}
 %  \begin{macrocode}
-  self.hybrid = options.hybrid
+  self.options = options
 %    \end{macrocode}
 % \par
 % \begin{markdown}
@@ -18399,16 +19456,11 @@ function M.writer.new(options)
 %
 % \end{markdown}
 %  \begin{macrocode}
-  local function ulitem(s)
-    return {"\\markdownRendererUlItem ",s,
-            "\\markdownRendererUlItemEnd "}
-  end
-
   function self.bulletlist(items,tight)
     if not self.is_writing then return "" end
     local buffer = {}
     for _,item in ipairs(items) do
-      buffer[#buffer + 1] = ulitem(item)
+      buffer[#buffer + 1] = self.bulletitem(item)
     end
     local contents = util.intersperse(buffer,"\n")
     if tight and options.tightLists then
@@ -18420,33 +19472,36 @@ function M.writer.new(options)
     end
   end
 %    \end{macrocode}
-% \par
 % \begin{markdown}
 %
-% Define \luamdef{writer->ollist} as a function that will transform an input
-% ordered list to the output format, where `items` is an array of the list
-% items and `tight` specifies, whether the list is tight or not. If the
-% optional parameter `startnum` is present, it should be used as the number
-% of the first list item.
+% Define \luamdef{writer->bulletitem} as a function that will transform an
+% input bulleted list item to the output format, where `s` is the text of
+% the list item.
 %
 % \end{markdown}
 %  \begin{macrocode}
-  local function olitem(s,num)
-    if num ~= nil then
-      return {"\\markdownRendererOlItemWithNumber{",num,"}",s,
-              "\\markdownRendererOlItemEnd "}
-    else
-      return {"\\markdownRendererOlItem ",s,
-              "\\markdownRendererOlItemEnd "}
-    end
+  function self.bulletitem(s)
+    return {"\\markdownRendererUlItem ",s,
+            "\\markdownRendererUlItemEnd "}
   end
-
+%    \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Define \luamdef{writer->orderedlist} as a function that will transform an
+% input ordered list to the output format, where `items` is an array of the
+% list items and `tight` specifies, whether the list is tight or not. If the
+% optional parameter `startnum` is present, it is the number of the first list
+% item.
+%
+% \end{markdown}
+%  \begin{macrocode}
   function self.orderedlist(items,tight,startnum)
     if not self.is_writing then return "" end
     local buffer = {}
     local num = startnum
     for _,item in ipairs(items) do
-      buffer[#buffer + 1] = olitem(item,num)
+      buffer[#buffer + 1] = self.ordereditem(item,num)
       if num ~= nil then
         num = num + 1
       end
@@ -18461,6 +19516,25 @@ function M.writer.new(options)
     end
   end
 %    \end{macrocode}
+% \begin{markdown}
+%
+% Define \luamdef{writer->ordereditem} as a function that will transform an
+% input ordered list item to the output format, where `s` is the text of
+% the list item. If the optional parameter `num` is present, it is the number
+% of the list item.
+%
+% \end{markdown}
+%  \begin{macrocode}
+  function self.ordereditem(s,num)
+    if num ~= nil then
+      return {"\\markdownRendererOlItemWithNumber{",num,"}",s,
+              "\\markdownRendererOlItemEnd "}
+    else
+      return {"\\markdownRendererOlItem ",s,
+              "\\markdownRendererOlItemEnd "}
+    end
+  end
+%    \end{macrocode}
 % \par
 % \begin{markdown}
 %
@@ -18514,7 +19588,7 @@ function M.writer.new(options)
 %  \begin{macrocode}
   function self.block_html_element(s)
     if not self.is_writing then return "" end
-    local name = util.cache(self.cacheDir, s, nil, nil, ".verbatim")
+    local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim")
     return {"\\markdownRendererInputBlockHtmlElement{",name,"}"}
   end
 %    \end{macrocode}
@@ -18585,7 +19659,7 @@ function M.writer.new(options)
   function self.verbatim(s)
     if not self.is_writing then return "" end
     s = string.gsub(s, '[\r\n%s]*$', '')
-    local name = util.cache(self.cacheDir, s, nil, nil, ".verbatim")
+    local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim")
     return {"\\markdownRendererInputVerbatim{",name,"}"}
   end
 %    \end{macrocode}
@@ -18724,7 +19798,7 @@ function M.writer.new(options)
           table.insert(buf, {"\\markdownRendererAttributeClassName{",
                              attributes[i]:sub(2), "}"})
         else
-          key, value = attributes[i]:match("(%w+)=(%w+)")
+          key, value = attributes[i]:match("([^= ]+)%s*=%s*(.*)")
           table.insert(buf, {"\\markdownRendererAttributeKeyValue{",
                              key, "}{", value, "}"})
         end
@@ -18872,12 +19946,13 @@ parsers.internal_punctuation   = S(":;,.?")
 
 parsers.doubleasterisks        = P("**")
 parsers.doubleunderscores      = P("__")
+parsers.doubletildes           = P("~~")
 parsers.fourspaces             = P("    ")
 
 parsers.any                    = P(1)
 parsers.fail                   = parsers.any - 1
 
-parsers.escapable              = S("\\`*_{}[]()+_.!<>#-~:^@;")
+parsers.escapable              = S("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")
 parsers.anyescaped             = parsers.backslash / "" * parsers.escapable
                                + parsers.any
 
@@ -18994,21 +20069,15 @@ parsers.commented_line         = Cg(Cc(""), "backslashes")
 parsers.chunk                  = parsers.line * (parsers.optionallyindentedline
                                                 - parsers.blankline)^0
 
-parsers.css_identifier_char    = R("AZ", "az", "09") + S("-_")
-parsers.css_identifier         = (parsers.hash + parsers.period)
-                               * (((parsers.css_identifier_char
-                                   - parsers.dash - parsers.digit)
-                                  * parsers.css_identifier_char^1)
-                                 + (parsers.dash
-                                   * (parsers.css_identifier_char
-                                     - parsers.digit)
-                                   * parsers.css_identifier_char^0))
-parsers.attribute_key_char     = parsers.any - parsers.space
-                               - parsers.squote - parsers.dquote
-                               - parsers.more - parsers.slash
-                               - parsers.equal
-parsers.attribute_value_char   = parsers.any - parsers.space
-                               - parsers.dquote - parsers.more
+parsers.attribute_key_char     = parsers.alphanumeric + S("_-")
+parsers.attribute_key          = (parsers.attribute_key_char
+                                 - parsers.dash - parsers.digit)
+                               * parsers.attribute_key_char^0
+parsers.attribute_value        = ( (parsers.dquote / "")
+                                 * (parsers.anyescaped - parsers.dquote)^0
+                                 * (parsers.dquote / ""))
+                               + ( parsers.anyescaped - parsers.dquote - parsers.rbrace
+                                 - parsers.space)^0
 
 -- block followed by 0 or more optionally
 -- indented blocks with first line indented.
@@ -19134,9 +20203,10 @@ parsers.leader      = parsers.space^-3
 
 -- content in balanced brackets, parentheses, or quotes:
 parsers.bracketed   = P{ parsers.lbracket
-                       * ((parsers.anyescaped - (parsers.lbracket
-                                                + parsers.rbracket
-                                                + parsers.blankline^2)
+                       * (( parsers.backslash / "" * parsers.rbracket
+                          + parsers.any - (parsers.lbracket
+                                          + parsers.rbracket
+                                          + parsers.blankline^2)
                           ) + V(1))^0
                        * parsers.rbracket }
 
@@ -19164,7 +20234,8 @@ parsers.tag         = parsers.lbracket
                     * Cs((parsers.alphanumeric^1
                          + parsers.bracketed
                          + parsers.inticks
-                         + (parsers.anyescaped
+                         + ( parsers.backslash / "" * parsers.rbracket
+                           + parsers.any
                            - (parsers.rbracket + parsers.blankline^2)))^0)
                     * parsers.rbracket
 
@@ -19373,16 +20444,18 @@ end
 %
 % \end{markdown}
 %  \begin{macrocode}
-parsers.heading_attribute = C(parsers.css_identifier)
-                          + C((parsers.attribute_key_char
-                             - parsers.rbrace)^1
-                             * parsers.equal
-                             * (parsers.attribute_value_char
-                               - parsers.rbrace)^1)
+parsers.heading_attribute = (parsers.dash * Cc(".unnumbered"))
+                          + C((parsers.hash + parsers.period)
+                             * parsers.attribute_key)
+                          + Cs( parsers.attribute_key
+                              * parsers.optionalspace * parsers.equal * parsers.optionalspace
+                              * parsers.attribute_value)
 parsers.HeadingAttributes = parsers.lbrace
+                          * parsers.optionalspace
                           * parsers.heading_attribute
                           * (parsers.spacechar^1
                             * parsers.heading_attribute)^0
+                          * parsers.optionalspace
                           * parsers.rbrace
 
 -- parse Atx heading start and return level
@@ -19431,12 +20504,14 @@ function M.reader.new(writer, options, extensions)
 % \par
 % \begin{markdown}
 %
-% Make the `writer` parameter available as \luamdef{reader->writer}, so that it
-% is accessible from extensions.
+% Make the `writer` and `options` parameters available as
+% \luamdef{reader->writer} and \luamdef{reader->options}, respectively, so
+% that they are accessible from extensions.
 %
 % \end{markdown}
 %  \begin{macrocode}
   self.writer = writer
+  self.options = options
 %    \end{macrocode}
 % \par
 % \begin{markdown}
@@ -20009,16 +21084,16 @@ function M.reader.new(writer, options, extensions)
                        * parsers.skipblanklines )
                      / writer.bulletlist
 
-  local function ordered_list(items,tight,startNumber)
+  local function ordered_list(items,tight,startnum)
     if options.startNumber then
-      startNumber = tonumber(startNumber) or 1  -- fallback for '#'
-      if startNumber ~= nil then
-        startNumber = math.floor(startNumber)
+      startnum = tonumber(startnum) or 1  -- fallback for '#'
+      if startnum ~= nil then
+        startnum = math.floor(startnum)
       end
     else
-      startNumber = nil
+      startnum = nil
     end
-    return writer.orderedlist(items,tight,startNumber)
+    return writer.orderedlist(items,tight,startnum)
   end
 
   parsers.OrderedList = Cg(parsers.enumerator, "listtype") *
@@ -20131,6 +21206,9 @@ function M.reader.new(writer, options, extensions)
                             + V("UlOrStarLine")
                             + V("Strong")
                             + V("Emph")
+                            + V("StrikeThrough")
+                            + V("Superscript")
+                            + V("Subscript")
                             + V("InlineNote")
                             + V("NoteRef")
                             + V("Citations")
@@ -20152,6 +21230,9 @@ function M.reader.new(writer, options, extensions)
                             + V("UlOrStarLine")
                             + V("Strong")
                             + V("Emph")
+                            + V("StrikeThrough")
+                            + V("Superscript")
+                            + V("Subscript")
                             + V("InlineNote")
                             + V("NoteRef")
                             + V("Citations")
@@ -20174,6 +21255,9 @@ function M.reader.new(writer, options, extensions)
       UlOrStarLine          = parsers.UlOrStarLine,
       Strong                = parsers.Strong,
       Emph                  = parsers.Emph,
+      StrikeThrough         = parsers.fail,
+      Superscript           = parsers.fail,
+      Subscript             = parsers.fail,
       InlineNote            = parsers.fail,
       NoteRef               = parsers.fail,
       Citations             = parsers.fail,
@@ -20195,9 +21279,9 @@ function M.reader.new(writer, options, extensions)
 % \par
 % \begin{markdown}
 %
-% Define a hash table of all characters with a special meaning that can be
-% escaped and add method `reader->add_special_character` that extends the
-% hash table and updates the \acro{peg} grammar.
+% Define a hash table of all characters with special meaning and add method
+% `reader->add_special_character` that extends the hash table and updates the
+% \acro{peg} grammar.
 %
 % \end{markdown}
 %  \begin{macrocode}
@@ -20378,7 +21462,7 @@ M.extensions = {}
 %#### Citations
 %
 % The \luamdef{extensions.citations} function implements the Pandoc citation
-% syntax extension. When the `citation_nbsps` parameter is `true`, the syntax
+% syntax extension. When the `citation_nbsps` parameter is enabled, the syntax
 % extension will replace regular spaces with non-breaking spaces inside the
 % prenotes and postnotes of citations.
 %
@@ -20403,6 +21487,8 @@ M.extensions.citations = function(citation_nbsps)
   }
   return {
     extend_writer = function(self)
+      local options = self.options
+
 %    \end{macrocode}
 % \par
 % \begin{markdown}
@@ -20426,7 +21512,7 @@ M.extensions.citations = function(citation_nbsps)
 %
 % \end{markdown}
 %  \begin{macrocode}
-      if self.hybrid then
+      if options.hybrid then
         self.citation = self.escape_minimal
       else
         self.citation = escape_citation
@@ -20870,6 +21956,8 @@ end
 M.extensions.fenced_code = function(blank_before_code_fence)
   return {
     extend_writer = function(self)
+      local options = self.options
+
 %    \end{macrocode}
 % \par
 % \begin{markdown}
@@ -20883,7 +21971,7 @@ M.extensions.fenced_code = function(blank_before_code_fence)
       function self.fencedCode(i, s)
         if not self.is_writing then return "" end
         s = string.gsub(s, '[\r\n%s]*$', '')
-        local name = util.cache(self.cacheDir, s, nil, nil, ".verbatim")
+        local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim")
         return {"\\markdownRendererInputFencedCode{",name,"}{",i,"}"}
       end
     end, extend_reader = function(self)
@@ -20963,6 +22051,8 @@ M.extensions.fenced_code = function(blank_before_code_fence)
 
       parsers.EndlineExceptions = parsers.EndlineExceptions + fencestart
       syntax.EndlineExceptions = parsers.EndlineExceptions
+
+      self.add_special_character("~")
     end
   }
 end
@@ -21126,8 +22216,8 @@ end
 %
 % The \luamdef{extensions.jekyll_data} function implements the Pandoc
 % `yaml_metadata_block` syntax extension for entering metadata in \acro{yaml}.
-% When the `expect_jekyll_data` is `true`, then a markdown document may
-% begin directly with \acro{yaml} metadata and may contain nothing but
+% When the `expect_jekyll_data` parameter is `true`, then a markdown document
+% may begin directly with \acro{yaml} metadata and may contain nothing but
 % \acro{yaml} metadata
 %
 % \end{markdown}
@@ -21282,7 +22372,7 @@ end
 %
 % The \luamdef{extensions.pipe_table} function implements the \acro{PHP}
 % Markdown table syntax extension (affectionately known as pipe tables). When
-% the parameter `table_captions` is `true`, the function also implements the
+% the `table_captions` parameter is `true`, the function also implements the
 % Pandoc `table_captions` syntax extension for table captions.
 %
 % \end{markdown}
@@ -21325,115 +22415,438 @@ M.extensions.pipe_tables = function(table_captions)
                     * parsers.optionalspace
     end
 
-    return Ct(row_beginning
-             * (-- single column with no leading pipes
-                #(column_separator
-                 * parsers.optionalspace
-                 * parsers.newline)
-               * column_separator
-               * parsers.optionalspace
-               -- single column with leading pipes or
-               -- more than a single column
-               + (column_separator
-                 * parsers.optionalspace
-                 * column
-                 * parsers.optionalspace)^1
-               * (column_separator
-                 * parsers.optionalspace)^-1))
-  end
+    return Ct(row_beginning
+             * (-- single column with no leading pipes
+                #(column_separator
+                 * parsers.optionalspace
+                 * parsers.newline)
+               * column_separator
+               * parsers.optionalspace
+               -- single column with leading pipes or
+               -- more than a single column
+               + (column_separator
+                 * parsers.optionalspace
+                 * column
+                 * parsers.optionalspace)^1
+               * (column_separator
+                 * parsers.optionalspace)^-1))
+  end
+
+  return {
+    extend_writer = function(self)
+%    \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Define \luamdef{writer->table} as a function that will transform an input
+% table to the output format, where `rows` is a sequence of columns and a
+% column is a sequence of cell texts.
+%
+% \end{markdown}
+%  \begin{macrocode}
+      function self.table(rows, caption)
+        if not self.is_writing then return "" end
+        local buffer = {"\\markdownRendererTable{",
+          caption or "", "}{", #rows - 1, "}{", #rows[1], "}"}
+        local temp = rows[2] -- put alignments on the first row
+        rows[2] = rows[1]
+        rows[1] = temp
+        for i, row in ipairs(rows) do
+          table.insert(buffer, "{")
+          for _, column in ipairs(row) do
+            if i > 1 then -- do not use braces for alignments
+              table.insert(buffer, "{")
+            end
+            table.insert(buffer, column)
+            if i > 1 then
+              table.insert(buffer, "}")
+            end
+          end
+          table.insert(buffer, "}")
+        end
+        return buffer
+      end
+    end, extend_reader = function(self)
+      local parsers = self.parsers
+      local syntax = self.syntax
+      local writer = self.writer
+
+      local table_hline_separator = parsers.pipe + parsers.plus
+
+      local table_hline_column = (parsers.dash
+                                 - #(parsers.dash
+                                    * (parsers.spacechar
+                                      + table_hline_separator
+                                      + parsers.newline)))^1
+                               * (parsers.colon * Cc("r")
+                                 + parsers.dash * Cc("d"))
+                               + parsers.colon
+                               * (parsers.dash
+                                 - #(parsers.dash
+                                    * (parsers.spacechar
+                                      + table_hline_separator
+                                      + parsers.newline)))^1
+                               * (parsers.colon * Cc("c")
+                                 + parsers.dash * Cc("l"))
+
+      local table_hline = pipe_table_row(false
+                                        , table_hline_column
+                                        , table_hline_separator
+                                        , table_hline_column)
+
+      local table_caption_beginning = parsers.skipblanklines
+                                    * parsers.nonindentspace
+                                    * (P("Table")^-1 * parsers.colon)
+                                    * parsers.optionalspace
+
+      local table_row = pipe_table_row(true
+                                      , (C((parsers.linechar - parsers.pipe)^1)
+                                        / self.parser_functions.parse_inlines)
+                                      , parsers.pipe
+                                      , (C((parsers.linechar - parsers.pipe)^0)
+                                        / self.parser_functions.parse_inlines))
+
+      local table_caption
+      if table_captions then
+        table_caption = #table_caption_beginning
+                      * table_caption_beginning
+                      * Ct(parsers.IndentedInline^1)
+                      * parsers.newline
+      else
+        table_caption = parsers.fail
+      end
+
+      local PipeTable = Ct(table_row * parsers.newline
+                        * table_hline
+                        * (parsers.newline * table_row)^0)
+                      / make_pipe_table_rectangular
+                      * table_caption^-1
+                      / writer.table
+
+      syntax.PipeTable = PipeTable
+    end
+  }
+end
+%    \end{macrocode}
+% \begin{markdown}
+%
+%#### Strike-Through
+%
+% The \luamdef{extensions.strike_through} function implements the Pandoc
+% strike-through syntax extension.
+%
+% \end{markdown}
+%  \begin{macrocode}
+M.extensions.strike_through = function()
+  return {
+    extend_writer = function(self)
+%    \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Define \luamdef{writer->strike_through} as a function that will transform
+% a strike-through span `s` of input text to the output format.
+%
+% \end{markdown}
+%  \begin{macrocode}
+      function self.strike_through(s)
+        return {"\\markdownRendererStrikeThrough{",s,"}"}
+      end
+    end, extend_reader = function(self)
+      local parsers = self.parsers
+      local syntax = self.syntax
+      local writer = self.writer
+
+      local StrikeThrough = (
+        parsers.between(parsers.Inline, parsers.doubletildes,
+                        parsers.doubletildes)
+      ) / writer.strike_through
+
+      syntax.StrikeThrough = StrikeThrough
+
+      self.add_special_character("~")
+    end
+  }
+end
+%    \end{macrocode}
+% \begin{markdown}
+%
+%#### Superscripts
+%
+% The \luamdef{extensions.superscripts} function implements the Pandoc
+% superscript syntax extension.
+%
+% \end{markdown}
+%  \begin{macrocode}
+M.extensions.superscripts = function()
+  return {
+    extend_writer = function(self)
+%    \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Define \luamdef{writer->superscript} as a function that will transform
+% a superscript span `s` of input text to the output format.
+%
+% \end{markdown}
+%  \begin{macrocode}
+      function self.superscript(s)
+        return {"\\markdownRendererSuperscript{",s,"}"}
+      end
+    end, extend_reader = function(self)
+      local parsers = self.parsers
+      local syntax = self.syntax
+      local writer = self.writer
+
+      local Superscript = (
+        parsers.between(parsers.Str, parsers.circumflex, parsers.circumflex)
+      ) / writer.superscript
+
+      syntax.Superscript = Superscript
+
+      self.add_special_character("^")
+    end
+  }
+end
+%    \end{macrocode}
+% \begin{markdown}
+%
+%#### Subscripts
+%
+% The \luamdef{extensions.subscripts} function implements the Pandoc
+% subscript syntax extension.
+%
+% \end{markdown}
+%  \begin{macrocode}
+M.extensions.subscripts = function()
+  return {
+    extend_writer = function(self)
+%    \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Define \luamdef{writer->subscript} as a function that will transform
+% a subscript span `s` of input text to the output format.
+%
+% \end{markdown}
+%  \begin{macrocode}
+      function self.subscript(s)
+        return {"\\markdownRendererSubscript{",s,"}"}
+      end
+    end, extend_reader = function(self)
+      local parsers = self.parsers
+      local syntax = self.syntax
+      local writer = self.writer
+
+      local Subscript = (
+        parsers.between(parsers.Str, parsers.tilde, parsers.tilde)
+      ) / writer.subscript
 
+      syntax.Subscript = Subscript
+
+      self.add_special_character("~")
+    end
+  }
+end
+%    \end{macrocode}
+% \begin{markdown}
+%
+%#### Fancy Lists
+%
+% The \luamdef{extensions.fancy_lists} function implements the Pandoc fancy
+% list extension.
+%
+% \end{markdown}
+%  \begin{macrocode}
+M.extensions.fancy_lists = function()
   return {
     extend_writer = function(self)
+      local options = self.options
+
 %    \end{macrocode}
 % \par
 % \begin{markdown}
 %
-% Define \luamdef{writer->table} as a function that will transform an input
-% table to the output format, where `rows` is a sequence of columns and a
-% column is a sequence of cell texts.
+% Define \luamdef{writer->fancylist} as a function that will transform an
+% input ordered list to the output format, where:
+%
+%- `items` is an array of the list items,
+%- `tight` specifies, whether the list is tight or not,
+%- `startnum` is the number of the first list item,
+%- `numstyle` is the style of the list item labels from among the following:
+%    - `Decimal` -- decimal arabic numbers,
+%    - `LowerRoman` -- lower roman numbers,
+%    - `UpperRoman` -- upper roman numbers,
+%    - `LowerAlpha` -- lower ASCII alphabetic characters, and
+%    - `UpperAlpha` -- upper ASCII alphabetic characters, and
+%- `numdelim` is the style of delimiters between list item labels and
+%  texts from among the following:
+%    - `Default` -- default style,
+%    - `OneParen` -- parentheses, and
+%    - `Period` -- periods.
 %
 % \end{markdown}
 %  \begin{macrocode}
-      function self.table(rows, caption)
+      function self.fancylist(items,tight,startnum,numstyle,numdelim)
         if not self.is_writing then return "" end
-        local buffer = {"\\markdownRendererTable{",
-          caption or "", "}{", #rows - 1, "}{", #rows[1], "}"}
-        local temp = rows[2] -- put alignments on the first row
-        rows[2] = rows[1]
-        rows[1] = temp
-        for i, row in ipairs(rows) do
-          table.insert(buffer, "{")
-          for _, column in ipairs(row) do
-            if i > 1 then -- do not use braces for alignments
-              table.insert(buffer, "{")
-            end
-            table.insert(buffer, column)
-            if i > 1 then
-              table.insert(buffer, "}")
-            end
+        local buffer = {}
+        local num = startnum
+        for _,item in ipairs(items) do
+          buffer[#buffer + 1] = self.fancyitem(item,num)
+          if num ~= nil then
+            num = num + 1
           end
-          table.insert(buffer, "}")
         end
-        return buffer
+        local contents = util.intersperse(buffer,"\n")
+        if tight and options.tightLists then
+          return {"\\markdownRendererFancyOlBeginTight{",
+                  numstyle,"}{",numdelim,"}",contents,
+                  "\n\\markdownRendererFancyOlEndTight "}
+        else
+          return {"\\markdownRendererFancyOlBegin{",
+                  numstyle,"}{",numdelim,"}",contents,
+                  "\n\\markdownRendererFancyOlEnd "}
+        end
+      end
+%    \end{macrocode}
+% \begin{markdown}
+%
+% Define \luamdef{writer->fancyitem} as a function that will transform an
+% input fancy ordered list item to the output format, where `s` is the text of
+% the list item. If the optional parameter `num` is present, it is the number
+% of the list item.
+%
+% \end{markdown}
+%  \begin{macrocode}
+      function self.fancyitem(s,num)
+        if num ~= nil then
+          return {"\\markdownRendererFancyOlItemWithNumber{",num,"}",s,
+                  "\\markdownRendererFancyOlItemEnd "}
+        else
+          return {"\\markdownRendererFancyOlItem ",s,"\\markdownRendererFancyOlItemEnd "}
+        end
       end
     end, extend_reader = function(self)
       local parsers = self.parsers
+      local options = self.options
       local syntax = self.syntax
       local writer = self.writer
 
-      local table_hline_separator = parsers.pipe + parsers.plus
+      local label = parsers.dig + parsers.letter
+      local numdelim = parsers.period + parsers.rparent
+      local enumerator = C(label^3 * numdelim) * #parsers.spacing
+                       + C(label^2 * numdelim) * #parsers.spacing
+                                         * (parsers.tab + parsers.space^1)
+                       + C(label * numdelim) * #parsers.spacing
+                                       * (parsers.tab + parsers.space^-2)
+                       + parsers.space * C(label^2 * numdelim)
+                                       * #parsers.spacing
+                       + parsers.space * C(label * numdelim)
+                                       * #parsers.spacing
+                                       * (parsers.tab + parsers.space^-1)
+                       + parsers.space * parsers.space * C(label^1
+                                       * numdelim) * #parsers.spacing
+      local starter = parsers.bullet + enumerator
 
-      local table_hline_column = (parsers.dash
-                                 - #(parsers.dash
-                                    * (parsers.spacechar
-                                      + table_hline_separator
-                                      + parsers.newline)))^1
-                               * (parsers.colon * Cc("r")
-                                 + parsers.dash * Cc("d"))
-                               + parsers.colon
-                               * (parsers.dash
-                                 - #(parsers.dash
-                                    * (parsers.spacechar
-                                      + table_hline_separator
-                                      + parsers.newline)))^1
-                               * (parsers.colon * Cc("c")
-                                 + parsers.dash * Cc("l"))
+      local NestedList = Cs((parsers.optionallyindentedline
+                            - starter)^1)
+                       / function(a) return "\001"..a end
 
-      local table_hline = pipe_table_row(false
-                                        , table_hline_column
-                                        , table_hline_separator
-                                        , table_hline_column)
+      local ListBlockLine  = parsers.optionallyindentedline
+                           - parsers.blankline - (parsers.indent^-1
+                                                 * starter)
 
-      local table_caption_beginning = parsers.skipblanklines
-                                    * parsers.nonindentspace
-                                    * (P("Table")^-1 * parsers.colon)
-                                    * parsers.optionalspace
+      local ListBlock = parsers.line * ListBlockLine^0
 
-      local table_row = pipe_table_row(true
-                                      , (C((parsers.linechar - parsers.pipe)^1)
-                                        / self.parser_functions.parse_inlines)
-                                      , parsers.pipe
-                                      , (C((parsers.linechar - parsers.pipe)^0)
-                                        / self.parser_functions.parse_inlines))
+      local ListContinuationBlock = parsers.blanklines * (parsers.indent / "")
+                                  * ListBlock
 
-      local table_caption
-      if table_captions then
-        table_caption = #table_caption_beginning
-                      * table_caption_beginning
-                      * Ct(parsers.IndentedInline^1)
-                      * parsers.newline
-      else
-        table_caption = parsers.fail
+      local TightListItem = function(starter)
+          return -parsers.HorizontalRule
+                 * (Cs(starter / "" * parsers.tickbox^-1 * ListBlock * NestedList^-1)
+                   / self.parser_functions.parse_blocks_nested)
+                 * -(parsers.blanklines * parsers.indent)
       end
 
-      local PipeTable = Ct(table_row * parsers.newline
-                        * table_hline
-                        * (parsers.newline * table_row)^0)
-                      / make_pipe_table_rectangular
-                      * table_caption^-1
-                      / writer.table
+      local LooseListItem = function(starter)
+          return -parsers.HorizontalRule
+                 * Cs( starter / "" * parsers.tickbox^-1 * ListBlock * Cc("\n")
+                   * (NestedList + ListContinuationBlock^0)
+                   * (parsers.blanklines / "\n\n")
+                   ) / self.parser_functions.parse_blocks_nested
+      end
+
+      local function roman2number(roman)
+        local romans = { ["L"] = 50, ["X"] = 10, ["V"] = 5, ["I"] = 1 }
+        local numeral = 0
+
+        local i = 1
+        local len = string.len(roman)
+        while i < len do
+          local z1, z2 = romans[ string.sub(roman, i, i) ], romans[ string.sub(roman, i+1, i+1) ]
+          if z1 < z2 then
+              numeral = numeral + (z2 - z1)
+              i = i + 2
+          else
+              numeral = numeral + z1
+              i = i + 1
+          end
+        end
+        if i <= len then numeral = numeral + romans[ string.sub(roman,i,i) ] end
+        return numeral
+      end
+
+      local function sniffstyle(itemprefix)
+        local numstr, delimend = itemprefix:match("^([A-Za-z0-9]*)([.)]*)")
+        local numdelim
+        if delimend == ")" then
+          numdelim = "OneParen"
+        elseif delimend == "." then
+          numdelim = "Period"
+        else
+          numdelim = "Default"
+        end
+        numstr = numstr or itemprefix
+
+        local num
+        num = numstr:match("^([IVXL]+)")
+        if num then
+          return roman2number(num), "UpperRoman", numdelim
+        end
+        num = numstr:match("^([ivxl]+)")
+        if num then
+          return roman2number(string.upper(num)), "LowerRoman", numdelim
+        end
+        num = numstr:match("^([A-Z])")
+        if num then
+          return string.byte(num) - string.byte("A") + 1, "UpperAlpha", numdelim
+        end
+        num = numstr:match("^([a-z])")
+        if num then
+          return string.byte(num) - string.byte("a") + 1, "LowerAlpha", numdelim
+        end
+        return math.floor(tonumber(numstr) or 1), "Decimal", numdelim
+      end
+
+      local function fancylist(items,tight,start)
+        local startnum, numstyle, numdelim = sniffstyle(start)
+        return writer.fancylist(items,tight,
+                                options.startNumber and startnum,
+                                numstyle or "Decimal",
+                                numdelim or "Default")
+      end
+
+      local FancyList = Cg(enumerator, "listtype") *
+                      ( Ct(TightListItem(Cb("listtype"))
+                          * TightListItem(enumerator)^0)
+                      * Cc(true) * parsers.skipblanklines * -enumerator
+                      + Ct(LooseListItem(Cb("listtype"))
+                          * LooseListItem(enumerator)^0)
+                      * Cc(false) * parsers.skipblanklines
+                      ) * Cb("listtype") / fancylist
+
+      syntax.OrderedList = FancyList
 
-      syntax.PipeTable = PipeTable
     end
   }
 end
@@ -21516,6 +22929,26 @@ function M.new(options)
     table.insert(extensions, pipe_tables_extension)
   end
 
+  if options.strikeThrough then
+    local strike_through_extension = M.extensions.strike_through()
+    table.insert(extensions, strike_through_extension)
+  end
+
+  if options.subscripts then
+    local subscript_extension = M.extensions.subscripts()
+    table.insert(extensions, subscript_extension)
+  end
+
+  if options.superscripts then
+    local superscript_extension = M.extensions.superscripts()
+    table.insert(extensions, superscript_extension)
+  end
+
+  if options.fancyLists then
+    local fancy_lists_extension = M.extensions.fancy_lists()
+    table.insert(extensions, fancy_lists_extension)
+  end
+
   local writer = M.writer.new(options)
   local reader = M.reader.new(writer, options, extensions)
 
@@ -21666,11 +23099,18 @@ end
 \def\markdownRendererUlEndTightPrototype{}%
 \def\markdownRendererOlBeginPrototype{}%
 \def\markdownRendererOlBeginTightPrototype{}%
+\def\markdownRendererFancyOlBeginPrototype#1#2{\markdownRendererOlBegin}%
+\def\markdownRendererFancyOlBeginTightPrototype#1#2{\markdownRendererOlBeginTight}%
 \def\markdownRendererOlItemPrototype{}%
 \def\markdownRendererOlItemWithNumberPrototype#1{}%
 \def\markdownRendererOlItemEndPrototype{}%
+\def\markdownRendererFancyOlItemPrototype{\markdownRendererOlItem}%
+\def\markdownRendererFancyOlItemWithNumberPrototype{\markdownRendererOlItemWithNumber}%
+\def\markdownRendererFancyOlItemEndPrototype{}%
 \def\markdownRendererOlEndPrototype{}%
 \def\markdownRendererOlEndTightPrototype{}%
+\def\markdownRendererFancyOlEndPrototype{\markdownRendererOlEnd}%
+\def\markdownRendererFancyOlEndTightPrototype{\markdownRendererOlEndTight}%
 \def\markdownRendererDlBeginPrototype{}%
 \def\markdownRendererDlBeginTightPrototype{}%
 \def\markdownRendererDlItemPrototype#1{#1}%
@@ -21700,6 +23140,9 @@ end
 \def\markdownRendererTickedBoxPrototype{[X]}%
 \def\markdownRendererHalfTickedBoxPrototype{[/]}%
 \def\markdownRendererUntickedBoxPrototype{[ ]}%
+\def\markdownRendererStrikeThroughPrototype#1{#1}%
+\def\markdownRendererSuperscriptPrototype#1{#1}%
+\def\markdownRendererSubscriptPrototype#1{#1}%
 %    \end{macrocode}
 % \par
 % \begin{markdown}
@@ -22974,9 +24417,8 @@ end
 %    \end{macrocode}
 % \begin{markdown}
 %
-% After processing the options, activate the `renderers`, `rendererPrototypes`,
-% and `code` keys. The `code` key is used to immediately expand and execute code,
-% which can be especially useful in \LaTeX{} setup snippets.
+% After processing the options, activate the `jekyllDataRenderes`, `renderers`,
+% `rendererPrototypes`, and `code` keys.
 %
 % \end{markdown}
 %  \begin{macrocode}
@@ -22994,8 +24436,50 @@ end
         { markdown/latex-options/renderer-prototypes }
         { #1 }
     },
+%    \end{macrocode}
+% \begin{markdown}
+%
+% The `code` key is used to immediately expand and execute code, which can be
+% especially useful in \LaTeX{} setup snippets.
+%
+% \end{markdown}
+%  \begin{macrocode}
     code .code:n = { #1 },
+%    \end{macrocode}
+% \begin{markdown}
+%
+% The `jekyllDataRenderers` key can be used as a syntactic sugar for setting
+% the `markdown/jekyllData` key--values (see Section <#sec:expl3yamlmetadata>)
+% without using the expl3 language.
+%
+% \end{markdown}
+%  \begin{macrocode}
+    jekyllDataRenderers .code:n = {
+      \keys_set:nn
+        { markdown/latex-options/jekyll-data-renderers }
+        { #1 }
+    },
+  }
+\keys_define:nn
+  { markdown/latex-options/jekyll-data-renderers }
+  {
+    unknown .code:n = {
+      \tl_set_eq:NN
+        \l_tmpa_tl
+        \l_keys_key_str
+      \tl_put_right:Nn
+        \l_tmpa_tl
+        {
+          .code:n = { #1 }
+        }
+      \keys_define:nV
+        { markdown/jekyllData }
+        \l_tmpa_tl
+    }
   }
+\cs_generate_variant:Nn
+  \keys_define:nn
+  { nV }
 \ExplSyntaxOff
 %    \end{macrocode}
 % \par
@@ -23031,22 +24515,121 @@ end
 %
 % \end{markdown}
 %  \begin{macrocode}
+\ExplSyntaxOn
 \@ifpackageloaded{paralist}{
+  \tl_new:N
+    \l_@@_latex_fancy_list_item_label_number_style_tl
+  \tl_new:N
+    \l_@@_latex_fancy_list_item_label_delimiter_style_tl
+  \cs_new:Nn
+    \@@_latex_fancy_list_item_label_number:nn
+    {
+      \str_case:nn
+        { #1 }
+        {
+          { Decimal } { #2 }
+          { LowerRoman } { \int_to_roman:n { #2 } }
+          { UpperRoman } { \int_to_Roman:n { #2 } }
+          { LowerAlpha } { \int_to_alph:n { #2 } }
+          { UpperAlpha } { \int_to_alph:n { #2 } }
+        }
+    }
+  \cs_new:Nn
+    \@@_latex_fancy_list_item_label_delimiter:n
+    {
+      \str_case:nn
+        { #1 }
+        {
+          { Default } { . }
+          { OneParen } { ) }
+          { Period } { - }
+        }
+    }
+  \cs_new:Nn
+    \@@_latex_fancy_list_item_label:nnn
+    {
+      \@@_latex_fancy_list_item_label_delimiter:n
+        { #2 }
+      \@@_latex_fancy_list_item_label_number:nn
+        { #1 }
+        { #3 }
+    }
+  \cs_new:Nn
+    \@@_latex_paralist_style:nn
+    {
+      \str_case:nn
+        { #1 }
+        {
+          { Decimal } { 1 }
+          { LowerRoman } { i }
+          { UpperRoman } { I }
+          { LowerAlpha } { a }
+          { UpperAlpha } { A }
+        }
+      \@@_latex_fancy_list_item_label_delimiter:n
+        { #2 }
+    }
   \markdownSetup{rendererPrototypes={
     ulBeginTight = {\begin{compactitem}},
     ulEndTight = {\end{compactitem}},
+    fancyOlBegin = {
+      \group_begin:
+      \tl_set:Nn
+        \l_@@_latex_fancy_list_item_label_number_style_tl
+        { #1 }
+      \tl_set:Nn
+        \l_@@_latex_fancy_list_item_label_delimiter_style_tl
+        { #2 }
+      \begin{enumerate}[ \@@_latex_paralist_style:nn { #1 } { #2 } ]
+    },
+    fancyOlEnd = {
+      \end{enumerate}
+      \group_end:
+    },
     olBeginTight = {\begin{compactenum}},
     olEndTight = {\end{compactenum}},
+    fancyOlBeginTight = {
+      \group_begin:
+      \tl_set:Nn
+        \l_@@_latex_fancy_list_item_label_number_style_tl
+        { #1 }
+      \tl_set:Nn
+        \l_@@_latex_fancy_list_item_label_delimiter_style_tl
+        { #2 }
+      \begin{compactenum}[ \@@_latex_paralist_style:nn { #1 } { #2 } ]
+    },
+    fancyOlEndTight = {
+      \end{compactenum}
+      \group_end:
+    },
+    fancyOlItemWithNumber = {
+      \markdownRendererOlItemWithNumber
+        {
+          \@@_latex_fancy_list_item_label:VVn
+            \l_@@_latex_fancy_list_item_label_number_style_tl
+            \l_@@_latex_fancy_list_item_label_delimiter_style_tl
+            { #1 }
+        }
+    },
     dlBeginTight = {\begin{compactdesc}},
     dlEndTight = {\end{compactdesc}}}}
+  \cs_generate_variant:Nn
+    \@@_latex_fancy_list_item_label:nnn
+    { VVn }
 }{
   \markdownSetup{rendererPrototypes={
     ulBeginTight = {\markdownRendererUlBegin},
     ulEndTight = {\markdownRendererUlEnd},
+    fancyOlBegin = {\markdownRendererOlBegin},
+    fancyOlEnd = {\markdownRendererOlEnd},
     olBeginTight = {\markdownRendererOlBegin},
     olEndTight = {\markdownRendererOlEnd},
+    fancyOlBeginTight = {\markdownRendererOlBegin},
+    fancyOlEndTight = {\markdownRendererOlEnd},
     dlBeginTight = {\markdownRendererDlBegin},
-    dlEndTight = {\markdownRendererDlEnd}}}}
+    dlEndTight = {\markdownRendererDlEnd}}}
+}
+\ExplSyntaxOff
 \RequirePackage{amsmath,ifthen}
 %    \end{macrocode}
 % \par
@@ -23177,6 +24760,8 @@ end
       },
     }%
   },
+  superscript = {\textsuperscript{#1}},
+  subscript = {\textsubscript{#1}},
   blockQuoteBegin = {\begin{quotation}},
   blockQuoteEnd = {\end{quotation}},
   inputVerbatim = {\VerbatimInput{#1}},
@@ -23801,6 +25386,26 @@ end
 % \par
 % \begin{markdown}
 %
+%#### Strike-Through
+% If the \Opt{strikeThrough} option is enabled, we will load the
+% \pkg{soulutf8} package and use it to implement strike-throughs.
+%
+% \end{markdown}
+%  \begin{macrocode}
+\markdownIfOption{strikeThrough}{%
+  \RequirePackage{soulutf8}%
+  \markdownSetup{
+    rendererPrototypes = {
+      strikeThrough = {%
+        \st{#1}%
+      },
+    }
+  }
+}{}
+%    \end{macrocode}
+% \par
+% \begin{markdown}
+%
 %### Miscellanea
 % When buffering user input, we should disable the bytes with the high bit set,
 % since these are made active by the \pkg{inputenc} package. We will do this by
@@ -23833,21 +25438,6 @@ end
 % consequence, we can directly reuse the existing plain \TeX{} implementation
 % after supplying the missing plain \TeX{} macros.
 %
-% The \Hologo{ConTeXt} implementation redefines the plain \TeX{} logging macros
-% (see Section <#sec:texinterfacelogging>) to use the \Hologo{ConTeXt}
-% \mref{writestatus} macro.
-%
-% \end{markdown}
-%  \begin{macrocode}
-\def\markdownInfo#1{\writestatus{markdown}{#1.}}%
-\def\markdownWarning#1{\writestatus{markdown\space warn}{#1.}}%
-\def\dospecials{\do\ \do\\\do\{\do\}\do\$\do\&%
-  \do\#\do\^\do\_\do\%\do\~}%
-\input markdown/markdown
-%    \end{macrocode}
-% \par
-% \begin{markdown}
-%
 % When buffering user input, we should disable the bytes with the high bit set,
 % since these are made active by the \mref{enableregime} macro. We will do this
 % by redefining the \mref{markdownMakeOther} macro accordingly. The code is
@@ -23877,6 +25467,26 @@ end
 % \begin{markdown}
 %
 %### Typesetting Markdown
+% The \mref{inputmarkdown} is defined to accept an optional argument with
+% options recognized by the \Hologo{ConTeXt} interface (see Section
+% <#sec:contextoptions>).
+%
+% \end{markdown}
+%  \begin{macrocode}
+\long\def\inputmarkdown{%
+  \dosingleempty
+  \doinputmarkdown}%
+\long\def\doinputmarkdown[#1]#2{%
+  \begingroup
+    \iffirstargument
+      \setupmarkdown{#1}%
+    \fi
+    \markdownInput{#2}%
+  \endgroup}%
+%    \end{macrocode}
+% \par
+% \begin{markdown}
+%
 % The \mref{startmarkdown} and \mref{stopmarkdown} macros are implemented using the
 % \mref{markdownReadAndConvert} macro.
 %
@@ -24046,11 +25656,17 @@ end
 \def\markdownRendererHorizontalRulePrototype{%
   \blackrule[height=1pt, width=\hsize]}%
 \def\markdownRendererFootnotePrototype#1{\footnote{#1}}%
-\stopmodule\protect
+\def\markdownRendererTickedBoxPrototype{$\boxtimes$}
+\def\markdownRendererHalfTickedBoxPrototype{$\boxdot$}
+\def\markdownRendererUntickedBoxPrototype{$\square$}
+\def\markdownRendererStrikeThroughPrototype#1{\overstrikes{#1}}
+\def\markdownRendererSuperscriptPrototype#1{\high{#1}}
+\def\markdownRendererSubscriptPrototype#1{\low{#1}}
 %    \end{macrocode}
 % \par
 % \begin{markdown}
 %
+%#### Tables
 % There is a basic implementation of tables.
 %
 % \end{markdown}
@@ -24120,9 +25736,7 @@ end
   \ifnum\markdownConTeXtColumnCounter<\markdownConTeXtColumnTotal\relax\else
     \expandafter\gobbleoneargument
   \fi\markdownConTeXtRenderTableCell}
-\def\markdownRendererTickedBox{$\boxtimes$}
-\def\markdownRendererHalfTickedBox{$\boxdot$}
-\def\markdownRendererUntickedBox{$\square$}
+\stopmodule\protect
 %    \end{macrocode}
 % \iffalse
 %</context>
-- 
cgit v1.2.3

