summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/generic/markdown/markdown.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/generic/markdown/markdown.dtx')
-rw-r--r--Master/texmf-dist/source/generic/markdown/markdown.dtx1420
1 files changed, 1118 insertions, 302 deletions
diff --git a/Master/texmf-dist/source/generic/markdown/markdown.dtx b/Master/texmf-dist/source/generic/markdown/markdown.dtx
index 5b3f73cb8e2..1a391e223fe 100644
--- a/Master/texmf-dist/source/generic/markdown/markdown.dtx
+++ b/Master/texmf-dist/source/generic/markdown/markdown.dtx
@@ -275,6 +275,15 @@ pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
+ counter-reset: line;
+}
+
+.sourceCode.linenos > span {
+ counter-increment: line;
+}
+
+.sourceCode.linenos > span:before{
+ content: counter(line) " ";
}
b, strong {
@@ -1213,7 +1222,8 @@ local md5 = require("md5")
%
%: A package that provides the `compactitem`, `compactenum`, and
% `compactdesc` macros for the typesetting of tight bulleted lists,
-% ordered lists, and definition lists.
+% ordered lists, and definition lists as well as the rendering of
+% fancy lists.
%
% \pkg{ifthen}
%
@@ -1263,13 +1273,24 @@ local md5 = require("md5")
%: A package that is used to polyfill the general hook management system in
% the default renderer prototypes for \acro{yaml} metadata, see Section
% <#sec:latexyamlmetadata>, and also in the default renderer prototype
-% for attribute identifiers.
+% for identifier attributes.
%
% \pkg{soulutf8}
%
%: A package that is used in the default renderer prototype for
% strike-throughs.
%
+% \pkg{ltxcmds}
+%
+%: A package that is used to detect whether the \pkg{minted} and
+% \pkg{listings} packages are loaded in the default renderer prototype
+% for fenced code blocks.
+%
+% \pkg{verse}
+%
+%: A package that is used in the default renderer prototypes for
+% line blocks.
+%
% \end{markdown}
% \begin{macrocode}
\RequirePackage{expl3}
@@ -1312,7 +1333,7 @@ local md5 = require("md5")
% Extensive user documentation for the Markdown package was kindly written by
% Lian Tze Lim and published by Overleaf.
%
-% Funding by the the Faculty of Informatics at the Masaryk~University
+% Funding by the Faculty of Informatics at the Masaryk~University
% in~Brno~[@novotny15] is gratefully acknowledged.
%
% Support for content slicing (Lua options \Opt{shiftHeadings} and \Opt{slice})
@@ -3290,6 +3311,7 @@ following content:
\begin{markdown}
A paragraph.
+
::: {.identifier}
A fenced div.
:::
@@ -3297,9 +3319,10 @@ A fenced div.
\begin{markdown*}{blankBeforeDivFence}
A paragraph.
-```
+
+::: {.identifier}
Not a fenced div.
-```
+:::
\end{markdown*}
\end{document}
@@ -3315,7 +3338,9 @@ following text:
>
> A fenced div.
>
-> A paragraph. ::: {.identifier} Not a fenced div. :::
+> A paragraph.
+>
+> ::: {.identifier} Not a fenced div. :::
%</manual-options>
%<*tex>
@@ -3612,10 +3637,10 @@ following content:
renderers = {
attributeKeyValue = {
\str_if_eq:nnT
- { #1 }
+ { ##1 }
{ color }
{
- \color_select:n { #2 }
+ \color_select:n { ##2 }
}
},
},
@@ -3636,12 +3661,12 @@ Here is some [colored text]{color=red}.
```````
Next, invoke LuaTeX from the terminal:
``` sh
-lualatex --shell-escape document.tex
+lualatex document.tex
``````
A PDF document named `document.pdf` should be produced and contain the
following text:
-> Here is some [colored text]{color=red}.
+> Here is some <span style="color: red">colored text</span>.
%</manual-options>
%<*tex>
@@ -5409,30 +5434,30 @@ defaultOptions.fencedCode = false
%</lua,lua-cli>
%<*manual-options>
-#### Option `fencedDivs`
+#### Option `fencedCodeAttributes`
-`fencedDivs` (default value: `false`)
+`fencedCodeAttributes` (default value: `false`)
% \fi
% \begin{markdown}
%
-% \Optitem[false]{fencedDivs}{\opt{true}, \opt{false}}
+% \Optitem[false]{fencedCodeAttributes}{\opt{true}, \opt{false}}
%
: true
- : Enable the Pandoc fenced divs extension:
-
- ``` md
- ::::: {#special .sidebar}
- Here is a paragraph.
+ : Enable the Pandoc fenced code attribute extension:
- And another.
- :::::
- ``````
+ ```````` md
+ ~~~~ {#mycode .haskell .numberLines startFrom="100"}
+ qsort [] = []
+ qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++
+ qsort (filter (>= x) xs)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ```````````
: false
- : Disable the Pandoc fenced divs extension:
+ : Disable the Pandoc fenced code attribute extension.
% \end{markdown}
% \iffalse
@@ -5443,16 +5468,33 @@ Using a text editor, create a text document named `document.tex` with the
following content:
```` tex
\documentclass{article}
-\usepackage[fencedDivs]{markdown}
+\usepackage[fencedCode,
+ fencedCodeAttributes]{markdown}
+\usepackage{minted}
+\markdownSetup{
+ renderers = {
+ fencedCodeAttributeContextBegin = {%
+ \begingroup
+ \markdownSetup{
+ renderers = {
+ attributeKeyValue = {%
+ \setminted{{#1} = {#2}}%
+ },
+ },
+ }%
+ },
+ fencedCodeAttributeContextEnd = {%
+ \endgroup
+ },
+ },
+}
\begin{document}
-\begin{markdown}{slice=special}
-Here is a regular paragraph.
-
-::::: {#special}
-Here is a special paragraph.
-:::::
-
-And here is another regular paragraph.
+\begin{markdown}
+``` js {linenos=true}
+if (a > 3) {
+ moveShip(5 * gravity, DOWN);
+}
+``````
\end{markdown}
\end{document}
```````
@@ -5463,13 +5505,65 @@ lualatex --shell-escape document.tex
A PDF document named `document.pdf` should be produced and contain the
following text:
-> Here is a special paragraph.
+> ``` js {.linenos}
+> 1. if (a > 3) {
+> 2. moveShip(5 * gravity, DOWN);
+> 3. }
+> ``````
%</manual-options>
%<*tex>
% \fi
% \begin{macrocode}
\@@_add_lua_option:nnn
+ { fencedCodeAttributes }
+ { boolean }
+ { false }
+% \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli>
+% \fi
+% \begin{macrocode}
+defaultOptions.fencedCodeAttributes = false
+% \end{macrocode}
+% \par
+% \iffalse
+%</lua,lua-cli>
+%<*manual-options>
+
+#### Option `fencedDivs`
+
+`fencedDivs` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{fencedDivs}{\opt{true}, \opt{false}}
+%
+: true
+
+ : Enable the Pandoc fenced divs extension:
+
+ ``` md
+ ::::: {#special .sidebar}
+ Here is a paragraph.
+
+ And another.
+ :::::
+ ``````
+
+: false
+
+ : Disable the Pandoc fenced divs extension:
+
+% \end{markdown}
+% \iffalse
+%</manual-options>
+%<*tex>
+% \fi
+% \begin{macrocode}
+\@@_add_lua_option:nnn
{ fencedDivs }
{ boolean }
{ false }
@@ -6726,6 +6820,138 @@ defaultOptions.jekyllData = false
%</lua,lua-cli>
%<*manual-options>
+#### Option `lineBlocks`
+
+`lineBlocks` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{lineBlocks}{\opt{true}, \opt{false}}
+%
+: true
+
+ : Enable the Pandoc line block syntax extension.
+
+ ``` md
+ | this is a line block that
+ | spans multiple
+ | even
+ discontinuous
+ | lines
+ ``````
+
+: false
+
+ : Disable the Pandoc line block 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\markdownOptionLineBlocks{true}
+\markdownBegin
+| I would spread the cloths under your feet:
+| But I, being poor, have only my dreams;
+| I have spread my dreams under your feet;
+| Tread softly because you tread on my dreams.
+\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:
+
+> | I would spread the cloths under your feet:
+> | But I, being poor, have only my dreams;
+> | I have spread my dreams under your feet;
+> | Tread softly because you tread on my dreams.
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[lineBlocks]{markdown}
+\begin{document}
+\begin{markdown}
+| I would spread the cloths under your feet:
+| But I, being poor, have only my dreams;
+| I have spread my dreams under your feet;
+| Tread softly because you tread on my dreams.
+\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:
+
+> | I would spread the cloths under your feet:
+> | But I, being poor, have only my dreams;
+> | I have spread my dreams under your feet;
+> | Tread softly because you tread on my dreams.
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\usemodule[t][markdown]
+\setupmarkdown[lineBlocks = yes]
+\starttext
+\startmarkdown
+| I would spread the cloths under your feet:
+| But I, being poor, have only my dreams;
+| I have spread my dreams under your feet;
+| Tread softly because you tread on my dreams.
+\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:
+
+> | I would spread the cloths under your feet:
+> | But I, being poor, have only my dreams;
+> | I have spread my dreams under your feet;
+> | Tread softly because you tread on my dreams.
+
+%</manual-options>
+%<*tex>
+% \fi
+% \begin{macrocode}
+\@@_add_lua_option:nnn
+ { lineBlocks }
+ { boolean }
+ { false }
+% \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli>
+% \fi
+% \begin{macrocode}
+defaultOptions.lineBlocks = false
+% \end{macrocode}
+% \par
+% \iffalse
+%</lua,lua-cli>
+%<*manual-options>
+
#### Option `notes`
`notes` (default value: `false`)
@@ -8480,7 +8706,7 @@ defaultOptions.tableCaptions = false
: true
: Enable the Pandoc `task_lists` syntax extension.
-
+
``` md
- [ ] an unticked task list item
@@ -9256,7 +9482,7 @@ following text:
> \$\\sqrt{-1}\$ *equals* \$i\$.
>
> √-̅1̅ *equals* $i$.
-
+
Invoking pdfTeX should have the same effect:
``` sh
pdftex --shell-escape document.tex
@@ -10249,7 +10475,7 @@ following text:
%
% \begin{markdown}
-#### Bracketed Spans Context Renderers
+#### Bracketed Spans Attribute Context Renderers
The following macros are only produced, when the \Opt{bracketedSpans} option is
enabled.
@@ -10271,8 +10497,8 @@ following content:
\usepackage[bracketedSpans]{markdown}
\markdownSetup{
renderers = {
- fencedDivAttributeContextBegin = {(},
- fencedDivAttributeContextEnd = {)},
+ bracketedSpanAttributeContextBegin = {(},
+ bracketedSpanAttributeContextEnd = {)},
},
}
\begin{document}
@@ -12157,7 +12383,106 @@ corresponds to the emphasized span of text.
%
% \begin{markdown}
-#### Fenced Div Context Renderers
+#### Fenced Code Attribute Context Renderers
+The following macros are only produced, when the \Opt{fencedCode} option is
+enabled.
+
+The \mdef{markdownRendererFencedCodeAttributeContextBegin} and
+\mdef{markdownRendererFencedCodeAttributeContextEnd} macros represent the
+beginning and the end of a context in which the attributes of a fenced code
+apply. The macros receive no arguments.
+
+% \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[fencedCode,
+ fencedCodeAttributes]{markdown}
+\usepackage{minted}
+\markdownSetup{
+ renderers = {
+ fencedCodeAttributeContextBegin = {%
+ \begingroup
+ \markdownSetup{
+ renderers = {
+ attributeKeyValue = {%
+ \setminted{{#1} = {#2}}%
+ },
+ },
+ }%
+ },
+ fencedCodeAttributeContextEnd = {%
+ \endgroup
+ },
+ },
+}
+\begin{document}
+\begin{markdown}
+``` js {linenos=true}
+if (a > 3) {
+ moveShip(5 * gravity, DOWN);
+}
+``````
+\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:
+
+> ``` js {.linenos}
+> 1. if (a > 3) {
+> 2. moveShip(5 * gravity, DOWN);
+> 3. }
+> ``````
+
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+% \begin{macrocode}
+\def\markdownRendererFencedCodeAttributeContextBegin{%
+ \markdownRendererFencedCodeAttributeContextBeginPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { fencedCodeAttributeContextBegin }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { fencedCodeAttributeContextBegin }
+ { 0 }
+\ExplSyntaxOff
+\def\markdownRendererFencedCodeAttributeContextEnd{%
+ \markdownRendererFencedCodeAttributeContextEndPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { fencedCodeAttributeContextEnd }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { fencedCodeAttributeContextEnd }
+ { 0 }
+\ExplSyntaxOff
+% \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+#### Fenced Div Attribute Context Renderers
The following macros are only produced, when the \Opt{fencedDiv} option is
enabled.
@@ -12176,7 +12501,7 @@ Using a text editor, create a text document named `document.tex` with the
following content:
``` tex
\documentclass{article}
-\usepackage[fencedDiv]{markdown}
+\usepackage[fencedDivs]{markdown}
\markdownSetup{
renderers = {
fencedDivAttributeContextBegin = {%
@@ -13108,6 +13433,137 @@ following text:
%
% \begin{markdown}
+#### Line Block Renderer
+The following macros are only produced, when the \Opt{lineBlocks} option
+is enabled.
+
+The \mdef{markdownRendererLineBlockBegin} and \mdef{markdownRendererLineBlockEnd} macros
+represent the beginning and the end of a line block. The macros receive 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\markdownOptionLineBlocks{true}
+\markdownBegin
+| I would spread the cloths under your feet:
+| But I, being poor, have only my dreams;
+| I have spread my dreams under your feet;
+| Tread softly because you tread on my dreams.
+\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:
+
+> | I would spread the cloths under your feet:
+> | But I, being poor, have only my dreams;
+> | I have spread my dreams under your feet;
+> | Tread softly because you tread on my dreams.
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[lineBlocks]{markdown}
+\begin{document}
+\begin{markdown}
+| I would spread the cloths under your feet:
+| But I, being poor, have only my dreams;
+| I have spread my dreams under your feet;
+| Tread softly because you tread on my dreams.
+\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:
+
+> | I would spread the cloths under your feet:
+> | But I, being poor, have only my dreams;
+> | I have spread my dreams under your feet;
+> | Tread softly because you tread on my dreams.
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\usemodule[t][markdown]
+\setupmarkdown[lineBlocks = yes]
+\starttext
+\startmarkdown
+| I would spread the cloths under your feet:
+| But I, being poor, have only my dreams;
+| I have spread my dreams under your feet;
+| Tread softly because you tread on my dreams.
+\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:
+
+> | I would spread the cloths under your feet:
+> | But I, being poor, have only my dreams;
+> | I have spread my dreams under your feet;
+> | Tread softly because you tread on my dreams.
+
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+% \begin{macrocode}
+\def\markdownRendererLineBlockBegin{%
+ \markdownRendererLineBlockBeginPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { lineBlockBegin }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { lineBlockBegin }
+ { 0 }
+\ExplSyntaxOff
+\def\markdownRendererLineBlockEnd{%
+ \markdownRendererLineBlockEndPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { lineBlockEnd }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { lineBlockEnd }
+ { 0 }
+\ExplSyntaxOff
+% \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
#### Line Break Renderer
The \mdef{markdownRendererLineBreak} macro represents a forced line break.
The macro receives no arguments.
@@ -14733,6 +15189,39 @@ following text:
%
% \begin{markdown}
+#### Replacement Character Renderers
+The \mdef{markdownRendererReplacementCharacter} macro represents the U+0000
+and U+FFFD Unicode characters. The macro receives no arguments.
+
+% \end{markdown}
+%
+% \iffalse
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+% \begin{macrocode}
+\def\markdownRendererReplacementCharacter{%
+ \markdownRendererReplacementCharacterPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { replacementCharacter }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { replacementCharacter }
+ { 0 }
+\ExplSyntaxOff
+% \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
#### Special Character Renderers
The following macros replace any special plain \TeX{} characters, including
% \iffalse
@@ -17918,7 +18407,7 @@ following text:
> \$\\sqrt{-1}\$ *equals* \$i\$.
>
> √-̅1̅ *equals* $i$.
-
+
Invoking pdfTeX should have the same effect:
``` sh
texexec --passon=--shell-escape document.tex
@@ -18262,7 +18751,6 @@ end
% \end{markdown}
% \begin{macrocode}
function util.cache_verbatim(dir, string)
- string = string:gsub('[\r\n%s]*$', '')
local name = util.cache(dir, string, nil, nil, ".verbatim")
return name
end
@@ -20789,7 +21277,7 @@ function M.writer.new(options)
% \end{markdown}
% \begin{macrocode}
function self.pack(name)
- return [[\input ]] .. name .. [[\relax]]
+ return [[\input{]] .. name .. [[}\relax]]
end
% \end{macrocode}
% \par
@@ -20846,40 +21334,53 @@ function M.writer.new(options)
%
% \end{markdown}
% \begin{macrocode}
- self.escaped_uri_chars = {
- ["{"] = "\\markdownRendererLeftBrace{}",
- ["}"] = "\\markdownRendererRightBrace{}",
- ["\\"] = "\\markdownRendererBackslash{}",
- }
- self.escaped_minimal_strings = {
- ["^^"] = "\\markdownRendererCircumflex\\markdownRendererCircumflex ",
- ["☒"] = "\\markdownRendererTickedBox{}",
- ["⌛"] = "\\markdownRendererHalfTickedBox{}",
- ["☐"] = "\\markdownRendererUntickedBox{}",
- }
+ self.escaped_uri_chars = {
+ ["{"] = "\\markdownRendererLeftBrace{}",
+ ["}"] = "\\markdownRendererRightBrace{}",
+ ["\\"] = "\\markdownRendererBackslash{}",
+ }
+ self.escaped_minimal_strings = {
+ ["^^"] = "\\markdownRendererCircumflex\\markdownRendererCircumflex ",
+ ["☒"] = "\\markdownRendererTickedBox{}",
+ ["⌛"] = "\\markdownRendererHalfTickedBox{}",
+ ["☐"] = "\\markdownRendererUntickedBox{}",
+ [entities.hex_entity('FFFD')] = "\\markdownRendererReplacementCharacter{}",
+ }
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Define table \luamdef{writer->escaped_strings} containing the mapping from
+% character strings that need to be escaped in typeset content.
+%
+% \end{markdown}
+% \begin{macrocode}
+ self.escaped_strings = util.table_copy(self.escaped_minimal_strings)
+ self.escaped_strings[entities.hex_entity('00A0')] = self.nbsp
% \end{macrocode}
% \par
% \begin{markdown}
%
% Define a table \luamdef{writer->escaped_chars} containing the mapping from
% special plain \TeX{} characters (including the active pipe character (`|`)
-% of \Hologo{ConTeXt}) that need to be escaped for typeset content.
+% of \Hologo{ConTeXt}) that need to be escaped in typeset content.
%
% \end{markdown}
% \begin{macrocode}
self.escaped_chars = {
- ["{"] = "\\markdownRendererLeftBrace{}",
- ["}"] = "\\markdownRendererRightBrace{}",
- ["%"] = "\\markdownRendererPercentSign{}",
- ["\\"] = "\\markdownRendererBackslash{}",
- ["#"] = "\\markdownRendererHash{}",
- ["$"] = "\\markdownRendererDollarSign{}",
- ["&"] = "\\markdownRendererAmpersand{}",
- ["_"] = "\\markdownRendererUnderscore{}",
- ["^"] = "\\markdownRendererCircumflex{}",
- ["~"] = "\\markdownRendererTilde{}",
- ["|"] = "\\markdownRendererPipe{}",
- }
+ ["{"] = "\\markdownRendererLeftBrace{}",
+ ["}"] = "\\markdownRendererRightBrace{}",
+ ["%"] = "\\markdownRendererPercentSign{}",
+ ["\\"] = "\\markdownRendererBackslash{}",
+ ["#"] = "\\markdownRendererHash{}",
+ ["$"] = "\\markdownRendererDollarSign{}",
+ ["&"] = "\\markdownRendererAmpersand{}",
+ ["_"] = "\\markdownRendererUnderscore{}",
+ ["^"] = "\\markdownRendererCircumflex{}",
+ ["~"] = "\\markdownRendererTilde{}",
+ ["|"] = "\\markdownRendererPipe{}",
+ [entities.hex_entity('0000')] = "\\markdownRendererReplacementCharacter{}",
+ }
% \end{macrocode}
% \par
% \begin{markdown}
@@ -20891,7 +21392,7 @@ function M.writer.new(options)
%
% \end{markdown}
% \begin{macrocode}
- self.escape = util.escaper(self.escaped_chars, self.escaped_minimal_strings)
+ self.escape = util.escaper(self.escaped_chars, self.escaped_strings)
self.escape_uri = util.escaper(self.escaped_uri_chars, self.escaped_minimal_strings)
self.escape_minimal = util.escaper({}, self.escaped_minimal_strings)
% \end{macrocode}
@@ -21170,6 +21671,7 @@ function M.writer.new(options)
% \begin{macrocode}
function self.verbatim(s)
if not self.is_writing then return "" end
+ s = s:gsub("\n$", "")
local name = util.cache_verbatim(options.cacheDir, s)
return {"\\markdownRendererInputVerbatim{",name,"}"}
end
@@ -21621,6 +22123,14 @@ parsers.attributes = parsers.lbrace
* parsers.optionalspace
* parsers.rbrace
+
+parsers.raw_attribute = parsers.lbrace
+ * parsers.optionalspace
+ * parsers.equal
+ * C(parsers.attribute_key)
+ * parsers.optionalspace
+ * parsers.rbrace
+
-- block followed by 0 or more optionally
-- indented blocks with first line indented.
parsers.indented_blocks = function(bl)
@@ -21687,73 +22197,6 @@ parsers.inticks = parsers.openticks * parsers.space^-1
% \par
% \begin{markdown}
%
-%#### Parsers Used for Fenced Code Blocks
-%
-% \end{markdown}
-% \begin{macrocode}
-local function captures_geq_length(_,i,a,b)
- return #a >= #b and i
-end
-
-parsers.tilde_infostring
- = C((parsers.linechar
- - (parsers.spacechar^1 * parsers.newline))^0)
- * parsers.optionalspace
- * (parsers.newline + parsers.eof)
-
-parsers.backtick_infostring
- = C((parsers.linechar
- - (parsers.backtick
- + parsers.spacechar^1 * parsers.newline))^0)
- * parsers.optionalspace
- * (parsers.newline + parsers.eof)
-
-local fenceindent
-parsers.fencehead = function(char, infostring)
- return C(parsers.nonindentspace) / function(s) fenceindent = #s end
- * Cg(char^3, "fencelength")
- * parsers.optionalspace * infostring
-end
-
-parsers.fencehead_with_attributes
- = function(char)
- return C(parsers.nonindentspace) / function(s) fenceindent = #s end
- * Cg(char^3, "fencelength")
- * parsers.optionalspace * Ct(parsers.attributes)
- * parsers.optionalspace * (parsers.newline + parsers.eof)
-end
-
-parsers.fencetail = function(char)
- return parsers.nonindentspace
- * Cmt(C(char^3) * Cb("fencelength"), captures_geq_length)
- * parsers.optionalspace * (parsers.newline + parsers.eof)
- + parsers.eof
-end
-
-parsers.fencedline = function(char)
- return C(parsers.line - parsers.fencetail(char))
- / function(s)
- local i = 1
- local remaining = fenceindent
- while true do
- local c = s:sub(i, i)
- if c == " " and remaining > 0 then
- remaining = remaining - 1
- i = i + 1
- elseif c == "\t" and remaining > 3 then
- remaining = remaining - 4
- i = i + 1
- else
- break
- end
- end
- return s:sub(i)
- end
-end
-% \end{macrocode}
-% \par
-% \begin{markdown}
-%
%#### Parsers Used for Markdown Tags and Links
%
% \end{markdown}
@@ -21982,18 +22425,6 @@ parsers.urlchar = parsers.anyescaped - parsers.newline - parsers.more
%
% \end{markdown}
% \begin{macrocode}
-parsers.TildeFencedCode
- = parsers.fencehead(parsers.tilde,
- parsers.tilde_infostring)
- * Cs(parsers.fencedline(parsers.tilde)^0)
- * parsers.fencetail(parsers.tilde)
-
-parsers.BacktickFencedCode
- = parsers.fencehead(parsers.backtick,
- parsers.backtick_infostring)
- * Cs(parsers.fencedline(parsers.backtick)^0)
- * parsers.fencetail(parsers.backtick)
-
parsers.lineof = function(c)
return (parsers.leader * (P(c) * parsers.optionalspace)^3
* (parsers.newline * parsers.blankline^1
@@ -22274,8 +22705,7 @@ function M.reader.new(writer, options)
-- strip off leading > and indents, and run through blocks
parsers.blockquote_body = ((parsers.leader * parsers.more * parsers.space^-1)/""
* parsers.linechar^0 * parsers.newline)^1
- * (-(parsers.leader * parsers.more
- + parsers.blankline) * parsers.linechar^1
+ * (-V("BlockquoteExceptions") * parsers.linechar^1
* parsers.newline)^0
if not options.breakableBlockquotes then
@@ -22511,14 +22941,14 @@ function M.reader.new(writer, options)
/ writer.string
parsers.EscapedChar = parsers.backslash * C(parsers.escapable) / writer.string
-
+
parsers.InlineHtml = parsers.emptyelt_any / writer.inline_html_tag
+ (parsers.htmlcomment / self.parser_functions.parse_inlines_no_html)
/ writer.inline_html_comment
+ parsers.htmlinstruction
+ parsers.openelt_any / writer.inline_html_tag
+ parsers.closeelt_any / writer.inline_html_tag
-
+
parsers.HtmlEntity = parsers.hexentity / entities.hex_entity / writer.string
+ parsers.decentity / entities.dec_entity / writer.string
+ parsers.tagentity / entities.char_entity / writer.string
@@ -22541,6 +22971,9 @@ function M.reader.new(writer, options)
* ((parsers.indentedline - parsers.blankline))^1)^1
) / self.expandtabs / writer.verbatim
+ parsers.BlockquoteExceptions = parsers.leader * parsers.more
+ + parsers.blankline
+
parsers.Blockquote = Cs(parsers.blockquote_body^1)
/ self.parser_functions.parse_blocks_nested
/ writer.blockquote
@@ -22796,7 +23229,9 @@ function M.reader.new(writer, options)
DisplayHtml = parsers.DisplayHtml,
Paragraph = parsers.Paragraph,
Plain = parsers.Plain,
+
EndlineExceptions = parsers.EndlineExceptions,
+ BlockquoteExceptions = parsers.BlockquoteExceptions,
Str = parsers.Str,
Space = parsers.Space,
@@ -22868,7 +23303,6 @@ function M.reader.new(writer, options)
end
self.add_special_character("*")
- self.add_special_character("`")
self.add_special_character("[")
self.add_special_character("]")
self.add_special_character("<")
@@ -23025,6 +23459,8 @@ function M.reader.new(writer, options)
if not options.codeSpans then
syntax.Code = parsers.fail
+ else
+ self.add_special_character("`")
end
if not options.html then
@@ -23086,13 +23522,22 @@ function M.reader.new(writer, options)
% \begin{markdown}
%
% Return a function that converts markdown string `input` into a plain \TeX{}
-% output and returns it. Note that the converter assumes that the input has
-% \acro{unix} line endings.
+% output and returns it..
%
% \end{markdown}
% \begin{macrocode}
return function(input)
- references = {}
+% \end{macrocode}
+% \begin{markdown}
+% Since the Lua converter expects \acro{unix} line endings, normalize the
+% input. Also add a line ending at the end of the file in case the input file
+% has none.
+% \end{markdown}
+% \begin{macrocode}
+ input = input:gsub("\r\n?", "\n")
+ if input:sub(-1) ~= "\n" then
+ input = input .. "\n"
+ end
% \end{macrocode}
% \begin{markdown}
% When determining the name of the cache file, create salt for the hashing
@@ -23101,6 +23546,7 @@ function M.reader.new(writer, options)
% is disregarded.
% \end{markdown}
% \begin{macrocode}
+ references = {}
local opt_string = {}
for k, _ in pairs(defaultOptions) do
local v = options[k]
@@ -23906,9 +24352,16 @@ end
% parameter is `true`, the syntax extension requires a blank line between a
% paragraph and the following fenced code block.
%
+% When the `allow_attributes` option is `true`, the syntax extension permits
+% attributes following the infostring. When the `allow_raw_blocks` option is
+% `true`, the syntax extension permits the specification of raw blocks using
+% Pandoc's raw attribute syntax extension.
+%
% \end{markdown}
% \begin{macrocode}
-M.extensions.fenced_code = function(blank_before_code_fence)
+M.extensions.fenced_code = function(blank_before_code_fence,
+ allow_attributes,
+ allow_raw_blocks)
return {
name = "built-in fenced_code syntax extension",
extend_writer = function(self)
@@ -23918,29 +24371,141 @@ M.extensions.fenced_code = function(blank_before_code_fence)
% \par
% \begin{markdown}
%
-% Define \luamdef{writer->codeFence} as a function that will transform an
-% input fenced code block `s` with the infostring `i` to the output
-% format.
+% Define \luamdef{writer->fencedCode} as a function that will transform an
+% input fenced code block `s` with the infostring `i` and optional attributes
+% `attr` to the output format.
%
% \end{markdown}
% \begin{macrocode}
- function self.fencedCode(s, i)
+ function self.fencedCode(s, i, attr)
if not self.is_writing then return "" end
+ s = s:gsub("\n$", "")
+ local buf = {}
+ if attr ~= nil then
+ table.insert(buf, {"\\markdownRendererFencedCodeAttributeContextBegin",
+ self.attributes(attr)})
+ end
local name = util.cache_verbatim(options.cacheDir, s)
- return {"\\markdownRendererInputFencedCode{",
- name,"}{",self.string(i),"}"}
+ table.insert(buf, {"\\markdownRendererInputFencedCode{",
+ name,"}{",self.string(i),"}"})
+ if attr ~= nil then
+ table.insert(buf, "\\markdownRendererFencedCodeAttributeContextEnd")
+ end
+ return buf
+ end
+
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Define \luamdef{writer->rawBlock} as a function that will transform an
+% input raw block `s` with the raw attribute `attr` to the output format.
+%
+% \end{markdown}
+% \begin{macrocode}
+ if allow_raw_blocks then
+ function self.rawBlock(s, attr)
+ if not self.is_writing then return "" end
+ s = s:gsub("\n$", "")
+ local name = util.cache_verbatim(options.cacheDir, s)
+ return {"\\markdownRendererInputRawBlock{",
+ name,"}{", self.string(attr),"}"}
+ end
end
end, extend_reader = function(self)
local parsers = self.parsers
local writer = self.writer
- local FencedCode = (parsers.TildeFencedCode
- + parsers.BacktickFencedCode)
- / function(infostring, code)
- local expanded_code = self.expandtabs(code)
- return writer.fencedCode(expanded_code,
- infostring)
- end
+ local function captures_geq_length(_,i,a,b)
+ return #a >= #b and i
+ end
+
+ local tilde_infostring
+ = C((parsers.linechar
+ - (parsers.spacechar^1 * parsers.newline))^0)
+
+ local backtick_infostring
+ = C((parsers.linechar
+ - (parsers.backtick
+ + parsers.spacechar^1 * parsers.newline))^0)
+
+ local fenceindent
+ local fencehead = function(char, infostring)
+ return C(parsers.nonindentspace) / function(s) fenceindent = #s end
+ * Cg(char^3, "fencelength")
+ * parsers.optionalspace
+ * infostring
+ * (parsers.newline + parsers.eof)
+ end
+
+ local fencetail = function(char)
+ return parsers.nonindentspace
+ * Cmt(C(char^3) * Cb("fencelength"), captures_geq_length)
+ * parsers.optionalspace * (parsers.newline + parsers.eof)
+ + parsers.eof
+ end
+
+ local fencedline = function(char)
+ return C(parsers.line - fencetail(char))
+ / function(s)
+ local i = 1
+ local remaining = fenceindent
+ while true do
+ local c = s:sub(i, i)
+ if c == " " and remaining > 0 then
+ remaining = remaining - 1
+ i = i + 1
+ elseif c == "\t" and remaining > 3 then
+ remaining = remaining - 4
+ i = i + 1
+ else
+ break
+ end
+ end
+ return s:sub(i)
+ end
+ end
+
+ local TildeFencedCode
+ = fencehead(parsers.tilde, tilde_infostring)
+ * Cs(fencedline(parsers.tilde)^0)
+ * fencetail(parsers.tilde)
+
+ local BacktickFencedCode
+ = fencehead(parsers.backtick, backtick_infostring)
+ * Cs(fencedline(parsers.backtick)^0)
+ * fencetail(parsers.backtick)
+
+ local infostring_with_attributes
+ = Ct(C((parsers.linechar
+ - ( parsers.optionalspace
+ * parsers.attributes))^0)
+ * parsers.optionalspace
+ * Ct(parsers.attributes))
+
+ local FencedCode
+ = (TildeFencedCode + BacktickFencedCode)
+ / function(infostring, code)
+ local expanded_code = self.expandtabs(code)
+
+ if allow_raw_blocks then
+ local raw_attr = lpeg.match(parsers.raw_attribute,
+ infostring)
+ if raw_attr then
+ return writer.rawBlock(expanded_code, raw_attr)
+ end
+ end
+
+ local attr = nil
+ if allow_attributes then
+ local match = lpeg.match(infostring_with_attributes,
+ infostring)
+ if match then
+ infostring, attr = table.unpack(match)
+ end
+ end
+ return writer.fencedCode(expanded_code, infostring, attr)
+ end
self.insert_pattern("Block after Verbatim",
FencedCode, "FencedCode")
@@ -23949,10 +24514,8 @@ M.extensions.fenced_code = function(blank_before_code_fence)
if blank_before_code_fence then
fencestart = parsers.fail
else
- fencestart = parsers.fencehead(parsers.backtick,
- parsers.backtick_infostring)
- + parsers.fencehead(parsers.tilde,
- parsers.tilde_infostring)
+ fencestart = fencehead(parsers.backtick, backtick_infostring)
+ + fencehead(parsers.tilde, tilde_infostring)
end
self.update_rule("EndlineExceptions", function(previous_pattern)
@@ -23962,6 +24525,7 @@ M.extensions.fenced_code = function(blank_before_code_fence)
return previous_pattern + fencestart
end)
+ self.add_special_character("`")
self.add_special_character("~")
end
}
@@ -24071,6 +24635,31 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
FencedDiv, "FencedDiv")
self.add_special_character(":")
+
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Patch blockquotes, so that they allow the end of a fenced div immediately
+% afterwards.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local function check_div_level(s, i, current_level) -- luacheck: ignore s i
+ current_level = tonumber(current_level)
+ return current_level > 0
+ end
+
+ local is_inside_div = Cmt(Cb("div_level"), check_div_level)
+ local fencestart = is_inside_div * fenced_div_end
+
+ self.update_rule("BlockquoteExceptions", function(previous_pattern)
+ if previous_pattern == nil then
+ previous_pattern = parsers.BlockquoteExceptions
+ end
+ return previous_pattern + fencestart
+ end)
+
% \end{macrocode}
% \par
% \begin{markdown}
@@ -24082,13 +24671,6 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
% \end{markdown}
% \begin{macrocode}
if not blank_before_div_fence then
- local function check_div_level(s, i, current_level) -- luacheck: ignore s i
- current_level = tonumber(current_level)
- return current_level > 0
- end
-
- local is_inside_div = Cmt(Cb("div_level"), check_div_level)
- local fencestart = is_inside_div * fenced_div_end
self.update_rule("EndlineExceptions", function(previous_pattern)
if previous_pattern == nil then
previous_pattern = parsers.EndlineExceptions
@@ -24167,6 +24749,64 @@ end
% \end{macrocode}
% \begin{markdown}
%
+%#### Line Blocks
+%
+% The \luamdef{extensions.line_blocks} function implements the Pandoc line blocks
+% syntax extension.
+%
+% \end{markdown}
+% \begin{macrocode}
+M.extensions.line_blocks = function()
+ return {
+ name = "built-in line_blocks syntax extension",
+ extend_writer = function(self)
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Define \luamdef{writer->lineblock} as a function that will transform
+% a line block consisted of `lines` to the output format, with
+% all but the last newline rendered as a line break.
+%
+% \end{markdown}
+% \begin{macrocode}
+ function self.lineblock(lines)
+ if not self.is_writing then return "" end
+ local buffer = {}
+ for i = 1, #lines - 1 do
+ buffer[#buffer + 1] = { lines[i], self.linebreak }
+ end
+ buffer[#buffer + 1] = lines[#lines]
+
+ return {"\\markdownRendererLineBlockBegin\n"
+ ,buffer,
+ "\n\\markdownRendererLineBlockEnd "}
+ end
+ end, extend_reader = function(self)
+ local parsers = self.parsers
+ local writer = self.writer
+
+ local LineBlock = Ct(
+ (Cs(
+ ( (parsers.pipe * parsers.space)/""
+ * ((parsers.space)/entities.char_entity("nbsp"))^0
+ * parsers.linechar^0 * (parsers.newline/""))
+ * (-parsers.pipe
+ * (parsers.space^1/" ")
+ * parsers.linechar^1
+ * (parsers.newline/"")
+ )^0
+ * (parsers.blankline/"")^0
+ ) / self.parser_functions.parse_inlines)^1) / writer.lineblock
+
+ self.insert_pattern("Block after Blockquote",
+ LineBlock, "LineBlock")
+ end
+ }
+end
+% \end{macrocode}
+% \begin{markdown}
+%
%#### Notes
%
% The \luamdef{extensions.notes} function implements the Pandoc note
@@ -24423,14 +25063,14 @@ end
%
%#### Raw Attributes
%
-% The \luamdef{extensions.raw_attribute} function implements the Pandoc
-% raw attribute syntax extension.
+% The \luamdef{extensions.raw_inline} function implements the Pandoc
+% raw attribute syntax extension for inline code spans.
%
% \end{markdown}
% \begin{macrocode}
-M.extensions.raw_attribute = function()
+M.extensions.raw_inline = function()
return {
- name = "built-in raw_attribute syntax extension",
+ name = "built-in raw_inline syntax extension",
extend_writer = function(self)
local options = self.options
@@ -24449,59 +25089,15 @@ M.extensions.raw_attribute = function()
return {"\\markdownRendererInputRawInline{",
name,"}{", self.string(attr),"}"}
end
-
- if options.fencedCode then
-% \end{macrocode}
-% \par
-% \begin{markdown}
-%
-% Define \luamdef{writer->rawBlock} as a function that will transform an
-% input raw block `s` with the raw attribute `attr` to the output format.
-%
-% \end{markdown}
-% \begin{macrocode}
- function self.rawBlock(s, attr)
- if not self.is_writing then return "" end
- local name = util.cache_verbatim(options.cacheDir, s)
- return {"\\markdownRendererInputRawBlock{",
- name,"}{", self.string(attr),"}"}
- end
- end
end, extend_reader = function(self)
- local options = self.options
local writer = self.writer
- local raw_attribute = parsers.lbrace
- * parsers.optionalspace
- * parsers.equal
- * C(parsers.attribute_key)
- * parsers.optionalspace
- * parsers.rbrace
-
local RawInline = parsers.inticks
- * raw_attribute
+ * parsers.raw_attribute
/ writer.rawInline
self.insert_pattern("Inline before Code",
RawInline, "RawInline")
-
- if options.fencedCode then
- local RawBlock = (parsers.TildeFencedCode
- + parsers.BacktickFencedCode)
- / function(infostring, code)
- local expanded_code = self.expandtabs(code)
- local attr = lpeg.match(raw_attribute, infostring)
- if attr then
- return writer.rawBlock(expanded_code, attr)
- else
- return writer.fencedCode(expanded_code,
- infostring)
- end
- end
-
- self.insert_pattern("Block after Verbatim",
- RawBlock, "RawBlock")
- end
end
}
end
@@ -24837,7 +25433,9 @@ function M.new(options)
if options.fencedCode then
local fenced_code_extension = M.extensions.fenced_code(
- options.blankBeforeCodeFence)
+ options.blankBeforeCodeFence,
+ options.fencedCodeAttributes,
+ options.rawAttribute)
table.insert(extensions, fenced_code_extension)
end
@@ -24865,8 +25463,8 @@ function M.new(options)
end
if options.rawAttribute then
- local raw_attribute_extension = M.extensions.raw_attribute()
- table.insert(extensions, raw_attribute_extension)
+ local raw_inline_extension = M.extensions.raw_inline()
+ table.insert(extensions, raw_inline_extension)
end
if options.strikeThrough then
@@ -24884,6 +25482,11 @@ function M.new(options)
table.insert(extensions, superscript_extension)
end
+ if options.lineBlocks then
+ local line_block_extension = M.extensions.line_blocks()
+ table.insert(extensions, line_block_extension)
+ end
+
% \end{macrocode}
% \begin{markdown}
%
@@ -25072,14 +25675,7 @@ if metadata.version ~= md.metadata.version then
"markdown.lua " .. md.metadata.version .. ".")
end
local convert = md.new(options)
-% \end{macrocode}
-% \begin{markdown}
-% Since the Lua converter expects \acro{unix} line endings, normalize the
-% input. Also add a line ending at the end of the file in case the input file
-% has none.
-% \end{markdown}
-% \begin{macrocode}
-local output = convert(input:gsub("\r\n?", "\n") .. "\n")
+local output = convert(input)
if output_filename then
local output_file = assert(io.open(output_filename, "w"),
@@ -25186,12 +25782,14 @@ end
\def\markdownRendererDlEndTightPrototype{}%
\def\markdownRendererEmphasisPrototype#1{{\it#1}}%
\def\markdownRendererStrongEmphasisPrototype#1{{\bf#1}}%
-\def\markdownRendererBlockQuoteBeginPrototype{\par\begingroup\it}%
+\def\markdownRendererBlockQuoteBeginPrototype{\begingroup\it}%
\def\markdownRendererBlockQuoteEndPrototype{\endgroup\par}%
+\def\markdownRendererLineBlockBeginPrototype{\begingroup\parindent=0pt}%
+\def\markdownRendererLineBlockEndPrototype{\endgroup}%
\def\markdownRendererInputVerbatimPrototype#1{%
\par{\tt\input#1\relax{}}\par}%
\def\markdownRendererInputFencedCodePrototype#1#2{%
- \markdownRendererInputVerbatimPrototype{#1}}%
+ \markdownRendererInputVerbatim{#1}}%
\def\markdownRendererHeadingOnePrototype#1{#1}%
\def\markdownRendererHeadingTwoPrototype#1{#1}%
\def\markdownRendererHeadingThreePrototype#1{#1}%
@@ -25208,6 +25806,46 @@ end
\def\markdownRendererStrikeThroughPrototype#1{#1}%
\def\markdownRendererSuperscriptPrototype#1{#1}%
\def\markdownRendererSubscriptPrototype#1{#1}%
+\ExplSyntaxOn
+\cs_gset:Npn
+ \markdownRendererHeaderAttributeContextBeginPrototype
+ {
+ \group_begin:
+ \color_group_begin:
+ }
+\cs_gset:Npn
+ \markdownRendererHeaderAttributeContextEndPrototype
+ {
+ \color_group_end:
+ \group_end:
+ }
+\cs_gset_eq:NN
+ \markdownRendererBracketedSpanAttributeContextBeginPrototype
+ \markdownRendererHeaderAttributeContextBeginPrototype
+\cs_gset_eq:NN
+ \markdownRendererBracketedSpanAttributeContextEndPrototype
+ \markdownRendererHeaderAttributeContextEndPrototype
+\cs_gset_eq:NN
+ \markdownRendererFencedDivAttributeContextBeginPrototype
+ \markdownRendererHeaderAttributeContextBeginPrototype
+\cs_gset_eq:NN
+ \markdownRendererFencedDivAttributeContextEndPrototype
+ \markdownRendererHeaderAttributeContextEndPrototype
+\cs_gset_eq:NN
+ \markdownRendererFencedCodeAttributeContextBeginPrototype
+ \markdownRendererHeaderAttributeContextBeginPrototype
+\cs_gset_eq:NN
+ \markdownRendererFencedCodeAttributeContextEndPrototype
+ \markdownRendererHeaderAttributeContextEndPrototype
+\cs_gset:Npn
+ \markdownRendererReplacementCharacterPrototype
+ {
+ % TODO: Replace with `\codepoint_generate:nn` in TeX Live 2023
+ \sys_if_engine_pdftex:TF
+ { ^^ef^^bf^^bd }
+ { ^^^^fffd }
+ }
+\ExplSyntaxOff
% \end{macrocode}
% \par
% \begin{markdown}
@@ -25221,19 +25859,40 @@ end
% \end{markdown}
% \begin{macrocode}
\ExplSyntaxOn
-\cs_gset:Npn
- \markdownRendererInputRawInlinePrototype#1#2
+\cs_new:Nn
+ \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
{
\str_case:nn
{ #2 }
{
- { tex } { \markdownEscape{#1} }
{ md } { \markdownInput{#1} }
+ { tex } { \markdownEscape{#1} \unskip }
}
}
-\cs_gset_eq:NN
- \markdownRendererInputRawBlockPrototype
- \markdownRendererInputRawInlinePrototype
+\cs_new:Nn
+ \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ {
+ \str_case:nn
+ { #2 }
+ {
+ { md } { \markdownInput{#1} }
+ { tex } { \markdownEscape{#1} }
+ }
+ }
+\cs_gset:Npn
+ \markdownRendererInputRawInlinePrototype#1#2
+ {
+ \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ { #1 }
+ { #2 }
+ }
+\cs_gset:Npn
+ \markdownRendererInputRawBlockPrototype#1#2
+ {
+ \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ { #1 }
+ { #2 }
+ }
\ExplSyntaxOff
% \end{macrocode}
% \par
@@ -25878,7 +26537,7 @@ end
% whether the shell access is enabled (`1`), disabled (`0`), or restricted
% (`2`).
%
-% Inherit the value of the the `\pdfshellescape` (Lua\TeX{}, \Hologo{pdfTeX})
+% Inherit the value of the `\pdfshellescape` (Lua\TeX{}, \Hologo{pdfTeX})
% or the `\shellescape` (\Hologo{XeTeX}) commands. If neither of these
% commands is defined and Lua is available, attempt to access the
% `status.shell_escape` configuration item.
@@ -26150,7 +26809,7 @@ end
% has none.
% \end{markdown}
% \begin{macrocode}
- print(convert(input:gsub("\r\n?", "\n") .. "\n"))}%
+ print(convert(input))}%
% \end{macrocode}
% \begin{markdown}
% In case we were finalizing the frozen cache, increment \Opt{frozenCacheCounter}.
@@ -26362,7 +27021,7 @@ end
%
% \end{markdown}
% \begin{macrocode}
-\renewcommand\markdownRendererInputFencedCode[2]{%
+\renewcommand\markdownRendererInputFencedCodePrototype[2]{%
\def\next##1 ##2\relax{%
\ifthenelse{\equal{##1}{dot}}{%
\markdownIfOption{frozenCache}{}{%
@@ -26690,14 +27349,16 @@ end
% \end{macrocode}
% \par
% \begin{markdown}%
-% If the \Opt{tightLists} Lua option is disabled or the current document class
-% is \pkg{beamer}, do not load the \pkg{paralist} package.
+% If either the \Opt{tightLists} or the \Opt{fancyLists} Lua option is enabled
+% and the current document class is not \pkg{beamer}, then load the
+% \pkg{paralist} package.
%
% \end{markdown}
% \begin{macrocode}
-\markdownIfOption{tightLists}{
- \@ifclassloaded{beamer}{}{\RequirePackage{paralist}}%
-}{}
+\@ifclassloaded{beamer}{}{%
+ \markdownIfOption{tightLists}{\RequirePackage{paralist}}{}%
+ \markdownIfOption{fancyLists}{\RequirePackage{paralist}}{}%
+}
% \end{macrocode}
% \par
% \begin{markdown}
@@ -26956,7 +27617,7 @@ end
%
% \end{markdown}
% \begin{macrocode}
- headerAttributeContextBegin = {
+ headerAttributeContextBegin = {%
\markdownSetup{
rendererPrototypes = {
attributeIdentifier = {%
@@ -26978,46 +27639,92 @@ end
},
}%
},
+ headerAttributeContextEnd = {},
superscript = {\textsuperscript{#1}},
subscript = {\textsubscript{#1}},
blockQuoteBegin = {\begin{quotation}},
blockQuoteEnd = {\end{quotation}},
inputVerbatim = {\VerbatimInput{#1}},
- inputFencedCode = {%
- \ifx\relax#2\relax
- \VerbatimInput{#1}%
- \else
- \@ifundefined{minted@code}{%
- \@ifundefined{lst@version}{%
- \markdownRendererInputFencedCode{#1}{}%
+ thematicBreak = {\noindent\rule[0.5ex]{\linewidth}{1pt}},
+ note = {\footnote{#1}}}}
% \end{macrocode}
% \par
% \begin{markdown}
%
-% When the \pkg{listings} package is loaded, use it for syntax highlighting.
+%#### Fenced Code
+% When no infostring has been specified, default to the indented code block
+% renderer.
%
% \end{markdown}
% \begin{macrocode}
- }{%
- \lstinputlisting[language=#2]{#1}%
- }%
+\RequirePackage{ltxcmds}
+\ExplSyntaxOn
+\cs_gset:Npn
+ \markdownRendererInputFencedCodePrototype#1#2
+ {
+ \tl_if_empty:nTF
+ { #2 }
+ { \markdownRendererInputVerbatim{#1} }
+% \end{macrocode}
+% \begin{markdown}
+%
+% Otherwise, extract the first word of the infostring and treat it as the name
+% of the programming language in which the code block is written.
+%
+% \end{markdown}
+% \begin{macrocode}
+ {
+ \regex_extract_once:nnN
+ { \w* }
+ { #2 }
+ \l_tmpa_seq
+ \seq_pop_left:NN
+ \l_tmpa_seq
+ \l_tmpa_tl
% \end{macrocode}
% \par
% \begin{markdown}
%
% When the \pkg{minted} package is loaded, use it for syntax highlighting.
-% The \pkg{minted} package is preferred over \pkg{listings}.
%
% \end{markdown}
% \begin{macrocode}
- }{%
- \catcode`\#=6\relax
- \inputminted{#2}{#1}%
- \catcode`\#=12\relax
- }%
- \fi},
- thematicBreak = {\noindent\rule[0.5ex]{\linewidth}{1pt}},
- note = {\footnote{#1}}}}
+ \ltx@ifpackageloaded
+ { minted }
+ {
+ \catcode`\#=6\relax
+ \exp_args:NV
+ \inputminted
+ \l_tmpa_tl
+ { #1 }
+ \catcode`\#=12\relax
+ }
+ {
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% When the \pkg{listings} package is loaded, use it for syntax highlighting.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \ltx@ifpackageloaded
+ { listings }
+ { \lstinputlisting[language=\l_tmpa_tl]{#1} }
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% When neither the \pkg{listings} package nor the \pkg{minted} package is
+% loaded, act as though no infostring were given.
+%
+% \end{markdown}
+% \begin{macrocode}
+ { \markdownRendererInputFencedCode{#1}{} }
+ }
+ }
+ }
+\ExplSyntaxOff
% \end{macrocode}
% \par
% \begin{markdown}
@@ -27544,6 +28251,32 @@ end
% \par
% \begin{markdown}
%
+%#### Line Blocks
+% Here is a basic implementation of line blocks. If the \pkg{verse} package is
+% loaded, then it is used to produce the verses.
+%
+% \end{markdown}
+% \begin{macrocode}
+
+\markdownIfOption{lineBlocks}{%
+ \RequirePackage{verse}
+ \markdownSetup{rendererPrototypes={
+ lineBlockBegin = {%
+ \begingroup
+ \def\markdownRendererLineBreak{\\}%
+ \begin{verse}%
+ },
+ lineBlockEnd = {%
+ \end{verse}%
+ \endgroup
+ },
+ }}
+}{}
+
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
%#### YAML Metadata {#latexyamlmetadata}
%
% The default setup of \acro{yaml} metadata will invoke the `\title`,
@@ -27621,9 +28354,8 @@ end
%
%#### Raw Attribute Renderer Prototypes
%
-% In the raw block and inline raw span renderer prototypes, execute the content
-% with TeX when the raw attribute is `tex` or `latex`, display the content as
-% markdown when the raw attribute is `md`, and ignore the content otherwise.
+% In the raw block and inline raw span renderer prototypes, default to the
+% plain TeX renderer prototypes, translating raw attribute `latex` to `tex`.
%
% \end{markdown}
% \begin{macrocode}
@@ -27631,17 +28363,41 @@ end
\cs_gset:Npn
\markdownRendererInputRawInlinePrototype#1#2
{
- \str_case:nn
+ \str_case:nnF
{ #2 }
{
- { tex } { \markdownEscape{#1} }
- { latex } { \markdownEscape{#1} }
- { md } { \markdownInput{#1} }
+ { latex }
+ {
+ \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ { #1 }
+ { tex }
+ }
+ }
+ {
+ \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ { #1 }
+ { #2 }
+ }
+ }
+\cs_gset:Npn
+ \markdownRendererInputRawBlockPrototype#1#2
+ {
+ \str_case:nnF
+ { #2 }
+ {
+ { latex }
+ {
+ \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ { #1 }
+ { tex }
+ }
+ }
+ {
+ \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ { #1 }
+ { #2 }
}
}
-\cs_gset_eq:NN
- \markdownRendererInputRawBlockPrototype
- \markdownRendererInputRawInlinePrototype
\ExplSyntaxOff
\fi % Closes `\markdownIfOption{Plain}{\iffalse}{iftrue}`
% \end{macrocode}
@@ -27856,18 +28612,42 @@ end
\def\markdownRendererStrongEmphasisPrototype#1{{\bf#1}}%
\def\markdownRendererBlockQuoteBeginPrototype{\startquotation}%
\def\markdownRendererBlockQuoteEndPrototype{\stopquotation}%
+\def\markdownRendererLineBlockBeginPrototype{%
+ \begingroup
+ \def\markdownRendererLineBreak{
+ }%
+ \startlines
+}%
+\def\markdownRendererLineBlockEndPrototype{%
+ \stoplines
+ \endgroup
+}%
\def\markdownRendererInputVerbatimPrototype#1{\typefile{#1}}%
-\def\markdownRendererInputFencedCodePrototype#1#2{%
- \ifx\relax#2\relax
- \typefile{#1}%
- \else
% \end{macrocode}
% \par
% \begin{markdown}
%
-% The code fence infostring is used as a name from the \Hologo{ConTeXt}
-% `\definetyping` macro. This allows the user to set up code highlighting
-% mapping as follows:
+%#### Fenced Code
+% When no infostring has been specified, default to the indented code block
+% renderer.
+%
+% \end{markdown}
+% \begin{macrocode}
+\ExplSyntaxOn
+\cs_gset:Npn
+ \markdownRendererInputFencedCodePrototype#1#2
+ {
+ \tl_if_empty:nTF
+ { #2 }
+ { \markdownRendererInputVerbatim{#1} }
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Otherwise, extract the first word of the infostring and treat it as the name
+% of the programming language in which the code block is written.
+% This name is then used in the \Hologo{ConTeXt} `\definetyping` macro, which
+% allows the user to set up code highlighting mapping as follows:
% ````` tex
% % Map the `TEX` syntax highlighter to the `latex` infostring.
% \definetyping [latex]
@@ -27887,8 +28667,18 @@ end
%
% \end{markdown}
% \begin{macrocode}
- \typefile[#2][]{#1}%
- \fi}%
+ {
+ \regex_extract_once:nnN
+ { \w* }
+ { #2 }
+ \l_tmpa_seq
+ \seq_pop_left:NN
+ \l_tmpa_seq
+ \l_tmpa_tl
+ \typefile[\l_tmpa_tl][]{#1}
+ }
+ }
+\ExplSyntaxOff
\def\markdownRendererHeadingOnePrototype#1{\chapter{#1}}%
\def\markdownRendererHeadingTwoPrototype#1{\section{#1}}%
\def\markdownRendererHeadingThreePrototype#1{\subsection{#1}}%
@@ -27984,9 +28774,8 @@ end
%
%#### Raw Attribute Renderer Prototypes
%
-% In the raw block and inline raw span renderer prototypes, execute the content
-% with TeX when the raw attribute is `tex` or `context`, display the content as
-% markdown when the raw attribute is `md`, and ignore the content otherwise.
+% In the raw block and inline raw span renderer prototypes, default to the
+% plain TeX renderer prototypes, translating raw attribute `context` to `tex`.
%
% \end{markdown}
% \begin{macrocode}
@@ -27994,12 +28783,39 @@ end
\cs_gset:Npn
\markdownRendererInputRawInlinePrototype#1#2
{
- \str_case:nn
+ \str_case:nnF
{ #2 }
{
- { tex } { \markdownEscape{#1} }
- { context } { \markdownEscape{#1} }
- { md } { \markdownInput{#1} }
+ { latex }
+ {
+ \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ { #1 }
+ { context }
+ }
+ }
+ {
+ \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ { #1 }
+ { #2 }
+ }
+ }
+\cs_gset:Npn
+ \markdownRendererInputRawBlockPrototype#1#2
+ {
+ \str_case:nnF
+ { #2 }
+ {
+ { context }
+ {
+ \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ { #1 }
+ { tex }
+ }
+ }
+ {
+ \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ { #1 }
+ { #2 }
}
}
\cs_gset_eq:NN