summaryrefslogtreecommitdiff
path: root/macros/generic/markdown/markdown.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/generic/markdown/markdown.dtx')
-rw-r--r--macros/generic/markdown/markdown.dtx10903
1 files changed, 7302 insertions, 3601 deletions
diff --git a/macros/generic/markdown/markdown.dtx b/macros/generic/markdown/markdown.dtx
index 4685ed3ee6..e13c91809f 100644
--- a/macros/generic/markdown/markdown.dtx
+++ b/macros/generic/markdown/markdown.dtx
@@ -78,20 +78,20 @@
\usepackage[
citations,
definitionLists,
- fencedCode,
+ experimental,
notes,
headerAttributes,
- html,
hybrid,
inlineNotes,
jekyllData,
+ linkAttributes,
relativeReferences,
stripPercentSigns,
underscores = false,
]{markdown}
\markdownSetup{
import = {
- witiko/dot,
+ witiko/diagrams@v2,
witiko/graphicx/http,
witiko/markdown/techdoc = {
options as lua-options
@@ -122,7 +122,7 @@
---
title: A Markdown Interpreter for \TeX
url: https://github.com/witiko/markdown
-authors: [Vít Starý Novotný]
+authors: [Vít Starý Novotný, Andrej Genčur]
email: witiko@mail.muni.cz
revision: \markdownVersion
date: \markdownLastModified
@@ -684,118 +684,153 @@ abbr {
%</techdoc-block-diagram>
%<*techdoc-bibliography>
@online{starynovotny24,
- author = {Starý Novotný, Vít and Enrico Gregorio and Max Chernoff and P. Spratte, Jonathan},
- title = {Convert control sequence with a variable number of undelimited parameters into a token list},
- url = {https://tex.stackexchange.com/q/716362/70941},
- urldate = {2024-04-28},
+ author = {Starý Novotný, Vít and Enrico Gregorio and Max Chernoff and P. Spratte, Jonathan},
+ title = {Convert control sequence with a variable number of undelimited parameters into a token list},
+ url = {https://tex.stackexchange.com/q/716362/70941},
+ urldate = {2024-04-28},
+}
+@online{starynovotny25,
+ author = {Starý Novotný, Vít},
+ title = {Routing YAML metadata to expl3 key–values},
+ titleaddon = {Markdown Enhancement Proposal},
+ url = {https://github.com/witiko/markdown/discussions/517},
+ date = {2024-10-14},
+ urldate = {2025-01-06},
}
@book{tantau21,
- author = {Till Tantau and Joseph Wright and Vedran Miletić},
- title = {The Beamer class},
- date = {2021-02-10},
- url = {https://mirrors.ctan.org/macros/latex/contrib/beamer/doc/beameruserguide.pdf},
- urldate = {2021-02-11}}
+ author = {Till Tantau and Joseph Wright and Vedran Miletić},
+ title = {The Beamer class},
+ date = {2021-02-10},
+ url = {https://mirrors.ctan.org/macros/latex/contrib/beamer/doc/beameruserguide.pdf},
+ urldate = {2021-02-11}}
@online{sotkov17,
- author = {Sotkov, Anton},
- title = {File transclusion syntax for Markdown},
- date = {2017-01-19},
- url = {https://github.com/iainc/Markdown-Content-Blocks},
- urldate = {2018-01-08}}
+ author = {Sotkov, Anton},
+ title = {File transclusion syntax for Markdown},
+ date = {2017-01-19},
+ url = {https://github.com/iainc/Markdown-Content-Blocks},
+ urldate = {2018-01-08}}
@book{luatex21,
- author = {{Lua\TeX{} development team}},
- title = {Lua\TeX{} reference manual},
- date = {2021-07-23},
- note = {Version 1.10 (stable)},
- url = {https://www.pragma-ade.com/general/manuals/luatex.pdf},
- urldate = {2022-09-30}}
+ author = {{Lua\TeX{} development team}},
+ title = {Lua\TeX{} reference manual},
+ date = {2021-07-23},
+ note = {Version 1.10 (stable)},
+ url = {https://www.pragma-ade.com/general/manuals/luatex.pdf},
+ urldate = {2022-09-30}}
@book{latex17,
- author = {Braams, Johannes and Carlisle, David and Jeffrey, Alan and
+ author = {Braams, Johannes and Carlisle, David and Jeffrey, Alan and
Lamport, Leslie and Mittelbach, Frank and Rowley, Chris and
Schöpf, Rainer},
- title = {The \Hologo{LaTeX2e} Sources},
- date = {2017-04-15},
- url = {https://mirrors.ctan.org/macros/latex/base/source2e.pdf},
- urldate = {2018-01-08}}
+ title = {The \Hologo{LaTeX2e} Sources},
+ date = {2017-04-15},
+ url = {https://mirrors.ctan.org/macros/latex/base/source2e.pdf},
+ urldate = {2018-01-08}}
@book{mittelbach17,
- author = {Mittelbach, Frank},
- title = {The \texttt{doc} and \texttt{shortvrb} Packages},
- date = {2017-04-15},
- url = {https://mirrors.ctan.org/macros/latex/base/doc.pdf},
- urldate = {2018-02-19}}
+ author = {Mittelbach, Frank},
+ title = {The \texttt{doc} and \texttt{shortvrb} Packages},
+ date = {2017-04-15},
+ url = {https://mirrors.ctan.org/macros/latex/base/doc.pdf},
+ urldate = {2018-02-19}}
+@book{mittelbach24,
+ author = {Mittelbach, Frank},
+ title = {\LaTeX's hook management},
+ date = {2024-06-26},
+ url = {https://mirrors.ctan.org/macros/latex/base/lthooks-code.pdf},
+ urldate = {2024-10-02}}
@book{poore17,
- author = {Poore, Geoffrey M.},
- title = {The \texttt{minted} Package},
- subtitle = {Highlighted source code in \LaTeX},
- date = {2017-07-19},
- version = {v2.5},
- url = {https://mirrors.ctan.org/macros/latex/contrib/minted/minted.pdf},
- urldate = {2020-09-01}}
+ author = {Poore, Geoffrey M.},
+ title = {The \texttt{minted} Package},
+ subtitle = {Highlighted source code in \LaTeX},
+ date = {2017-07-19},
+ version = {v2.5},
+ url = {https://mirrors.ctan.org/macros/latex/contrib/minted/minted.pdf},
+ urldate = {2020-09-01}}
@online{macfarlane22,
- title = {Pandoc},
- subtitle = {a universal document converter},
- author = {John MacFarlane},
- year = {2022},
- url = {https://pandoc.org/},
- urldate = {2022-10-05}}
+ title = {Pandoc},
+ subtitle = {a universal document converter},
+ author = {John MacFarlane},
+ year = {2022},
+ url = {https://pandoc.org/},
+ urldate = {2022-10-05}}
@online{novotny15,
- author = {Novotný, Vít},
- year = {2015},
- title = {TeXový interpret jazyka Markdown (markdown.sty)},
- location = {Brno, Czech Republic},
- publisher = {Masaryk University},
- url = {https://www.muni.cz/en/research/projects/32984},
- urldate = {2018-02-19}}
+ author = {Novotný, Vít},
+ year = {2015},
+ title = {TeXový interpret jazyka Markdown (markdown.sty)},
+ location = {Brno, Czech Republic},
+ publisher = {Masaryk University},
+ url = {https://www.muni.cz/en/research/projects/32984},
+ urldate = {2018-02-19}}
@book{ierusalimschy13,
- author = {Ierusalimschy, Roberto},
- year = {2013},
- title = {Programming in Lua},
- edition = {3},
- isbn = {978-85-903798-5-0},
- pagetotal = {xviii, 347},
- location = {Rio de Janeiro},
- publisher = {PUC-Rio}}
+ author = {Ierusalimschy, Roberto},
+ year = {2013},
+ title = {Programming in Lua},
+ edition = {3},
+ isbn = {978-85-903798-5-0},
+ pagetotal = {xviii, 347},
+ location = {Rio de Janeiro},
+ publisher = {PUC-Rio}}
@book{knuth86a,
- author = {Knuth, Donald Ervin},
- year = {1986},
- title = {The \TeX{}book},
- edition = {3},
- isbn = {0-201-13447-0},
- pagetotal = {ix, 479},
- series = {Computers \& Typesetting},
- volume = {A},
- location = {Reading, MA},
- publisher = {Addison-Wesley}}
+ author = {Knuth, Donald Ervin},
+ year = {1986},
+ title = {The \TeX{}book},
+ edition = {3},
+ isbn = {0-201-13447-0},
+ pagetotal = {ix, 479},
+ series = {Computers \& Typesetting},
+ volume = {A},
+ location = {Reading, MA},
+ publisher = {Addison-Wesley}}
@book{knuth86b,
- author = {Knuth, Donald Ervin},
- year = {1986},
- title = {\TeX: The Program},
- isbn = {978-0-201-13437-7},
- pagetotal = {xvi, 594},
- series = {Computers \& Typesetting},
- volume = {B},
- location = {Reading, MA},
- publisher = {Addison-Wesley}}
+ author = {Knuth, Donald Ervin},
+ year = {1986},
+ title = {\TeX: The Program},
+ isbn = {978-0-201-13437-7},
+ pagetotal = {xvi, 594},
+ series = {Computers \& Typesetting},
+ volume = {B},
+ location = {Reading, MA},
+ publisher = {Addison-Wesley}}
@book{eijkhout92,
- author = {Victor Eijkhout},
- title = {\TeX{} by Topic},
- subtitle = {A \TeX nician's Reference},
- isbn = {978-0-201-56882-0},
- pagetotal = {307},
- date = {1992-02-01},
- location = {Wokingham, England},
- publisher = {Addison-Wesley}}
+ author = {Victor Eijkhout},
+ title = {\TeX{} by Topic},
+ subtitle = {A \TeX nician's Reference},
+ isbn = {978-0-201-56882-0},
+ pagetotal = {307},
+ date = {1992-02-01},
+ location = {Wokingham, England},
+ publisher = {Addison-Wesley}}
@inproceedings{sharif10,
- author = {Sharif, Bonita and Maletic, Jonathan I.},
- booktitle = {2010 IEEE 18th International Conference on Program Comprehension},
- title = {An Eye Tracking Study on camelCase and under\_score Identifier Styles},
- year = {2010},
- pages = {196-205},
- doi = {10.1109/ICPC.2010.41}}
+ author = {Sharif, Bonita and Maletic, Jonathan I.},
+ booktitle = {2010 IEEE 18th International Conference on Program Comprehension},
+ title = {An Eye Tracking Study on camelCase and under\_score Identifier Styles},
+ year = {2010},
+ pages = {196-205},
+ doi = {10.1109/ICPC.2010.41}}
+@online{novotny24,
+ author = {Starý Novotný, Vít},
+ title = {Versioned Themes},
+ titleaddon = {Markdown Enhancement Proposal},
+ date = {2024-10-13},
+ urldate = {2024-10-21},
+ url = {https://github.com/Witiko/markdown/discussions/514}}
+@book{latex24,
+ author = {Frank Mittelbach and Ulrike Fischer and {\LaTeX{} Project}},
+ title = {The \texttt{documentmetadata-support} code},
+ date = {2024-06-01},
+ url = {https://mirrors.ctan.org/macros/latex/required/latex-lab/documentmetadata-support-code.pdf},
+ urldate = {2024-10-21}}
+@online{latex25,
+ author = {{\LaTeX{} Project}},
+ title = {l3kernel},
+ subtitle = {\LaTeX3 programming conventions},
+ date = {2024-12-25},
+ url = {https://ctan.org/pkg/l3kernel},
+ urldate = {2025-01-06}}
%</techdoc-bibliography>
%<@@=markdown>
%<*themes-witiko-markdown-techdoc>
\ProvidesPackage{markdownthemewitiko_markdown_techdoc}[2022/12/13]
\RequirePackage{etoolbox}
+\gdef\ltd@title@author{\@gobble}%
\markdownSetup{
renderers = {
head*Four = {\paragraph{#1}\leavevmode},
@@ -804,40 +839,55 @@ abbr {
codeSpan = {\inline{#1}},
jekyllData(End) = {%
\AfterEndPreamble{%
+ \hypersetup{pdfauthor=\ltd@title@author}%
\printtitlepage
\tableofcontents
{\def\addcontentsline##1##2##3{}\listoffigures}%
}%
},
},
- jekyllDataRenderers = {
- /authors/* = {%
- \gdef\ltd@title@author{#1}%
- \hypersetup{pdfauthor={#1}}%
+}
+\ExplSyntaxOn
+\keys_define:nn
+ { markdown / techdoc }
+ {
+ authors / unknown .code:n = {
+ \tl_gput_right:Nn
+ \ltd@title@author
+ { ,~#1 }
},
- title = {%
- \gdef\ltd@title@title{#1}%
- \gdef\ltd@title@subtitle{}%
- \hypersetup{pdftitle={#1}}%
+ title .code:n = {
+ \tl_gset:Nn
+ \ltd@title@title
+ { #1 }
+ \tl_gset:Nn
+ \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}},
+ date .tl_gset:N = \ltd@title@date,
+ email .tl_gset:N = \ltd@title@email,
+ revision .tl_gset:N = \ltd@title@revision,
+ url .tl_gset:N = \ltd@title@url,
}
-}
-\ExplSyntaxOn
-\markdownSetup{
- rendererPrototypes = {
- headerAttributeContextEnd = {
- \seq_map_inline:Nn
- \l_@@_header_identifiers_seq
- { \label { sec:##1 } }
- \seq_clear:N
- \l_@@_header_identifiers_seq
+\cs_generate_variant:Nn
+ \cs_gset:Npn
+ { NpV }
+\yamlSetup
+ { jekyllDataKeyValue = markdown / techdoc }
+\markdownSetup
+ {
+ rendererPrototypes = {
+ headerAttributeContextEnd = {
+ \seq_map_inline:Nn
+ \g_@@_header_identifiers_seq
+ { \label { sec:##1 } }
+ \seq_gclear:N
+ \g_@@_header_identifiers_seq
+ },
},
- },
-}
+ }
\ExplSyntaxOff
\renewcommand\markdownLaTeXRendererDirectOrIndirectLink[4]{%
#1\footnote{See \url{#3}.}}
@@ -875,14 +925,13 @@ abbr {
---
title: Markdown Package User Manual
-author: Vít Starý Novotný
+author: Vít Starý Novotný, Andrej Genčur
date: \markdownVersion{} \markdownLastModified{}
---
<link href="https://afeld.github.io/emoji-css/emoji.css" rel="stylesheet" />
% \fi
-% \par
% \begin{markdown}
Introduction
@@ -890,7 +939,7 @@ Introduction
The [Markdown package][pkg] converts [CommonMark][] markup to \TeX{} commands. The
functionality is provided both as a Lua module and as plain \TeX{}, \LaTeX{}, and
\Hologo{ConTeXt} macro packages that can be used to directly typeset \TeX{} documents
-containing markdown markup. Unlike other convertors, the Markdown package
+containing markdown markup. Unlike other converters, the Markdown package
does not require any external programs, and makes it easy to redefine how each
and every markdown element is rendered. Creative abuse of the markdown
syntax is encouraged. 😉
@@ -922,21 +971,23 @@ documentation][techdoc].
(A Markdown Interpreter for TeX)
%</manual>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader,lua-unicode-data>
% \fi
% \begin{macrocode}
local metadata = {
version = "(((VERSION)))",
- comment = "A module for the conversion from markdown to plain TeX",
- author = "John MacFarlane, Hans Hagen, Vít Starý Novotný",
+ comment = "A module for the conversion from markdown "
+ .. "to plain TeX",
+ author = "John MacFarlane, Hans Hagen, Vít Starý Novotný, "
+ .. "Andrej Genčur",
copyright = {"2009-2016 John MacFarlane, Hans Hagen",
- "2016-2023 Vít Starý Novotný"},
+ "2016-2024 Vít Starý Novotný, Andrej Genčur"},
license = "LPPL 1.3c"
}
% \end{macrocode}
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader,lua-unicode-data>
%<*lua>
% \fi
% \begin{macrocode}
@@ -952,7 +1003,7 @@ Requirements
The package requires either [our official Docker image][docker], which contains
the latest development version of the Markdown package, or a \TeX{}
-distribution: [\TeX{} Live][tl] ≥ 2022 is known to work with the current
+distribution: [\TeX{} Live][tl] ≥ 2023 is known to work with the current
version of the Markdown package and so are recent versions of [Mik\TeX{}][mik].
If you are using an older, incomplete, or atypical \TeX{} distribution, please
consult the [technical documentation][techdoc] for a detailed list of
@@ -988,14 +1039,10 @@ make base
Either of the two abovelisted approaches should produce the following files:
-* `markdown.lua`: The Lua module
-* `libraries/markdown-tinyyaml.lua`: An external library for reading \acro{yaml}
-* `markdown-cli.lua`: The Lua command-line interface
+* `markdown.lua`, `markdown-parser.lua`, and `markdown-unicode-data.lua`: The Lua module
+* `markdown-cli.lua` and `markdown2tex.lua`: The Lua command-line interface
* `markdown.tex`: The plain \TeX{} macro package
* `markdown.sty`: The \LaTeX{} package
-* `markdownthemewitiko_dot.sty`: The `witiko/dot` \LaTeX{} theme
-* `markdownthemewitiko_graphicx_http.sty`: The `witiko/graphicx/http` \LaTeX{} theme
-* `markdownthemewitiko_tilde.tex`: The `witiko/tilde` theme
* `markdownthemewitiko_markdown_defaults.tex`,
`markdownthemewitiko_markdown_defaults.sty`, and
`t-markdownthemewitiko_markdown_defaults.tex`: The `witiko/markdown/defaults`
@@ -1009,14 +1056,13 @@ directory structure. This is generally where the individual files should be
placed:
* `⟨TEXMF⟩/tex/luatex/markdown/markdown.lua`
-* `⟨TEXMF⟩/tex/luatex/markdown/markdown-tinyyaml.lua`
+* `⟨TEXMF⟩/tex/luatex/markdown/markdown-parser.lua`
+* `⟨TEXMF⟩/tex/luatex/markdown/markdown-unicode-data.lua`
* `⟨TEXMF⟩/scripts/markdown/markdown-cli.lua`
+* `⟨TEXMF⟩/scripts/markdown/markdown2tex.lua`
* `⟨TEXMF⟩/tex/generic/markdown/markdown.tex`
-* `⟨TEXMF⟩/tex/generic/markdown/markdownthemewitiko_tilde.tex`
* `⟨TEXMF⟩/tex/generic/markdown/markdownthemewitiko_markdown_defaults.tex`
* `⟨TEXMF⟩/tex/latex/markdown/markdown.sty`
-* `⟨TEXMF⟩/tex/latex/markdown/markdownthemewitiko_dot.sty`
-* `⟨TEXMF⟩/tex/latex/markdown/markdownthemewitiko_graphicx_http.sty`
* `⟨TEXMF⟩/tex/latex/markdown/markdownthemewitiko_markdown_defaults.sty`
* `⟨TEXMF⟩/tex/context/third/markdown/t-markdown.tex`
* `⟨TEXMF⟩/tex/context/third/markdown/t-markdownthemewitiko_markdown_defaults.tex`
@@ -1035,14 +1081,13 @@ portably typeset on legacy \TeX{} distributions.
This is where the individual files should be placed:
* `./markdown.lua`
-* `./markdown-tinyyaml.lua`
+* `./markdown-parser.lua`
+* `./markdown-unicode-data.lua`
* `./markdown-cli.lua`
+* `./markdown2tex.lua`
* `./markdown/markdown.tex`
* `./markdown.sty`
* `./t-markdown.tex`
-* `./markdownthemewitiko_dot.sty`
-* `./markdownthemewitiko_graphicx_http.sty`
-* `./markdownthemewitiko_tilde.tex`
* `./markdownthemewitiko_markdown_defaults.tex`
* `./markdownthemewitiko_markdown_defaults.sty`
* `./t-markdownthemewitiko_markdown_defaults.tex`
@@ -1052,7 +1097,6 @@ The file `markdown.tex` *must* be placed in a directory named `markdown`.
%</manual>
%<*lua>
% \fi
-% \par
% \begin{markdown}
%
% Requirements
@@ -1075,10 +1119,13 @@ The file `markdown.tex` *must* be placed in a directory named `markdown`.
% Live${}\geq{}2013$).
%
% \end{markdown}
+% \iffalse
+%</lua>
+%<*lua,lua-unicode-data>
+% \fi
% \begin{macrocode}
local lpeg = require("lpeg")
% \end{macrocode}
-% \par
% \begin{markdown}
%
% \pkg{Selene Unicode}
@@ -1089,10 +1136,13 @@ local lpeg = require("lpeg")
% Lua\TeX{} (\TeX Live${}\geq{}2008$).
%
% \end{markdown}
+% \iffalse
+%</lua,lua-unicode-data>
+%<*lua,lua-unicode-data-generator>
+% \fi
% \begin{macrocode}
local unicode = require("unicode")
% \end{macrocode}
-% \par
% \begin{markdown}
%
% \pkg{MD5}
@@ -1103,9 +1153,17 @@ local unicode = require("unicode")
% Live${}\geq{}2008$).
%
% \end{markdown}
+% \iffalse
+%</lua,lua-unicode-data-generator>
+%<*lua,lua-loader>
+% \fi
% \begin{macrocode}
-local md5 = require("md5");
+local md5 = require("md5")
% \end{macrocode}
+% \iffalse
+%</lua,lua-loader>
+%<*lua,lua-unicode-data-generator>
+% \fi
% \begin{markdown}
%
% \pkg{Kpathsea}
@@ -1115,7 +1173,7 @@ local md5 = require("md5");
%
% \end{markdown}
% \begin{macrocode}
-(function()
+;(function()
% \end{macrocode}
% \begin{markdown}
%
@@ -1136,7 +1194,6 @@ local md5 = require("md5");
end
end)()
% \end{macrocode}
-% \par
% \begin{markdown}
%
% All the abovelisted modules are statically linked into the current version of
@@ -1148,27 +1205,40 @@ end)()
%: A package that implements Unicode case-folding in \TeX{} Live${}\geq{}2020$.
%
% \end{markdown}
+% \iffalse
+%</lua,lua-unicode-data-generator>
+%<*depends>
+% \fi
+% \begin{macrocode}
+hard lua-uni-algos
+% \end{macrocode}
+% \iffalse
+%</depends>
+%<*lua>
+% \fi
% \begin{macrocode}
local uni_algos = require("lua-uni-algos")
% \end{macrocode}
-% \par
% \begin{markdown}
%
% \pkg{api7/lua-tinyyaml}
%
%: A library that provides a regex-based recursive descent \acro{yaml}
% (subset) parser that is used to read \acro{yaml} metadata when the
-% \Opt{jekyllData} option is enabled. We carry a copy of the library
-% in file `markdown-tinyyaml.lua` distributed together with the Markdown
-% package. <!-- TODO: Stop carrying the copy of the library in TeX Live
-% 2023. -->
+% \Opt{jekyllData} option is enabled.
%
% \end{markdown}
% \iffalse
%</lua>
+%<*depends>
+% \fi
+% \begin{macrocode}
+hard lua-tinyyaml
+% \end{macrocode}
+% \iffalse
+%</depends>
%<*tex>
% \fi
-% \par
% \begin{markdown}
%
%### Plain \TeX{} Requirements {#tex-prerequisites}
@@ -1179,24 +1249,39 @@ local uni_algos = require("lua-uni-algos")
%
% \pkg{expl3}
%
-%: A package that enables the expl3 language from the \LaTeX3 kernel in
-% \TeX{} Live${}\leq{}2019$. It is used to implement reflection
+%: A package that enables the expl3 language [@latex25] from the \LaTeX3
+% kernel in \TeX{} Live${}\leq{}2019$. It is used to implement reflection
% capabilities that allow us to enumerate and inspect high-level concepts
% such as options, renderers, and renderer prototypes.
%
% \end{markdown}
-% \begin{macrocode}
+% \iffalse
%</tex>
+%<*depends>
+% \fi
+% \begin{macrocode}
+hard l3kernel
+% \end{macrocode}
+% \iffalse
+%</depends>
%<*context>
+% \fi
+% \begin{macrocode}
\unprotect
+% \end{macrocode}
+% \iffalse
%</context>
%<*context,tex>
-\ifx\ExplSyntaxOn\undefined
+% \fi
+% \begin{macrocode}
+\expandafter\ifx\csname ExplSyntaxOn\endcsname\relax
\input expl3-generic
\fi
+% \end{macrocode}
+% \iffalse
%</context,tex>
%<*tex>
-% \end{macrocode}
+% \fi
% \begin{markdown}
%
% \pkg{lt3luabridge}
@@ -1205,6 +1290,20 @@ local uni_algos = require("lua-uni-algos")
% with other TeX engines that provide the *shell escape* capability,
% which allows them to execute code with the system's shell.
%
+% \end{markdown}
+% \iffalse
+%</tex>
+%<*depends>
+% \fi
+% \begin{macrocode}
+hard lt3luabridge
+% \end{macrocode}
+% \iffalse
+%</depends>
+%<*tex>
+% \fi
+% \begin{markdown}
+%
% The plain \TeX{} part of the package also requires the following Lua module:
%
% \pkg{Lua File System}
@@ -1237,26 +1336,25 @@ local uni_algos = require("lua-uni-algos")
%</tex>
%<*latex>
% \fi
-% \par
% \begin{markdown}
%
%### \LaTeX{} Requirements {#latex-prerequisites}
%
% The \LaTeX{} part of the package requires that the \Hologo{LaTeX2e} format is
-% loaded,
+% loaded, a \TeX{} engine that extends \Hologo{eTeX}, and all the plain \TeX{}
+% prerequisites (see Section <#sec:tex-prerequisites>).
% \end{markdown}
% \iffalse
-%<*themes-witiko-dot,latex-themes-witiko-graphicx-http>
% \fi
% \begin{macrocode}
-\NeedsTeXFormat{LaTeX2e}%
+\NeedsTeXFormat{LaTeX2e}
+\RequirePackage{expl3}
% \end{macrocode}
% \iffalse
-%</themes-witiko-dot,latex-themes-witiko-graphicx-http>
+%</latex>
+%<*depends>
% \fi
% \begin{markdown}
-% a \TeX{} engine that extends \Hologo{eTeX}, and all the plain \TeX{}
-% prerequisites (see Section <#sec:tex-prerequisites>):
%
% The following packages are soft prerequisites. They are only used to provide
% default token renderer prototypes (see sections
@@ -1269,78 +1367,117 @@ local uni_algos = require("lua-uni-algos")
%
%: A package that provides the `\url` macro for the typesetting of links.
%
+% \end{markdown}
+% \begin{macrocode}
+soft url
+% \end{macrocode}
+% \begin{markdown}
+%
% \pkg{graphicx}
%
%: A package that provides the `\includegraphics` macro for the typesetting
-% of images.
+% of images. Furthermore, it also provides a key--value interface that is
+% used in the default renderer prototypes for image attribute contexts.
%
-% \pkg{paralist}
+% \end{markdown}
+% \begin{macrocode}
+soft graphics
+% \end{macrocode}
+% \begin{markdown}
%
-%: A package that provides the `compactitem`, `compactenum`, and
-% `compactdesc` macros for the typesetting of tight bulleted lists,
-% ordered lists, and definition lists as well as the rendering of
-% fancy lists.
+% \pkg{enumitem} and \pkg{paralist}
%
-% \pkg{ifthen}
+%: Packages that provide macros for the default renderer prototypes for
+% tight and fancy lists.
%
-%: A package that provides a concise syntax for the inspection of macro
-% values. It is used in the `witiko/dot` \LaTeX{} theme (see Section
-% <#sec:latexthemes>).
+% The package \pkg{paralist} will be used unless the option
+% \Opt{experimental} has been enabled, in which case, the package
+% \pkg{enumitem} will be used. Furthermore, enabling any test phase
+% [@latex24] will also cause \pkg{enumitem} to be used. In a future
+% major version, \pkg{enumitem} will replace \pkg{paralist} altogether.
+%
+% \end{markdown}
+% \begin{macrocode}
+soft enumitem
+soft paralist
+% \end{macrocode}
+% \begin{markdown}
%
% \pkg{fancyvrb}
%
%: A package that provides the `\VerbatimInput` macros for the verbatim
% inclusion of files containing code.
%
+% \end{markdown}
+% \begin{macrocode}
+soft fancyvrb
+% \end{macrocode}
+% \begin{markdown}
+%
% \pkg{csvsimple}
%
%: A package that provides the `\csvautotabular` macro for typesetting
% \acro{csv} files in the default renderer prototypes for iA\\,Writer
% content blocks.
%
-% \pkg{gobble}
-%
-%: A package that provides the `\@gobblethree` \TeX{} command that
-% is used in the default renderer prototype for citations. The package
-% is included in \TeX Live${}\geq{}2016$.
+% \end{markdown}
+% \begin{macrocode}
+soft csvsimple
+soft pgf # required by `csvsimple`, which loads `pgfkeys.sty`
+soft tools # required by `csvsimple`, which loads `shellesc.sty`
+soft etoolbox # required by `csvsimple`, which loads `etoolbox.sty`
+% \end{macrocode}
+% \begin{markdown}
%
% \pkg{amsmath} and \pkg{amssymb}
%
%: Packages that provide symbols used for drawing ticked and unticked
% boxes.
%
-% \pkg{catchfile}
-%
-%: A package that catches the contents of a file and puts it in a macro. It
-% is used in the `witiko/graphicx/http` \LaTeX{} theme, see Section
-% <#sec:latexthemes>.
+% \end{markdown}
+% \begin{macrocode}
+soft amsmath
+soft amsfonts
+% \end{macrocode}
+% \begin{markdown}
%
% \pkg{graphicx}
%
-%: A package that builds upon the \pkg{graphics} package, which is part of
-% the \LaTeXe{} kernel. It provides a key-value interface that is used in
-% the default renderer prototypes for image attribute contexts.
+%: A package that provides extended support for graphics. It is used in
+% the `witiko/diagrams`, and `witiko/graphicx/http` plain \TeX{} themes,
+% see Section <#sec:themes>.
%
-% \pkg{grffile}
+% \end{markdown}
+% \begin{macrocode}
+soft graphics
+soft epstopdf # required by `graphics` and `graphicx`, which load `epsopdf-base.sty`
+soft epstopdf-pkg # required by `graphics` and `graphicx`, which load `epsopdf-base.sty`
+% \end{macrocode}
+% \begin{markdown}
+%
+% \pkg{soul} and \pkg{xcolor}
%
-%: A package that extends the name processing of the \pkg{graphics} package
-% to support a larger range of file names in $2006\leq{}$\TeX{}
-% Live${}\leq{}2019$. Since \TeX{} Live${}\geq{}2020$, the functionality
-% of the package has been integrated in the \LaTeXe{} kernel. It is used in
-% the `witiko/dot` and `witiko/graphicx/http` \LaTeX{} themes, see Section
-% <#sec:latexthemes>.
+%: Packages that are used in the default renderer prototypes for
+% strike-throughs and marked text in pdf\TeX.
%
-% \pkg{etoolbox}
+% \end{markdown}
+% \begin{macrocode}
+soft soul
+soft xcolor
+% \end{macrocode}
+% \begin{markdown}
%
-%: A package that is used to polyfill the general hook management system in
-% the default renderer prototypes for \acro{yaml} metadata, see Section
-% <#sec:latex-yaml-metadata>, and also in the default renderer prototype
-% for identifier attributes.
+% \pkg{lua-ul} and \pkg{luacolor}
%
-% \pkg{soulutf8}
+%: Packages that are used in the default renderer prototypes for
+% strike-throughs and marked text in Lua\TeX.
%
-%: A package that is used in the default renderer prototype for
-% strike-throughs and marked text.
+% \end{markdown}
+% \begin{macrocode}
+soft lua-ul
+soft luacolor
+% \end{macrocode}
+% \begin{markdown}
%
% \pkg{ltxcmds}
%
@@ -1348,6 +1485,23 @@ local uni_algos = require("lua-uni-algos")
% \pkg{listings} packages are loaded in the default renderer prototype
% for fenced code blocks.
%
+% \end{markdown}
+% \begin{macrocode}
+soft ltxcmds
+% \end{macrocode}
+% \begin{markdown}
+%
+% \pkg{luaxml}
+%
+%: A package that is used to convert \acro{HTML} to \LaTeX{} in the default
+% renderer prototypes for content blocks, raw blocks, and inline raw spans.
+%
+% \end{markdown}
+% \begin{macrocode}
+soft luaxml
+% \end{macrocode}
+% \begin{markdown}
+%
% \pkg{verse}
%
%: A package that is used in the default renderer prototypes for
@@ -1355,13 +1509,15 @@ local uni_algos = require("lua-uni-algos")
%
% \end{markdown}
% \begin{macrocode}
-\RequirePackage{expl3}
+soft verse
% \end{macrocode}
+% \begin{markdown}
+%
+% \end{markdown}
% \iffalse
-%</latex>
+%</depends>
%<*context>
% \fi
-% \par
% \begin{markdown}
%
%### \Hologo{ConTeXt} Prerequisites
@@ -1501,21 +1657,14 @@ Hello *world*!
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ -- hello.md hello.tex
+markdown2tex -- hello.md hello.tex
luatex document.tex
``````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
-
- [Kpathsea]: https://tug.org/kpathsea/ (Kpathsea - TeX Users Group)
A PDF document named `document.pdf` should be produced and contain the text “Hello
*world*!” Invoking pdfTeX should have the same effect:
``` sh
-texlua ⟨CLI pathname⟩ -- hello.md hello.tex
+markdown2tex -- hello.md hello.tex
pdftex document.tex
``````
@@ -1708,7 +1857,6 @@ Each part will be shown by example, leaving the implementation details to the
%</manual>
%<*lua>
% \fi
-% \par
% \begin{markdown}
%
% Lua Interface {#luainterface}
@@ -1739,7 +1887,7 @@ module and a command-line interface (CLI).
(Lua library for conversion between markup formats)
%</manual-interfaces>
-%<*lua>
+%<*lua,lua-loader,lua-unicode-data>
% \fi
% \begin{markdown}
%
@@ -1754,7 +1902,10 @@ module and a command-line interface (CLI).
% \begin{macrocode}
local M = {metadata = metadata}
% \end{macrocode}
-% \par
+% \iffalse
+%</lua,lua-loader,lua-unicode-data>
+%<*lua>
+% \fi
% \begin{markdown}
%
%### Conversion from Markdown to Plain \TeX{} {#lua-conversion}
@@ -1823,7 +1974,6 @@ local walkable_syntax = {
},
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamref{reader->insert_pattern} method inserts a \acro{peg} pattern into
@@ -1983,15 +2133,10 @@ $\sqrt{-1}$ *equals* $i$.
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ -- example.md nomath.tex
-texlua ⟨CLI pathname⟩ tex_math_dollars=true -- example.md math.tex
+markdown2tex -- example.md nomath.tex
+markdown2tex tex_math_dollars=true -- example.md math.tex
luatex document.tex
``````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -2004,8 +2149,8 @@ following text:
Invoking pdfTeX should have the same effect:
``` sh
-texlua ⟨CLI pathname⟩ -- example.md nomath.tex
-texlua ⟨CLI pathname⟩ tex_math_dollars=true -- example.md math.tex
+markdown2tex -- example.md nomath.tex
+markdown2tex tex_math_dollars=true -- example.md math.tex
pdftex document.tex
``````
@@ -2030,16 +2175,15 @@ In this section, I will describe all the options recognized by the Markdown
package.
%</manual-options>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
local defaultOptions = {}
% \end{macrocode}
% \begingroup
% \markdownSetup{snippet=lua-options}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
### Lua
@@ -2073,7 +2217,9 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces.
\prop_new:N \g_@@_default_lua_options_prop
\seq_new:N \g_@@_option_layers_seq
\tl_const:Nn \c_@@_option_layer_lua_tl { lua }
-\seq_gput_right:NV \g_@@_option_layers_seq \c_@@_option_layer_lua_tl
+\seq_gput_right:NV
+ \g_@@_option_layers_seq
+ \c_@@_option_layer_lua_tl
\cs_new:Nn
\@@_add_lua_option:nnn
{
@@ -2150,21 +2296,50 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces.
\cs_generate_variant:Nn
\msg_error:nnnn
{ nnnV }
-\seq_new:N \g_@@_option_types_seq
-\tl_const:Nn \c_@@_option_type_clist_tl { clist }
-\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_clist_tl
-\tl_const:Nn \c_@@_option_type_counter_tl { counter }
-\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_counter_tl
-\tl_const:Nn \c_@@_option_type_boolean_tl { boolean }
-\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_boolean_tl
-\tl_const:Nn \c_@@_option_type_number_tl { number }
-\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_number_tl
-\tl_const:Nn \c_@@_option_type_path_tl { path }
-\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_path_tl
-\tl_const:Nn \c_@@_option_type_slice_tl { slice }
-\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_slice_tl
-\tl_const:Nn \c_@@_option_type_string_tl { string }
-\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_string_tl
+\seq_new:N
+ \g_@@_option_types_seq
+\tl_const:Nn
+ \c_@@_option_type_clist_tl
+ { clist }
+\seq_gput_right:NV
+ \g_@@_option_types_seq
+ \c_@@_option_type_clist_tl
+\tl_const:Nn
+ \c_@@_option_type_counter_tl
+ { counter }
+\seq_gput_right:NV
+ \g_@@_option_types_seq
+ \c_@@_option_type_counter_tl
+\tl_const:Nn
+ \c_@@_option_type_boolean_tl
+ { boolean }
+\seq_gput_right:NV
+ \g_@@_option_types_seq
+ \c_@@_option_type_boolean_tl
+\tl_const:Nn
+ \c_@@_option_type_number_tl
+ { number }
+\seq_gput_right:NV
+ \g_@@_option_types_seq
+ \c_@@_option_type_number_tl
+\tl_const:Nn
+ \c_@@_option_type_path_tl
+ { path }
+\seq_gput_right:NV
+ \g_@@_option_types_seq
+ \c_@@_option_type_path_tl
+\tl_const:Nn
+ \c_@@_option_type_slice_tl
+ { slice }
+\seq_gput_right:NV
+ \g_@@_option_types_seq
+ \c_@@_option_type_slice_tl
+\tl_const:Nn
+ \c_@@_option_type_string_tl
+ { string }
+\seq_gput_right:NV
+ \g_@@_option_types_seq
+ \c_@@_option_type_string_tl
\cs_new:Nn
\@@_get_option_type:nN
{
@@ -2270,7 +2445,7 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces.
\l_tmpa_tl
\tl_set:Nx
#2
- { \the \cs:w \l_tmpa_tl \cs_end: }
+ { \the \cs:w \l_tmpa_tl \cs_end: } % noqa: W200
}
{
\@@_option_tl_to_csname:nN
@@ -2296,7 +2471,6 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces.
}
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% To make it easier to support different coding styles in the interface,
@@ -2327,7 +2501,6 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces.
{ #2 }
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% To interrupt the \mref{\@\@_with_various_cases:nn} function
@@ -2381,25 +2554,27 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces.
%### General Behavior
%
% \end{markdown}
-% \par
% \iffalse
#### Option `eagerCache`
-`eagerCache` (default value: `false`)
+`eagerCache` (default value: `true`)
% \fi
% \begin{markdown}
%
-% \Optitem[false]{eagerCache}{\opt{true}, \opt{false}}
+% \Optitem[true]{eagerCache}{\opt{true}, \opt{false}}
%
: true
: Converted markdown documents will be cached in \Opt{cacheDir}. This can be
useful for post-processing the converted documents and for recovering
- historical versions of the documents from the cache. However, it also
- produces a large number of auxiliary files on the disk and obscures the
- output of the Lua command-line interface when it is used for plumbing.
+ historical versions of the documents from the cache. Furthermore, it can
+ also significantly improve the processing speed for documents that require
+ multiple compilation runs, since each markdown document is only converted once.
+ However, it also produces a large number of auxiliary files on the disk
+ and obscures the output of the Lua command-line interface when it is
+ used for plumbing.
This behavior will always be used if the \Opt{finalizeCache} option is
enabled.
@@ -2408,7 +2583,11 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces.
: Converted markdown documents will not be cached. This decreases the number
of auxiliary files that we produce and makes it easier to use the Lua
- command-line interface for plumbing.
+ command-line interface for plumbing. However, it makes it impossible to
+ post-process the converted documents and recover historical versions of
+ the documents from the cache. Furthermore, it can significantly reduce
+ the processing speed for documents that require multiple compilation
+ runs, since each markdown document is converted multiple times needlessly.
This behavior will only be used when the \Opt{finalizeCache} option is
disabled.
@@ -2426,13 +2605,8 @@ Hello *world*!
Next, invoke LuaTeX from the terminal with the \Opt{eagerCache} option
disabled:
``` sh
-texlua ⟨CLI pathname⟩ eagerCache=false -- hello.md hello.tex
+markdown2tex eagerCache=false -- hello.md hello.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A \TeX{} document named `hello.tex` should be produced and contain the
following code:
@@ -2446,7 +2620,7 @@ Invoke LuaTeX from the terminal again, this time with the \Opt{eagerCache}
option enabled:
``` tex
-texlua ⟨CLI pathname⟩ eagerCache=true -- hello.md hello.tex
+markdown2tex eagerCache=true -- hello.md hello.tex
```
A \TeX{} document named `hello.tex` should be produced and contain the
@@ -2470,18 +2644,62 @@ Hello \markdownRendererEmphasis{world}!\relax
\@@_add_lua_option:nnn
{ eagerCache }
{ boolean }
+ { true }
+% \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli,lua-loader>
+% \fi
+% \begin{macrocode}
+defaultOptions.eagerCache = true
+% \end{macrocode}
+% \iffalse
+%</lua,lua-cli,lua-loader>
+%<*manual-options>
+
+#### Option `experimental`
+
+`experimental` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{experimental}{\opt{true}, \opt{false}}
+%
+: true
+
+ : Experimental features that are planned to be the new default in the
+ next major release of the Markdown package will be enabled.
+
+ At the moment, this just means that the version `experimental` of the
+ theme `witiko/markdown/defaults` will be loaded and warnings for
+ hard-deprecated features will become errors. However, the effects may
+ extend to other areas in the future as well.
+
+: false
+
+ : Experimental features will be disabled.
+
+% \end{markdown}
+% \iffalse
+%</manual-options>
+%<*tex>
+% \fi
+% \begin{macrocode}
+\@@_add_lua_option:nnn
+ { experimental }
+ { boolean }
{ false }
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
-defaultOptions.eagerCache = false
+defaultOptions.experimental = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `singletonCache`
@@ -2509,12 +2727,11 @@ defaultOptions.eagerCache = false
: Every call to the function \luamref{new}`(options)` will produce a new
conversion function that will not be cached. This is slower than
caching conversion functions and may expose bugs related to memory
- leaks in the creation of conversion functions, see also issue
- [#226][issue-226].
+ leaks in the creation of conversion functions, see also [#226 (comment)][226-comment].
This was the default behavior until version 3.0.0 of the Markdown package.
- [issue-226]: https://github.com/witiko/markdown/pull/226#issuecomment-1599641634
+ [226-comment]: https://github.com/witiko/markdown/pull/226#issuecomment-1599641634
% \end{markdown}
% \iffalse
@@ -2563,13 +2780,13 @@ conversion function.
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.singletonCache = true
% \end{macrocode}
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*lua>
% \fi
% \begin{macrocode}
@@ -2578,7 +2795,6 @@ local singletonCache = {
options = nil,
}
% \end{macrocode}
-% \par
% \iffalse
%</lua>
%<*manual-options>
@@ -2618,14 +2834,13 @@ local singletonCache = {
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.unicodeNormalization = true
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `unicodeNormalizationForm`
@@ -2674,14 +2889,13 @@ defaultOptions.unicodeNormalization = true
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.unicodeNormalizationForm = "nfc"
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
% \fi
% \begin{markdown}
@@ -2689,7 +2903,6 @@ defaultOptions.unicodeNormalizationForm = "nfc"
%### File and Directory Names
%
% \end{markdown}
-% \par
% \iffalse
#### Option `cacheDir`
@@ -2760,14 +2973,9 @@ Hello *world*!
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ cacheDir=cache -- hello.md hello.tex
+markdown2tex cacheDir=cache -- hello.md hello.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the text
“Hello *world*!” A directory named `cache` containing several cache files of
@@ -2850,14 +3058,13 @@ option.
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.cacheDir = "."
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `contentBlocksLanguageMap`
@@ -3014,14 +3221,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.contentBlocksLanguageMap = "markdown-languages.json"
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `debugExtensionsFileName`
@@ -3063,14 +3269,13 @@ defaultOptions.contentBlocksLanguageMap = "markdown-languages.json"
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.debugExtensionsFileName = "debug-extensions.json"
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `frozenCacheFileName`
@@ -3142,14 +3347,9 @@ Hello *world*!
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ finalizeCache=true frozenCacheFileName=cache.tex -- hello.md hello.tex
+markdown2tex finalizeCache=true frozenCacheFileName=cache.tex -- hello.md hello.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the text
“Hello *world*!” A frozen cache will also be produced in the `cache.tex`
@@ -3305,14 +3505,13 @@ the markdown document from “Hello *world*!” to “Hi *world*!” was not ref
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.frozenCacheFileName = "frozenCache.tex"
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
% \fi
% \begin{markdown}
@@ -3320,7 +3519,6 @@ defaultOptions.frozenCacheFileName = "frozenCache.tex"
%### Parser Options
%
% \end{markdown}
-% \par
% \iffalse
#### Option `autoIdentifiers`
@@ -3362,14 +3560,13 @@ See also the option \Opt{gfmAutoIdentifiers}.
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.autoIdentifiers = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `blankBeforeBlockquote`
@@ -3455,15 +3652,10 @@ A paragraph.
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ blankBeforeBlockquote=true -- content.md optiontrue.tex
+markdown2tex -- content.md optionfalse.tex
+markdown2tex blankBeforeBlockquote=true -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -3586,14 +3778,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.blankBeforeBlockquote = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `blankBeforeCodeFence`
@@ -3690,15 +3881,10 @@ A code fence?
```````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ fencedCode=true -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ fencedCode=true blankBeforeCodeFence=true -- content.md optiontrue.tex
+markdown2tex fencedCode=true -- content.md optionfalse.tex
+markdown2tex fencedCode=true blankBeforeCodeFence=true -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -3843,14 +4029,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.blankBeforeCodeFence = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `blankBeforeDivFence`
@@ -3926,14 +4111,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.blankBeforeDivFence = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `blankBeforeHeading`
@@ -4025,15 +4209,10 @@ A heading?
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ blankBeforeHeading=true -- content.md optiontrue.tex
+markdown2tex -- content.md optionfalse.tex
+markdown2tex blankBeforeHeading=true -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -4166,14 +4345,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.blankBeforeHeading = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `blankBeforeList`
@@ -4261,15 +4439,10 @@ A paragraph.
```````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ blankBeforeList=true -- content.md optiontrue.tex
+markdown2tex -- content.md optionfalse.tex
+markdown2tex blankBeforeList=true -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -4392,14 +4565,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.blankBeforeList = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `bracketedSpans`
@@ -4488,14 +4660,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.bracketedSpans = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `breakableBlockquotes`
@@ -4583,15 +4754,10 @@ following content:
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ breakableBlockquotes=false -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ -- content.md optiontrue.tex
+markdown2tex breakableBlockquotes=false -- content.md optionfalse.tex
+markdown2tex -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -4722,14 +4888,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.breakableBlockquotes = true
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `citationNbsps`
@@ -4816,14 +4981,13 @@ following text, where the middot (`·`) denotes a non-breaking space:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.citationNbsps = true
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `citations`
@@ -4919,14 +5083,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.citations = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `codeSpans`
@@ -5022,15 +5185,10 @@ following content:
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ codeSpans=false -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ -- content.md optiontrue.tex
+markdown2tex codeSpans=false -- content.md optionfalse.tex
+markdown2tex -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -5145,14 +5303,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.codeSpans = true
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `contentBlocks`
@@ -5319,14 +5476,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.contentBlocks = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `contentLevel`
@@ -5456,14 +5612,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.contentLevel = "block"
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `debugExtensions`
@@ -5611,14 +5766,13 @@ inserted to the grammar of markdown.
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.debugExtensions = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `definitionLists`
@@ -5750,14 +5904,58 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.definitionLists = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
+%<*manual-options>
+
+#### Option `ensureJekyllData`
+
+`ensureJekyllData` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{ensureJekyllData}{\opt{true}, \opt{false}}
+%
+: false
+
+ : When the \Opt{jekyllData} and \Opt{expectJekyllData} options are
+ enabled, then a markdown document may begin directly with \acro{yaml}
+ metadata and may contain nothing but \acro{yaml} metadata. Otherwise,
+ the markdown document is processed as markdown text.
+
+: true
+
+ : When the \Opt{jekyllData} and \Opt{expectJekyllData} options are
+ enabled, then a markdown document must begin directly with \acro{yaml}
+ metadata and must contain nothing but \acro{yaml} metadata. Otherwise,
+ an error is produced.
+
+% \end{markdown}
+% \iffalse
+%</manual-options>
+%<*tex>
+% \fi
+% \begin{macrocode}
+\@@_add_lua_option:nnn
+ { ensureJekyllData }
+ { boolean }
+ { false }
+% \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli,lua-loader>
+% \fi
+% \begin{macrocode}
+defaultOptions.ensureJekyllData = false
+% \end{macrocode}
+% \iffalse
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `expectJekyllData`
@@ -5874,14 +6072,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.expectJekyllData = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `extensions`
@@ -6025,14 +6222,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.extensions = {}
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `fancyLists`
@@ -6127,14 +6323,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.fancyLists = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `fencedCode`
@@ -6294,14 +6489,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.fencedCode = true
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `fencedCodeAttributes`
@@ -6394,14 +6588,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.fencedCodeAttributes = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `fencedDivs` {#fenced-divs}
@@ -6473,14 +6666,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.fencedDivs = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `finalizeCache`
@@ -6637,14 +6829,13 @@ the markdown document from “Hello *world*!” to “Hi *world*!” was not ref
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.finalizeCache = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `frozenCacheCounter`
@@ -6706,14 +6897,13 @@ requested using the `frozenCacheCounter` option.
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.frozenCacheCounter = 0
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `gfmAutoIdentifiers`
@@ -6755,14 +6945,13 @@ See also the option \Opt{autoIdentifiers}.
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.gfmAutoIdentifiers = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `hashEnumerators`
@@ -6886,14 +7075,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.hashEnumerators = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `headerAttributes` {#header-attributes}
@@ -6935,14 +7123,13 @@ defaultOptions.hashEnumerators = false
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.headerAttributes = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `html`
@@ -7045,15 +7232,10 @@ _Is there <? HTML instruction ?> support?_
````````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ html=false -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ -- content.md optiontrue.tex
+markdown2tex html=false -- content.md optionfalse.tex
+markdown2tex -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -7207,14 +7389,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.html = true
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `hybrid`
@@ -7237,10 +7418,62 @@ defaultOptions.html = true
: false
: Enable the escaping of special plain \TeX{} characters outside verbatim
- environments, so that they are not interpretted by \TeX{}. This is
+ environments, so that they are not interpreted by \TeX{}. This is
encouraged when typesetting automatically generated content or
markdown documents that were not prepared with this package in mind.
+The \Opt{hybrid} option makes it difficult to untangle \TeX{} input from
+markdown text, which makes documents written with the \Opt{hybrid} option
+less interoperable and more difficult to read for authors. Therefore, the
+option has been soft-deprecated in version 3.7.1 of the Markdown package:
+It will never be removed but using it prints a warning and is discouraged.
+
+Consider one of the following better alternatives for mixing \TeX{} and
+markdown:
+
+- With the \Opt{contentBlocks} option, authors can move large blocks of TeX
+ code to separate files and include them in their markdown documents as
+ external resources:
+
+ ``` md
+ Here is a mathematical formula:
+
+ /math-formula.tex
+ ```
+
+- With the \Opt{rawAttribute} option, authors can denote raw text spans and
+ code blocks that will be interpreted as \TeX{} code:
+
+ `````` md
+ `$H_2 O$`{=tex} is a liquid.
+
+ Here is a mathematical formula:
+ ``` {=tex}
+ \[distance[i] =
+ \begin{dcases}
+ a & b \\
+ c & d
+ \end{dcases}
+ \]
+ ```
+ ``````
+
+- With options \Opt{texMathDollars}, \Opt{texMathSingleBackslash}, and
+ \Opt{texMathDoubleBackslash}, authors can freely type \TeX{} commands between
+ dollar signs or backslash-escaped brackets:
+
+ ``` md
+ $H_2 O$ is a liquid.
+
+ Here is a mathematical formula:
+ \[distance[i] =
+ \begin{dcases}
+ a & b \\
+ c & d
+ \end{dcases}
+ \]
+ ```
+
% \end{markdown}
% \iffalse
@@ -7307,15 +7540,10 @@ $\sqrt{-1}$ *equals* $i$.
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ hybrid=true -- content.md optiontrue.tex
+markdown2tex -- content.md optionfalse.tex
+markdown2tex hybrid=true -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -7433,14 +7661,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.hybrid = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `inlineCodeAttributes`
@@ -7529,14 +7756,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.inlineCodeAttributes = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `inlineNotes`
@@ -7630,14 +7856,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.inlineNotes = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `jekyllData`
@@ -7797,14 +8022,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.jekyllData = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `linkAttributes`
@@ -7894,14 +8118,13 @@ image (from [Martin Scharrer's mwe package][mwe]) displayed at size 5cm × 4cm.
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.linkAttributes = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `lineBlocks`
@@ -8029,14 +8252,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.lineBlocks = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `mark`
@@ -8100,14 +8322,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.mark = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `notes`
@@ -8263,14 +8484,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.notes = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `pipeTables` {#pipe-tables}
@@ -8372,14 +8592,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.pipeTables = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `preserveTabs`
@@ -8412,14 +8631,13 @@ defaultOptions.pipeTables = false
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.preserveTabs = true
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `rawAttribute`
@@ -8507,14 +8725,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.rawAttribute = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `relativeReferences`
@@ -8596,14 +8813,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.relativeReferences = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `shiftHeadings`
@@ -8736,14 +8952,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.shiftHeadings = 0
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `slice`
@@ -8954,14 +9169,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.slice = "^ $"
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `smartEllipses`
@@ -9045,15 +9259,10 @@ Are these just three regular dots, a victorian ellipsis, or ... ?
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ smartEllipses=true -- content.md optiontrue.tex
+markdown2tex -- content.md optionfalse.tex
+markdown2tex smartEllipses=true -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -9169,14 +9378,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.smartEllipses = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `startNumber`
@@ -9305,14 +9513,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.startNumber = true
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `strikeThrough`
@@ -9349,7 +9556,7 @@ following content:
``` tex
\input markdown
\def\markdownOptionStrikeThrough{true}
-\input soulutf8.sty
+\input soul.sty
\def\markdownRendererStrikeThrough#1{\st{#1}}
\markdownBegin
This is ~~a lunar roving vehicle~~ strike-through text.
@@ -9372,7 +9579,7 @@ following content:
``` tex
\documentclass{article}
\usepackage[strikeThrough]{markdown}
-\usepackage{soulutf8}
+\usepackage{soul}
\markdownSetup{
renderers = {
strikeThrough = {\st{#1}},
@@ -9427,14 +9634,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.strikeThrough = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `stripIndent`
@@ -9540,14 +9746,13 @@ text “Hello *world*!”
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.stripIndent = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `subscripts`
@@ -9632,14 +9837,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.subscripts = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `superscripts`
@@ -9724,14 +9928,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.superscripts = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `tableAttributes`
@@ -9849,14 +10052,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.tableAttributes = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `tableCaptions` {#table-captions}
@@ -9979,14 +10181,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.tableCaptions = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `taskLists`
@@ -10092,14 +10293,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.taskLists = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `texComments`
@@ -10208,14 +10408,13 @@ text “Hello *world*!”
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.texComments = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `texMathDollars`
@@ -10304,15 +10503,10 @@ $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ texMathDollars=true -- content.md optiontrue.tex
+markdown2tex -- content.md optionfalse.tex
+markdown2tex texMathDollars=true -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -10419,14 +10613,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.texMathDollars = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `texMathDoubleBackslash`
@@ -10515,15 +10708,10 @@ following content:
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ texMathDoubleBackslash=true -- content.md optiontrue.tex
+markdown2tex -- content.md optionfalse.tex
+markdown2tex texMathDoubleBackslash=true -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -10630,14 +10818,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.texMathDoubleBackslash = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `texMathSingleBackslash`
@@ -10726,15 +10913,10 @@ following content:
``````
Next, invoke LuaTeX from the terminal:
``` sh
-texlua ⟨CLI pathname⟩ -- content.md optionfalse.tex
-texlua ⟨CLI pathname⟩ texMathSingleBackslash=true -- content.md optiontrue.tex
+markdown2tex -- content.md optionfalse.tex
+markdown2tex texMathSingleBackslash=true -- content.md optiontrue.tex
luatex document.tex
```````
-where \meta{CLI pathname} corresponds to the location of the Lua CLI script file,
-such as `~/texmf/scripts/markdown/markdown-cli.lua` on UN\*X systems or
-`C:\Users\`\meta{Your username}`\texmf\scripts\markdown\markdown-cli.lua` on Windows
-systems. Use the command `kpsewhich -a markdown-cli.lua` to locate the Lua CLI
-script file using [Kpathsea][].
A PDF document named `document.pdf` should be produced and contain the
following text:
@@ -10841,14 +11023,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.texMathSingleBackslash = false
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `tightLists`
@@ -10962,14 +11143,13 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.tightLists = true
% \end{macrocode}
-% \par
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*manual-options>
#### Option `underscores`
@@ -11105,17 +11285,16 @@ following text:
% \end{macrocode}
% \iffalse
%</tex>
-%<*lua,lua-cli>
+%<*lua,lua-cli,lua-loader>
% \fi
% \begin{macrocode}
defaultOptions.underscores = true
% \end{macrocode}
% \endgroup
% \iffalse
-%</lua,lua-cli>
+%</lua,lua-cli,lua-loader>
%<*lua-cli>
% \fi
-% \par
% \begin{markdown}
%
%### Command-Line Interface {#lua-cli-interface}
@@ -11190,7 +11369,7 @@ Report bugs to: witiko@mail.muni.cz
Markdown package home page: <https://github.com/witiko/markdown>]]
local VERSION_STRING = [[
-markdown-cli.lua (Markdown) ]] .. metadata.version .. [[
+markdown-cli (Markdown) ]] .. metadata.version .. [[
Copyright (C) ]] .. table.concat(metadata.copyright,
"\nCopyright (C) ") .. [[
@@ -11198,7 +11377,8 @@ Copyright (C) ]] .. table.concat(metadata.copyright,
License: ]] .. metadata.license
local function warn(s)
- io.stderr:write("Warning: " .. s .. "\n") end
+ io.stderr:write("Warning: " .. s .. "\n")
+end
local function error(s)
io.stderr:write("Error: " .. s .. "\n")
@@ -11289,8 +11469,8 @@ for i = 1, #arg do
if default_type == "nil" then
warn('Option "' .. key .. '" not recognized.')
else
- warn('Option "' .. key .. '" type not recognized, please file ' ..
- 'a report to the package maintainer.')
+ warn('Option "' .. key .. '" type not recognized, ' ..
+ 'please file a report to the package maintainer.')
end
warn('Parsing the ' .. 'value "' .. value ..'" of option "' ..
key .. '" as a string.')
@@ -11322,7 +11502,7 @@ for i = 1, #arg do
end
% \end{macrocode}
% \begin{markdown}
-% The first argument that matches none of the above patters is assumed to be
+% The first argument that matches none of the above patterns is assumed to be
% the input filename. The input filename should correspond to the Markdown
% document that is going to be converted to a \TeX{} document.
% \end{markdown}
@@ -11331,7 +11511,7 @@ for i = 1, #arg do
input_filename = arg[i]
% \end{macrocode}
% \begin{markdown}
-% The first argument that matches none of the above patters is assumed to be
+% The first argument that matches none of the above patterns is assumed to be
% the output filename. The output filename should correspond to the \TeX{}
% document that will result from the conversion.
% \end{markdown}
@@ -11344,7 +11524,6 @@ for i = 1, #arg do
::continue::
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The command-line Lua interface is implemented by the `markdown-cli.lua`
@@ -11364,7 +11543,6 @@ end
%</lua-cli>
%<*tex>
% \fi
-% \par
% \begin{markdown}
%
% Plain \TeX{} Interface {#texinterface}
@@ -11437,7 +11615,6 @@ pdftex --shell-escape document.tex
\def\markdownLastModified{(((LASTMODIFIED)))}%
\def\markdownVersion{(((VERSION)))}%
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The plain \TeX{} interface is implemented by the `markdown.tex` file that can
@@ -11448,10 +11625,13 @@ pdftex --shell-escape document.tex
% \noindent It is expected that the special plain \TeX{} characters have the
% expected category codes, when `\input`ting the file.
%
-%### Typesetting Markdown {#tex-typesetting}
+%### Typesetting Markdown and YAML {#tex-typesetting}
%
% The interface exposes the \mdef{markdownBegin}, \mdef{markdownEnd},
-% \mdef{markinline}, \mdef{markdownInput}, and \mdef{markdownEscape} macros.
+% \mdef{yamlBegin}, \mref{yamlEnd}, \mdef{markinline}, \mdef{markdownInput},
+% \mdef{yamlInput}, and \mdef{markdownEscape} macros.
+%
+%#### Typesetting Markdown and YAML directly
%
% The \mref{markdownBegin} macro marks the beginning of a markdown document
% fragment and the \mref{markdownEnd} macro marks its end.
@@ -11461,7 +11641,6 @@ pdftex --shell-escape document.tex
\let\markdownBegin\relax
\let\markdownEnd\relax
% \end{macrocode}
-% \par
% \begin{markdown}
%
% You may prepend your own code to the \mref{markdownBegin} macro and redefine the
@@ -11509,13 +11688,49 @@ pdftex --shell-escape document.tex
% \bye
% ```````
%
+% The \mref{yamlBegin} macro marks the beginning of an \acro{YAML} document
+% fragment and the \mref{yamlEnd} macro marks its end.
+%
+% \end{markdown}
+% \begin{macrocode}
+\let\yamlBegin\relax
+\def\yamlEnd{\markdownEnd\endgroup}
+% \end{macrocode}
+% \begin{markdown}
+%
+% The \mref{yamlBegin} and \mref{yamlEnd} macros are subject to the same
+% limitations as the \mref{markdownBegin} and \mref{markdownEnd} macros.
+%
+% The following example plain \TeX{} code showcases the usage of the
+% \mref{markdownBegin} and \mref{markdownEnd} macros:
+%
+% ``` tex
+% \input markdown
+% \yamlBegin
+% title: _Hello_ **world** ...
+% author: John Doe
+% \yamlEnd
+% \bye
+% ```````
+%
+% The above code has the same effect as the below code:
+%
+% ``` tex
+% \input markdown
+% \yamlSetup{jekyllData, expectJekyllData, ensureJekyllData}
+% \markdownBegin
+% title: _Hello_ **world** ...
+% author: John Doe
+% \markdownEnd
+% \bye
+% ```````
+%
% You can use the \mref{markinline} macro to input inline markdown content.
%
% \end{markdown}
% \begin{macrocode}
\let\markinline\relax
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The following example plain \TeX{} code showcases the usage of the
@@ -11541,6 +11756,8 @@ pdftex --shell-escape document.tex
% The \mref{markinline} macro is subject to the same limitations as the
% \mref{markdownBegin} and \mref{markdownEnd} macros.
%
+%#### Typesetting Markdown and YAML from external documents
+%
% You can use the \mref{markdownInput} macro to include markdown documents,
% similarly to how you might use the \mref{input} \TeX{} primitive to include
% \TeX{} documents. The \mref{markdownInput} macro accepts a single parameter
@@ -11551,10 +11768,9 @@ pdftex --shell-escape document.tex
% \begin{macrocode}
\let\markdownInput\relax
% \end{macrocode}
-% \par
% \begin{markdown}
%
-% This macro is not subject to the limitations of the
+% The macro \mref{markdownInput} is not subject to the limitations of the
% \mref{markdownBegin} and \mref{markdownEnd} macros.
%
% The following example plain \TeX{} code showcases the usage of the
@@ -11566,6 +11782,46 @@ pdftex --shell-escape document.tex
% \bye
% ```````
%
+% You can use the \mref{yamlInput} macro to include \acro{YAML} documents.
+% similarly to how you might use the \mref{input} \TeX{} primitive to include
+% \TeX{} documents. The \mref{yamlInput} macro accepts a single parameter with
+% the filename of a \acro{YAML} document and expands to the result of the
+% conversion of the input \acro{YAML} document to plain \TeX{}.
+%
+% \end{markdown}
+% \begin{macrocode}
+\def\yamlInput#1{%
+ \begingroup
+ \yamlSetup{jekyllData, expectJekyllData, ensureJekyllData}%
+ \markdownInput{#1}%
+ \endgroup
+}%
+% \end{macrocode}
+% \begin{markdown}
+%
+% The macro \mref{yamlInput} is also not subject to the limitations of the
+% \mref{markdownBegin} and \mref{markdownEnd} macros.
+%
+% The following example plain \TeX{} code showcases the usage of the
+% \mref{markdownInput} macro:
+%
+% ``` tex
+% \input markdown
+% \yamlInput{hello.yml}
+% \bye
+% ```````
+%
+% The above code has the same effect as the below code:
+%
+% ``` tex
+% \input markdown
+% \yamlSetup{jekyllData, expectJekyllData, ensureJekyllData}
+% \markdownInput{hello.yml}
+% \bye
+% ```````
+%
+%#### Typesetting TeX from inside Markdown and YAML documents
+%
% The \mref{markdownEscape} macro accepts a single parameter with the filename
% of a \TeX{} document and executes the \TeX{} document in the middle of a
% markdown document fragment. Unlike the `\input` built-in of \TeX,
@@ -11576,7 +11832,6 @@ pdftex --shell-escape document.tex
% \begin{macrocode}
\let\markdownEscape\relax
% \end{macrocode}
-% \par
% \begin{markdown}
%
%### Options {#tex-options}
@@ -11625,7 +11880,9 @@ pdftex --shell-escape document.tex
% \begin{macrocode}
\prop_new:N \g_@@_plain_tex_option_types_prop
\prop_new:N \g_@@_default_plain_tex_options_prop
-\seq_gput_right:NV \g_@@_option_layers_seq \c_@@_option_layer_plain_tex_tl
+\seq_gput_right:NV
+ \g_@@_option_layers_seq
+ \c_@@_option_layer_plain_tex_tl
\cs_new:Nn
\@@_add_plain_tex_option:nnn
{
@@ -11660,7 +11917,6 @@ following code in your plain \TeX{} document:
%</manual-options>
%<*tex>
% \fi
-% \par
% \begin{markdown}
%
% The plain \TeX{} options may be also be specified via the \mdef{markdownSetup}
@@ -11684,6 +11940,18 @@ following code in your plain \TeX{} document:
\markdownSetup
\@@_setup:n
% \end{macrocode}
+% \begin{markdown}
+%
+% The command \mdef{yamlSetup} is also available as an alias for the command
+% \mref{markdownSetup}.
+%
+% \end{markdown}
+% \begin{macrocode}
+\cs_gset_eq:NN
+ \yamlSetup
+ \markdownSetup
+% \end{macrocode}
+%
% \iffalse
%</tex>
%<*manual-options>
@@ -11699,7 +11967,6 @@ you would include the following code in your plain \TeX{} document:
%</manual-options>
%<*tex>
% \fi
-% \par
% \begin{markdown}
%
% The
@@ -11743,7 +12010,9 @@ you would include the following code in your plain \TeX{} document:
Option~#1~has~type~#2,~
but~a~boolean~was~expected.
}
-\let\markdownIfOption=\@@_if_option:nTF
+\let
+ \markdownIfOption
+ \@@_if_option:nTF
% \end{macrocode}
% \begin{markdown}
%
@@ -11834,7 +12103,6 @@ For more information, see the examples for the \Opt{finalizeCache} option.
{ path }
{ \jobname.markdown.in }
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \mdef{markdownOptionOutputDir} macro sets the path to the directory that
@@ -11850,53 +12118,14 @@ For more information, see the examples for the \Opt{finalizeCache} option.
% \Opt{inputTempFileName} macro.
%
% The \mref{markdownOptionOutputDir} macro has been deprecated and will be
-% removed in the next major version of the Markdown package. <!-- After the
-% macro has been removed, we should remove support for TeX Live 2023 and
-% earlier, where the automatic detection does not work. -->
+% removed in the next major version of the Markdown package.
%
% \end{markdown}
% \begin{macrocode}
-\cs_generate_variant:Nn
- \@@_add_plain_tex_option:nnn
- { nnV }
-% \end{macrocode}
-% \begin{markdown}
-%
-% Use the \pkg{lt3luabridge} library to determine the default value of the
-% \mref{markdownOptionOutputDir} macro by using the environmental variable
-% `TEXMF_OUTPUT_DIRECTORY` that is available since TeX~Live 2024.
-%
-% \end{markdown}
-% \begin{macrocode}
-\ExplSyntaxOff
-\input lt3luabridge.tex
-\ExplSyntaxOn
-\bool_if:nTF
- {
- \cs_if_exist_p:N
- \luabridge_tl_set:Nn &&
- (
- \int_compare_p:nNn
- { \g_luabridge_method_int }
- =
- { \c_luabridge_method_directlua_int } ||
- \sys_if_shell_unrestricted_p:
- )
- }
- {
- \luabridge_tl_set:Nn
- \l_tmpa_tl
- { print(os.getenv("TEXMF_OUTPUT_DIRECTORY") or ".") }
- }
- {
- \tl_set:Nn
- \l_tmpa_tl
- { . }
- }
-\@@_add_plain_tex_option:nnV
+\@@_add_plain_tex_option:nnn
{ outputDir }
{ path }
- \l_tmpa_tl
+ { . }
% \end{macrocode}
% \iffalse
%</tex>
@@ -12114,16 +12343,16 @@ A PDF document named `document.pdf` should be produced and contain the text
%#### Generating Plain \TeX{} Option Macros and Key-Values
%
% We define the command \mdef{@@_define_option_commands_and_keyvals:} that
-% defines plain \TeX{} macros and the key-value interface
+% defines plain \TeX{} macros and the key--value interface
% of the \mref{markdownSetup} macro for the above plain \TeX{} options.
%
-% The command also defines macros and key-values that map
+% The command also defines macros and key--values that map
% directly to the options recognized by the Lua interface, such as
% \mdef{markdownOptionHybrid} for the \Opt{hybrid} Lua option (see Section
% <#sec:lua-options>), which are not processed by the plain \TeX{}
% implementation, only passed along to Lua.
%
-% Furthermore, the command also defines options and key-values
+% Furthermore, the command also defines options and key--values
% for subsequently loaded layers that correspond to higher-level \TeX{} formats
% such as \LaTeX{} and \Hologo{ConTeXt}.
%
@@ -12172,22 +12401,95 @@ A PDF document named `document.pdf` should be produced and contain the text
% \end{macrocode}
% \begin{markdown}
%
-% Do not override options defined before loading the package.
+% Use the \pkg{lt3luabridge} library to determine the default value of the
+% \mref{markdownOptionOutputDir} macro by using the environmental variable
+% `TEXMF_OUTPUT_DIRECTORY` that is available since TeX~Live 2024.
%
% \end{markdown}
% \begin{macrocode}
- \@@_option_tl_to_csname:nN
+ \str_if_eq:nnTF
{ #1 }
- \l_tmpa_tl
- \cs_if_exist:cF
- { \l_tmpa_tl }
+ { outputDir }
+ { \@@_define_option_command_output_dir: }
{
- \@@_get_default_option_value:nN
- { #1 }
- \l_tmpa_tl
- \@@_set_option_value:nV
+% \end{macrocode}
+% \begin{markdown}
+%
+% Do not override options defined before loading the package.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \@@_option_tl_to_csname:nN
{ #1 }
\l_tmpa_tl
+ \cs_if_exist:cF
+ { \l_tmpa_tl }
+ {
+ \@@_get_default_option_value:nN
+ { #1 }
+ \l_tmpa_tl
+ \@@_set_option_value:nV
+ { #1 }
+ \l_tmpa_tl
+ }
+ }
+ }
+\ExplSyntaxOff
+\input lt3luabridge.tex
+% \end{macrocode}
+% \begin{markdown}
+%
+% Use the \pkg{lt3luabridge} library to determine the default value of the
+% \mref{markdownOptionOutputDir} macro by using the environmental variable
+% `TEXMF_OUTPUT_DIRECTORY` that is available since TeX~Live 2024.
+%
+% \end{markdown}
+% \begin{macrocode}
+\ExplSyntaxOn
+\cs_new:Nn
+ \@@_define_option_command_output_dir:
+ {
+ \cs_if_free:NT
+ \markdownOptionOutputDir
+ {
+ \bool_if:nTF
+ {
+ \cs_if_exist_p:N
+ \luabridge_tl_set:Nn &&
+ (
+ \int_compare_p:nNn
+ { \g_luabridge_method_int }
+ =
+ { \c_luabridge_method_directlua_int } ||
+ \sys_if_shell_unrestricted_p:
+ )
+ }
+ {
+% \end{macrocode}
+% \begin{markdown}
+%
+% Set most catcodes to category 12 (other) to ensure that special characters in
+% `TEXMF_OUTPUT_DIRECTORY` such as backslashes (`\`) are not interpreted as
+% control sequences.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \group_begin:
+ \cctab_select:N
+ \c_str_cctab
+ \luabridge_tl_set:Nn
+ \l_tmpa_tl
+ { print(os.getenv("TEXMF_OUTPUT_DIRECTORY") or ".") }
+ \tl_gset:NV
+ \markdownOptionOutputDir
+ \l_tmpa_tl
+ \group_end:
+ }
+ {
+ \tl_gset:Nn
+ \markdownOptionOutputDir
+ { . }
+ }
}
}
\cs_new:Nn
@@ -12347,7 +12649,7 @@ A PDF document named `document.pdf` should be produced and contain the text
\l_tmpa_tl
\clist_set:NV
\l_tmpa_clist
- { \l_tmpa_tl, { ##1 } }
+ { \l_tmpa_tl , { ##1 } }
\@@_set_option_value:nV
{ #2 }
\l_tmpa_clist
@@ -12370,7 +12672,7 @@ A PDF document named `document.pdf` should be produced and contain the text
\prg_generate_conditional_variant:Nnn
\str_if_eq:nn
{ en }
- { F }
+ { p, F }
\msg_new:nnn
{ markdown }
{ malformed-name-for-clist-option }
@@ -12382,7 +12684,7 @@ A PDF document named `document.pdf` should be produced and contain the text
%
% If plain \TeX{} is the top layer, we use the
% \mref{@@_define_option_commands_and_keyvals:} macro to define plain \TeX{}
-% option macros and key-values immediately. Otherwise, we
+% option macros and key--values immediately. Otherwise, we
% postpone the definition until the upper layers have been loaded.
%
% \end{markdown}
@@ -12401,34 +12703,43 @@ A PDF document named `document.pdf` should be produced and contain the text
% \fi
% \begin{markdown}
-### Themes {#themes}
+%### Themes {#themes}
+% \iffalse
+#### Themes {#themes}
+% \fi
User-defined themes for the Markdown package provide a domain-specific
interpretation of Markdown tokens. Themes allow the authors to achieve
a specific look and other high-level goals without low-level programming.
-% The key-values `theme`=\meta{theme name} and `import`=\meta{theme name} load
-% a \TeX{} document (further referred to as *a theme*) named
-% `markdowntheme`\meta{munged theme name}`.tex`, where the *munged theme name*
-% is the *theme name* after the substitution of all forward slashes (`/`) for
-% an underscore (`_`). The theme name is *qualified* and contains no
-% underscores. A theme name is qualified if and only if it contains at least
-% one forward slash. Themes are inspired by the Beamer \LaTeX{} package, which
-% provides similar functionality with its `\usetheme` macro [@tantau21, Section
-% 15.1].
-%
-% Theme names must be qualified to minimize naming conflicts between different
-% themes with a similar purpose. The preferred format of a theme name is
-% \meta{theme author}`/`\meta{theme purpose}`/`\meta{private naming
-% scheme}, where the *private naming scheme* may contain additional forward
-% slashes. For example, a theme by a user `witiko` for the MU theme of the
-% Beamer document class may have the name `witiko/beamer/MU`.
+% The key--values `theme`=\meta{theme name} and `import`=\meta{theme name},
+% optionally followed by `@`\meta{theme version}, load a \TeX{} document
+% (further referred to as *a theme*) named `markdowntheme`\meta{munged theme
+% name}`.tex`, where the *munged theme name* is the *theme name* after the
+% substitution of all forward slashes (`/`) for an underscore (`_`).
+% The theme name must be *qualified* and contain no underscores or at signs
+% (`@`). Themes are inspired by the Beamer \LaTeX{} package, which provides
+% similar functionality with its `\usetheme` macro [@tantau21, Section 15.1].
+%
+% A theme name is qualified if and only if it contains at least one forward
+% slash. Theme names must be qualified to minimize naming conflicts between
+% different themes with a similar purpose. The preferred format of a theme name
+% is \meta{theme author}`/`\meta{theme purpose}`/`\meta{private naming scheme},
+% where the *private naming scheme* may contain additional forward slashes. For
+% example, a theme by a user `witiko` for the MU theme of the Beamer document
+% class may have the name `witiko/beamer/MU`.
%
% Theme names are munged to allow structure inside theme names without
% dictating where the themes should be located inside the \TeX{} directory
% structure. For example, loading a theme named `witiko/beamer/MU` would
% load a \TeX{} document package named `markdownthemewitiko_beamer_MU.tex`.
%
+% If `@`\meta{theme version} is specified after \meta{theme name}, then the
+% text *theme version* will be available in the macro
+% \mdef{markdownThemeVersion} when the theme is loaded. If `@`\meta{theme
+% version} is not specified, the macro \mref{markdownThemeVersion} will
+% contain the text `latest` [@novotny24].
+%
% \end{markdown}
% \iffalse
%</manual-options>
@@ -12471,21 +12782,31 @@ a specific look and other high-level goals without low-level programming.
% \begin{markdown}
%
% To keep track of the current theme when themes are nested, we will
-% maintain the \mdef{g_\@\@_themes_seq} stack of theme names.
-% For convenience, the name of the current theme is also available in the
-% \mdef{g_@@_current_theme_tl} macro.
+% maintain the stacks \mdef{g_\@\@_theme_names_seq} and
+% \mdef{g_\@\@_theme_versions_seq} stack of theme names and versions,
+% respectively. For convenience, the name of the current theme and version is
+% also available in the macros \mdef{g_@@_current_theme_tl} and
+% \mref{markdownThemeVersion}, respectively.
%
% \end{markdown}
% \begin{macrocode}
\seq_new:N
- \g_@@_themes_seq
+ \g_@@_theme_names_seq
+\seq_new:N
+ \g_@@_theme_versions_seq
\tl_new:N
\g_@@_current_theme_tl
\tl_gset:Nn
\g_@@_current_theme_tl
{ }
\seq_gput_right:NV
- \g_@@_themes_seq
+ \g_@@_theme_names_seq
+ \g_@@_current_theme_tl
+\cs_new:Npn
+ \markdownThemeVersion
+ { }
+\seq_gput_right:NV
+ \g_@@_theme_versions_seq
\g_@@_current_theme_tl
\cs_new:Nn
\@@_set_theme:n
@@ -12518,13 +12839,55 @@ a specific look and other high-level goals without low-level programming.
% \end{macrocode}
% \begin{markdown}
%
+% Next, we extract the theme version.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \str_if_in:nnTF
+ { #1 }
+ { @ }
+ {
+ \regex_extract_once:nnN
+ { (.*) @ (.*) }
+ { #1 }
+ \l_tmpa_seq
+ \seq_gpop_left:NN
+ \l_tmpa_seq
+ \l_tmpa_tl
+ \seq_gpop_left:NN
+ \l_tmpa_seq
+ \l_tmpa_tl
+ \tl_gset:NV
+ \g_@@_current_theme_tl
+ \l_tmpa_tl
+ \seq_gpop_left:NN
+ \l_tmpa_seq
+ \l_tmpa_tl
+ \cs_gset:Npe
+ \markdownThemeVersion
+ {
+ \tl_use:N
+ \l_tmpa_tl
+ }
+ }
+ {
+ \tl_gset:Nn
+ \g_@@_current_theme_tl
+ { #1 }
+ \cs_gset:Npn
+ \markdownThemeVersion
+ { latest }
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
% Next, we munge the theme name.
%
% \end{markdown}
% \begin{macrocode}
- \str_set:Nn
+ \str_set:NV
\l_tmpa_str
- { #1 }
+ \g_@@_current_theme_tl
\str_replace_all:Nnn
\l_tmpa_str
{ / }
@@ -12532,28 +12895,56 @@ a specific look and other high-level goals without low-level programming.
% \end{macrocode}
% \begin{markdown}
%
-% Finally, we load the theme.
+% Finally, we load the theme. Before loading the theme, we push down the
+% current name and version of the theme on the stack.
%
% \end{markdown}
% \begin{macrocode}
- \tl_gset:Nn
+ \tl_set:NV
+ \l_tmpa_tl
+ \g_@@_current_theme_tl
+ \tl_put_right:Nn
\g_@@_current_theme_tl
- { #1 / }
+ { / }
\seq_gput_right:NV
- \g_@@_themes_seq
+ \g_@@_theme_names_seq
\g_@@_current_theme_tl
- \@@_load_theme:nV
- { #1 }
+ \seq_gput_right:NV
+ \g_@@_theme_versions_seq
+ \markdownThemeVersion
+ \@@_load_theme:VeV
+ \l_tmpa_tl
+ { \markdownThemeVersion }
\l_tmpa_str
+% \end{macrocode}
+% \begin{markdown}
+%
+% After the theme has been loaded, we recover the name and version of the
+% previous theme from the stack.
+%
+% \end{markdown}
+% \begin{macrocode}
\seq_gpop_right:NN
- \g_@@_themes_seq
+ \g_@@_theme_names_seq
\l_tmpa_tl
\seq_get_right:NN
- \g_@@_themes_seq
+ \g_@@_theme_names_seq
\l_tmpa_tl
\tl_gset:NV
\g_@@_current_theme_tl
\l_tmpa_tl
+ \seq_gpop_right:NN
+ \g_@@_theme_versions_seq
+ \l_tmpa_tl
+ \seq_get_right:NN
+ \g_@@_theme_versions_seq
+ \l_tmpa_tl
+ \cs_gset:Npe
+ \markdownThemeVersion
+ {
+ \tl_use:N
+ \l_tmpa_tl
+ }
}
\msg_new:nnnn
{ markdown }
@@ -12568,17 +12959,324 @@ a specific look and other high-level goals without low-level programming.
\cs_generate_variant:Nn
\tl_replace_all:Nnn
{ NnV }
-\ExplSyntaxOff
+\cs_generate_variant:Nn
+ \cs_gset:Npn
+ { Npe }
+% \end{macrocode}
+% \begin{markdown}
+%
+% We also define the prop \mdef{g_@@_plain_tex_built_in_themes_prop} that
+% contains the code of built-in themes. This is a packaging optimization,
+% so that built-in themes does not need to be distributed in many small files.
+%
+% \end{markdown}
+% \begin{macrocode}
+\prop_new:N
+ \g_@@_plain_tex_built_in_themes_prop
% \end{macrocode}
% \iffalse
%</tex>
%<*manual-options>
% \fi
-% \par
-% \begin{markdown}
+% \markdownBegin
Built-in plain \TeX{} themes provided with the Markdown package include:
+\pkg{witiko/diagrams}
+
+: A theme that typesets fenced code blocks with the infostrings
+ `dot`, `mermaid`, and `plantuml` as figures with diagrams produced with
+ the command `dot` from Graphviz tools, the command `mmdc` from the npm
+ package `@mermaid-js/mermaid-cli`, and the command `plantuml` from the
+ package PlantUML, respectively. The key-value attribute `caption` can be
+ used to specify the caption of the figure. The remaining attributes are
+ treated as image attributes.
+
+% ```` tex
+% \documentclass{article}
+% \usepackage[import=witiko/diagrams@v2, relativeReferences]{markdown}
+% \begin{document}
+% \begin{markdown}
+% ``` dot {caption="An example directed graph" width=12cm #dot}
+% digraph tree {
+% margin = 0;
+% rankdir = "LR";
+%
+% latex -> pmml;
+% latex -> cmml;
+% pmml -> slt;
+% cmml -> opt;
+% cmml -> prefix;
+% cmml -> infix;
+% pmml -> mterms [style=dashed];
+% cmml -> mterms;
+%
+% latex [label = "LaTeX"];
+% pmml [label = "Presentation MathML"];
+% cmml [label = "Content MathML"];
+% slt [label = "Symbol Layout Tree"];
+% opt [label = "Operator Tree"];
+% prefix [label = "Prefix"];
+% infix [label = "Infix"];
+% mterms [label = "M-Terms"];
+% }
+% ```
+%
+% ``` mermaid {caption="An example mindmap" width=9cm #mermaid}
+% mindmap
+% root )base-idea(
+% sub<br/>idea 1
+% ((?))
+% sub<br/>idea 2
+% ((?))
+% sub<br/>idea 3
+% ((?))
+% sub<br/>idea 4
+% ((?))
+% ```
+%
+% ``` plantuml {caption="An example UML sequence diagram" width=7cm #plantuml}
+% @startuml
+% ' Define participants (actors)
+% participant "Client" as C
+% participant "Server" as S
+% participant "Database" as DB
+%
+% ' Diagram title
+% title Simple Request-Response Flow
+%
+% ' Messages
+% C -> S: Send Request
+% note over S: Process request
+%
+% alt Request is valid
+% S -> DB: Query Data
+% DB -> S: Return Data
+% S -> C: Respond with Data
+% else Request is invalid
+% S -> C: Return Error
+% end
+% @enduml
+% ```
+%
+% See the diagrams in figures <#dot>, <#mermaid>, and <#plantuml>.
+% \end{markdown}
+% \end{document}
+% ````````
+%
+% Typesetting the above document produces the output shown in
+% figures <#fig:witiko-diagrams-dot>, <#fig:witiko-diagrams-mermaid>, and
+% <#fig:witiko-diagrams-plantuml>.
+%
+% ``` dot {caption="An example directed graph" #fig:witiko-diagrams-dot}
+% digraph tree {
+% margin = 0;
+% rankdir = "LR";
+%
+% latex -> pmml;
+% latex -> cmml;
+% pmml -> slt;
+% cmml -> opt;
+% cmml -> prefix;
+% cmml -> infix;
+% pmml -> mterms [style=dashed];
+% cmml -> mterms;
+%
+% latex [label = "LaTeX"];
+% pmml [label = "Presentation MathML"];
+% cmml [label = "Content MathML"];
+% slt [label = "Symbol Layout Tree"];
+% opt [label = "Operator Tree"];
+% prefix [label = "Prefix"];
+% infix [label = "Infix"];
+% mterms [label = "M-Terms"];
+% }
+% ```
+%
+% ``` mermaid {caption="An example mindmap" #fig:witiko-diagrams-mermaid}
+% mindmap
+% root )base-idea(
+% sub<br/>idea 1
+% ((?))
+% sub<br/>idea 2
+% ((?))
+% sub<br/>idea 3
+% ((?))
+% sub<br/>idea 4
+% ((?))
+% ```
+%
+% ``` plantuml {caption="An example UML sequence diagram" #fig:witiko-diagrams-plantuml}
+% @startuml
+% ' Define participants (actors)
+% participant "Client" as C
+% participant "Server" as S
+% participant "Database" as DB
+%
+% ' Diagram title
+% title Simple Request-Response Flow
+%
+% ' Messages
+% C -> S: Send Request
+% note over S: Process request
+%
+% alt Request is valid
+% S -> DB: Query Data
+% DB -> S: Return Data
+% S -> C: Respond with Data
+% else Request is invalid
+% S -> C: Return Error
+% end
+% @enduml
+% ```
+
+ The theme requires a Unix-like operating system with GNU Diffutils,
+ Graphviz, the npm package `@mermaid-js/mermaid-cli`, and PlantUML
+ installed. All these packages are already included in the Docker image
+ `witiko/markdown`; consult `Dockerfile` to see how they are installed.
+ The theme also requires shell access unless the \Opt{frozenCache} plain
+ \TeX{} option is enabled.
+
+% \markdownEnd
+% \iffalse
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+```` tex
+\documentclass{article}
+\usepackage[import=witiko/diagrams@v2, relativeReferences]{markdown}
+\begin{document}
+\begin{markdown}
+``` dot {caption="An example directed graph" width=12cm #dot}
+digraph tree {
+ margin = 0;
+ rankdir = "LR";
+
+ latex -> pmml;
+ latex -> cmml;
+ pmml -> slt;
+ cmml -> opt;
+ cmml -> prefix;
+ cmml -> infix;
+ pmml -> mterms [style=dashed];
+ cmml -> mterms;
+
+ latex [label = "LaTeX"];
+ pmml [label = "Presentation MathML"];
+ cmml [label = "Content MathML"];
+ slt [label = "Symbol Layout Tree"];
+ opt [label = "Operator Tree"];
+ prefix [label = "Prefix"];
+ infix [label = "Infix"];
+ mterms [label = "M-Terms"];
+}
+```
+
+``` mermaid {caption="An example mindmap" width=9cm #mermaid}
+mindmap
+ root )base-idea(
+ sub<br/>idea 1
+ ((?))
+ sub<br/>idea 2
+ ((?))
+ sub<br/>idea 3
+ ((?))
+ sub<br/>idea 4
+ ((?))
+```
+
+``` plantuml {caption="An example UML sequence diagram" width=7cm #plantuml}
+@startuml
+' Define participants (actors)
+participant "Client" as C
+participant "Server" as S
+participant "Database" as DB
+
+' Diagram title
+title Simple Request-Response Flow
+
+' Messages
+C -> S: Send Request
+note over S: Process request
+
+alt Request is valid
+ S -> DB: Query Data
+ DB -> S: Return Data
+ S -> C: Respond with Data
+else Request is invalid
+ S -> C: Return Error
+end
+@enduml
+```
+
+See the diagrams in figures <#dot>, <#mermaid>, and <#plantuml>.
+\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
+three diagrams.
+
+% \fi
+% \markdownBegin
+
+\pkg{witiko/graphicx/http}
+
+: A theme that adds support for downloading images whose URL has the
+ http or https protocol.
+% ``` tex
+% \documentclass{article}
+% \usepackage[import=witiko/graphicx/http]{markdown}
+% \begin{document}
+% \begin{markdown}
+% ![img](https://github.com/witiko/markdown/raw/main/markdown.png
+% "The banner of the Markdown package")
+% \end{markdown}
+% \end{document}
+% ```````
+% Typesetting the above document produces the output shown in
+% Figure <#fig:witiko-graphicx-http>.
+% ![img](https://github.com/witiko/markdown/raw/main/markdown.png
+% "The banner of the Markdown package"){#fig:witiko-graphicx-http}
+ The theme requires the \pkg{catchfile} \LaTeX{} package and a Unix-like
+ operating system with GNU Coreutils `md5sum` and either GNU Wget or cURL
+ installed. The theme also requires shell access unless the
+ \Opt{frozenCache} plain \TeX{} option is enabled.
+
+% \markdownEnd
+% \iffalse
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[import=witiko/graphicx/http, link_attributes]{markdown}
+\begin{document}
+\begin{markdown}
+![img](https://github.com/witiko/markdown/raw/main/markdown.png
+ "The banner of the Markdown package"){width=5in}
+\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 image:
+
+> ![Figure 1: The banner of the Markdown package](https://github.com/witiko/markdown/raw/main/markdown.png)
+
+% \fi
+% \begin{markdown}
+
\pkg{witiko/tilde}
: A theme that makes tilde (`~`) always typeset the non-breaking space even
@@ -12619,7 +13317,6 @@ following text, where the middot (`·`) denotes a non-breaking space:
> Bartel·Leendert van·der·Waerden
% \fi
-% \par
% \begin{markdown}
\pkg{witiko/markdown/defaults}
@@ -12630,8 +13327,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
% Please, see Section <#sec:themes-implementation> for implementation
% details of the built-in plain \TeX{} themes.
-
-### Snippets {#snippets}
+%
+%### Snippets {#snippets}
+% \iffalse
+#### Snippets {#snippets}
+% \fi
% \end{markdown}
% \iffalse
@@ -12644,7 +13344,6 @@ options locally.
%</manual-options>
%<*tex>
% \fi
-% \par
% \begin{markdown}
%
% We may set up options as *snippets* using the
@@ -12654,7 +13353,6 @@ options locally.
%
% \end{markdown}
% \begin{macrocode}
-\ExplSyntaxOn
\prop_new:N
\g_@@_snippets_prop
\cs_new:Nn
@@ -12682,10 +13380,14 @@ options locally.
{ redefined-snippet }
\l_tmpa_tl
}
- \prop_gput:NVn
+ \keys_precompile:nnN
+ { markdown/options }
+ { #2 }
+ \l_tmpb_tl
+ \prop_gput:NVV
\g_@@_snippets_prop
\l_tmpa_tl
- { #2 }
+ \l_tmpb_tl
}
\cs_gset_eq:NN
\markdownSetupSnippet
@@ -12707,20 +13409,21 @@ options locally.
%
% \end{markdown}
% \begin{macrocode}
+\tl_new:N
+ \l_@@_current_snippet_tl
\prg_new_conditional:Nnn
\@@_if_snippet_exists:n
{ TF, T, F }
{
\tl_set:NV
- \l_tmpa_tl
+ \l_@@_current_snippet_tl
\g_@@_current_theme_tl
\tl_put_right:Nn
- \l_tmpa_tl
+ \l_@@_current_snippet_tl
{ #1 }
- \prop_get:NVNTF
+ \prop_if_in:NVTF
\g_@@_snippets_prop
- \l_tmpa_tl
- \l_tmpb_tl
+ \l_@@_current_snippet_tl
{ \prg_return_true: }
{ \prg_return_false: }
}
@@ -12751,7 +13454,7 @@ options locally.
\g_@@_snippets_prop
\l_tmpa_tl
\l_tmpb_tl
- \@@_setup:V
+ \tl_use:N
\l_tmpb_tl
}
{
@@ -12766,16 +13469,12 @@ options locally.
{ markdown }
{ undefined-snippet }
{ Can't~invoke~undefined~snippet~#1 }
-\cs_generate_variant:Nn
- \@@_setup:n
- { V }
\ExplSyntaxOff
% \end{macrocode}
% \iffalse
%</tex>
%<*manual-options>
% \fi
-% \par
% \markdownBegin
Here is how we can use snippets to store options and invoke them later
@@ -13032,7 +13731,6 @@ In this section, I will describe the individual token renderers.
%
% \end{markdown}
% \begin{macrocode}
-\ExplSyntaxOn
\seq_new:N \g_@@_renderers_seq
% \end{macrocode}
% \begin{markdown}
@@ -13045,7 +13743,6 @@ In this section, I will describe the individual token renderers.
\prop_new:N \g_@@_renderer_arities_prop
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13146,9 +13843,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererAttributeIdentifier{%
- \markdownRendererAttributeIdentifierPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererAttributeIdentifier
+ {
+ \markdownRendererAttributeIdentifierPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ attributeIdentifier }
@@ -13156,10 +13856,11 @@ following text:
\g_@@_renderer_arities_prop
{ attributeIdentifier }
{ 1 }
-\ExplSyntaxOff
-\def\markdownRendererAttributeClassName{%
- \markdownRendererAttributeClassNamePrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererAttributeClassName
+ {
+ \markdownRendererAttributeClassNamePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ attributeClassName }
@@ -13167,10 +13868,11 @@ following text:
\g_@@_renderer_arities_prop
{ attributeClassName }
{ 1 }
-\ExplSyntaxOff
-\def\markdownRendererAttributeKeyValue{%
- \markdownRendererAttributeKeyValuePrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererAttributeKeyValue
+ {
+ \markdownRendererAttributeKeyValuePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ attributeKeyValue }
@@ -13180,7 +13882,6 @@ following text:
{ 2 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13201,9 +13902,12 @@ a block quote. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererBlockQuoteBegin{%
- \markdownRendererBlockQuoteBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererBlockQuoteBegin
+ {
+ \markdownRendererBlockQuoteBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ blockQuoteBegin }
@@ -13213,7 +13917,6 @@ a block quote. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13346,9 +14049,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererBlockQuoteEnd{%
- \markdownRendererBlockQuoteEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererBlockQuoteEnd
+ {
+ \markdownRendererBlockQuoteEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ blockQuoteEnd }
@@ -13358,7 +14064,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13415,9 +14120,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererBracketedSpanAttributeContextBegin{%
- \markdownRendererBracketedSpanAttributeContextBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererBracketedSpanAttributeContextBegin
+ {
+ \markdownRendererBracketedSpanAttributeContextBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ bracketedSpanAttributeContextBegin }
@@ -13425,10 +14133,11 @@ following text:
\g_@@_renderer_arities_prop
{ bracketedSpanAttributeContextBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererBracketedSpanAttributeContextEnd{%
- \markdownRendererBracketedSpanAttributeContextEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererBracketedSpanAttributeContextEnd
+ {
+ \markdownRendererBracketedSpanAttributeContextEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ bracketedSpanAttributeContextEnd }
@@ -13438,7 +14147,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13460,9 +14168,12 @@ list is not tight). The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererUlBegin{%
- \markdownRendererUlBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererUlBegin
+ {
+ \markdownRendererUlBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ ulBegin }
@@ -13472,7 +14183,6 @@ list is not tight). The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13494,9 +14204,12 @@ is disabled. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererUlBeginTight{%
- \markdownRendererUlBeginTightPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererUlBeginTight
+ {
+ \markdownRendererUlBeginTightPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ ulBeginTight }
@@ -13506,7 +14219,6 @@ is disabled. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13526,9 +14238,12 @@ list. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererUlItem{%
- \markdownRendererUlItemPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererUlItem
+ {
+ \markdownRendererUlItemPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ ulItem }
@@ -13538,7 +14253,6 @@ list. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13558,9 +14272,12 @@ bulleted list. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererUlItemEnd{%
- \markdownRendererUlItemEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererUlItemEnd
+ {
+ \markdownRendererUlItemEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ ulItemEnd }
@@ -13570,7 +14287,6 @@ bulleted list. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13591,9 +14307,12 @@ tight). The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererUlEnd{%
- \markdownRendererUlEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererUlEnd
+ {
+ \markdownRendererUlEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ ulEnd }
@@ -13603,7 +14322,6 @@ tight). The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13827,9 +14545,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererUlEndTight{%
- \markdownRendererUlEndTightPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererUlEndTight
+ {
+ \markdownRendererUlEndTightPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ ulEndTight }
@@ -13839,7 +14560,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -13924,9 +14644,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererCite{%
- \markdownRendererCitePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererCite
+ {
+ \markdownRendererCitePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ cite }
@@ -13936,7 +14659,6 @@ following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14015,9 +14737,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererTextCite{%
- \markdownRendererTextCitePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererTextCite
+ {
+ \markdownRendererTextCitePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ textCite }
@@ -14027,7 +14752,6 @@ following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14039,7 +14763,7 @@ following text:
#### Code Block Renderers
The \mdef{markdownRendererInputVerbatim} macro represents a code
block. The macro receives a single argument that corresponds to the
-filename of a file contaning the code block contents.
+filename of a file containing the code block contents.
% \end{markdown}
%
@@ -14049,9 +14773,12 @@ filename of a file contaning the code block contents.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererInputVerbatim{%
- \markdownRendererInputVerbatimPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererInputVerbatim
+ {
+ \markdownRendererInputVerbatimPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ inputVerbatim }
@@ -14061,7 +14788,6 @@ filename of a file contaning the code block contents.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14073,7 +14799,7 @@ filename of a file contaning the code block contents.
The \mdef{markdownRendererInputFencedCode} macro represents a fenced code
block. This macro will only be produced, when the \Opt{fencedCode} option is
enabled. The macro receives three arguments that correspond to the filename of
-a file contaning the code block contents, the fully escaped code fence infostring
+a file containing the code block contents, the fully escaped code fence infostring
that can be directly typeset, and the raw code fence infostring that can be used
outside typesetting.
@@ -14167,9 +14893,12 @@ following text except for the filename, which may differ:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererInputFencedCode{%
- \markdownRendererInputFencedCodePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererInputFencedCode
+ {
+ \markdownRendererInputFencedCodePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ inputFencedCode }
@@ -14179,7 +14908,6 @@ following text except for the filename, which may differ:
{ 3 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14317,9 +15045,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererCodeSpan{%
- \markdownRendererCodeSpanPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererCodeSpan
+ {
+ \markdownRendererCodeSpanPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ codeSpan }
@@ -14329,7 +15060,6 @@ following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14387,9 +15117,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererCodeSpanAttributeContextBegin{%
- \markdownRendererCodeSpanAttributeContextBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererCodeSpanAttributeContextBegin
+ {
+ \markdownRendererCodeSpanAttributeContextBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ codeSpanAttributeContextBegin }
@@ -14397,10 +15130,11 @@ following text:
\g_@@_renderer_arities_prop
{ codeSpanAttributeContextBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererCodeSpanAttributeContextEnd{%
- \markdownRendererCodeSpanAttributeContextEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererCodeSpanAttributeContextEnd
+ {
+ \markdownRendererCodeSpanAttributeContextEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ codeSpanAttributeContextEnd }
@@ -14410,7 +15144,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14435,9 +15168,12 @@ and the title of the content block.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererContentBlock{%
- \markdownRendererContentBlockPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererContentBlock
+ {
+ \markdownRendererContentBlockPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ contentBlock }
@@ -14447,7 +15183,6 @@ and the title of the content block.
{ 4 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14468,9 +15203,12 @@ as \mref{markdownRendererContentBlock}.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererContentBlockOnlineImage{%
- \markdownRendererContentBlockOnlineImagePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererContentBlockOnlineImage
+ {
+ \markdownRendererContentBlockOnlineImagePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ contentBlockOnlineImage }
@@ -14480,7 +15218,6 @@ as \mref{markdownRendererContentBlock}.
{ 4 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14663,9 +15400,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererContentBlockCode{%
- \markdownRendererContentBlockCodePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererContentBlockCode
+ {
+ \markdownRendererContentBlockCodePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ contentBlockCode }
@@ -14675,7 +15415,6 @@ following text:
{ 5 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14700,9 +15439,12 @@ list is not tight). The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererDlBegin{%
- \markdownRendererDlBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDlBegin
+ {
+ \markdownRendererDlBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ dlBegin }
@@ -14712,7 +15454,6 @@ list is not tight). The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14734,9 +15475,12 @@ list is tight). This macro will only be produced, when the
% \fi
%
% \begin{macrocode}
-\def\markdownRendererDlBeginTight{%
- \markdownRendererDlBeginTightPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDlBeginTight
+ {
+ \markdownRendererDlBeginTightPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ dlBeginTight }
@@ -14746,7 +15490,6 @@ list is tight). This macro will only be produced, when the
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14767,9 +15510,12 @@ being defined.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererDlItem{%
- \markdownRendererDlItemPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDlItem
+ {
+ \markdownRendererDlItemPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ dlItem }
@@ -14779,7 +15525,6 @@ being defined.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14799,9 +15544,12 @@ definitions for a single term.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererDlItemEnd{%
- \markdownRendererDlItemEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDlItemEnd
+ {
+ \markdownRendererDlItemEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ dlItemEnd }
@@ -14811,7 +15559,6 @@ definitions for a single term.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14832,9 +15579,12 @@ a single term.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererDlDefinitionBegin{%
- \markdownRendererDlDefinitionBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDlDefinitionBegin
+ {
+ \markdownRendererDlDefinitionBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ dlDefinitionBegin }
@@ -14844,7 +15594,6 @@ a single term.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14865,9 +15614,12 @@ single term.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererDlDefinitionEnd{%
- \markdownRendererDlDefinitionEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDlDefinitionEnd
+ {
+ \markdownRendererDlDefinitionEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ dlDefinitionEnd }
@@ -14877,7 +15629,6 @@ single term.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -14898,9 +15649,12 @@ tight). The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererDlEnd{%
- \markdownRendererDlEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDlEnd
+ {
+ \markdownRendererDlEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ dlEnd }
@@ -14910,7 +15664,6 @@ tight). The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15267,9 +16020,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererDlEndTight{%
- \markdownRendererDlEndTightPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDlEndTight
+ {
+ \markdownRendererDlEndTightPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ dlEndTight }
@@ -15279,7 +16035,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15289,7 +16044,7 @@ following text:
% \begin{markdown}
#### Ellipsis Renderer
-The \mdef{markdownRendererEllipsis} macro replaces any occurance of ASCII
+The \mdef{markdownRendererEllipsis} macro replaces any occurrence 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.
@@ -15378,9 +16133,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererEllipsis{%
- \markdownRendererEllipsisPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererEllipsis
+ {
+ \markdownRendererEllipsisPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ ellipsis }
@@ -15390,7 +16148,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15399,7 +16156,7 @@ following text:
%
% \begin{markdown}
-#### Emphasis Renderers
+#### Emphasis Renderers {#emphasis-renderers}
The \mdef{markdownRendererEmphasis} macro represents an emphasized span of
text. The macro receives a single argument that corresponds to the emphasized
span of text.
@@ -15412,9 +16169,12 @@ span of text.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererEmphasis{%
- \markdownRendererEmphasisPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererEmphasis
+ {
+ \markdownRendererEmphasisPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ emphasis }
@@ -15424,7 +16184,6 @@ span of text.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15531,9 +16290,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererStrongEmphasis{%
- \markdownRendererStrongEmphasisPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererStrongEmphasis
+ {
+ \markdownRendererStrongEmphasisPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ strongEmphasis }
@@ -15543,7 +16305,6 @@ following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15553,8 +16314,8 @@ following text:
% \begin{markdown}
#### Fenced Code Attribute Context Renderers
-The following macros are only produced, when the \Opt{fencedCode} option is
-enabled.
+The following macros are only produced, when the \Opt{fencedCode} and
+\Opt{fencedCodeAttributes} options are enabled.
The \mdef{markdownRendererFencedCodeAttributeContextBegin} and
\mdef{markdownRendererFencedCodeAttributeContextEnd} macros represent the
@@ -15619,9 +16380,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererFencedCodeAttributeContextBegin{%
- \markdownRendererFencedCodeAttributeContextBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFencedCodeAttributeContextBegin
+ {
+ \markdownRendererFencedCodeAttributeContextBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fencedCodeAttributeContextBegin }
@@ -15629,10 +16393,11 @@ following text:
\g_@@_renderer_arities_prop
{ fencedCodeAttributeContextBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererFencedCodeAttributeContextEnd{%
- \markdownRendererFencedCodeAttributeContextEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFencedCodeAttributeContextEnd
+ {
+ \markdownRendererFencedCodeAttributeContextEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fencedCodeAttributeContextEnd }
@@ -15642,7 +16407,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15739,9 +16503,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererFencedDivAttributeContextBegin{%
- \markdownRendererFencedDivAttributeContextBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFencedDivAttributeContextBegin
+ {
+ \markdownRendererFencedDivAttributeContextBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fencedDivAttributeContextBegin }
@@ -15749,10 +16516,11 @@ following text:
\g_@@_renderer_arities_prop
{ fencedDivAttributeContextBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererFencedDivAttributeContextEnd{%
- \markdownRendererFencedDivAttributeContextEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFencedDivAttributeContextEnd
+ {
+ \markdownRendererFencedDivAttributeContextEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fencedDivAttributeContextEnd }
@@ -15762,7 +16530,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15842,9 +16609,12 @@ following text:
%<*tex>
% \fi
% \begin{macrocode}
-\def\markdownRendererHeaderAttributeContextBegin{%
- \markdownRendererHeaderAttributeContextBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHeaderAttributeContextBegin
+ {
+ \markdownRendererHeaderAttributeContextBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ headerAttributeContextBegin }
@@ -15852,10 +16622,11 @@ following text:
\g_@@_renderer_arities_prop
{ headerAttributeContextBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererHeaderAttributeContextEnd{%
- \markdownRendererHeaderAttributeContextEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHeaderAttributeContextEnd
+ {
+ \markdownRendererHeaderAttributeContextEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ headerAttributeContextEnd }
@@ -15865,7 +16636,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15886,9 +16656,12 @@ The macro receives a single argument that corresponds to the heading text.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererHeadingOne{%
- \markdownRendererHeadingOnePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHeadingOne
+ {
+ \markdownRendererHeadingOnePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ headingOne }
@@ -15898,7 +16671,6 @@ The macro receives a single argument that corresponds to the heading text.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15919,9 +16691,12 @@ text.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererHeadingTwo{%
- \markdownRendererHeadingTwoPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHeadingTwo
+ {
+ \markdownRendererHeadingTwoPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ headingTwo }
@@ -15931,7 +16706,6 @@ text.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15952,9 +16726,12 @@ text.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererHeadingThree{%
- \markdownRendererHeadingThreePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHeadingThree
+ {
+ \markdownRendererHeadingThreePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ headingThree }
@@ -15964,7 +16741,6 @@ text.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -15985,9 +16761,12 @@ text.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererHeadingFour{%
- \markdownRendererHeadingFourPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHeadingFour
+ {
+ \markdownRendererHeadingFourPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ headingFour }
@@ -15997,7 +16776,6 @@ text.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -16018,9 +16796,12 @@ text.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererHeadingFive{%
- \markdownRendererHeadingFivePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHeadingFive
+ {
+ \markdownRendererHeadingFivePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ headingFive }
@@ -16030,7 +16811,6 @@ text.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -16152,9 +16932,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererHeadingSix{%
- \markdownRendererHeadingSixPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHeadingSix
+ {
+ \markdownRendererHeadingSixPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ headingSix }
@@ -16164,7 +16947,6 @@ following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -16225,9 +17007,12 @@ The horizontal margins should contain the following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererInlineHtmlComment{%
- \markdownRendererInlineHtmlCommentPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererInlineHtmlComment
+ {
+ \markdownRendererInlineHtmlCommentPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ inlineHtmlComment }
@@ -16237,7 +17022,6 @@ The horizontal margins should contain the following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -16302,9 +17086,12 @@ following body text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererInlineHtmlTag{%
- \markdownRendererInlineHtmlTagPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererInlineHtmlTag
+ {
+ \markdownRendererInlineHtmlTagPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ inlineHtmlTag }
@@ -16312,10 +17099,11 @@ following body text:
\g_@@_renderer_arities_prop
{ inlineHtmlTag }
{ 1 }
-\ExplSyntaxOff
-\def\markdownRendererInputBlockHtmlElement{%
- \markdownRendererInputBlockHtmlElementPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererInputBlockHtmlElement
+ {
+ \markdownRendererInputBlockHtmlElementPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ inputBlockHtmlElement }
@@ -16325,7 +17113,6 @@ following body text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -16403,9 +17190,12 @@ that the \TeX{} engine has shell access.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererImage{%
- \markdownRendererImagePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererImage
+ {
+ \markdownRendererImagePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ image }
@@ -16415,7 +17205,6 @@ that the \TeX{} engine has shell access.
{ 4 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -16473,9 +17262,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererImageAttributeContextBegin{%
- \markdownRendererImageAttributeContextBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererImageAttributeContextBegin
+ {
+ \markdownRendererImageAttributeContextBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ imageAttributeContextBegin }
@@ -16483,10 +17275,11 @@ following text:
\g_@@_renderer_arities_prop
{ imageAttributeContextBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererImageAttributeContextEnd{%
- \markdownRendererImageAttributeContextEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererImageAttributeContextEnd
+ {
+ \markdownRendererImageAttributeContextEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ imageAttributeContextEnd }
@@ -16496,7 +17289,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -16619,9 +17411,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererInterblockSeparator{%
- \markdownRendererInterblockSeparatorPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererInterblockSeparator
+ {
+ \markdownRendererInterblockSeparatorPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ interblockSeparator }
@@ -16631,7 +17426,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -16694,9 +17488,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererParagraphSeparator{%
- \markdownRendererParagraphSeparatorPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererParagraphSeparator
+ {
+ \markdownRendererParagraphSeparatorPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ paragraphSeparator }
@@ -16706,7 +17503,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -16814,9 +17610,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererLineBlockBegin{%
- \markdownRendererLineBlockBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererLineBlockBegin
+ {
+ \markdownRendererLineBlockBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ lineBlockBegin }
@@ -16824,10 +17623,11 @@ following text:
\g_@@_renderer_arities_prop
{ lineBlockBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererLineBlockEnd{%
- \markdownRendererLineBlockEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererLineBlockEnd
+ {
+ \markdownRendererLineBlockEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ lineBlockEnd }
@@ -16837,7 +17637,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -16933,9 +17732,12 @@ following text:
%<*tex>
% \fi
% \begin{macrocode}
-\def\markdownRendererSoftLineBreak{%
- \markdownRendererSoftLineBreakPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererSoftLineBreak
+ {
+ \markdownRendererSoftLineBreakPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ softLineBreak }
@@ -16945,7 +17747,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17041,9 +17842,12 @@ following text:
%<*tex>
% \fi
% \begin{macrocode}
-\def\markdownRendererHardLineBreak{%
- \markdownRendererHardLineBreakPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHardLineBreak
+ {
+ \markdownRendererHardLineBreakPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ hardLineBreak }
@@ -17053,7 +17857,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17165,9 +17968,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererLink{%
- \markdownRendererLinkPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererLink
+ {
+ \markdownRendererLinkPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ link }
@@ -17177,7 +17983,6 @@ following text:
{ 4 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17235,9 +18040,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererLinkAttributeContextBegin{%
- \markdownRendererLinkAttributeContextBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererLinkAttributeContextBegin
+ {
+ \markdownRendererLinkAttributeContextBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ linkAttributeContextBegin }
@@ -17245,10 +18053,11 @@ following text:
\g_@@_renderer_arities_prop
{ linkAttributeContextBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererLinkAttributeContextEnd{%
- \markdownRendererLinkAttributeContextEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererLinkAttributeContextEnd
+ {
+ \markdownRendererLinkAttributeContextEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ linkAttributeContextEnd }
@@ -17258,7 +18067,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17313,9 +18121,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererMark{%
- \markdownRendererMarkPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererMark
+ {
+ \markdownRendererMarkPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ mark }
@@ -17325,7 +18136,6 @@ following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17455,9 +18265,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererDocumentBegin{%
- \markdownRendererDocumentBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDocumentBegin
+ {
+ \markdownRendererDocumentBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ documentBegin }
@@ -17465,10 +18278,11 @@ following text:
\g_@@_renderer_arities_prop
{ documentBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererDocumentEnd{%
- \markdownRendererDocumentEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDocumentEnd
+ {
+ \markdownRendererDocumentEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ documentEnd }
@@ -17478,7 +18292,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17551,9 +18364,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererNbsp{%
- \markdownRendererNbspPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererNbsp
+ {
+ \markdownRendererNbspPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ nbsp }
@@ -17563,7 +18379,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17684,7 +18499,6 @@ following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17707,9 +18521,12 @@ option is disabled. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererOlBegin{%
- \markdownRendererOlBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererOlBegin
+ {
+ \markdownRendererOlBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ olBegin }
@@ -17719,7 +18536,6 @@ option is disabled. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17742,9 +18558,12 @@ receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererOlBeginTight{%
- \markdownRendererOlBeginTightPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererOlBeginTight
+ {
+ \markdownRendererOlBeginTightPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ olBeginTight }
@@ -17754,7 +18573,6 @@ receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17779,9 +18597,12 @@ and the style of delimiters between list item labels and texts (`Default`,
% \fi
%
% \begin{macrocode}
-\def\markdownRendererFancyOlBegin{%
- \markdownRendererFancyOlBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFancyOlBegin
+ {
+ \markdownRendererFancyOlBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fancyOlBegin }
@@ -17791,7 +18612,6 @@ and the style of delimiters between list item labels and texts (`Default`,
{ 2 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17816,9 +18636,12 @@ the valid style values.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererFancyOlBeginTight{%
- \markdownRendererFancyOlBeginTightPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFancyOlBeginTight
+ {
+ \markdownRendererFancyOlBeginTightPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fancyOlBeginTight }
@@ -17828,7 +18651,6 @@ the valid style values.
{ 2 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17850,9 +18672,12 @@ arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererOlItem{%
- \markdownRendererOlItemPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererOlItem
+ {
+ \markdownRendererOlItemPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ olItem }
@@ -17862,7 +18687,6 @@ arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17883,9 +18707,12 @@ option is disabled. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererOlItemEnd{%
- \markdownRendererOlItemEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererOlItemEnd
+ {
+ \markdownRendererOlItemEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ olItemEnd }
@@ -17895,7 +18722,6 @@ option is disabled. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17917,9 +18743,12 @@ receives a single numeric argument that corresponds to the item number.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererOlItemWithNumber{%
- \markdownRendererOlItemWithNumberPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererOlItemWithNumber
+ {
+ \markdownRendererOlItemWithNumberPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ olItemWithNumber }
@@ -17929,7 +18758,6 @@ receives a single numeric argument that corresponds to the item number.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17951,9 +18779,12 @@ no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererFancyOlItem{%
- \markdownRendererFancyOlItemPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFancyOlItem
+ {
+ \markdownRendererFancyOlItemPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fancyOlItem }
@@ -17963,7 +18794,6 @@ no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -17984,9 +18814,12 @@ option is enabled. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererFancyOlItemEnd{%
- \markdownRendererFancyOlItemEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFancyOlItemEnd
+ {
+ \markdownRendererFancyOlItemEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fancyOlItemEnd }
@@ -17996,7 +18829,6 @@ option is enabled. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18018,9 +18850,12 @@ argument that corresponds to the item number.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererFancyOlItemWithNumber{%
- \markdownRendererFancyOlItemWithNumberPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFancyOlItemWithNumber
+ {
+ \markdownRendererFancyOlItemWithNumberPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fancyOlItemWithNumber }
@@ -18030,7 +18865,6 @@ argument that corresponds to the item number.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18052,9 +18886,12 @@ disabled. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererOlEnd{%
- \markdownRendererOlEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererOlEnd
+ {
+ \markdownRendererOlEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ olEnd }
@@ -18064,7 +18901,6 @@ disabled. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18087,9 +18923,12 @@ arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererOlEndTight{%
- \markdownRendererOlEndTightPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererOlEndTight
+ {
+ \markdownRendererOlEndTightPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ olEndTight }
@@ -18099,7 +18938,6 @@ arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18121,9 +18959,12 @@ option is enabled. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererFancyOlEnd{%
- \markdownRendererFancyOlEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFancyOlEnd
+ {
+ \markdownRendererFancyOlEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fancyOlEnd }
@@ -18133,7 +18974,6 @@ option is enabled. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18412,9 +19252,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererFancyOlEndTight{%
- \markdownRendererFancyOlEndTightPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererFancyOlEndTight
+ {
+ \markdownRendererFancyOlEndTightPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ fancyOlEndTight }
@@ -18424,7 +19267,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18435,7 +19277,7 @@ following text:
#### Raw Content Renderers
The \mdef{markdownRendererInputRawInline} macro represents an inline raw span.
-The macro receives two arguments: the filename of a file contaning the inline
+The macro receives two arguments: the filename of a file containing the inline
raw span contents and the raw attribute that designates the format of the
inline raw span. This macro will only be produced, when the \Opt{rawAttribute}
option is enabled.
@@ -18448,9 +19290,12 @@ option is enabled.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererInputRawInline{%
- \markdownRendererInputRawInlinePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererInputRawInline
+ {
+ \markdownRendererInputRawInlinePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ inputRawInline }
@@ -18460,7 +19305,6 @@ option is enabled.
{ 2 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18470,7 +19314,7 @@ option is enabled.
% \begin{markdown}
The \mdef{markdownRendererInputRawBlock} macro represents a raw block. The
-macro receives two arguments: the filename of a file contaning the raw block
+macro receives two arguments: the filename of a file containing the raw block
and the raw attribute that designates the format of the raw block. This macro
will only be produced, when the \Opt{rawAttribute} and \Opt{fencedCode} options
are enabled.
@@ -18530,9 +19374,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererInputRawBlock{%
- \markdownRendererInputRawBlockPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererInputRawBlock
+ {
+ \markdownRendererInputRawBlockPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ inputRawBlock }
@@ -18542,7 +19389,6 @@ following text:
{ 2 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18563,9 +19409,12 @@ macros represent the beginning and the end of a section based on headings.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererSectionBegin{%
- \markdownRendererSectionBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererSectionBegin
+ {
+ \markdownRendererSectionBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ sectionBegin }
@@ -18573,10 +19422,11 @@ macros represent the beginning and the end of a section based on headings.
\g_@@_renderer_arities_prop
{ sectionBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererSectionEnd{%
- \markdownRendererSectionEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererSectionEnd
+ {
+ \markdownRendererSectionEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ sectionEnd }
@@ -18586,7 +19436,6 @@ macros represent the beginning and the end of a section based on headings.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18607,9 +19456,12 @@ and U+FFFD Unicode characters. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererReplacementCharacter{%
- \markdownRendererReplacementCharacterPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererReplacementCharacter
+ {
+ \markdownRendererReplacementCharacterPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ replacementCharacter }
@@ -18619,7 +19471,6 @@ and U+FFFD Unicode characters. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18732,9 +19583,12 @@ following text, where the middot (`·`) denotes a non-breaking space:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererLeftBrace{%
- \markdownRendererLeftBracePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererLeftBrace
+ {
+ \markdownRendererLeftBracePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ leftBrace }
@@ -18742,10 +19596,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
\g_@@_renderer_arities_prop
{ leftBrace }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererRightBrace{%
- \markdownRendererRightBracePrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererRightBrace
+ {
+ \markdownRendererRightBracePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ rightBrace }
@@ -18753,10 +19608,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
\g_@@_renderer_arities_prop
{ rightBrace }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererDollarSign{%
- \markdownRendererDollarSignPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDollarSign
+ {
+ \markdownRendererDollarSignPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ dollarSign }
@@ -18764,10 +19620,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
\g_@@_renderer_arities_prop
{ dollarSign }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererPercentSign{%
- \markdownRendererPercentSignPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererPercentSign
+ {
+ \markdownRendererPercentSignPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ percentSign }
@@ -18775,10 +19632,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
\g_@@_renderer_arities_prop
{ percentSign }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererAmpersand{%
- \markdownRendererAmpersandPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererAmpersand
+ {
+ \markdownRendererAmpersandPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ ampersand }
@@ -18786,10 +19644,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
\g_@@_renderer_arities_prop
{ ampersand }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererUnderscore{%
- \markdownRendererUnderscorePrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererUnderscore
+ {
+ \markdownRendererUnderscorePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ underscore }
@@ -18797,10 +19656,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
\g_@@_renderer_arities_prop
{ underscore }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererHash{%
- \markdownRendererHashPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHash
+ {
+ \markdownRendererHashPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ hash }
@@ -18808,10 +19668,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
\g_@@_renderer_arities_prop
{ hash }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererCircumflex{%
- \markdownRendererCircumflexPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererCircumflex
+ {
+ \markdownRendererCircumflexPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ circumflex }
@@ -18819,10 +19680,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
\g_@@_renderer_arities_prop
{ circumflex }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererBackslash{%
- \markdownRendererBackslashPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererBackslash
+ {
+ \markdownRendererBackslashPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ backslash }
@@ -18830,10 +19692,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
\g_@@_renderer_arities_prop
{ backslash }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererTilde{%
- \markdownRendererTildePrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererTilde
+ {
+ \markdownRendererTildePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ tilde }
@@ -18841,10 +19704,11 @@ following text, where the middot (`·`) denotes a non-breaking space:
\g_@@_renderer_arities_prop
{ tilde }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererPipe{%
- \markdownRendererPipePrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererPipe
+ {
+ \markdownRendererPipePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ pipe }
@@ -18854,7 +19718,6 @@ following text, where the middot (`·`) denotes a non-breaking space:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -18880,7 +19743,7 @@ following content:
``` tex
\input markdown
\def\markdownOptionStrikeThrough{true}
-\input soulutf8.sty
+\input soul.sty
\def\markdownRendererStrikeThrough#1{\st{#1}}
\markdownBegin
This is ~~a lunar roving vehicle~~ strike-through text.
@@ -18903,7 +19766,7 @@ following content:
``` tex
\documentclass{article}
\usepackage[strikeThrough]{markdown}
-\usepackage{soulutf8}
+\usepackage{soul}
\markdownSetup{
renderers = {
strikeThrough = {\st{#1}},
@@ -18952,9 +19815,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererStrikeThrough{%
- \markdownRendererStrikeThroughPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererStrikeThrough
+ {
+ \markdownRendererStrikeThroughPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ strikeThrough }
@@ -18964,7 +19830,6 @@ following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19060,9 +19925,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererSubscript{%
- \markdownRendererSubscriptPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererSubscript
+ {
+ \markdownRendererSubscriptPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ subscript }
@@ -19071,7 +19939,6 @@ following text:
{ subscript }
{ 1 }
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19167,9 +20034,11 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererSuperscript{%
- \markdownRendererSuperscriptPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererSuperscript
+ {
+ \markdownRendererSuperscriptPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ superscript }
@@ -19179,7 +20048,6 @@ following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19276,9 +20144,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererTableAttributeContextBegin{%
- \markdownRendererTableAttributeContextBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererTableAttributeContextBegin
+ {
+ \markdownRendererTableAttributeContextBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ tableAttributeContextBegin }
@@ -19286,10 +20157,11 @@ following text:
\g_@@_renderer_arities_prop
{ tableAttributeContextBegin }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererTableAttributeContextEnd{%
- \markdownRendererTableAttributeContextEndPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererTableAttributeContextEnd
+ {
+ \markdownRendererTableAttributeContextEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ tableAttributeContextEnd }
@@ -19299,7 +20171,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19308,7 +20179,7 @@ following text:
%
% \begin{markdown}
-#### Table Renderer
+#### Table Renderer {#table-renderer}
The \mdef{markdownRendererTable} macro represents a table. This macro will only
be produced, when the \Opt{pipeTables} option is enabled. The macro receives the
parameters `{`\meta{caption}`}{`\meta{number of rows}`}{`\meta{number of columns}`}`
@@ -19368,7 +20239,7 @@ following content:
\markdownSetup{
renderers = {
table = {%
- This is a table with caption \emph{#1} that is #3 colums wide
+ This is a table with caption \emph{#1} that is #3 columns wide
and #2 rows long.
\rowCounter=0%
\def\rowTotal{#2}%
@@ -19397,7 +20268,7 @@ A PDF document named `document.pdf` should be produced and contain the
following text:
> This is a table with caption *Demonstration of pipe table syntax* that is 4
-> colums wide and 4 rows long. As for the alignment, column number 1 is
+> columns wide and 4 rows long. As for the alignment, column number 1 is
> right-aligned, column number 2 is left-aligned, column number 3 has default
> alignment, and column number 4 is centered. In row 1, column number 1 says
> *Right*, column number 2 says *Left*, column number 3 says *Default*, and
@@ -19414,9 +20285,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererTable{%
- \markdownRendererTablePrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererTable
+ {
+ \markdownRendererTablePrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ table }
@@ -19426,7 +20300,6 @@ following text:
{ 3 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19535,9 +20408,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererInlineMath{%
- \markdownRendererInlineMathPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererInlineMath
+ {
+ \markdownRendererInlineMathPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ inlineMath }
@@ -19545,10 +20421,11 @@ following text:
\g_@@_renderer_arities_prop
{ inlineMath }
{ 1 }
-\ExplSyntaxOff
-\def\markdownRendererDisplayMath{%
- \markdownRendererDisplayMathPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererDisplayMath
+ {
+ \markdownRendererDisplayMathPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ displayMath }
@@ -19558,7 +20435,6 @@ following text:
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19673,9 +20549,12 @@ following text:
%<*tex>
% \fi
% \begin{macrocode}
-\def\markdownRendererThematicBreak{%
- \markdownRendererThematicBreakPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererThematicBreak
+ {
+ \markdownRendererThematicBreakPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ thematicBreak }
@@ -19685,7 +20564,6 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19767,9 +20645,12 @@ following text:
% \fi
%
% \begin{macrocode}
-\def\markdownRendererTickedBox{%
- \markdownRendererTickedBoxPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererTickedBox
+ {
+ \markdownRendererTickedBoxPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ tickedBox }
@@ -19777,10 +20658,11 @@ following text:
\g_@@_renderer_arities_prop
{ tickedBox }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererHalfTickedBox{%
- \markdownRendererHalfTickedBoxPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererHalfTickedBox
+ {
+ \markdownRendererHalfTickedBoxPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ halfTickedBox }
@@ -19788,10 +20670,11 @@ following text:
\g_@@_renderer_arities_prop
{ halfTickedBox }
{ 0 }
-\ExplSyntaxOff
-\def\markdownRendererUntickedBox{%
- \markdownRendererUntickedBoxPrototype}%
-\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererUntickedBox
+ {
+ \markdownRendererUntickedBoxPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ untickedBox }
@@ -19801,7 +20684,64 @@ following text:
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+#### Warning and Error Renderers
+
+The \mdef{markdownRendererWarning} and \mdef{markdownRendererError} macros
+represent warnings and errors produced by the markdown parser. Both macros
+receive four parameters:
+
+1. The fully escaped text of the warning or error that can be directly typeset
+2. The raw text of the warning or error that can be used outside typesetting
+ for e.g. logging the warning or error.
+3. The fully escaped text with more details about the warning or error that
+ can be directly typeset. Can be empty, unlike the first two parameters.
+4. The raw text with more details about the warning or error that can be used
+ outside typesetting for e.g. logging the warning or error. Can be empty,
+ unlike the first two parameters.
+
+% \end{markdown}
+%
+% \iffalse
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+% \begin{macrocode}
+\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererWarning
+ {
+ \markdownRendererWarningPrototype
+ }
+\cs_gset_protected:Npn
+ \markdownRendererError
+ {
+ \markdownRendererErrorPrototype
+ }
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { warning }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { warning }
+ { 4 }
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { error }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { error }
+ { 4 }
+\ExplSyntaxOff
+% \end{macrocode}
%
% \iffalse
%</tex>
@@ -19824,9 +20764,12 @@ option is enabled. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererJekyllDataBegin{%
- \markdownRendererJekyllDataBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataBegin
+ {
+ \markdownRendererJekyllDataBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ jekyllDataBegin }
@@ -19836,7 +20779,6 @@ option is enabled. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19857,9 +20799,12 @@ The \mdef{markdownRendererJekyllDataEnd} macro represents the end of a
% \fi
%
% \begin{macrocode}
-\def\markdownRendererJekyllDataEnd{%
- \markdownRendererJekyllDataEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataEnd
+ {
+ \markdownRendererJekyllDataEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ jekyllDataEnd }
@@ -19869,7 +20814,6 @@ The \mdef{markdownRendererJekyllDataEnd} macro represents the end of a
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19892,9 +20836,12 @@ arguments: the scalar key in the parent structure, cast to a string following
% \fi
%
% \begin{macrocode}
-\def\markdownRendererJekyllDataMappingBegin{%
- \markdownRendererJekyllDataMappingBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataMappingBegin
+ {
+ \markdownRendererJekyllDataMappingBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ jekyllDataMappingBegin }
@@ -19904,7 +20851,6 @@ arguments: the scalar key in the parent structure, cast to a string following
{ 2 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19925,9 +20871,12 @@ when the \Opt{jekyllData} option is enabled. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererJekyllDataMappingEnd{%
- \markdownRendererJekyllDataMappingEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataMappingEnd
+ {
+ \markdownRendererJekyllDataMappingEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ jekyllDataMappingEnd }
@@ -19937,7 +20886,6 @@ when the \Opt{jekyllData} option is enabled. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19960,9 +20908,12 @@ arguments: the scalar key in the parent structure, cast to a string following
% \fi
%
% \begin{macrocode}
-\def\markdownRendererJekyllDataSequenceBegin{%
- \markdownRendererJekyllDataSequenceBeginPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataSequenceBegin
+ {
+ \markdownRendererJekyllDataSequenceBeginPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ jekyllDataSequenceBegin }
@@ -19972,7 +20923,6 @@ arguments: the scalar key in the parent structure, cast to a string following
{ 2 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -19993,9 +20943,12 @@ when the \Opt{jekyllData} option is enabled. The macro receives no arguments.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererJekyllDataSequenceEnd{%
- \markdownRendererJekyllDataSequenceEndPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataSequenceEnd
+ {
+ \markdownRendererJekyllDataSequenceEndPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ jekyllDataSequenceEnd }
@@ -20005,7 +20958,6 @@ when the \Opt{jekyllData} option is enabled. The macro receives no arguments.
{ 0 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -20028,9 +20980,12 @@ following \acro{yaml} serialization rules.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererJekyllDataBoolean{%
- \markdownRendererJekyllDataBooleanPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataBoolean
+ {
+ \markdownRendererJekyllDataBooleanPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ jekyllDataBoolean }
@@ -20040,7 +20995,6 @@ following \acro{yaml} serialization rules.
{ 2 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -20063,9 +21017,12 @@ following \acro{yaml} serialization rules.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererJekyllDataNumber{%
- \markdownRendererJekyllDataNumberPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataNumber
+ {
+ \markdownRendererJekyllDataNumberPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ jekyllDataNumber }
@@ -20075,7 +21032,6 @@ following \acro{yaml} serialization rules.
{ 2 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -20084,12 +21040,24 @@ following \acro{yaml} serialization rules.
%
% \begin{markdown}
-The \mdef{markdownRendererJekyllDataString} macro represents a string scalar
-value in a \acro{yaml} document. This macro will only be produced when the
-\Opt{jekyllData} option is enabled. The macro receives two arguments: the
+The \mdef{markdownRendererJekyllDataTypographicString} and
+\mdef{markdownRendererJekyllDataProgrammaticString} macros represent string
+scalar values in a \acro{yaml} document. This macro will only be produced when
+the \Opt{jekyllData} option is enabled. The macro receives two arguments: the
scalar key in the parent structure, cast to a string following \acro{yaml}
serialization rules, and the scalar value.
+For each string scalar value, both macros are produced. Whereas
+\mref{markdownRendererJekyllDataTypographicString} receives the scalar value
+after all markdown markup and special \TeX{} characters in the string have been
+replaced by \TeX{} macros, \mref{markdownRendererJekyllDataProgrammaticString}
+receives the raw scalar value. Therefore, whereas the
+\mref{markdownRendererJekyllDataTypographicString} macro is more appropriate
+for texts that are supposed to be typeset with \TeX{}, such as document titles,
+author names, or exam questions, the
+\mref{markdownRendererJekyllDataProgrammaticString} macro is more appropriate
+for identifiers and other programmatic text that won't be typeset by \TeX{}.
+
% \end{markdown}
%
% \iffalse
@@ -20098,9 +21066,109 @@ serialization rules, and the scalar value.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererJekyllDataString{%
- \markdownRendererJekyllDataStringPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataTypographicString
+ {
+ \markdownRendererJekyllDataTypographicStringPrototype
+ }
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataProgrammaticString
+ {
+ \markdownRendererJekyllDataProgrammaticStringPrototype
+ }
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { jekyllDataTypographicString }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { jekyllDataTypographicString }
+ { 2 }
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { jekyllDataProgrammaticString }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { jekyllDataProgrammaticString }
+ { 2 }
+\ExplSyntaxOff
+% \end{macrocode}
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
+Before Markdown 3.7.0, the \mref{markdownRendererJekyllDataTypographicString}
+macro was named \mref{markdownRendererJekyllDataString} and the
+\mref{markdownRendererJekyllDataProgrammaticString} macro was not produced.
+The \mref{markdownRendererJekyllDataString} has been deprecated and will be
+removed in Markdown 4.0.0.
+
+% \end{markdown}
+%
+% \iffalse
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+% \begin{macrocode}
+\ExplSyntaxOn
+\cs_gset:Npn
+ \markdownRendererJekyllDataTypographicString
+ {
+ \cs_if_exist:NTF
+ \markdownRendererJekyllDataString
+ {
+ \@@_if_option:nTF
+ { experimental }
+ {
+ \markdownError
+ {
+ The~jekyllDataString~renderer~has~been~deprecated,~
+ to~be~removed~in~Markdown~4.0.0
+ }
+ }
+ {
+ \markdownWarning
+ {
+ The~jekyllDataString~renderer~has~been~deprecated,~
+ to~be~removed~in~Markdown~4.0.0
+ }
+ \markdownRendererJekyllDataString
+ }
+ }
+ {
+ \cs_if_exist:NTF
+ \markdownRendererJekyllDataStringPrototype
+ {
+ \@@_if_option:nTF
+ { experimental }
+ {
+ \markdownError
+ {
+ The~jekyllDataString~renderer~prototype~
+ has~been~deprecated,~
+ to~be~removed~in~Markdown~4.0.0
+ }
+ }
+ {
+ \markdownWarning
+ {
+ The~jekyllDataString~renderer~prototype~
+ has~been~deprecated,~
+ to~be~removed~in~Markdown~4.0.0
+ }
+ \markdownRendererJekyllDataStringPrototype
+ }
+ }
+ {
+ \markdownRendererJekyllDataTypographicStringPrototype
+ }
+ }
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ jekyllDataString }
@@ -20110,7 +21178,6 @@ serialization rules, and the scalar value.
{ 2 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -20137,9 +21204,12 @@ serialization rules.
% \fi
%
% \begin{macrocode}
-\def\markdownRendererJekyllDataEmpty{%
- \markdownRendererJekyllDataEmptyPrototype}%
\ExplSyntaxOn
+\cs_gset_protected:Npn
+ \markdownRendererJekyllDataEmpty
+ {
+ \markdownRendererJekyllDataEmptyPrototype
+ }
\seq_gput_right:Nn
\g_@@_renderers_seq
{ jekyllDataEmpty }
@@ -20149,7 +21219,6 @@ serialization rules.
{ 1 }
\ExplSyntaxOff
% \end{macrocode}
-% \par
%
% \iffalse
%</tex>
@@ -20162,7 +21231,7 @@ following content:
``` tex
\input markdown
\def\markdownOptionJekyllData{true}
-\def\markdownRendererJekyllDataString#1#2{\gdef\name{#2}}
+\def\markdownRendererJekyllDataTypographicString#1#2{\gdef\name{#2}}
\def\markdownRendererJekyllDataNumber#1#2{\gdef\age{#2}}
\def\markdownRendererJekyllDataEnd{%
\name{} is \age{} years old.}
@@ -20192,7 +21261,7 @@ following content:
\usepackage[jekyllData]{markdown}
\markdownSetup{
renderers = {
- jekyllDataString = {\gdef\name{#2}},
+ jekyllDataTypographicString = {\gdef\name{#2}},
jekyllDataNumber = {\gdef\age{#2}},
jekyllDataEnd = {\name{} is \age{} years old.},
}
@@ -20224,7 +21293,7 @@ following content:
``` tex
\usemodule[t][markdown]
\setupmarkdown[jekyllData = yes]
-\def\markdownRendererJekyllDataString#1#2{\gdef\name{#2}}
+\def\markdownRendererJekyllDataTypographicString#1#2{\gdef\name{#2}}
\def\markdownRendererJekyllDataNumber#1#2{\gdef\age{#2}}
\def\markdownRendererJekyllDataEnd{%
\name{} is \age{} years old.}
@@ -20256,19 +21325,26 @@ following text:
%#### Generating Plain \TeX{} Token Renderer Macros and Key-Values {#plain-tex-renderers}
%
% We define the command \mdef{@@_define_renderers:} that defines plain \TeX{}
-% macros for token renderers. Futhermore, the `\markdownSetup` macro also accepts
-% the `renderers` key, whose value must be a list of key-values, where the keys
-% correspond to the markdown token renderer macros and the values are new
-% definitions of these token renderers.
+% macros for token renderers. Furthermore, the `\markdownSetup` macro also accepts
+% the `renderers` and `unprotectedRenderers` keys. The value for these keys
+% must be a list of key--values, where the keys correspond to the markdown token
+% renderer macros and the values are new definitions of these token renderers.
+%
+% Whereas the key `renderers` defines protected functions, which are usually
+% preferable for typesetting, the key `unprotectedRenderers` defines unprotected
+% functions, which are easier to expand and may be preferable for programming.
%
% \end{markdown}
% \begin{macrocode}
\ExplSyntaxOn
\cs_new:Nn \@@_define_renderers:
{
- \seq_map_function:NN
+ \seq_map_inline:Nn
\g_@@_renderers_seq
- \@@_define_renderer:n
+ {
+ \@@_define_renderer:n
+ { ##1 }
+ }
}
\cs_new:Nn \@@_define_renderer:n
{
@@ -20301,6 +21377,8 @@ following text:
\l_@@_renderer_definition_tl
\bool_new:N
\g_@@_appending_renderer_bool
+\bool_new:N
+ \g_@@_unprotected_renderer_bool
\cs_new:Nn \@@_define_renderer:nNn
{
\keys_define:nn
@@ -20325,16 +21403,45 @@ following text:
\l_@@_renderer_definition_tl
\l_tmpa_tl
}
- \cs_generate_from_arg_count:NNnV
+ \bool_if:NTF
+ \g_@@_unprotected_renderer_bool
+ {
+ \tl_set:Nn
+ \l_tmpa_tl
+ { \cs_set:Npn }
+ }
+ {
+ \tl_set:Nn
+ \l_tmpa_tl
+ { \cs_set_protected:Npn }
+ }
+ \exp_last_unbraced:NNV
+ \cs_generate_from_arg_count:NNnV
#2
- \cs_set:Npn
+ \l_tmpa_tl
{ #3 }
\l_@@_renderer_definition_tl
},
}
+% \end{macrocode}
+% \begin{markdown}
+%
+% If the token renderer macro has been deprecated, we undefine it.
+%
+% The \mref{markdownRendererJekyllDataString} macro has been deprecated and
+% will be removed in Markdown 4.0.0.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \str_if_eq:nnT
+ { #1 }
+ { jekyllDataString }
+ {
+ \cs_undefine:N
+ #2
+ }
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% We define the function \mdef{@@_tl_set_from_cs:NNn}
@@ -20392,13 +21499,21 @@ following text:
{ markdown/options }
{
renderers .code:n = {
+ \bool_gset_false:N
+ \g_@@_unprotected_renderer_bool
+ \keys_set:nn
+ { markdown/options/renderers }
+ { #1 }
+ },
+ unprotectedRenderers .code:n = {
+ \bool_gset_true:N
+ \g_@@_unprotected_renderer_bool
\keys_set:nn
{ markdown/options/renderers }
{ #1 }
},
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The following example code showcases a possible configuration of the
@@ -20427,7 +21542,6 @@ following text:
{
unknown .code:n = {
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Besides defining renderers at once, we can also define them incrementally
@@ -20489,7 +21603,6 @@ following text:
\g_@@_appending_renderer_bool
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% In addition to exact token renderer names, we also support wildcards (`*`)
@@ -20629,11 +21742,6 @@ following text:
\l_tmpa_clist
}
}
-% TODO: Remove in TeX Live 2023.
-\prg_generate_conditional_variant:Nnn
- \prop_get:NnN
- { NeN }
- { TF }
\cs_generate_variant:Nn
\regex_set:Nn
{ NV }
@@ -20644,7 +21752,7 @@ following text:
% \begin{markdown}
%
% If plain \TeX{} is the top layer, we use the \mref{@@_define_renderers:}
-% macro to define plain \TeX{} token renderer macros and key-values
+% macro to define plain \TeX{} token renderer macros and key--values
% immediately. Otherwise, we postpone the definition until the upper layers
% have been loaded.
%
@@ -20780,9 +21888,9 @@ following text:
#### 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 \LaTeX{}3 kernel.
+For simple \acro{YAML} metadata, a simple high-level interface is provided
+that can be programmed by setting the expl3 key--values [@latex25] for the
+module `markdown/jekyllData`.
% \end{markdown}
% \iffalse
@@ -20906,8 +22014,9 @@ following text:
% \end{macrocode}
% \begin{markdown}
%
-% The `jekyllDataRenderers` key can be used as a syntactic sugar for setting
-% the `markdown/jekyllData` key--values without using the expl3 language.
+% The option `jekyllDataRenderers`=\meta{key--values} can be used to set the
+% \meta{key--values} for the module `markdown/jekyllData` without using the
+% expl3 syntax.
%
% \end{markdown}
% \begin{macrocode}
@@ -20971,22 +22080,109 @@ following text:
% \end{macrocode}
% \begin{markdown}
%
+% For complex \acro{YAML} metadata, the option `jekyllDataKeyValue`=\meta{module}
+% [@starynovotny25] can be used to route the processing of all \acro{YAML}
+% metadata in the current \TeX{} group to the key--values from \meta{module}.
+%
+% \end{markdown}
+% \iffalse
+%</tex>
+%<*manual-tokens>
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage{markdown}
+\ExplSyntaxOn
+\str_new:N \g_markdown_example_title_str
+\seq_new:N \g_markdown_example_authors_seq
+\keys_define:nn
+ { markdown / example / module }
+ { % Define a key--value that processes YAML metadata.
+ title / programmaticString .str_gset:N = \g_markdown_example_title_str, % Store the raw title in a variable.
+ title .code:n = { \title { #1 } }, % Set the title. This is the same as writing `title / typographicString`.
+ authors / unknown .code:n = { % Store a variable-length list of authors in an array variable.
+ \seq_put_right:Nn
+ \g_markdown_example_authors_seq
+ { #1 }
+ },
+ }
+\markdownSetupSnippet
+ { metadata }
+ { % Define a snippet that routes YAML metadata to the above key key–value.
+ jekyllDataKeyValue = markdown / example / module,
+ renderers = {
+ jekyllDataEnd = { % At the end of the YAML metadata, ...
+ \clist_set_from_seq:NN % ... set the list of authors and
+ \l_tmpa_clist
+ \g_markdown_example_authors_seq
+ \exp_args:Nx
+ \author
+ { \clist_use:Nn \l_tmpa_clist { ,~ } }
+ \AtBeginDocument { \maketitle } % ... typeset the title page.
+ },
+ }
+ }
+\ExplSyntaxOff
+% Process the YAML metadata.
+\begin{yaml}[snippet=metadata]
+title: Some title that includes _markup_
+authors: [Jane Doe, John Moe]
+\end{yaml}
+\begin{document}
+The raw title of the document is:
+\ExplSyntaxOn
+\str_use:N \g_markdown_example_title_str
+\ExplSyntaxOff
+\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:
+
+> ### Some title that includes _markup_
+> ##### Jane Doe, John Moe
+> ##### _⟨Current date⟩_
+>
+> The raw title of the document is:
+> Some title that includes \_markup\_
+
+%</manual-tokens>
+%<*tex>
+% \fi
+% \begin{markdown}
+%
%#### Generating Plain \TeX{} Token Renderer Prototype Macros and Key-Values {#plain-tex-renderer-prototypes}
%
% We define the command \mdef{@@_define_renderer_prototypes:} that defines plain \TeX{}
-% macros for token renderer prototypes. Futhermore, the `\markdownSetup` macro also accepts
-% the `rendererPrototype` key, whose value must be a list of key-values, where the keys
-% correspond to the markdown token renderer prototype macros and the values are new
-% definitions of these token renderer prototypes.
+% macros for token renderer prototypes. Furthermore, the `\markdownSetup` macro also accepts
+% the `rendererPrototypes` and `unprotectedRendererPrototypes` keys. The value
+% for these keys must be a list of key--values, where the keys correspond to the
+% markdown token renderer prototype macros and the values are new definitions
+% of these token renderer prototypes.
+%
+% Whereas the key `rendererPrototypes` defines protected functions, which are
+% usually preferable for typesetting, the key `unprotectedRendererPrototypes`
+% defines unprotected functions, which are easier to expand and may be
+% preferable for programming.
%
% \end{markdown}
% \begin{macrocode}
\ExplSyntaxOn
\cs_new:Nn \@@_define_renderer_prototypes:
{
- \seq_map_function:NN
+ \seq_map_inline:Nn
\g_@@_renderers_seq
- \@@_define_renderer_prototype:n
+ {
+ \@@_define_renderer_prototype:n
+ { ##1 }
+ }
}
\cs_new:Nn \@@_define_renderer_prototype:n
{
@@ -21020,6 +22216,8 @@ following text:
\l_@@_renderer_prototype_definition_tl
\bool_new:N
\g_@@_appending_renderer_prototype_bool
+\bool_new:N
+ \g_@@_unprotected_renderer_prototype_bool
\cs_new:Nn \@@_define_renderer_prototype:nNn
{
\keys_define:nn
@@ -21044,9 +22242,22 @@ following text:
\l_@@_renderer_prototype_definition_tl
\l_tmpa_tl
}
- \cs_generate_from_arg_count:NNnV
+ \bool_if:NTF
+ \g_@@_unprotected_renderer_prototype_bool
+ {
+ \tl_set:Nn
+ \l_tmpa_tl
+ { \cs_set:Npn }
+ }
+ {
+ \tl_set:Nn
+ \l_tmpa_tl
+ { \cs_set_protected:Npn }
+ }
+ \exp_last_unbraced:NNV
+ \cs_generate_from_arg_count:NNnV
#2
- \cs_set:Npn
+ \l_tmpa_tl
{ #3 }
\l_@@_renderer_prototype_definition_tl
},
@@ -21054,26 +22265,33 @@ following text:
% \end{macrocode}
% \begin{markdown}
%
-% Unless the token renderer prototype macro has already been defined,
-% we provide an empty definition.
+% Unless the token renderer prototype macro has already been defined or unless,
+% it has been deprecated, we provide an empty definition.
+%
+% The \mref{markdownRendererJekyllDataStringPrototype} macro has been
+% deprecated and will be removed in Markdown 4.0.0.
%
% \end{markdown}
% \begin{macrocode}
- \cs_if_free:NT
- #2
+ \str_if_eq:nnF
+ { #1 }
+ { jekyllDataString }
{
- \cs_generate_from_arg_count:NNnn
+ \cs_if_free:NT
#2
- \cs_set:Npn
- { #3 }
- { }
+ {
+ \cs_generate_from_arg_count:NNnn
+ #2
+ \cs_gset_protected:Npn
+ { #3 }
+ { }
+ }
}
}
\cs_generate_variant:Nn
\@@_define_renderer_prototype:nNn
{ ncV }
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The following example code showcases a possible configuration of the
@@ -21095,7 +22313,6 @@ following text:
{
unknown .code:n = {
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Besides defining renderer prototypes at once, we can also define them
@@ -21157,7 +22374,6 @@ following text:
\g_@@_appending_renderer_prototype_bool
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% In addition to exact token renderer prototype names, we also support
@@ -21242,6 +22458,23 @@ following text:
{ markdown/options }
{
#1 .code:n = {
+ \bool_gset_false:N
+ \g_@@_unprotected_renderer_prototype_bool
+ \keys_set:nn
+ { markdown/options/renderer-prototypes }
+ { ##1 }
+ },
+ }
+ }
+\@@_with_various_cases:nn
+ { unprotectedRendererPrototypes }
+ {
+ \keys_define:nn
+ { markdown/options }
+ {
+ #1 .code:n = {
+ \bool_gset_true:N
+ \g_@@_unprotected_renderer_prototype_bool
\keys_set:nn
{ markdown/options/renderer-prototypes }
{ ##1 }
@@ -21252,7 +22485,7 @@ following text:
% \begin{markdown}
%
% If plain \TeX{} is the top layer, we use the \mref{@@_define_renderer_prototypes:}
-% macro to define plain \TeX{} token renderer prototype macros and key-values
+% macro to define plain \TeX{} token renderer prototype macros and key--values
% immediately. Otherwise, we postpone the definition until the upper layers
% have been loaded.
%
@@ -21292,16 +22525,15 @@ following text:
% \begin{macrocode}
\let\markdownMakeOther\relax
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \mdef{markdownReadAndConvert} macro implements the \mref{markdownBegin}
-% macro. The first argument specifies the token sequence that will terminate
-% the markdown input (\mref{markdownEnd} in the instance of the \mref{markdownBegin}
-% macro) when the plain \TeX{} special characters have had their category
-% changed to *other*. The second argument specifies the token sequence
-% that will actually be inserted into the document, when the ending token
-% sequence has been found.
+% and \mref{yamlBegin} macros. The first argument specifies the token sequence
+% that will terminate the markdown input when the plain \TeX{} special
+% characters have had their category changed to *other*: \mref{markdownEnd} for
+% the \mref{markdownBegin} macro and \mref{yamlEnd} for the \mref{yamlBegin}
+% macro. The second argument specifies the token sequence that will actually be
+% inserted into the document, when the ending token sequence has been found.
%
% \end{markdown}
% \begin{macrocode}
@@ -21320,6 +22552,11 @@ following text:
|gdef|markdownBegin{%
|markdownReadAndConvert{\markdownEnd}%
{|markdownEnd}}%
+ |gdef|yamlBegin{%
+ |begingroup
+ |yamlSetup{jekyllData, expectJekyllData, ensureJekyllData}%
+ |markdownReadAndConvert{\yamlEnd}%
+ {|yamlEnd}}%
|endgroup
% \end{macrocode}
% \begin{markdown}
@@ -21346,7 +22583,6 @@ following text:
% \iffalse
%</tex>
% \fi
-% \par
% \begin{markdown}
%
% \LaTeX{} Interface {#latexinterface}
@@ -21458,19 +22694,19 @@ pdflatex --shell-escape document.tex
% \Hologo{LaTeX2e} parses package options.
%
% \end{markdown}
-% \par
% \begin{markdown}
%
%### Typesetting Markdown
-% The interface exposes the \envmdef{markdown} and \envmdef{markdown*}
-% \LaTeX{} environments, and redefines the \mref{markinline} and
-% \mref{markdownInput} commands.
%
-% The \envmref{markdown} and \envmref{markdown*} \LaTeX{} environments are used
-% to typeset markdown document fragments. Both \LaTeX{} environments accept
-% \LaTeX{} interface options (see ection <#sec:latex-options>) as the only
-% argument. This argument is optional for the \envmref{markdown} environment
-% and mandatory for the \envmref{markdown*} environment.
+% The interface exposes the \envmdef{markdown}, \envmdef{markdown*}, and
+% \envmdef{yaml} \LaTeX{} environments, and redefines the \mref{markinline},
+% \mref{markdownInput}, and \mref{yamlInput} commands.
+%
+%#### Typesetting Markdown and YAML directly
+%
+% The \envmref{markdown} and \envmref{markdown*} \LaTeX{} environments are
+% aliases for the macros \mref{markdownBegin} and \mref{markdownEnd} exposed
+% by the plain \TeX{} interface.
%
% The \envmref{markdown*} environment has been deprecated and will be removed
% in the next major version of the Markdown package.
@@ -21482,56 +22718,255 @@ pdflatex --shell-escape document.tex
% \end{macrocode}
% \markdownBegin
%
-% You may prepend your own code to the \mdef{markdown} macro and append your own
-% code to the \mref{markdownEnd} macro to produce special effects before and after
-% the \envmref{markdown} \LaTeX{} environment (and likewise for the starred
-% version).
+% Furthermore, both environments accept \LaTeX{} interface options (see Section
+% <#sec:latex-options>) as the only argument. This argument is optional for the
+% \envmref{markdown} environment and mandatory for the \envmref{markdown*}
+% environment.
%
-% Note that the \envmref{markdown} and \envmref{markdown*} \LaTeX{} environments are
-% subject to the same limitations as the \mref{markdownBegin} and \mref{markdownEnd}
-% macros exposed by the plain \TeX{} interface.
+% The \envmref{markdown} and \envmref{markdown*} environments are
+% subject to the same limitations as the \mref{markdownBegin} and
+% \mref{markdownEnd} macros.
%
% The following example \LaTeX{} code showcases the usage of the
% \envmref{markdown} and \envmref{markdown*} environments:
+%
% ``` tex
% \documentclass{article} \documentclass{article}
% \usepackage{markdown} \usepackage{markdown}
% \begin{document} \begin{document}
-% \% ... \% ...
% \begin{markdown}[smartEllipses] \begin{markdown*}{smartEllipses}
% _Hello_ **world** ... _Hello_ **world** ...
% \end{markdown} \end{markdown*}
-% \% ... \% ...
% \end{document} \end{document}
% ```````
%
+% You can't directly extend the \envmref{markdown} \LaTeX{} environment by
+% using it in other environments as follows:
+%
+% ``` tex
+% \newenvironment{foo}\%
+% {code before \begin{markdown}[some, options]}\%
+% {\end{markdown} code after}
+% ```
+%
+% This is because the implementation looks for the literal string
+% `\end{markdown}` to stop scanning the markdown text. However, you can work
+% around this limitation by using the \mref{markdown} and \mref{markdownEnd}
+% macros directly in the definition as follows:
+%
+% \markdownEnd
+% \begin{markdown}
+%
+% ``` tex
+% \newenvironment{foo}\%
+% {code before \markdown[some, options]}\%
+% {\markdownEnd code after}
+% ```
+%
+% Specifically, the \mref{markdown} macro must appear at the end of the
+% replacement before-text and must be followed by text that has not yet been
+% ingested by \TeX's input processor.
+%
+% Furthermore, using the \mref{markdownEnd} macro in of after the replacement
+% after-text is optional and only makes a difference if you redefined it to
+% produce special effects before and after the \envmref{markdown} \LaTeX{}
+% environment.
+%
+% Lastly, you can't nest the other environments. For example, the following
+% definition would be incorrect:
+%
+% ``` tex
+% \newenvironment{bar}{\begin{foo}}{\end{foo}}
+% ```
+%
+% In this example, you should use the \mref{markdown} macro directly in the
+% definition of the environment `bar`:
+%
+% ``` tex
+% \newenvironment{bar}{\markdown[some, options]}{\markdownEnd}
+% ```
+%
+% The \envmref{yaml} \LaTeX{} environment is an alias for the macros
+% \mref{yamlBegin} and \mref{yamlEnd} exposed by the plain \TeX{} interface.
+%
+% \end{markdown}
+% \begin{macrocode}
+\newenvironment{yaml}\relax\relax
+% \end{macrocode}
+% \begin{markdown}
+%
+% Furthermore, the environment accepts \LaTeX{} interface options (see Section
+% <#sec:latex-options>) as the only optional argument.
+%
+% The \envmref{yaml} environment is subject to the same limitations as
+% the \mref{markdownBegin} and \mref{markdownEnd} macros.
+%
+% The following example \LaTeX{} code showcases the usage of the
+% \envmref{yaml} environment:
+%
+% ``` tex
+% \documentclass{article}
+% \usepackage{markdown}
+% \begin{document}
+% \begin{yaml}[smartEllipses]
+% title: _Hello_ **world** ...
+% author: John Doe
+% \end{yaml}
+% \end{document}
+% ```````
+%
+% \end{markdown}
+% \markdownBegin
+%
+% The above code has the same effect as the below code:
+%
+% ``` tex
+% \documentclass{article}
+% \usepackage{markdown}
+% \begin{document}
+% \begin{markdown}[
+% jekyllData,
+% expectJekyllData,
+% ensureJekyllData,
+% smartEllipses,
+% ]
+% title: _Hello_ **world** ...
+% author: John Doe
+% \end{markdown}
+% \end{document}
+% ```````
+%
+% You can't directly extend the \envmref{yaml} \LaTeX{} environment by using it
+% in other environments. However, you can work around this limitation by using
+% the \mref{yaml} and \mref{yamlEnd} macros directly in the definition,
+% similarly to the \mref{markdown} and \mref{markdownEnd} macros described
+% previously. Unlike with the \mref{markdown} and \mref{markdownEnd} macros,
+% The \mref{yamlEnd} macro _must_ be used in or after the replacement after-text.
+%
% The \mref{markinline} macro accepts a single mandatory parameter containing
% inline markdown content and expands to the result of the conversion of the
% input markdown document to plain \TeX{}. Unlike the \mref{markinline} macro
% provided by the plain \TeX{} interface, this macro also accepts \LaTeX{}
% interface options (see Section <#sec:latex-options>) as its optional
-% argument. These options will only influnce this markdown content.
+% argument. These options will only influence this markdown content.
+%
+%#### Typesetting Markdown and YAML from external documents
%
% The \mref{markdownInput} 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 \LaTeX{} interface options (see Section <#sec:latex-options>)
-% as its optional argument. These options will only influnce this markdown
+% as its optional argument. These options will only influence this markdown
% document.
%
% The following example \LaTeX{} code showcases the usage of the
% \mref{markdownInput} macro:
+%
% ``` tex
% \documentclass{article}
% \usepackage{markdown}
% \begin{document}
-% % ...
% \markdownInput[smartEllipses]{hello.md}
-% % ...
% \end{document}
% ```````
%
+% The \mref{yamlInput} macro accepts a single mandatory parameter containing
+% the filename of a \acro{YAML} document and expands to the result of the
+% conversion of the input \acro{YAML} document to plain \TeX{}. Unlike the
+% \mref{yamlInput} macro provided by the plain \TeX{} interface, this macro
+% also accepts \LaTeX{} interface options (see Section <#sec:latex-options>)
+% as its optional argument. These options will only influence this \acro{YAML}
+% document.
+%
+% The following example \LaTeX{} code showcases the usage of the
+% \mref{yamlInput} macro:
+%
+% ``` tex
+% \documentclass{article}
+% \usepackage{markdown}
+% \begin{document}
+% \yamlInput[smartEllipses]{hello.yml}
+% \end{document}
+% ```````
+%
+% The above code has the same effect as the below code:
+%
+% ``` tex
+% \documentclass{article}
+% \usepackage{markdown}
+% \begin{document}
+% \markdownInput[
+% jekyllData,
+% expectJekyllData,
+% ensureJekyllData,
+% smartEllipses,
+% ]{hello.yml}
+% \end{document}
+% ```````
+%
+%### Using \LaTeX{} hooks with the Markdown package
+%
+% \LaTeX{} provides an intricate hook management system that allows users to
+% insert extra material before and after certain \TeX{} macros and \LaTeX{}
+% environments, among other things. [@mittelbach24, Section 3.1.2]
+%
+% The Markdown package is compatible with hooks and allows the use of hooks
+% to insert extra material before \TeX{} commands and before/after \LaTeX{}
+% environments without restriction:
+%
+% ``` tex
+% \documentclass{article}
+% \usepackage{markdown}
+% \begin{document}
+% \AddToHook{cmd/markdownRendererEmphasis/before}{emphasis: }
+% \AddToHook{env/markdown/before}{<markdown>}
+% \AddToHook{env/markdown/after}{</markdown>}
+% \begin{markdown}
+% foo _bar_ baz!
+% \end{markdown}
+% \end{document}
+% ```
+%
+% Processing the above example with \LaTeX{} will produce the text
+% “<markdown>foo emphasis: _bar_ baz!</markdown>”, as expected.
+%
+% However, using hooks to insert extra material after \TeX{} commands only works
+% for commands with a fixed number of parameters that don't use currying.
+%
+% If, in the above example, you explicitly defined the renderer for emphasis
+% using \mref{markdownSetup} or another method that does not use currying, then
+% you would be able to insert extra material even after the renderer:
+%
+% ``` tex
+% \documentclass{article}
+% \usepackage{markdown}
+% \markdownSetup{renderers={emphasis={\emph{#1}}}}
+% \begin{document}
+% \AddToHook{cmd/markdownRendererEmphasis/before}{<emphasis>}
+% \AddToHook{cmd/markdownRendererEmphasis/after}{</emphasis>}
+% \AddToHook{env/markdown/before}{<markdown>}
+% \AddToHook{env/markdown/after}{</markdown>}
+% \begin{markdown}
+% foo _bar_ baz!
+% \end{markdown}
+% \end{document}
+% ```
+%
+% Processing the above example with \LaTeX{} will produce the text
+% “<markdown>foo <emphasis>_bar_</emphasis> baz!</markdown>”, as expected.
+%
+% However, the default renderer for emphasis uses currying and calls the
+% renderer prototype in a way that prevents the use of hooks to insert extra
+% material after the renderer, see Section~<#sec:emphasis-renderers>. In such
+% a case, you would need to redefine the renderer in a way that does not use
+% currying before you would be able to use hooks to insert extra material
+% after it.
+%
+% Hooks also cannot be used to insert extra material after renderers with a
+% variable number of parameters such as the renderer for tables, see
+% Section~<#sec:table-renderer>.
+%
%### Options {#latex-options}
%
% The \LaTeX{} options are represented by a comma-delimited list of
@@ -21600,7 +23035,7 @@ following code in our \LaTeX{} document:
We can also set all plain \TeX{} options directly from \LaTeX{}. For example,
to set the `\markdownOptionInputTempFileName` plain \TeX{} option to
-`helper-script.lua`, we would inclde the following code in our \LaTeX{}
+`helper-script.lua`, we would include the following code in our \LaTeX{}
document:
``` tex
@@ -21619,7 +23054,7 @@ document:
% If \LaTeX{} is the top layer, we use the
% \mref{@@_define_option_commands_and_keyvals:}, \mref{@@_define_renderers:},
% and \mref{@@_define_renderer_prototypes:} macro to define plain \TeX{}
-% option, token renderer, and token renderer prototype macros and key-values
+% option, token renderer, and token renderer prototype macros and key--values
% immediately. Otherwise, we postpone the definition until the upper layers
% have been loaded.
%
@@ -21636,7 +23071,6 @@ document:
}
\ExplSyntaxOff
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The following example \LaTeX{} code showcases a possible configuration of
@@ -21657,7 +23091,10 @@ document:
% \fi
% \begin{markdown}
-### Themes {#latexthemes}
+%### Themes {#latexthemes}
+% \iffalse
+#### Themes {#latexthemes}
+% \fi
% In Section~\ref{sec:themes}, we described the concept of themes.
In \LaTeX{}, we expand on the concept of
@@ -21665,7 +23102,7 @@ In \LaTeX{}, we expand on the concept of
[themes](#themes)
% \fi
by allowing a theme to be a full-blown \LaTeX{} package. Specifically, the
-key-values `theme`=\meta{theme name} and `import`=\meta{theme name} load a
+key--values `theme`=\meta{theme name} and `import`=\meta{theme name} load a
\LaTeX{} package named `markdowntheme`\meta{munged theme name}`.sty` if it
exists and a \TeX{} document named `markdowntheme`\meta{munged theme
name}`.tex` otherwise.
@@ -21683,25 +23120,21 @@ developers can load the `.tex` theme file from the `.sty` theme file using the
% specified in the `\usepackage` macro, the loading of the theme(s) will be
% postponed in first-in-first-out order until after the Markdown \LaTeX{}
% package has been loaded. Otherwise, the theme(s) will be loaded immediately.
-% For example, there is a theme named `witiko/dot`, which typesets fenced code
-% blocks with the `dot` infostring as images of directed graphs rendered by the
-% Graphviz tools. The following code would first load the Markdown package,
-% then the `markdownthemewitiko_beamer_MU.sty` \LaTeX{} package, and finally
-% the `markdownthemewitiko_dot.sty` \LaTeX{} package:
+% For example, the following code would first load the Markdown package, then
+% the theme `witiko/example/foo`, and finally the theme `witiko/example/bar`:
% \end{markdown}
% \iffalse
-For example, to load themes named `witiko/beamer/MU` and `witiko/dot`, you
-would use the following code in the preamble of your document:
+For example, to load themes named `witiko/example/foo` and `witiko/example/bar`,
+you would use the following code in the preamble of your document:
% \fi
-% \par
% \begin{markdown}
``` tex
\usepackage[
- import=witiko/beamer/MU,
- import=witiko/dot,
+ import=witiko/example/foo,
+ import=witiko/example/bar,
]{markdown}
```````
@@ -21718,221 +23151,34 @@ would use the following code in the preamble of your document:
%</latex>
%<*manual-options>
% \fi
-% \par
% \begin{markdown}
Due to limitations of \LaTeX{}, themes may not be loaded after the
beginning of a \LaTeX{} document.
-% \end{markdown}
-% \par
-% \markdownBegin
-
-Built-in \LaTeX{} themes provided with the Markdown package include:
-
-\pkg{witiko/dot}
-
-: A theme that typesets fenced code blocks with the `dot …` infostring
- as images of directed graphs rendered by the Graphviz tools. The
- right tail of the infostring is used as the image title.
-% ```` tex
-% \documentclass{article}
-% \usepackage[import=witiko/dot]{markdown}
-% \setkeys{Gin}{
-% width = \columnwidth,
-% height = 0.65\paperheight,
-% keepaspectratio}
-% \begin{document}
-% \begin{markdown}
-% ``` dot Various formats of mathemathical formulae
-% digraph tree {
-% margin = 0;
-% rankdir = "LR";
-%
-% latex -> pmml;
-% latex -> cmml;
-% pmml -> slt;
-% cmml -> opt;
-% cmml -> prefix;
-% cmml -> infix;
-% pmml -> mterms [style=dashed];
-% cmml -> mterms;
+% We also define the prop \mdef{g_@@_latex_built_in_themes_prop} that
+% contains the code of built-in themes. This is a packaging optimization,
+% so that built-in themes does not need to be distributed in many small files.
%
-% latex [label = "LaTeX"];
-% pmml [label = "Presentation MathML"];
-% cmml [label = "Content MathML"];
-% slt [label = "Symbol Layout Tree"];
-% opt [label = "Operator Tree"];
-% prefix [label = "Prefix"];
-% infix [label = "Infix"];
-% mterms [label = "M-Terms"];
-% }
-% ```
-% \end{markdown}
-% \end{document}
-% ````````
-% Typesetting the above document produces the output shown in
-% Figure <#fig:witiko/dot>.
-% ``` dot Various formats of mathemathical formulae \label{fig:witiko/dot}
-% digraph tree {
-% margin = 0;
-% rankdir = "LR";
-%
-% latex -> pmml;
-% latex -> cmml;
-% pmml -> slt;
-% cmml -> opt;
-% cmml -> prefix;
-% cmml -> infix;
-% pmml -> mterms [style=dashed];
-% cmml -> mterms;
-%
-% latex [label = "LaTeX"];
-% pmml [label = "Presentation MathML"];
-% cmml [label = "Content MathML"];
-% slt [label = "Symbol Layout Tree"];
-% opt [label = "Operator Tree"];
-% prefix [label = "Prefix"];
-% infix [label = "Infix"];
-% mterms [label = "M-Terms"];
-% }
-% ```
- The theme requires a Unix-like operating system with GNU Diffutils and
- Graphviz installed. The theme also requires shell access unless the
- \Opt{frozenCache} plain \TeX{} option is enabled.
-
-% \markdownEnd
-% \iffalse
-
-##### \LaTeX{} Example {.unnumbered}
-
-Using a text editor, create a text document named `document.tex` with the
-following content:
-```` tex
-\documentclass{article}
-\usepackage[import=witiko/dot]{markdown}
-\setkeys{Gin}{
- width=\columnwidth,
- height=0.65\paperheight,
- keepaspectratio}
-\begin{document}
-\begin{markdown}
-``` dot Various formats of mathemathical formulae
-digraph tree {
- margin = 0;
- rankdir = "LR";
-
- latex -> pmml;
- latex -> cmml;
- pmml -> slt;
- cmml -> opt;
- cmml -> prefix;
- cmml -> infix;
- pmml -> mterms [style=dashed];
- cmml -> mterms;
-
- latex [label = "LaTeX"];
- pmml [label = "Presentation MathML"];
- cmml [label = "Content MathML"];
- slt [label = "Symbol Layout Tree"];
- opt [label = "Operator Tree"];
- prefix [label = "Prefix"];
- infix [label = "Infix"];
- mterms [label = "M-Terms"];
-}
-```
-\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
-a drawing of a directed graph similar to Figure 1 from the following
-conference article:
-
-> NOVOTNÝ, Vít, Petr SOJKA, Michal ŠTEFÁNIK and Dávid LUPTÁK. Three is Better
-> than One: Ensembling Math Information Retrieval Systems. *CEUR Workshop
-> Proceedings*. Thessaloniki, Greece: M. Jeusfeld c/o Redaktion Sun SITE,
-> Informatik V, RWTH Aachen., 2020, vol. 2020, No 2696, p. 1-30. ISSN 1613-0073.
-> <http://ceur-ws.org/Vol-2696/paper_235.pdf>
-
-%</manual-options>
-%<*themes-witiko-dot>
-% \fi
-% \begin{macrocode}
-\ProvidesPackage{markdownthemewitiko_dot}[2021/03/09]%
-% \end{macrocode}
-% \iffalse
-%</themes-witiko-dot>
-%<*manual-options>
-% \fi
-% \par
-% \markdownBegin
-
-\pkg{witiko/graphicx/http}
-
-: A theme that adds support for downloading images whose URL has the
- http or https protocol.
-% ``` tex
-% \documentclass{article}
-% \usepackage[import=witiko/graphicx/http]{markdown}
-% \begin{document}
-% \begin{markdown}
-% ![img](https://github.com/witiko/markdown/raw/main/markdown.png
-% "The banner of the Markdown package")
-% \end{markdown}
-% \end{document}
-% ```````
-% Typesetting the above document produces the output shown in
-% Figure <#fig:witiko/graphicx/http>.
-% ![img](https://github.com/witiko/markdown/raw/main/markdown.png
-% "The banner of the Markdown package \label{fig:witiko/graphicx/http}")
- The theme requires the \pkg{catchfile} \LaTeX{} package and a Unix-like
- operating system with GNU Coreutils `md5sum` and either GNU Wget or cURL
- installed. The theme also requires shell access unless the
- \Opt{frozenCache} plain \TeX{} option is enabled.
-
-% \markdownEnd
+% \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[import=witiko/graphicx/http]{markdown}
-\begin{document}
-\begin{markdown}
-![img](https://github.com/witiko/markdown/raw/main/markdown.png
- "The banner of the Markdown package")
-\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 image:
-
-> ![img](https://github.com/witiko/markdown/raw/main/markdown.png "The banner of the Markdown package")
-
%</manual-options>
-%<*themes-witiko-graphicx-http>
+%<*latex>
% \fi
% \begin{macrocode}
-\ProvidesPackage{markdownthemewitiko_graphicx_http}[2021/03/22]%
+\ExplSyntaxOn
+\prop_new:N
+ \g_@@_latex_built_in_themes_prop
+\ExplSyntaxOff
% \end{macrocode}
% \iffalse
-%</themes-witiko-graphicx-http>
+%</latex>
%<*manual-options>
% \fi
-% \par
% \begin{markdown}
+Built-in \LaTeX{} themes provided with the Markdown package include:
+
\pkg{witiko/markdown/defaults}
: A \LaTeX{} theme with the default definitions of token renderer prototypes
@@ -21945,8 +23191,7 @@ following image:
%<*latex>
% \fi
% \begin{macrocode}
-\AtEndOfPackage{
- \markdownLaTeXLoadedtrue
+\AtEndOfPackage{\markdownLaTeXLoadedtrue}
% \end{macrocode}
% \begin{markdown}
%
@@ -21957,23 +23202,39 @@ following image:
%
% \end{markdown}
% \begin{macrocode}
- \markdownIfOption{noDefaults}{}{
- \markdownSetup{theme=witiko/markdown/defaults}
+\ExplSyntaxOn
+\str_if_eq:VVT
+ \c_@@_top_layer_tl
+ \c_@@_option_layer_latex_tl
+ {
+ \use:c
+ { ExplSyntaxOff }
+ \AtEndOfPackage
+ {
+ \@@_if_option:nF
+ { noDefaults }
+ {
+ \@@_if_option:nTF
+ { experimental }
+ {
+ \@@_setup:n
+ { theme = witiko/markdown/defaults@experimental }
+ }
+ {
+ \@@_setup:n
+ { theme = witiko/markdown/defaults }
+ }
+ }
+ }
+ \use:c
+ { ExplSyntaxOn }
}
-}
+\ExplSyntaxOff
% \end{macrocode}
% \iffalse
%</latex>
-%<*themes-witiko-markdown-defaults-latex>
-% \fi
-% \begin{macrocode}
-\ProvidesPackage{markdownthemewitiko_markdown_defaults}[2024/01/03]%
-% \end{macrocode}
-% \iffalse
-%</themes-witiko-markdown-defaults-latex>
%<*context>
% \fi
-% \par
% \begin{markdown}
%
% Please, see Section <#sec:latex-themes-implementation> for implementation
@@ -22069,7 +23330,6 @@ following text:
\do\#\do\^\do\_\do\%\do\~}%
\input markdown/markdown
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \Hologo{ConTeXt} interface is implemented by the
@@ -22080,30 +23340,35 @@ following text:
% \noindent It is expected that the special plain \TeX{} characters have the
% expected category codes, when `\input`ting the file.
%
-%### Typesetting Markdown
-% The interface exposes the \mdef{startmarkdown} and \mdef{stopmarkdown} macro
-% pair for the typesetting of a markdown document fragment, and defines the
-% \mdef{inputmarkdown} macro.
+%### Typesetting Markdown and YAML
+%
+% The interface exposes the \mdef{startmarkdown}, \mdef{stopmarkdown},
+% \mdef{startyaml}, \mdef{stopyaml}, \mdef{inputmarkdown}, and \mdef{inputyaml}
+% macros.
+%
+%#### Typesetting Markdown and YAML directly
+%
+% The \mref{startmarkdown} and \mref{stopmarkdown} macros are aliases for the
+% macros \mref{markdownBegin} and \mref{markdownEnd} exposed by the plain
+% \TeX{} interface.
%
% \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 macros \mref{startmarkdown} and \mref{stopmarkdown} are subject to the
+% same limitations as the \mref{markdownBegin} and \mref{markdownEnd} macros.
%
% The following example \Hologo{ConTeXt} code showcases the usage of the
% \mref{startmarkdown} and \mref{stopmarkdown} macros:
+%
% ``` tex
% \usemodule[t][markdown]
% \starttext
@@ -22113,22 +23378,114 @@ following text:
% \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:context-options>) as its optional argument. These options will only
-% influnce this markdown document.
+% The \mref{startyaml} and \mref{stopyaml} macros are aliases for the macros
+% \mref{yamlBegin} and \mref{yamlEnd} exposed by the plain \TeX{} interface.
+%
+% \end{markdown}
+% \begin{macrocode}
+\let\startyaml\relax
+\let\stopyaml\relax
+% \end{macrocode}
+% \begin{markdown}
+%
+% You may prepend your own code to the \mref{startyaml} macro and append your
+% own code to the \mref{stopyaml} macro to produce special effects before and
+% after the \acro{YAML} document.
+%
+% The macros \mref{startyaml} and \mref{stopyaml} are subject to the same
+% limitations as the \mref{markdownBegin} and \mref{markdownEnd} macros.
+%
+% The following example \Hologo{ConTeXt} code showcases the usage of the
+% \mref{startyaml} and \mref{stopyaml} macros:
+%
+% ``` tex
+% \usemodule[t][markdown]
+% \starttext
+% \startyaml
+% title: _Hello_ **world** ...
+% author: John Doe
+% \stopyaml
+% \stoptext
+% ```````
+%
+% The above code has the same effect as the below code:
+%
+% ``` tex
+% \usemodule[t][markdown]
+% \starttext
+% \setupyaml[jekyllData, expectJekyllData, ensureJekyllData]
+% \startyaml
+% title: _Hello_ **world** ...
+% author: John Doe
+% \stopyaml
+% \stoptext
+% ```````
+%
+%#### Typesetting Markdown and YAML from external documents
+%
+% The \mref{inputmarkdown} macro aliases the macro \mref{markdownInput} exposed
+% by the plain \TeX{} interface.
+%
+% \end{markdown}
+% \begin{macrocode}
+\let\inputmarkdown\relax
+% \end{macrocode}
+% \begin{markdown}
+%
+% Furthermore, the \mref{inputmarkdown} macro also accepts \Hologo{ConTeXt}
+% interface options (see Section <#sec:context-options>) as its optional
+% argument. These options will only influence this markdown document.
+%
+% The following example \Hologo{ConTeXt} code showcases the usage of the
+% \mref{inputmarkdown} macro:
%
-% The following example \LaTeX{} code showcases the usage of the
-% \mref{markdownInput} macro:
% ``` tex
% \usemodule[t][markdown]
% \starttext
-% % ...
% \inputmarkdown[smartEllipses]{hello.md}
-% % ...
+% \stoptext
+% ```````
+%
+% The above code has the same effect as the below code:
+%
+% ``` tex
+% \usemodule[t][markdown]
+% \starttext
+% \setupmarkdown[smartEllipses]
+% \inputmarkdown{hello.md}
+% \stoptext
+% ```````
+%
+% The \mref{inputyaml} macro aliases the macro \mref{yamlInput} exposed by the
+% plain \TeX{} interface.
+%
+% \end{markdown}
+% \begin{macrocode}
+\let\inputyaml\relax
+% \end{macrocode}
+% \begin{markdown}
+%
+% Furthermore, the \mref{inputyaml} macro also accepts \Hologo{ConTeXt}
+% interface options (see Section <#sec:context-options>) as its optional
+% argument. These options will only influence this \acro{YAML} document.
+%
+% The following example \Hologo{ConTeXt} code showcases the usage of the
+% \mref{inputyaml} macro:
+%
+% ``` tex
+% \usemodule[t][markdown]
+% \starttext
+% \inputyaml[smartEllipses]{hello.yml}
+% \stoptext
+% ```````
+%
+% The above code has the same effect as the below code:
+%
+% ``` tex
+% \usemodule[t][markdown]
+% \starttext
+% \setupyaml[smartEllipses]
+% \inputyaml{hello.yml}
% \stoptext
% ```````
%
@@ -22158,7 +23515,17 @@ following text:
\@@_setup:n
{ #1 }
}
-\ExplSyntaxOff
+% \end{macrocode}
+% \begin{markdown}
+%
+% The command \mdef{setupyaml} is also available as an alias for
+% the command \mref{setupmarkdown}.
+%
+% \end{markdown}
+% \begin{macrocode}
+\cs_gset_eq:NN
+ \setupyaml
+ \setupmarkdown
% \end{macrocode}
% \begin{markdown}
%
@@ -22169,7 +23536,6 @@ following text:
%
% \end{markdown}
% \begin{macrocode}
-\ExplSyntaxOn
\cs_new:Nn \@@_caseless:N
{
\regex_replace_all:nnN
@@ -22187,7 +23553,7 @@ following text:
% If \Hologo{ConTeXt} is the top layer, we use the
% \mref{@@_define_option_commands_and_keyvals:}, \mref{@@_define_renderers:},
% and \mref{@@_define_renderer_prototypes:} macro to define plain \TeX{}
-% option, token renderer, and token renderer prototype macros and key-values
+% option, token renderer, and token renderer prototype macros and key--values
% immediately. Otherwise, we postpone the definition until the upper layers
% have been loaded.
%
@@ -22201,23 +23567,26 @@ following text:
\@@_define_renderers:
\@@_define_renderer_prototypes:
}
-\ExplSyntaxOff
% \end{macrocode}
% \iffalse
%</context>
%<*manual-options>
% \fi
% \begin{markdown}
-
-### Themes
-
+%
+%### Themes {#contextthemes}
+% \iffalse
+### \Hologo{ConTeXt}
+#### Themes {#contextthemes}
+% \fi
+%
% In Section~\ref{sec:themes}, we described the concept of themes.
In \Hologo{ConTeXt}, we expand on the concept of
% themes\iffalse
[themes](#themes)
% \fi
by allowing a theme to be a full-blown \Hologo{ConTeXt} module. Specifically,
-the key-values `theme`=\meta{theme name} and `import`=\meta{theme name} load a
+the key--values `theme`=\meta{theme name} and `import`=\meta{theme name} load a
\Hologo{ConTeXt} module named `t-markdowntheme`\meta{munged theme name}`.tex`
if it exists and a \TeX{} document named `markdowntheme`\meta{munged theme
name}`.tex` otherwise.
@@ -22238,6 +23607,26 @@ For example, to load a theme named `witiko/tilde` in your document:
\setupmarkdown[import=witiko/tilde]
```````
+% We also define the prop \mdef{g_@@_context_built_in_themes_prop} that
+% contains the code of built-in themes. This is a packaging optimization,
+% so that built-in themes does not need to be distributed in many small files.
+%
+% \end{markdown}
+% \iffalse
+%</manual-options>
+%<*context>
+% \fi
+% \begin{macrocode}
+\prop_new:N
+ \g_@@_context_built_in_themes_prop
+\ExplSyntaxOff
+% \end{macrocode}
+% \iffalse
+%</context>
+%<*manual-options>
+% \fi
+% \begin{markdown}
+
Built-in \Hologo{ConTeXt} themes provided with the Markdown package include:
\pkg{witiko/markdown/defaults}
@@ -22249,14 +23638,14 @@ Built-in \Hologo{ConTeXt} themes provided with the Markdown package include:
% \end{markdown}
% \iffalse
%</manual-options>
-%<*themes-witiko-markdown-defaults-context>
+%<*themes-witiko-markdown-defaults-ctx>
% \fi
% \begin{macrocode}
\startmodule[markdownthemewitiko_markdown_defaults]
\unprotect
% \end{macrocode}
% \iffalse
-%</themes-witiko-markdown-defaults-context>
+%</themes-witiko-markdown-defaults-ctx>
%<*manual-options>
% \fi
% \begin{markdown}
@@ -22307,7 +23696,6 @@ local P, R, S, V, C, Cg, Cb, Cmt, Cc, Ct, B, Cs, Cp, any =
lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Cg, lpeg.Cb,
lpeg.Cmt, lpeg.Cc, lpeg.Ct, lpeg.B, lpeg.Cs, lpeg.Cp, lpeg.P(1)
% \end{macrocode}
-% \par
% \begin{markdown}
%
%### Utility Functions
@@ -22317,10 +23705,17 @@ local P, R, S, V, C, Cg, Cb, Cmt, Cc, Ct, B, Cs, Cp, any =
% `lunamark/util.lua` file in the Lunamark Lua module.
%
% \end{markdown}
+% \iffalse
+%</lua>
+%<*lua,lua-loader>
+% \fi
% \begin{macrocode}
local util = {}
% \end{macrocode}
-% \par
+% \iffalse
+%</lua,lua-loader>
+%<*lua>
+% \fi
% \begin{markdown}
%
% The \luamdef{util.err} method prints an error message `msg` and exits.
@@ -22334,13 +23729,16 @@ function util.err(msg, exit_code)
os.exit(exit_code or 1)
end
% \end{macrocode}
-% \par
+% \iffalse
+%</lua>
+%<*lua,lua-loader>
+% \fi
% \begin{markdown}
%
-% The \luamdef{util.cache} method computes the digest of `string` and
-% `salt`, adds the `suffix` and looks into the directory `dir`, whether a
-% file with such a name exists. If it does not, it gets created with
-% `transform(string)` as its content. The filename is then returned.
+% The \luamdef{util.cache} method used `dir`, `string`, `salt`, and `suffix`
+% to determine a pathname. If a file with such a pathname does not exists,
+% it gets created with `transform(string)` as its content. Regardless, the
+% pathname is then returned.
%
% \end{markdown}
% \begin{macrocode}
@@ -22348,7 +23746,7 @@ function util.cache(dir, string, salt, transform, suffix)
local digest = md5.sumhexa(string .. (salt or ""))
local name = util.pathname(dir, digest .. suffix)
local file = io.open(name, "r")
- if file == nil then -- If no cache entry exists, then create a new one.
+ if file == nil then -- If no cache entry exists, create a new one.
file = assert(io.open(name, "w"),
[[Could not open file "]] .. name .. [[" for writing]])
local result = string
@@ -22361,7 +23759,10 @@ function util.cache(dir, string, salt, transform, suffix)
return name
end
% \end{macrocode}
-% \par
+% \iffalse
+%</lua,lua-loader>
+%<*lua>
+% \fi
% \begin{markdown}
%
% The \luamdef{util.cache_verbatim} method strips whitespaces from the
@@ -22375,7 +23776,6 @@ function util.cache_verbatim(dir, string)
return name
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{util.table_copy} method creates a shallow copy of a table `t`
@@ -22389,7 +23789,6 @@ function util.table_copy(t)
return setmetatable(u, getmetatable(t))
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{util.encode_json_string} method encodes a string `s` in
@@ -22403,7 +23802,6 @@ function util.encode_json_string(s)
return [["]] .. s .. [["]]
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{util.expand_tabs_in_line} expands tabs in string `s`. If
@@ -22423,7 +23821,6 @@ function util.expand_tabs_in_line(s, tabstop)
end))
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{util.walk} method walks a rope `t`, applying a function `f`
@@ -22456,7 +23853,6 @@ function util.walk(t, f)
end
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{util.flatten} method flattens an array `ary` that does not
@@ -22478,7 +23874,6 @@ function util.flatten(ary)
return new
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{util.rope_to_string} method converts a rope `rope` to a
@@ -22493,7 +23888,6 @@ function util.rope_to_string(rope)
return table.concat(buffer)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{util.rope_last} method retrieves the last item in a rope. For
@@ -22514,7 +23908,6 @@ function util.rope_last(rope)
end
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Given an array `ary` and a string `x`, the \luamdef{util.intersperse}
@@ -22536,7 +23929,6 @@ function util.intersperse(ary, x)
return new
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Given an array `ary` and a function `f`, the \luamdef{util.map} method
@@ -22553,13 +23945,12 @@ function util.map(ary, f)
return new
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Given a table `char_escapes` mapping escapable characters to escaped
% strings and optionally a table `string_escapes` mapping escapable strings
% to escaped strings, the \luamdef{util.escaper} method returns an escaper
-% function that escapes all occurances of escapable strings and characters (in
+% function that escapes all occurrences of escapable strings and characters (in
% this order).
%
% The method uses \pkg{LPeg}, which is faster than the Lua `string.gsub`
@@ -22588,7 +23979,7 @@ function util.escaper(char_escapes, string_escapes)
% \begin{markdown}
% If `string_escapes` is provided, turn `escapable` into the
% $$\sum^^B{(`k`, `v`)\in`string_escapes`}`P(k) / v` + `escapable`$$
-% capture that replaces any occurance of the string `k` with the string
+% capture that replaces any occurrence of the string `k` with the string
% `v` for each $(`k`, `v`)\in`string_escapes`$. Note that the pattern
% summation is not commutative and its operands are inspected in the
% summation order during the matching. As a corrolary, the strings always
@@ -22619,7 +24010,10 @@ function util.escaper(char_escapes, string_escapes)
end
end
% \end{macrocode}
-% \par
+% \iffalse
+%</lua>
+%<*lua,lua-loader>
+% \fi
% \begin{markdown}
%
% The \luamdef{util.pathname} method produces a pathname out of a directory
@@ -22635,7 +24029,54 @@ function util.pathname(dir, file)
end
end
% \end{macrocode}
-% \par
+% \begin{markdown}
+%
+% The \luamdef{util.salt} method produces cryptographic salt out of a table of
+% options `options`.
+%
+% \end{markdown}
+% \begin{macrocode}
+function util.salt(options)
+ local opt_string = {}
+ for k, _ in pairs(defaultOptions) do
+ local v = options[k]
+ if type(v) == "table" then
+ for _, i in ipairs(v) do
+ opt_string[#opt_string+1] = k .. "=" .. tostring(i)
+ end
+% \end{macrocode}
+% \begin{markdown}
+%
+% The \Opt{cacheDir} option is disregarded.
+%
+% \end{markdown}
+% \begin{macrocode}
+ elseif k ~= "cacheDir" then
+ opt_string[#opt_string+1] = k .. "=" .. tostring(v)
+ end
+ end
+ table.sort(opt_string)
+ local salt = table.concat(opt_string, ",")
+ .. "," .. metadata.version
+ return salt
+end
+% \end{macrocode}
+% \begin{markdown}
+%
+% The \luamdef{util.warning} method produces a warning `s` that is unrelated to
+% any specific markdown text being processed. For warnings that are specific to
+% a markdown text, use \luamref{writer->warning} function.
+%
+% \end{markdown}
+% \begin{macrocode}
+function util.warning(s)
+ io.stderr:write("Warning: " .. s .. "\n")
+end
+% \end{macrocode}
+% \iffalse
+%</lua,lua-loader>
+%<*lua>
+% \fi
% \begin{markdown}
%
%### HTML Entities
@@ -24776,7 +26217,6 @@ local character_entities = {
["zopf"] = 120171,
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Given a string `s` of decimal digits, the \luamdef{entities.dec_entity}
@@ -24792,7 +26232,6 @@ function entities.dec_entity(s)
return unicode.utf8.char(n)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Given a string `s` of hexadecimal digits, the
@@ -24809,7 +26248,6 @@ function entities.hex_entity(s)
return unicode.utf8.char(n)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Given a captured character `x` and a string `s` of hexadecimal digits, the
@@ -24826,7 +26264,6 @@ function entities.hex_entity_with_x_char(x, s)
return unicode.utf8.char(n)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Given a character entity name `s` (like `ouml`), the
@@ -24850,7 +26287,6 @@ function entities.char_entity(s)
return table.concat(char_table)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
%### Plain \TeX{} Writer {#tex-writer}
@@ -24871,7 +26307,6 @@ end
% \begin{macrocode}
M.writer = {}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{writer.new} method creates and returns a new \TeX{} writer
@@ -24889,7 +26324,6 @@ M.writer = {}
function M.writer.new(options)
local self = {}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Make `options` available as \luamdef{writer->options}, so that it is
@@ -24899,7 +26333,6 @@ function M.writer.new(options)
% \begin{macrocode}
self.options = options
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->flatten\_inlines}, which indicates whether or not the
@@ -24911,7 +26344,6 @@ function M.writer.new(options)
% \begin{macrocode}
self.flatten_inlines = false
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Parse the \Opt{slice} option and define \luamdef{writer->slice\_begin},
@@ -24951,16 +26383,6 @@ function M.writer.new(options)
self.is_writing = false
end
% \end{macrocode}
-% \par
-% \begin{markdown}
-%
-% Define \luamdef{writer->suffix} as the suffix of the produced cache files.
-%
-% \end{markdown}
-% \begin{macrocode}
- self.suffix = ".tex"
-% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->space} as the output format of a space character.
@@ -24969,7 +26391,6 @@ function M.writer.new(options)
% \begin{macrocode}
self.space = " "
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->nbsp} as the output format of a non-breaking space
@@ -24979,7 +26400,6 @@ function M.writer.new(options)
% \begin{macrocode}
self.nbsp = "\\markdownRendererNbsp{}"
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->plain} as a function that will transform an input
@@ -24991,7 +26411,6 @@ function M.writer.new(options)
return s
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->paragraph} as a function that will transform an
@@ -25004,20 +26423,6 @@ function M.writer.new(options)
return s
end
% \end{macrocode}
-% \par
-% \begin{markdown}
-%
-% Define \luamdef{writer->pack} as a function that will take the filename
-% `name` of the output file prepared by the reader and transform it to the
-% output format.
-%
-% \end{markdown}
-% \begin{macrocode}
- function self.pack(name)
- return [[\input{]] .. name .. [[}\relax]]
- end
-% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->interblocksep} as the output format of a block
@@ -25031,7 +26436,6 @@ function M.writer.new(options)
return self.interblocksep_text
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->paragraphsep} as the output format of a paragraph
@@ -25047,7 +26451,6 @@ function M.writer.new(options)
return self.paragraphsep_text
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->undosep} as a function that will remove the output
@@ -25061,7 +26464,6 @@ function M.writer.new(options)
return self.undosep_text
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->soft_line_break} as the output format of a soft
@@ -25074,7 +26476,6 @@ function M.writer.new(options)
return "\\markdownRendererSoftLineBreak\n{}"
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->hard_line_break} as the output format of a hard
@@ -25087,7 +26488,6 @@ function M.writer.new(options)
return "\\markdownRendererHardLineBreak\n{}"
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->ellipsis} as the output format of an ellipsis.
@@ -25096,7 +26496,6 @@ function M.writer.new(options)
% \begin{macrocode}
self.ellipsis = "\\markdownRendererEllipsis{}"
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->thematic_break} as the output format of a thematic
@@ -25109,7 +26508,6 @@ function M.writer.new(options)
return "\\markdownRendererThematicBreak{}"
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define tables \luamdef{writer->escaped_uri_chars} and
@@ -25123,16 +26521,19 @@ function M.writer.new(options)
["{"] = "\\markdownRendererLeftBrace{}",
["}"] = "\\markdownRendererRightBrace{}",
["\\"] = "\\markdownRendererBackslash{}",
+ ["\r"] = " ",
+ ["\n"] = " ",
}
self.escaped_minimal_strings = {
- ["^^"] = "\\markdownRendererCircumflex\\markdownRendererCircumflex ",
+ ["^^"] = "\\markdownRendererCircumflex"
+ .. "\\markdownRendererCircumflex ",
["☒"] = "\\markdownRendererTickedBox{}",
["⌛"] = "\\markdownRendererHalfTickedBox{}",
["☐"] = "\\markdownRendererUntickedBox{}",
- [entities.hex_entity('FFFD')] = "\\markdownRendererReplacementCharacter{}",
+ [entities.hex_entity('FFFD')]
+ = "\\markdownRendererReplacementCharacter{}",
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define table \luamdef{writer->escaped_strings} containing the mapping from
@@ -25143,7 +26544,6 @@ function M.writer.new(options)
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
@@ -25164,17 +26564,17 @@ function M.writer.new(options)
["^"] = "\\markdownRendererCircumflex{}",
["~"] = "\\markdownRendererTilde{}",
["|"] = "\\markdownRendererPipe{}",
- [entities.hex_entity('0000')] = "\\markdownRendererReplacementCharacter{}",
+ [entities.hex_entity('0000')]
+ = "\\markdownRendererReplacementCharacter{}",
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Use the \luamref{writer->escaped_chars}, \luamref{writer->escaped_uri_chars},
% and \luamref{writer->escaped_minimal_strings} tables to create the
-% \luamdef{writer->escape_typographic_text},
-% \luamdef{writer->escape_programmatic_text}, and
-% \luamdef{writer->escape_minimal} escaper functions.
+% \luamdef{escape_typographic_text},
+% \luamdef{escape_programmatic_text}, and
+% \luamdef{escape_minimal} local escaper functions.
%
% \end{markdown}
% \begin{macrocode}
@@ -25192,7 +26592,6 @@ function M.writer.new(options)
local escape_minimal = create_escaper(
{}, self.escaped_minimal_strings)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define the following semantic aliases for the escaper functions:
@@ -25223,7 +26622,32 @@ function M.writer.new(options)
self.infostring = escape_programmatic_text
end
% \end{macrocode}
-% \par
+% \begin{markdown}
+%
+% Define \luamdef{writer->warning} as a function that will transform an input
+% warning `t` with optional more warning text `m` to the output format.
+%
+% \end{markdown}
+% \begin{macrocode}
+ function self.warning(t, m)
+ return {"\\markdownRendererWarning{", self.escape(t), "}{",
+ escape_minimal(t), "}{", self.escape(m or ""), "}{",
+ escape_minimal(m or ""), "}"}
+ end
+% \end{macrocode}
+% \begin{markdown}
+%
+% Define \luamdef{writer->error} as a function that will transform an input
+% error text `t` with optional more error text `m` to the output format.
+%
+% \end{markdown}
+% \begin{macrocode}
+ function self.error(t, m)
+ return {"\\markdownRendererError{", self.escape(t), "}{",
+ escape_minimal(t), "}{", self.escape(m or ""), "}{",
+ escape_minimal(m or ""), "}"}
+ end
+% \end{macrocode}
% \begin{markdown}
%
% Define \luamdef{writer->code} as a function that will transform an input
@@ -25249,7 +26673,6 @@ function M.writer.new(options)
return buf
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->link} as a function that will transform an input
@@ -25278,7 +26701,6 @@ function M.writer.new(options)
return buf
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->image} as a function that will transform an input
@@ -25307,7 +26729,6 @@ function M.writer.new(options)
return buf
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->bulletlist} as a function that will transform an input
@@ -25347,7 +26768,6 @@ function M.writer.new(options)
"\\markdownRendererUlItemEnd "}
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->orderedlist} as a function that will transform an
@@ -25399,7 +26819,6 @@ function M.writer.new(options)
end
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->inline_html_comment} as a function that will
@@ -25413,7 +26832,6 @@ function M.writer.new(options)
return {"\\markdownRendererInlineHtmlComment{",contents,"}"}
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->inline_html_tag} as a function that will
@@ -25425,10 +26843,10 @@ function M.writer.new(options)
% \begin{macrocode}
function self.inline_html_tag(contents)
if self.flatten_inlines then return contents end
- return {"\\markdownRendererInlineHtmlTag{",self.string(contents),"}"}
+ return {"\\markdownRendererInlineHtmlTag{",
+ self.string(contents),"}"}
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->block_html_element} as a function that will
@@ -25443,7 +26861,6 @@ function M.writer.new(options)
return {"\\markdownRendererInputBlockHtmlElement{",name,"}"}
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->emphasis} as a function that will transform an
@@ -25456,7 +26873,6 @@ function M.writer.new(options)
return {"\\markdownRendererEmphasis{",s,"}"}
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->tickbox} as a function that will transform a
@@ -25474,7 +26890,6 @@ function M.writer.new(options)
end
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->strong} as a function that will transform a strongly
@@ -25487,7 +26902,6 @@ function M.writer.new(options)
return {"\\markdownRendererStrongEmphasis{",s,"}"}
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->blockquote} as a function that will transform an
@@ -25501,7 +26915,6 @@ function M.writer.new(options)
"\\markdownRendererBlockQuoteEnd "}
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->verbatim} as a function that will transform an
@@ -25516,7 +26929,6 @@ function M.writer.new(options)
return {"\\markdownRendererInputVerbatim{",name,"}"}
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->document} as a function that will transform a
@@ -25525,7 +26937,23 @@ function M.writer.new(options)
% \end{markdown}
% \begin{macrocode}
function self.document(d)
- local buf = {"\\markdownRendererDocumentBegin\n", d}
+ local buf = {"\\markdownRendererDocumentBegin\n"}
+
+ -- warn against the `hybrid` option
+ if options.hybrid then
+ local text = "The `hybrid` option has been soft-deprecated."
+ local more = "Consider using one of the following better options "
+ .. "for mixing TeX and markdown: `contentBlocks`, "
+ .. "`rawAttribute`, `texComments`, `texMathDollars`, "
+ .. "`texMathSingleBackslash`, and "
+ .. "`texMathDoubleBackslash`. "
+ .. "For more information, see the user manual at "
+ .. "<https://witiko.github.io/markdown/>."
+ table.insert(buf, self.warning(text, more))
+ end
+
+ -- insert the text of the document
+ table.insert(buf, d)
-- pop all attributes
table.insert(buf, self.pop_attributes())
@@ -25535,7 +26963,6 @@ function M.writer.new(options)
return buf
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->attributes} as a function that will transform
@@ -25645,7 +27072,6 @@ function M.writer.new(options)
return buf
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->active\_attributes} as a stack of block-level
@@ -25656,7 +27082,6 @@ function M.writer.new(options)
% \begin{macrocode}
self.active_attributes = {}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->attribute\_type\_levels} as a hash table that
@@ -25669,7 +27094,6 @@ function M.writer.new(options)
setmetatable(self.attribute_type_levels,
{ __index = function() return 0 end })
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->push\_attributes} and
@@ -25716,8 +27140,10 @@ function M.writer.new(options)
% \begin{macrocode}
function self.push_attributes(attribute_type, attributes,
start_output, end_output)
- local attribute_type_level = self.attribute_type_levels[attribute_type]
- self.attribute_type_levels[attribute_type] = attribute_type_level + 1
+ local attribute_type_level
+ = self.attribute_type_levels[attribute_type]
+ self.attribute_type_levels[attribute_type]
+ = attribute_type_level + 1
-- index attributes in a hash table for easy lookup
attributes = attributes or {}
@@ -25772,8 +27198,10 @@ function M.writer.new(options)
local attributes, _, end_output
current_attribute_type, attributes, _, end_output = table.unpack(
self.active_attributes[#self.active_attributes])
- local attribute_type_level = self.attribute_type_levels[current_attribute_type]
- self.attribute_type_levels[current_attribute_type] = attribute_type_level - 1
+ local attribute_type_level
+ = self.attribute_type_levels[current_attribute_type]
+ self.attribute_type_levels[current_attribute_type]
+ = attribute_type_level - 1
if self.is_writing and end_output ~= nil then
table.insert(buf, end_output)
end
@@ -25807,7 +27235,8 @@ function M.writer.new(options)
local prev_space = false
local letter_found = false
local normalized_s = s
- if not options.unicodeNormalization or options.unicodeNormalizationForm ~= "nfc" then
+ if not options.unicodeNormalization
+ or options.unicodeNormalizationForm ~= "nfc" then
normalized_s = uni_algos.normalize.NFC(normalized_s)
end
@@ -25824,7 +27253,8 @@ function M.writer.new(options)
end
end
- -- Remove all non-alphanumeric characters, except underscores, hyphens, and periods.
+ -- Remove all non-alphanumeric characters, except underscores,
+ -- hyphens, and periods.
if not unicode.utf8.match(char, "[%w_%-%.%s]") then
goto continue
end
@@ -25852,7 +27282,8 @@ function M.writer.new(options)
table.remove(buffer)
end
- local identifier = #buffer == 0 and "section" or table.concat(buffer, "")
+ local identifier = #buffer == 0 and "section"
+ or table.concat(buffer, "")
return identifier
end
% \end{macrocode}
@@ -25867,7 +27298,8 @@ function M.writer.new(options)
local prev_space = false
local letter_found = false
local normalized_s = s
- if not options.unicodeNormalization or options.unicodeNormalizationForm ~= "nfc" then
+ if not options.unicodeNormalization
+ or options.unicodeNormalizationForm ~= "nfc" then
normalized_s = uni_algos.normalize.NFC(normalized_s)
end
@@ -25884,7 +27316,8 @@ function M.writer.new(options)
end
end
- -- Remove all non-alphanumeric characters, except underscores and hyphens.
+ -- Remove all non-alphanumeric characters, except underscores
+ -- and hyphens.
if not unicode.utf8.match(char, "[%w_%-%s]") then
prev_space = false
goto continue
@@ -25913,11 +27346,11 @@ function M.writer.new(options)
table.remove(buffer)
end
- local identifier = #buffer == 0 and "section" or table.concat(buffer, "")
+ local identifier = #buffer == 0 and "section"
+ or table.concat(buffer, "")
return identifier
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->heading} as a function that will transform an
@@ -25952,9 +27385,11 @@ function M.writer.new(options)
table.insert(auto_identifiers, create_auto_identifier(flat_text))
end
if self.options.gfmAutoIdentifiers then
- table.insert(auto_identifiers, create_gfm_auto_identifier(flat_text))
+ table.insert(auto_identifiers,
+ create_gfm_auto_identifier(flat_text))
end
- local normalized_attributes = normalize_attributes(attributes, auto_identifiers)
+ local normalized_attributes = normalize_attributes(attributes,
+ auto_identifiers)
-- push attributes for the new section
local start_output = {}
@@ -25970,7 +27405,8 @@ function M.writer.new(options)
-- render the heading and its attributes
if self.is_writing and #normalized_attributes > 0 then
- table.insert(buf, "\\markdownRendererHeaderAttributeContextBegin\n")
+ table.insert(buf,
+ "\\markdownRendererHeaderAttributeContextBegin\n")
table.insert(buf, self.attributes(normalized_attributes, false))
end
@@ -26002,7 +27438,6 @@ function M.writer.new(options)
return buf
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->get_state} as a function that returns the current
@@ -26019,7 +27454,6 @@ function M.writer.new(options)
}
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->set_state} as a function that restores the input
@@ -26035,7 +27469,6 @@ function M.writer.new(options)
return previous_state
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->defer_call} as a function that will encapsulate the
@@ -26057,7 +27490,6 @@ function M.writer.new(options)
return self
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
%### Parsers
@@ -26068,7 +27500,6 @@ end
% \begin{macrocode}
local parsers = {}
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Basic Parsers
@@ -26128,8 +27559,12 @@ parsers.fail = P(false)
parsers.internal_punctuation = S(":;,.?")
parsers.ascii_punctuation = S("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")
+
% \end{macrocode}
-% \par
+% \iffalse
+%</lua>
+%<*lua-unicode-data-generator>
+% \fi
% \begin{markdown}
%
%### Unicode punctuation
@@ -26141,36 +27576,143 @@ parsers.ascii_punctuation = S("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")
% [unicode-punctuation]: https://spec.commonmark.org/0.31.2/#unicode-punctuation-character
% (CommonMark Spec, Version 0.31.2 (2024-01-28))
%
+% All code from this section will be executed during the compilation of
+% the Markdown package and the standard output will be stored in a file
+% named `markdown-unicode-data.lua` with the precompiled parser of Unicode
+% punctuation.
+%
% \end{markdown}
% \begin{macrocode}
-parsers.punctuation = {}
-(function()
- local pathname = kpse.lookup("UnicodeData.txt")
+;(function()
+ local pathname = assert(kpse.find_file("UnicodeData.txt"),
+ [[Could not locate file "UnicodeData.txt"]])
local file = assert(io.open(pathname, "r"),
[[Could not open file "UnicodeData.txt"]])
+% \end{macrocode}
+% \begin{markdown}
+%
+% In order to minimize the size and speed of the parser, we will first
+% construct a prefix tree of UTF-8 encodings for all codepoints of a
+% given code length.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local prefix_trees = {}
for line in file:lines() do
local codepoint, major_category = line:match("^(%x+);[^;]*;(%a)")
if major_category == "P" or major_category == "S" then
local code = unicode.utf8.char(tonumber(codepoint, 16))
- if parsers.punctuation[#code] == nil then
- parsers.punctuation[#code] = parsers.fail
+ if prefix_trees[#code] == nil then
+ prefix_trees[#code] = {}
end
- local code_parser = parsers.succeed
+ local node = prefix_trees[#code]
for i = 1, #code do
local byte = code:sub(i, i)
- local byte_parser = S(byte)
- code_parser = code_parser
- * byte_parser
+ if i < #code then
+ if node[byte] == nil then
+ node[byte] = {}
+ end
+ node = node[byte]
+ else
+ table.insert(node, byte)
+ end
end
- parsers.punctuation[#code] = parsers.punctuation[#code]
- + code_parser
end
end
assert(file:close())
+
+% \end{macrocode}
+% \begin{markdown}
+%
+% Next, we will construct a parser out of the prefix tree.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local function depth_first_search(node, path, visit, leave)
+ visit(node, path)
+ for label, child in pairs(node) do
+ if type(child) == "table" then
+ depth_first_search(child, path .. label, visit, leave)
+ else
+ visit(child, path)
+ end
+ end
+ leave(node, path)
+ end
+
+ print("M.punctuation = {}")
+ print("local P = lpeg.P")
+ print("-- luacheck: push no max line length")
+ for length, prefix_tree in pairs(prefix_trees) do
+ local subparsers = {}
+ depth_first_search(prefix_tree, "", function(node, path)
+ if type(node) == "string" then
+ local suffix
+ if node == "]" then
+ suffix = "P('" .. node .. "')"
+ else
+ suffix = "P([[" .. node .. "]])"
+ end
+ if subparsers[path] ~= nil then
+ subparsers[path] = subparsers[path] .. " + " .. suffix
+ else
+ subparsers[path] = suffix
+ end
+ end
+ end, function(_, path)
+ if #path > 0 then
+ local byte = path:sub(#path, #path)
+ local parent_path = path:sub(1, #path-1)
+ local prefix
+ if byte == "]" then
+ prefix = "P('" .. byte .. "')"
+ else
+ prefix = "P([[" .. byte .. "]])"
+ end
+ local suffix
+ if subparsers[path]:find(" %+ ") then
+ suffix = prefix .. " * (" .. subparsers[path] .. ")"
+ else
+ suffix = prefix .. " * " .. subparsers[path]
+ end
+ if subparsers[parent_path] ~= nil then
+ subparsers[parent_path] = subparsers[parent_path]
+ .. " + " .. suffix
+ else
+ subparsers[parent_path] = suffix
+ end
+ else
+ print("M.punctuation[" .. length .. "] = " .. subparsers[path])
+ end
+ end)
+ end
+ print("-- luacheck: pop")
end)()
+print("return M")
+% \end{macrocode}
+% \iffalse
+%</lua-unicode-data-generator>
+%<*lua>
+% \fi
+% \begin{markdown}
+%
+% Back in the Markdown package, we will load the precompiled parser of
+% Unicode punctuation.
+%
+% \end{markdown}
+% \begin{macrocode}
+local unicode_data = require("markdown-unicode-data")
+if metadata.version ~= unicode_data.metadata.version then
+ util.warning(
+ "markdown.lua " .. metadata.version .. " used with " ..
+ "markdown-unicode-data.lua " .. unicode_data.metadata.version .. "."
+ )
+end
+parsers.punctuation = unicode_data.punctuation
parsers.escapable = parsers.ascii_punctuation
-parsers.anyescaped = parsers.backslash / "" * parsers.escapable
+parsers.anyescaped = parsers.backslash / ""
+ * parsers.escapable
+ parsers.any
parsers.spacechar = S("\t ")
@@ -26189,18 +27731,21 @@ parsers.linechar = P(1 - parsers.newline)
parsers.blankline = parsers.optionalspace
* parsers.newline / "\n"
parsers.blanklines = parsers.blankline^0
-parsers.skipblanklines = (parsers.optionalspace * parsers.newline)^0
+parsers.skipblanklines = ( parsers.optionalspace
+ * parsers.newline)^0
parsers.indentedline = parsers.indent /""
- * C(parsers.linechar^1 * parsers.newline^-1)
+ * C( parsers.linechar^1
+ * parsers.newline^-1)
parsers.optionallyindentedline = parsers.indent^-1 /""
- * C(parsers.linechar^1 * parsers.newline^-1)
+ * C( parsers.linechar^1
+ * parsers.newline^-1)
parsers.sp = parsers.spacing^0
parsers.spnl = parsers.optionalspace
- * (parsers.newline * parsers.optionalspace)^-1
+ * ( parsers.newline
+ * parsers.optionalspace)^-1
parsers.line = parsers.linechar^0 * parsers.newline
parsers.nonemptyline = parsers.line - parsers.blankline
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Parsers Used for Indentation
@@ -26279,7 +27824,8 @@ local function update_indent_table(indent_table, new_indent, add)
if add then
indent_table.indents[#indent_table.indents + 1] = new_indent
else
- if indent_table.indents[#indent_table.indents].name == new_indent.name then
+ if indent_table.indents[#indent_table.indents].name
+ == new_indent.name then
indent_table.indents[#indent_table.indents] = nil
end
end
@@ -26295,10 +27841,12 @@ end
% \end{markdown}
% \begin{macrocode}
local function remove_indent(name)
- local function remove_indent_level(s, i, indent_table) -- luacheck: ignore s i
- indent_table = update_indent_table(indent_table, {name=name}, false)
- return true, indent_table
- end
+ local remove_indent_level =
+ function(s, i, indent_table) -- luacheck: ignore s i
+ indent_table = update_indent_table(indent_table, {name=name},
+ false)
+ return true, indent_table
+ end
return Cg(Cmt(Cb("indent_info"), remove_indent_level), "indent_info")
end
@@ -26314,7 +27862,8 @@ end
%
% \end{markdown}
% \begin{macrocode}
-local function process_starter_spacing(indent, spacing, minimum, left_strip_length)
+local function process_starter_spacing(indent, spacing,
+ minimum, left_strip_length)
left_strip_length = left_strip_length or 0
local count = 0
@@ -26351,14 +27900,16 @@ local function process_starter_spacing(indent, spacing, minimum, left_strip_leng
minimum_remainder = minimum_remainder .. character
elseif (count >= minimum) then
minimum_found = true
- minimum_remainder = minimum_remainder .. string.rep(" ", count - minimum)
+ minimum_remainder = minimum_remainder
+ .. string.rep(" ", count - minimum)
end
if (code_started) then
code_start = code_start .. character
elseif (count >= minimum + 4) then
code_started = true
- code_start = code_start .. string.rep(" ", count - (minimum + 4))
+ code_start = code_start
+ .. string.rep(" ", count - (minimum + 4))
end
end
end
@@ -26425,7 +27976,8 @@ end
%
% \end{markdown}
% \begin{macrocode}
-local function process_starter_indent(_, _, indent_table, starter, is_blank, indent_type, breakable)
+local function process_starter_indent(_, _, indent_table, starter,
+ is_blank, indent_type, breakable)
local last_trail = starter[1]
local delimiter = starter[2]
local raw_new_trail = starter[3]
@@ -26453,11 +28005,13 @@ local function process_starter_indent(_, _, indent_table, starter, is_blank, ind
local last_trail_length = #last_trail
local delimiter_length = total_delimiter_length(delimiter)
- local total_indent_level = preceding_indentation + last_trail_length + delimiter_length
+ local total_indent_level = preceding_indentation + last_trail_length
+ + delimiter_length
local sp = {}
if not is_blank then
- sp = process_starter_spacing(total_indent_level, raw_new_trail, 0, 1)
+ sp = process_starter_spacing(total_indent_level, raw_new_trail,
+ 0, 1)
end
local del_trail_length = sp.left_total_stripped
@@ -26467,12 +28021,17 @@ local function process_starter_indent(_, _, indent_table, starter, is_blank, ind
del_trail_length = del_trail_length + #sp.remainder
end
- local indent_length = last_trail_length + delimiter_length + del_trail_length
+ local indent_length = last_trail_length + delimiter_length
+ + del_trail_length
local new_indent_info = {name=indent_type, length=indent_length}
- indent_table = update_indent_table(indent_table, new_indent_info, true)
- indent_table = add_trail(indent_table, {is_code=sp.is_code, remainder=sp.remainder, total_length=sp.total_length,
- full_remainder=sp.full_remainder})
+ indent_table = update_indent_table(indent_table, new_indent_info,
+ true)
+ indent_table = add_trail(indent_table,
+ {is_code=sp.is_code,
+ remainder=sp.remainder,
+ total_length=sp.total_length,
+ full_remainder=sp.full_remainder})
return true, indent_table
end
@@ -26490,7 +28049,8 @@ local function decode_pattern(name)
delimeter = parsers.more
end
- return C(parsers.optionalspace) * C(delimeter) * C(parsers.optionalspace) * Cp()
+ return C(parsers.optionalspace) * C(delimeter)
+ * C(parsers.optionalspace) * Cp()
end
% \end{macrocode}
@@ -26531,7 +28091,8 @@ end
%
% \end{markdown}
% \begin{macrocode}
-local function traverse_indent(s, i, indent_table, is_optional, is_blank, current_line_indents)
+local function traverse_indent(s, i, indent_table, is_optional,
+ is_blank, current_line_indents)
local new_index = i
local preceding_indentation = 0
@@ -26550,12 +28111,17 @@ local function traverse_indent(s, i, indent_table, is_optional, is_blank, curren
-- match decoded pattern
local new_indent_info = lpeg.match(Ct(pattern), s, new_index)
if new_indent_info == nil then
- local blankline_end = lpeg.match(Ct(parsers.blankline * Cg(Cp(), "pos")), s, new_index)
- if is_optional or not indent_table.ignore_blockquote_blank or not blankline_end then
- return is_optional, new_index, current_trail, current_line_indents
+ local blankline_end = lpeg.match(
+ Ct(parsers.blankline * Cg(Cp(), "pos")), s, new_index)
+ if is_optional or not indent_table.ignore_blockquote_blank
+ or not blankline_end then
+ return is_optional, new_index, current_trail,
+ current_line_indents
end
- return traverse_indent(s, tonumber(blankline_end.pos), indent_table, is_optional, is_blank, current_line_indents)
+ return traverse_indent(s, tonumber(blankline_end.pos),
+ indent_table, is_optional, is_blank,
+ current_line_indents)
end
local raw_last_trail = new_indent_info[1]
@@ -26568,13 +28134,15 @@ local function traverse_indent(s, i, indent_table, is_optional, is_blank, curren
-- check previous trail
if not space_only and next(current_trail) == nil then
local sp = process_starter_spacing(0, raw_last_trail, 0, 0)
- current_trail = {is_code=sp.is_code, remainder=sp.remainder, total_length=sp.total_length,
+ current_trail = {is_code=sp.is_code, remainder=sp.remainder,
+ total_length=sp.total_length,
full_remainder=sp.full_remainder}
end
if next(current_trail) ~= nil then
if not space_only and current_trail.is_code then
- return is_optional, new_index, current_trail, current_line_indents
+ return is_optional, new_index, current_trail,
+ current_line_indents
end
if current_trail.internal_remainder ~= nil then
raw_last_trail = current_trail.internal_remainder
@@ -26589,7 +28157,8 @@ local function traverse_indent(s, i, indent_table, is_optional, is_blank, curren
raw_last_trail_length = #raw_last_trail
end
- local total_indent_level = preceding_indentation + raw_last_trail_length + delimiter_length
+ local total_indent_level = preceding_indentation
+ + raw_last_trail_length + delimiter_length
local spacing_to_process
local minimum = 0
@@ -26603,13 +28172,17 @@ local function traverse_indent(s, i, indent_table, is_optional, is_blank, curren
minimum = value.length
end
- local sp = process_starter_spacing(total_indent_level, spacing_to_process, minimum, left_strip_length)
+ local sp = process_starter_spacing(total_indent_level,
+ spacing_to_process, minimum,
+ left_strip_length)
if space_only and not sp.is_minimum then
- return is_optional or (is_blank and blank_starter <= index), new_index, current_trail, current_line_indents
+ return is_optional or (is_blank and blank_starter <= index),
+ new_index, current_trail, current_line_indents
end
- local indent_length = raw_last_trail_length + delimiter_length + sp.left_total_stripped
+ local indent_length = raw_last_trail_length + delimiter_length
+ + sp.left_total_stripped
-- update info for the next pattern
if not space_only then
@@ -26618,8 +28191,10 @@ local function traverse_indent(s, i, indent_table, is_optional, is_blank, curren
preceding_indentation = preceding_indentation + value.length
end
- current_trail = {is_code=sp.is_code, remainder=sp.remainder, internal_remainder=sp.minimum_remainder,
- total_length=sp.total_length, full_remainder=sp.full_remainder}
+ current_trail = {is_code=sp.is_code, remainder=sp.remainder,
+ internal_remainder=sp.minimum_remainder,
+ total_length=sp.total_length,
+ full_remainder=sp.full_remainder}
current_line_indents[#current_line_indents + 1] = new_indent_info
new_index = next_index
@@ -26647,34 +28222,36 @@ end
%
% \end{markdown}
% \begin{macrocode}
-local function check_trail_joined(s, i, indent_table, spacing, expect_code, omit_remainder) -- luacheck: ignore s i
- local is_code
- local remainder
+local check_trail_joined =
+ function(s, i, indent_table, -- luacheck: ignore s i
+ spacing, expect_code, omit_remainder)
+ local is_code
+ local remainder
- if has_trail(indent_table) then
- local trail = indent_table.trail
- is_code = trail.is_code
- if is_code then
- remainder = trail.remainder
- else
- remainder = trail.full_remainder
- end
- else
- local sp = process_starter_spacing(0, spacing, 0, 0)
- is_code = sp.is_code
- if is_code then
- remainder = sp.remainder
+ if has_trail(indent_table) then
+ local trail = indent_table.trail
+ is_code = trail.is_code
+ if is_code then
+ remainder = trail.remainder
+ else
+ remainder = trail.full_remainder
+ end
else
- remainder = sp.full_remainder
+ local sp = process_starter_spacing(0, spacing, 0, 0)
+ is_code = sp.is_code
+ if is_code then
+ remainder = sp.remainder
+ else
+ remainder = sp.full_remainder
+ end
end
- end
- local result = check_trail(expect_code, is_code)
- if omit_remainder then
- return result
+ local result = check_trail(expect_code, is_code)
+ if omit_remainder then
+ return result
+ end
+ return result, remainder
end
- return result, remainder
-end
% \end{macrocode}
% \begin{markdown}
@@ -26683,22 +28260,24 @@ end
%
% \end{markdown}
% \begin{macrocode}
-local function check_trail_length(s, i, indent_table, spacing, min, max) -- luacheck: ignore s i
- local trail
+local check_trail_length =
+ function(s, i, indent_table, -- luacheck: ignore s i
+ spacing, min, max)
+ local trail
- if has_trail(indent_table) then
- trail = indent_table.trail
- else
- trail = process_starter_spacing(0, spacing, 0, 0)
- end
+ if has_trail(indent_table) then
+ trail = indent_table.trail
+ else
+ trail = process_starter_spacing(0, spacing, 0, 0)
+ end
- local total_length = trail.total_length
- if total_length == nil then
- return false
- end
+ local total_length = trail.total_length
+ if total_length == nil then
+ return false
+ end
- return min <= total_length and total_length <= max
-end
+ return min <= total_length and total_length <= max
+ end
% \end{macrocode}
% \begin{markdown}
@@ -26708,7 +28287,8 @@ end
%
% \end{markdown}
% \begin{macrocode}
-local function check_continuation_indentation(s, i, indent_table, is_optional, is_blank)
+local function check_continuation_indentation(s, i, indent_table,
+ is_optional, is_blank)
if not has_indents(indent_table) then
return true
end
@@ -26761,27 +28341,29 @@ end
%
% \end{markdown}
% \begin{macrocode}
-local function check_trail_type(s, i, trail, spacing, trail_type) -- luacheck: ignore s i
- if trail == nil then
- trail = process_starter_spacing(0, spacing, 0, 0)
- end
+local check_trail_type =
+ function(s, i, -- luacheck: ignore s i
+ trail, spacing, trail_type)
+ if trail == nil then
+ trail = process_starter_spacing(0, spacing, 0, 0)
+ end
- if trail_type == "non-code" then
- return check_trail(false, trail.is_code)
- end
- if trail_type == "code" then
- return check_trail(true, trail.is_code)
- end
- if trail_type == "full-code" then
- if (trail.is_code) then
- return i, trail.remainder
+ if trail_type == "non-code" then
+ return check_trail(false, trail.is_code)
+ end
+ if trail_type == "code" then
+ return check_trail(true, trail.is_code)
+ end
+ if trail_type == "full-code" then
+ if (trail.is_code) then
+ return i, trail.remainder
+ end
+ return i, ""
+ end
+ if trail_type == "full-any" then
+ return i, trail.internal_remainder
end
- return i, ""
- end
- if trail_type == "full-any" then
- return i, trail.internal_remainder
end
-end
% \end{macrocode}
% \begin{markdown}
@@ -26790,20 +28372,22 @@ end
%
% \end{markdown}
% \begin{macrocode}
-local function trail_freezing(s, i, indent_table, is_freezing) -- luacheck: ignore s i
- if is_freezing then
- if indent_table.is_trail_frozen then
- indent_table.trail = indent_table.frozen_trail
+local trail_freezing =
+ function(s, i, -- luacheck: ignore s i
+ indent_table, is_freezing)
+ if is_freezing then
+ if indent_table.is_trail_frozen then
+ indent_table.trail = indent_table.frozen_trail
+ else
+ indent_table.frozen_trail = indent_table.trail
+ indent_table.is_trail_frozen = true
+ end
else
- indent_table.frozen_trail = indent_table.trail
- indent_table.is_trail_frozen = true
+ indent_table.frozen_trail = nil
+ indent_table.is_trail_frozen = false
end
- else
- indent_table.frozen_trail = nil
- indent_table.is_trail_frozen = false
+ return true, indent_table
end
- return true, indent_table
-end
% \end{macrocode}
% \begin{markdown}
@@ -26814,53 +28398,59 @@ end
%
% \end{markdown}
% \begin{macrocode}
-local function check_continuation_indentation_and_trail(s, i, indent_table, is_optional, is_blank, trail_type,
- reset_rem, omit_remainder)
- if not has_indents(indent_table) then
- local spacing, new_index = lpeg.match(C(parsers.spacechar^0) * Cp(), s, i)
- local result, remainder = check_trail_type(s, i, indent_table.trail, spacing, trail_type)
- if remainder == nil then
+local check_continuation_indentation_and_trail =
+ function (s, i, indent_table, is_optional, is_blank, trail_type,
+ reset_rem, omit_remainder)
+ if not has_indents(indent_table) then
+ local spacing, new_index = lpeg.match( C(parsers.spacechar^0)
+ * Cp(), s, i)
+ local result, remainder = check_trail_type(s, i,
+ indent_table.trail, spacing, trail_type)
+ if remainder == nil then
+ if result then
+ return new_index
+ end
+ return false
+ end
if result then
- return new_index
+ return new_index, remainder
end
return false
end
- if result then
- return new_index, remainder
- end
- return false
- end
- local passes, new_index, current_trail = traverse_indent(s, i, indent_table, is_optional, is_blank)
+ local passes, new_index, current_trail = traverse_indent(s, i,
+ indent_table, is_optional, is_blank)
+
+ if passes then
+ local spacing
+ if current_trail == nil then
+ local newer_spacing, newer_index = lpeg.match(
+ C(parsers.spacechar^0) * Cp(), s, i)
+ current_trail = process_starter_spacing(0, newer_spacing, 0, 0)
+ new_index = newer_index
+ spacing = newer_spacing
+ else
+ spacing = current_trail.remainder
+ end
+ local result, remainder = check_trail_type(s, new_index,
+ current_trail, spacing, trail_type)
+ if remainder == nil or omit_remainder then
+ if result then
+ return new_index
+ end
+ return false
+ end
- if passes then
- local spacing
- if current_trail == nil then
- local newer_spacing, newer_index = lpeg.match(C(parsers.spacechar^0) * Cp(), s, i)
- current_trail = process_starter_spacing(0, newer_spacing, 0, 0)
- new_index = newer_index
- spacing = newer_spacing
- else
- spacing = current_trail.remainder
- end
- local result, remainder = check_trail_type(s, new_index, current_trail, spacing, trail_type)
- if remainder == nil or omit_remainder then
+ if is_blank and reset_rem then
+ remainder = remove_remainder_if_blank(indent_table, remainder)
+ end
if result then
- return new_index
+ return new_index, remainder
end
return false
end
-
- if is_blank and reset_rem then
- remainder = remove_remainder_if_blank(indent_table, remainder)
- end
- if result then
- return new_index, remainder
- end
return false
end
- return false
-end
% \end{macrocode}
% \begin{markdown}
@@ -26869,14 +28459,20 @@ end
%
% \end{markdown}
% \begin{macrocode}
-parsers.check_trail = Cmt(Cb("indent_info") * C(parsers.spacechar^0) * Cc(false), check_trail_joined)
+parsers.check_trail = Cmt( Cb("indent_info") * C(parsers.spacechar^0)
+ * Cc(false), check_trail_joined)
-parsers.check_trail_no_rem = Cmt(Cb("indent_info") * C(parsers.spacechar^0) * Cc(false) * Cc(true), check_trail_joined)
+parsers.check_trail_no_rem = Cmt( Cb("indent_info")
+ * C(parsers.spacechar^0) * Cc(false)
+ * Cc(true), check_trail_joined)
-parsers.check_code_trail = Cmt(Cb("indent_info") * C(parsers.spacechar^0) * Cc(true), check_trail_joined)
+parsers.check_code_trail = Cmt( Cb("indent_info")
+ * C(parsers.spacechar^0)
+ * Cc(true), check_trail_joined)
parsers.check_trail_length_range = function(min, max)
- return Cmt(Cb("indent_info") * C(parsers.spacechar^0) * Cc(min) * Cc(max), check_trail_length)
+ return Cmt( Cb("indent_info") * C(parsers.spacechar^0) * Cc(min)
+ * Cc(max), check_trail_length)
end
parsers.check_trail_length = function(n)
@@ -26891,9 +28487,11 @@ end
%
% \end{markdown}
% \begin{macrocode}
-parsers.freeze_trail = Cg(Cmt(Cb("indent_info") * Cc(true), trail_freezing), "indent_info")
+parsers.freeze_trail = Cg( Cmt(Cb("indent_info")
+ * Cc(true), trail_freezing), "indent_info")
-parsers.unfreeze_trail = Cg(Cmt(Cb("indent_info") * Cc(false), trail_freezing), "indent_info")
+parsers.unfreeze_trail = Cg(Cmt(Cb("indent_info") * Cc(false),
+ trail_freezing), "indent_info")
% \end{macrocode}
% \begin{markdown}
@@ -26902,11 +28500,16 @@ parsers.unfreeze_trail = Cg(Cmt(Cb("indent_info") * Cc(false), trail_freezing),
%
% \end{markdown}
% \begin{macrocode}
-parsers.check_minimal_indent = Cmt(Cb("indent_info") * Cc(false), check_continuation_indentation)
+parsers.check_minimal_indent = Cmt(Cb("indent_info") * Cc(false),
+ check_continuation_indentation)
-parsers.check_optional_indent = Cmt(Cb("indent_info") * Cc(true), check_continuation_indentation)
+parsers.check_optional_indent = Cmt(Cb("indent_info") * Cc(true),
+ check_continuation_indentation)
-parsers.check_minimal_blank_indent = Cmt(Cb("indent_info") * Cc(false) * Cc(true), check_continuation_indentation)
+parsers.check_minimal_blank_indent
+ = Cmt( Cb("indent_info") * Cc(false)
+ * Cc(true)
+ , check_continuation_indentation)
% \end{macrocode}
% \begin{markdown}
@@ -26917,37 +28520,45 @@ parsers.check_minimal_blank_indent = Cmt(Cb("indent_info") * Cc(false) * Cc(true
% \end{markdown}
% \begin{macrocode}
-parsers.check_minimal_indent_and_trail = Cmt( Cb("indent_info")
- * Cc(false) * Cc(false) * Cc("non-code") * Cc(true),
- check_continuation_indentation_and_trail)
+parsers.check_minimal_indent_and_trail =
+ Cmt( Cb("indent_info")
+ * Cc(false) * Cc(false) * Cc("non-code") * Cc(true)
+ , check_continuation_indentation_and_trail)
-parsers.check_minimal_indent_and_code_trail = Cmt( Cb("indent_info")
- * Cc(false) * Cc(false) * Cc("code") * Cc(false),
- check_continuation_indentation_and_trail)
+parsers.check_minimal_indent_and_code_trail =
+ Cmt( Cb("indent_info")
+ * Cc(false) * Cc(false) * Cc("code") * Cc(false)
+ , check_continuation_indentation_and_trail)
-parsers.check_minimal_blank_indent_and_full_code_trail = Cmt( Cb("indent_info")
- * Cc(false) * Cc(true) * Cc("full-code") * Cc(true),
- check_continuation_indentation_and_trail)
+parsers.check_minimal_blank_indent_and_full_code_trail =
+ Cmt( Cb("indent_info")
+ * Cc(false) * Cc(true) * Cc("full-code") * Cc(true)
+ , check_continuation_indentation_and_trail)
-parsers.check_minimal_indent_and_any_trail = Cmt( Cb("indent_info")
- * Cc(false) * Cc(false) * Cc("full-any") * Cc(true) * Cc(false),
- check_continuation_indentation_and_trail)
+parsers.check_minimal_indent_and_any_trail =
+ Cmt( Cb("indent_info")
+ * Cc(false) * Cc(false) * Cc("full-any") * Cc(true) * Cc(false)
+ , check_continuation_indentation_and_trail)
-parsers.check_minimal_blank_indent_and_any_trail = Cmt( Cb("indent_info")
- * Cc(false) * Cc(true) * Cc("full-any") * Cc(true) * Cc(false),
- check_continuation_indentation_and_trail)
+parsers.check_minimal_blank_indent_and_any_trail =
+ Cmt( Cb("indent_info")
+ * Cc(false) * Cc(true) * Cc("full-any") * Cc(true) * Cc(false)
+ , check_continuation_indentation_and_trail)
-parsers.check_minimal_blank_indent_and_any_trail_no_rem = Cmt( Cb("indent_info")
- * Cc(false) * Cc(true) * Cc("full-any") * Cc(true) * Cc(true),
- check_continuation_indentation_and_trail)
+parsers.check_minimal_blank_indent_and_any_trail_no_rem =
+ Cmt( Cb("indent_info")
+ * Cc(false) * Cc(true) * Cc("full-any") * Cc(true) * Cc(true)
+ , check_continuation_indentation_and_trail)
-parsers.check_optional_indent_and_any_trail = Cmt( Cb("indent_info")
- * Cc(true) * Cc(false) * Cc("full-any") * Cc(true) * Cc(false),
- check_continuation_indentation_and_trail)
+parsers.check_optional_indent_and_any_trail =
+ Cmt( Cb("indent_info")
+ * Cc(true) * Cc(false) * Cc("full-any") * Cc(true) * Cc(false)
+ , check_continuation_indentation_and_trail)
-parsers.check_optional_blank_indent_and_any_trail = Cmt( Cb("indent_info")
- * Cc(true) * Cc(true) * Cc("full-any") * Cc(true) * Cc(false),
- check_continuation_indentation_and_trail)
+parsers.check_optional_blank_indent_and_any_trail =
+ Cmt( Cb("indent_info")
+ * Cc(true) * Cc(true) * Cc("full-any") * Cc(true) * Cc(false)
+ , check_continuation_indentation_and_trail)
% \end{macrocode}
% \begin{markdown}
@@ -26958,7 +28569,8 @@ parsers.check_optional_blank_indent_and_any_trail = Cmt( Cb("indent_info")
% \begin{macrocode}
parsers.spnlc_noexc = parsers.optionalspace
- * (parsers.newline * parsers.check_minimal_indent_and_any_trail)^-1
+ * ( parsers.newline
+ * parsers.check_minimal_indent_and_any_trail)^-1
parsers.spnlc = parsers.optionalspace
* (V("EndlineNoSub"))^-1
@@ -26966,9 +28578,10 @@ parsers.spnlc = parsers.optionalspace
parsers.spnlc_sep = parsers.optionalspace * V("EndlineNoSub")
+ parsers.spacechar^1
-parsers.only_blank = parsers.spacechar^0 * (parsers.newline + parsers.eof)
+parsers.only_blank = parsers.spacechar^0
+ * (parsers.newline + parsers.eof)
-% \end{macrocode}
+% \end{macrocode}
% \begin{figure}
% \hspace*{-0.1\textwidth}
% \begin{minipage}{1.2\textwidth}
@@ -27013,64 +28626,68 @@ parsers.commented_line_letter = parsers.linechar
+ parsers.newline
- parsers.backslash
- parsers.percent
-parsers.commented_line = Cg(Cc(""), "backslashes")
- * ((#(parsers.commented_line_letter
- - parsers.newline)
- * Cb("backslashes")
- * Cs(parsers.commented_line_letter
- - parsers.newline)^1 -- initial
- * Cg(Cc(""), "backslashes"))
- + #(parsers.backslash * parsers.backslash)
- * Cg((parsers.backslash -- even backslash
- * parsers.backslash)^1, "backslashes")
- + (parsers.backslash
- * (#parsers.percent
- * Cb("backslashes")
- / function(backslashes)
- return string.rep("\\", #backslashes / 2)
- end
- * C(parsers.percent)
- + #parsers.commented_line_letter
- * Cb("backslashes")
- * Cc("\\")
- * C(parsers.commented_line_letter))
- * Cg(Cc(""), "backslashes")))^0
- * (#parsers.percent
- * Cb("backslashes")
- / function(backslashes)
- return string.rep("\\", #backslashes / 2)
- end
- * ((parsers.percent -- comment
- * parsers.line
- * #parsers.blankline) -- blank line
- / "\n"
- + parsers.percent -- comment
- * parsers.line
- * parsers.optionalspace) -- leading tabs and spaces
- + #(parsers.newline)
- * Cb("backslashes")
- * C(parsers.newline))
-
-parsers.chunk = parsers.line * (parsers.optionallyindentedline
- - parsers.blankline)^0
-
-parsers.attribute_key_char = parsers.alphanumeric + S("-_:.")
-parsers.attribute_raw_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.squote / "")
- * (parsers.anyescaped - parsers.squote)^0
- * (parsers.squote / ""))
- + ( parsers.anyescaped - parsers.dquote - parsers.rbrace
- - parsers.space)^0
-parsers.attribute_identifier = parsers.attribute_key_char^1
-parsers.attribute_classname = parsers.letter
- * parsers.attribute_key_char^0
-parsers.attribute_raw = parsers.attribute_raw_char^1
+parsers.commented_line = Cg(Cc(""), "backslashes")
+ * ((#(parsers.commented_line_letter
+ - parsers.newline)
+ * Cb("backslashes")
+ * Cs(parsers.commented_line_letter
+ - parsers.newline)^1 -- initial
+ * Cg(Cc(""), "backslashes"))
+ + #( parsers.backslash
+ * (parsers.backslash + parsers.newline))
+ * Cg((parsers.backslash -- even backslash
+ * ( parsers.backslash
+ + #parsers.newline))^1, "backslashes")
+ + (parsers.backslash
+ * (#parsers.percent
+ * Cb("backslashes")
+ / function(backslashes)
+ return string.rep("\\", #backslashes / 2)
+ end
+ * C(parsers.percent)
+ + #parsers.commented_line_letter
+ * Cb("backslashes")
+ * Cc("\\")
+ * C(parsers.commented_line_letter))
+ * Cg(Cc(""), "backslashes")))^0
+ * (#parsers.percent
+ * Cb("backslashes")
+ / function(backslashes)
+ return string.rep("\\", #backslashes / 2)
+ end
+ * ((parsers.percent -- comment
+ * parsers.line
+ * #parsers.blankline) -- blank line
+ / "\n"
+ + parsers.percent -- comment
+ * parsers.line
+ * parsers.optionalspace) -- leading spaces
+ + #(parsers.newline)
+ * Cb("backslashes")
+ * C(parsers.newline))
+
+parsers.chunk = parsers.line * (parsers.optionallyindentedline
+ - parsers.blankline)^0
+
+parsers.attribute_key_char = parsers.alphanumeric + S("-_:.")
+parsers.attribute_raw_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.squote / "")
+ * (parsers.anyescaped - parsers.squote)^0
+ * (parsers.squote / ""))
+ + ( parsers.anyescaped
+ - parsers.dquote
+ - parsers.rbrace
+ - parsers.space)^0
+parsers.attribute_identifier = parsers.attribute_key_char^1
+parsers.attribute_classname = parsers.letter
+ * parsers.attribute_key_char^0
+parsers.attribute_raw = parsers.attribute_raw_char^1
parsers.attribute = (parsers.dash * Cc(".unnumbered"))
+ C( parsers.hash
@@ -27078,7 +28695,9 @@ parsers.attribute = (parsers.dash * Cc(".unnumbered"))
+ C( parsers.period
* parsers.attribute_classname)
+ Cs( parsers.attribute_key
- * parsers.optionalspace * parsers.equal * parsers.optionalspace
+ * parsers.optionalspace
+ * parsers.equal
+ * parsers.optionalspace
* parsers.attribute_value)
parsers.attributes = parsers.lbrace
* parsers.optionalspace
@@ -27088,7 +28707,6 @@ parsers.attributes = parsers.lbrace
* parsers.optionalspace
* parsers.rbrace
-
parsers.raw_attribute = parsers.lbrace
* parsers.optionalspace
* parsers.equal
@@ -27100,11 +28718,13 @@ parsers.raw_attribute = parsers.lbrace
-- indented blocks with first line indented.
parsers.indented_blocks = function(bl)
return Cs( bl
- * (parsers.blankline^1 * parsers.indent * -parsers.blankline * bl)^0
+ * ( parsers.blankline^1
+ * parsers.indent
+ * -parsers.blankline
+ * bl)^0
* (parsers.blankline^1 + parsers.eof) )
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Parsers Used for HTML Entities
@@ -27116,17 +28736,19 @@ local function repeat_between(pattern, min, max)
end
parsers.hexentity = parsers.ampersand * parsers.hash * C(S("Xx"))
- * C(repeat_between(parsers.hexdigit, 1, 6)) * parsers.semicolon
+ * C(repeat_between(parsers.hexdigit, 1, 6))
+ * parsers.semicolon
parsers.decentity = parsers.ampersand * parsers.hash
- * C(repeat_between(parsers.digit, 1, 7)) * parsers.semicolon
+ * C(repeat_between(parsers.digit, 1, 7))
+ * parsers.semicolon
parsers.tagentity = parsers.ampersand * C(parsers.alphanumeric^1)
* parsers.semicolon
-parsers.html_entities = parsers.hexentity / entities.hex_entity_with_x_char
- + parsers.decentity / entities.dec_entity
- + parsers.tagentity / entities.char_entity
+parsers.html_entities
+ = parsers.hexentity / entities.hex_entity_with_x_char
+ + parsers.decentity / entities.dec_entity
+ + parsers.tagentity / entities.char_entity
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Parsers Used for Markdown Lists
@@ -27138,7 +28760,8 @@ parsers.bullet = function(bullet_char, interrupting)
if interrupting then
allowed_end = C(parsers.spacechar^1) * #parsers.linechar
else
- allowed_end = C(parsers.spacechar^1) + #(parsers.newline + parsers.eof)
+ allowed_end = C(parsers.spacechar^1)
+ + #(parsers.newline + parsers.eof)
end
return parsers.check_trail
* Ct(C(bullet_char) * Cc(""))
@@ -27155,7 +28778,6 @@ parsers.halfticked_box = tickbox(S("./")) * Cc(0.5)
parsers.unticked_box = tickbox(parsers.spacechar^1) * Cc(0.0)
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Parsers Used for Markdown Code Spans
@@ -27189,14 +28811,14 @@ parsers.inticks = parsers.openticks
* parsers.closeticks
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Parsers Used for HTML
%
% \end{markdown}
% \begin{macrocode}
--- case-insensitive match (we assume s is lowercase). must be single byte encoding
+-- case-insensitive match (we assume s is lowercase)
+-- must be single byte encoding
parsers.keyword_exact = function(s)
local parser = P(0)
for i=1,#s do
@@ -27278,13 +28900,14 @@ parsers.block_keyword =
parsers.keyword_exact("ul")
-- end conditions
-parsers.html_blankline_end_condition = parsers.linechar^0
- * ( parsers.newline
- * (parsers.check_minimal_blank_indent_and_any_trail
- * #parsers.blankline
- + parsers.check_minimal_indent_and_any_trail)
- * parsers.linechar^1)^0
- * (parsers.newline^-1 / "")
+parsers.html_blankline_end_condition
+ = parsers.linechar^0
+ * ( parsers.newline
+ * (parsers.check_minimal_blank_indent_and_any_trail
+ * #parsers.blankline
+ + parsers.check_minimal_indent_and_any_trail)
+ * parsers.linechar^1)^0
+ * (parsers.newline^-1 / "")
local function remove_trailing_blank_lines(s)
return s:gsub("[\n\r]+%s*$", "")
@@ -27306,9 +28929,14 @@ parsers.html_attribute_spacing = parsers.optionalspace
* parsers.optionalspace
+ parsers.spacechar^1
-parsers.html_attribute_name = (parsers.letter + parsers.colon + parsers.underscore)
- * (parsers.alphanumeric + parsers.colon + parsers.underscore
- + parsers.period + parsers.dash)^0
+parsers.html_attribute_name = ( parsers.letter
+ + parsers.colon
+ + parsers.underscore)
+ * ( parsers.alphanumeric
+ + parsers.colon
+ + parsers.underscore
+ + parsers.period
+ + parsers.dash)^0
parsers.html_attribute_value = parsers.squote
* (parsers.linechar - parsers.squote)^0
@@ -27316,9 +28944,15 @@ parsers.html_attribute_value = parsers.squote
+ parsers.dquote
* (parsers.linechar - parsers.dquote)^0
* parsers.dquote
- + ( parsers.any - parsers.spacechar - parsers.newline
- - parsers.dquote - parsers.squote - parsers.backtick
- - parsers.equal - parsers.less - parsers.more)^1
+ + ( parsers.any
+ - parsers.spacechar
+ - parsers.newline
+ - parsers.dquote
+ - parsers.squote
+ - parsers.backtick
+ - parsers.equal
+ - parsers.less
+ - parsers.more)^1
parsers.html_inline_attribute_value = parsers.squote
* (V("NoSoftLineBreakEndline")
@@ -27332,30 +28966,41 @@ parsers.html_inline_attribute_value = parsers.squote
- parsers.blankline^2
- parsers.dquote)^0
* parsers.dquote
- + (parsers.any - parsers.spacechar - parsers.newline
- - parsers.dquote - parsers.squote - parsers.backtick
- - parsers.equal - parsers.less - parsers.more)^1
-
-parsers.html_attribute_value_specification = parsers.optionalspace
- * parsers.equal
- * parsers.optionalspace
- * parsers.html_attribute_value
+ + (parsers.any
+ - parsers.spacechar
+ - parsers.newline
+ - parsers.dquote
+ - parsers.squote
+ - parsers.backtick
+ - parsers.equal
+ - parsers.less
+ - parsers.more)^1
+
+parsers.html_attribute_value_specification
+ = parsers.optionalspace
+ * parsers.equal
+ * parsers.optionalspace
+ * parsers.html_attribute_value
parsers.html_spnl = parsers.optionalspace
- * (V("NoSoftLineBreakEndline") * parsers.optionalspace)^-1
+ * (V("NoSoftLineBreakEndline")
+ * parsers.optionalspace)^-1
-parsers.html_inline_attribute_value_specification = parsers.html_spnl
- * parsers.equal
- * parsers.html_spnl
- * parsers.html_inline_attribute_value
+parsers.html_inline_attribute_value_specification
+ = parsers.html_spnl
+ * parsers.equal
+ * parsers.html_spnl
+ * parsers.html_inline_attribute_value
-parsers.html_attribute = parsers.html_attribute_spacing
- * parsers.html_attribute_name
- * parsers.html_inline_attribute_value_specification^-1
+parsers.html_attribute
+ = parsers.html_attribute_spacing
+ * parsers.html_attribute_name
+ * parsers.html_inline_attribute_value_specification^-1
-parsers.html_non_newline_attribute = parsers.spacechar^1
- * parsers.html_attribute_name
- * parsers.html_attribute_value_specification^-1
+parsers.html_non_newline_attribute
+ = parsers.spacechar^1
+ * parsers.html_attribute_name
+ * parsers.html_attribute_value_specification^-1
parsers.nested_breaking_blank = parsers.newline
* parsers.check_minimal_blank_indent
@@ -27365,49 +29010,59 @@ parsers.html_comment_start = P("<!--")
parsers.html_comment_end = P("-->")
-parsers.html_comment = Cs( parsers.html_comment_start
- * parsers.html_until_end(parsers.html_comment_end))
+parsers.html_comment
+ = Cs( parsers.html_comment_start
+ * parsers.html_until_end(parsers.html_comment_end))
parsers.html_inline_comment = (parsers.html_comment_start / "")
* -P(">") * -P("->")
- * Cs((V("NoSoftLineBreakEndline") + parsers.any
- - parsers.nested_breaking_blank - parsers.html_comment_end)^0)
+ * Cs(( V("NoSoftLineBreakEndline")
+ + parsers.any
+ - parsers.nested_breaking_blank
+ - parsers.html_comment_end)^0)
* (parsers.html_comment_end / "")
parsers.html_cdatasection_start = P("<![CDATA[")
parsers.html_cdatasection_end = P("]]>")
-parsers.html_cdatasection = Cs( parsers.html_cdatasection_start
- * parsers.html_until_end(parsers.html_cdatasection_end))
+parsers.html_cdatasection
+ = Cs( parsers.html_cdatasection_start
+ * parsers.html_until_end(parsers.html_cdatasection_end))
-parsers.html_inline_cdatasection = parsers.html_cdatasection_start
- * Cs(V("NoSoftLineBreakEndline") + parsers.any
- - parsers.nested_breaking_blank - parsers.html_cdatasection_end)^0
- * parsers.html_cdatasection_end
+parsers.html_inline_cdatasection
+ = parsers.html_cdatasection_start
+ * Cs(V("NoSoftLineBreakEndline") + parsers.any
+ - parsers.nested_breaking_blank - parsers.html_cdatasection_end)^0
+ * parsers.html_cdatasection_end
parsers.html_declaration_start = P("<!") * parsers.letter
parsers.html_declaration_end = P(">")
-parsers.html_declaration = Cs( parsers.html_declaration_start
- * parsers.html_until_end(parsers.html_declaration_end))
+parsers.html_declaration
+ = Cs( parsers.html_declaration_start
+ * parsers.html_until_end(parsers.html_declaration_end))
-parsers.html_inline_declaration = parsers.html_declaration_start
- * Cs(V("NoSoftLineBreakEndline") + parsers.any
- - parsers.nested_breaking_blank - parsers.html_declaration_end)^0
- * parsers.html_declaration_end
+parsers.html_inline_declaration
+ = parsers.html_declaration_start
+ * Cs(V("NoSoftLineBreakEndline") + parsers.any
+ - parsers.nested_breaking_blank - parsers.html_declaration_end)^0
+ * parsers.html_declaration_end
parsers.html_instruction_start = P("<?")
parsers.html_instruction_end = P("?>")
-parsers.html_instruction = Cs( parsers.html_instruction_start
- * parsers.html_until_end(parsers.html_instruction_end))
+parsers.html_instruction
+ = Cs( parsers.html_instruction_start
+ * parsers.html_until_end(parsers.html_instruction_end))
parsers.html_inline_instruction = parsers.html_instruction_start
- * Cs(V("NoSoftLineBreakEndline") + parsers.any
- - parsers.nested_breaking_blank - parsers.html_instruction_end)^0
+ * Cs( V("NoSoftLineBreakEndline")
+ + parsers.any
+ - parsers.nested_breaking_blank
+ - parsers.html_instruction_end)^0
* parsers.html_instruction_end
parsers.html_blankline = parsers.newline
@@ -27453,25 +29108,28 @@ parsers.incomplete_tag_following = parsers.spacechar
+ parsers.slash * parsers.more
+ #(parsers.newline + parsers.eof)
-parsers.incomplete_special_tag_following = parsers.spacechar
- + parsers.more
- + #(parsers.newline + parsers.eof)
+parsers.incomplete_special_tag_following = parsers.spacechar
+ + parsers.more
+ + #( parsers.newline
+ + parsers.eof)
parsers.html_incomplete_open_tag = parsers.html_tag_start
* parsers.block_keyword
* parsers.incomplete_tag_following
-parsers.html_incomplete_open_special_tag = parsers.html_tag_start
- * parsers.special_block_keyword
- * parsers.incomplete_special_tag_following
+parsers.html_incomplete_open_special_tag
+ = parsers.html_tag_start
+ * parsers.special_block_keyword
+ * parsers.incomplete_special_tag_following
parsers.html_incomplete_close_tag = parsers.html_tag_closing_start
* parsers.block_keyword
* parsers.incomplete_tag_following
-parsers.html_incomplete_close_special_tag = parsers.html_tag_closing_start
- * parsers.special_block_keyword
- * parsers.incomplete_tag_following
+parsers.html_incomplete_close_special_tag
+ = parsers.html_tag_closing_start
+ * parsers.special_block_keyword
+ * parsers.incomplete_tag_following
-- closing tags
parsers.html_close_tag = parsers.html_tag_closing_start
@@ -27509,27 +29167,33 @@ parsers.html_empty_special_tag = parsers.html_tag_start
* parsers.html_attribute^0
* parsers.html_empty_tag_end
-parsers.html_incomplete_blocks = parsers.html_incomplete_open_tag
- + parsers.html_incomplete_open_special_tag
- + parsers.html_incomplete_close_tag
+parsers.html_incomplete_blocks
+ = parsers.html_incomplete_open_tag
+ + parsers.html_incomplete_open_special_tag
+ + parsers.html_incomplete_close_tag
-- parse special html blocks
-parsers.html_blankline_ending_special_block_opening = (parsers.html_close_special_tag
- + parsers.html_empty_special_tag)
- * #(parsers.optionalspace
- * (parsers.newline + parsers.eof))
+parsers.html_blankline_ending_special_block_opening
+ = ( parsers.html_close_special_tag
+ + parsers.html_empty_special_tag)
+ * #( parsers.optionalspace
+ * (parsers.newline + parsers.eof))
-parsers.html_blankline_ending_special_block = parsers.html_blankline_ending_special_block_opening
- * parsers.html_blankline_end_condition
+parsers.html_blankline_ending_special_block
+ = parsers.html_blankline_ending_special_block_opening
+ * parsers.html_blankline_end_condition
-parsers.html_special_block_opening = parsers.html_incomplete_open_special_tag
- - parsers.html_empty_special_tag
+parsers.html_special_block_opening
+ = parsers.html_incomplete_open_special_tag
+ - parsers.html_empty_special_tag
-parsers.html_closing_special_block = parsers.html_special_block_opening
- * parsers.html_until_end(parsers.html_close_special_tag)
+parsers.html_closing_special_block
+ = parsers.html_special_block_opening
+ * parsers.html_until_end(parsers.html_close_special_tag)
-parsers.html_special_block = parsers.html_blankline_ending_special_block
- + parsers.html_closing_special_block
+parsers.html_special_block
+ = parsers.html_blankline_ending_special_block
+ + parsers.html_closing_special_block
-- parse html blocks
parsers.html_block_opening = parsers.html_incomplete_open_tag
@@ -27539,18 +29203,21 @@ parsers.html_block = parsers.html_block_opening
* parsers.html_blankline_end_condition
-- parse any html blocks
-parsers.html_any_block_opening = (parsers.html_any_open_tag
- + parsers.html_any_close_tag
- + parsers.html_any_empty_tag)
- * #(parsers.optionalspace * (parsers.newline + parsers.eof))
+parsers.html_any_block_opening
+ = ( parsers.html_any_open_tag
+ + parsers.html_any_close_tag
+ + parsers.html_any_empty_tag)
+ * #(parsers.optionalspace * (parsers.newline + parsers.eof))
parsers.html_any_block = parsers.html_any_block_opening
* parsers.html_blankline_end_condition
parsers.html_inline_comment_full = parsers.html_comment_start
* -P(">") * -P("->")
- * Cs((V("NoSoftLineBreakEndline") + parsers.any - P("--")
- - parsers.nested_breaking_blank - parsers.html_comment_end)^0)
+ * Cs(( V("NoSoftLineBreakEndline")
+ + parsers.any - P("--")
+ - parsers.nested_breaking_blank
+ - parsers.html_comment_end)^0)
* parsers.html_comment_end
parsers.html_inline_tags = parsers.html_inline_comment_full
@@ -27562,7 +29229,6 @@ parsers.html_inline_tags = parsers.html_inline_comment_full
+ parsers.html_any_close_tag
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Parsers Used for Markdown Tags and Links
@@ -27583,21 +29249,25 @@ parsers.auto_link_scheme = parsers.letter
* parsers.auto_link_scheme_part^-30
parsers.absolute_uri = parsers.auto_link_scheme * parsers.colon
- * (parsers.any - parsers.spacing - parsers.less - parsers.more)^0
+ * ( parsers.any - parsers.spacing
+ - parsers.less - parsers.more)^0
parsers.printable_characters = S(".!#$%&'*+/=?^_`{|}~-")
parsers.email_address_local_part_char = parsers.alphanumeric
+ parsers.printable_characters
-parsers.email_address_local_part = parsers.email_address_local_part_char^1
+parsers.email_address_local_part
+ = parsers.email_address_local_part_char^1
parsers.email_address_dns_label = parsers.alphanumeric
- * (parsers.alphanumeric + parsers.dash)^-62
+ * ( parsers.alphanumeric
+ + parsers.dash)^-62
* B(parsers.alphanumeric)
parsers.email_address_domain = parsers.email_address_dns_label
- * (parsers.period * parsers.email_address_dns_label)^0
+ * ( parsers.period
+ * parsers.email_address_dns_label)^0
parsers.email_address = parsers.email_address_local_part
* parsers.at
@@ -27653,25 +29323,37 @@ parsers.link_text = parsers.lbracket
+ parsers.autolink
+ V("InlineHtml")
+ ( parsers.backslash * parsers.backslash)
- + ( parsers.backslash * (parsers.lbracket + parsers.rbracket)
+ + ( parsers.backslash
+ * ( parsers.lbracket
+ + parsers.rbracket)
+ V("NoSoftLineBreakSpace")
+ V("NoSoftLineBreakEndline")
+ (parsers.any
- - (parsers.newline + parsers.lbracket + parsers.rbracket + parsers.blankline^2))))^0)
+ - ( parsers.newline
+ + parsers.lbracket
+ + parsers.rbracket
+ + parsers.blankline^2))))^0)
* parsers.rbracket
parsers.link_label_body = -#(parsers.sp * parsers.rbracket)
- * #((parsers.any - parsers.rbracket)^-999 * parsers.rbracket)
+ * #( ( parsers.any
+ - parsers.rbracket)^-999
+ * parsers.rbracket)
* Cs((parsers.alphanumeric^1
+ parsers.inticks
+ parsers.autolink
+ V("InlineHtml")
+ ( parsers.backslash * parsers.backslash)
- + ( parsers.backslash * (parsers.lbracket + parsers.rbracket)
+ + ( parsers.backslash
+ * ( parsers.lbracket
+ + parsers.rbracket)
+ V("NoSoftLineBreakSpace")
+ V("NoSoftLineBreakEndline")
+ (parsers.any
- - (parsers.newline + parsers.lbracket + parsers.rbracket + parsers.blankline^2))))^1)
+ - ( parsers.newline
+ + parsers.lbracket
+ + parsers.rbracket
+ + parsers.blankline^2))))^1)
parsers.link_label = parsers.lbracket
* parsers.link_label_body
@@ -27701,32 +29383,40 @@ parsers.title_s = parsers.squote
* Cs((parsers.html_entities
+ V("NoSoftLineBreakSpace")
+ V("NoSoftLineBreakEndline")
- + (parsers.anyescaped - parsers.newline - parsers.squote - parsers.blankline^2))^0)
+ + ( parsers.anyescaped
+ - parsers.newline
+ - parsers.squote
+ - parsers.blankline^2))^0)
* parsers.squote
parsers.title_d = parsers.dquote
* Cs((parsers.html_entities
+ V("NoSoftLineBreakSpace")
+ V("NoSoftLineBreakEndline")
- + (parsers.anyescaped - parsers.newline - parsers.dquote - parsers.blankline^2))^0)
+ + ( parsers.anyescaped
+ - parsers.newline
+ - parsers.dquote
+ - parsers.blankline^2))^0)
* parsers.dquote
parsers.title_p = parsers.lparent
* Cs((parsers.html_entities
+ V("NoSoftLineBreakSpace")
+ V("NoSoftLineBreakEndline")
- + (parsers.anyescaped - parsers.newline - parsers.lparent - parsers.rparent
+ + ( parsers.anyescaped
+ - parsers.newline
+ - parsers.lparent
+ - parsers.rparent
- parsers.blankline^2))^0)
* parsers.rparent
-parsers.title = parsers.title_d + parsers.title_s + parsers.title_p
+parsers.title
+ = parsers.title_d + parsers.title_s + parsers.title_p
parsers.optionaltitle
- = parsers.spnlc * parsers.title * parsers.spacechar^0
- + Cc("")
+ = parsers.spnlc * parsers.title * parsers.spacechar^0 + Cc("")
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Helpers for Links and Link Reference Definitions
@@ -27734,12 +29424,13 @@ parsers.optionaltitle
% \end{markdown}
% \begin{macrocode}
-- parse a reference definition: [foo]: /bar "title"
-parsers.define_reference_parser = (parsers.check_trail / "") * parsers.link_label * parsers.colon
+parsers.define_reference_parser = (parsers.check_trail / "")
+ * parsers.link_label * parsers.colon
* parsers.spnlc * parsers.url
- * ( parsers.spnlc_sep * parsers.title * parsers.only_blank
+ * ( parsers.spnlc_sep * parsers.title
+ * parsers.only_blank
+ Cc("") * parsers.only_blank)
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Inline Elements
@@ -27751,11 +29442,13 @@ parsers.Inline = V("Inline")
-- parse many p between starter and ender
parsers.between = function(p, starter, ender)
local ender2 = B(parsers.nonspacechar) * ender
- return (starter * #parsers.nonspacechar * Ct(p * (p - ender2)^0) * ender2)
+ return ( starter
+ * #parsers.nonspacechar
+ * Ct(p * (p - ender2)^0)
+ * ender2)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Block Elements
@@ -27763,7 +29456,8 @@ end
% \end{markdown}
% \begin{macrocode}
parsers.lineof = function(c)
- return (parsers.check_trail_no_rem * (P(c) * parsers.optionalspace)^3
+ return ( parsers.check_trail_no_rem
+ * (P(c) * parsers.optionalspace)^3
* (parsers.newline + parsers.eof))
end
@@ -27771,7 +29465,6 @@ parsers.thematic_break_lines = parsers.lineof(parsers.asterisk)
+ parsers.lineof(parsers.dash)
+ parsers.lineof(parsers.underscore)
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Headings
@@ -27783,8 +29476,11 @@ parsers.heading_start = #parsers.hash * C(parsers.hash^-6)
* -parsers.hash / length
-- parse setext header ending and return level
-parsers.heading_level = parsers.nonindentspace * parsers.equal^1 * parsers.optionalspace * #parsers.newline * Cc(1)
- + parsers.nonindentspace * parsers.dash^1 * parsers.optionalspace * #parsers.newline * Cc(2)
+parsers.heading_level
+ = parsers.nonindentspace * parsers.equal^1
+ * parsers.optionalspace * #parsers.newline * Cc(1)
+ + parsers.nonindentspace * parsers.dash^1
+ * parsers.optionalspace * #parsers.newline * Cc(2)
local function strip_atx_end(s)
return s:gsub("%s+#*%s*\n$","")
@@ -27799,7 +29495,6 @@ parsers.atx_heading = parsers.check_trail_no_rem
+ parsers.spacechar^1
* C(parsers.line))
% \end{macrocode}
-% \par
% \begin{markdown}
%
%### Markdown Reader {#markdown-reader}
@@ -27825,7 +29520,6 @@ M.reader = {}
function M.reader.new(writer, options)
local self = {}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Make the `writer` and `options` parameters available as
@@ -27837,7 +29531,6 @@ function M.reader.new(writer, options)
self.writer = writer
self.options = options
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Create a \luamdef{reader->parsers} hash table that stores \acro{peg} patterns
@@ -27865,7 +29558,6 @@ function M.reader.new(writer, options)
% \begin{macrocode}
local parsers = self.parsers
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Top-Level Helper Functions
@@ -27883,7 +29575,6 @@ function M.reader.new(writer, options)
return tag
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{iterlines} as a function that iterates over the lines of
@@ -27897,7 +29588,6 @@ function M.reader.new(writer, options)
return util.rope_to_string(rope)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{expandtabs} either as an identity function, when the
@@ -27918,7 +29608,6 @@ function M.reader.new(writer, options)
end
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### High-Level Parser Functions
@@ -27936,7 +29625,6 @@ function M.reader.new(writer, options)
self.create_parser = function(name, grammar, toplevel)
self.parser_functions[name] = function(str)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% If the parser function is top-level and the \Opt{stripIndent} Lua option is
@@ -27956,16 +29644,17 @@ function M.reader.new(writer, options)
local prefix = lpeg.match(C(parsers.optionalspace), line)
local prefix_length = #prefix
local is_shorter = min_prefix_length == nil
- is_shorter = is_shorter or prefix_length < min_prefix_length
+ if not is_shorter then
+ is_shorter = prefix_length < min_prefix_length
+ end
if is_shorter then
- min_prefix_length, min_prefix = prefix_length, prefix
+ min_prefix_length, min_prefix = prefix_length, prefix
end
return line
end)
str = str:gsub('^' .. min_prefix, '')
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% If the parser is top-level and the \Opt{texComments} or \Opt{hybrid} Lua
@@ -27980,7 +29669,11 @@ function M.reader.new(writer, options)
end
local res = lpeg.match(grammar(), str)
if res == nil then
- error(format("%s failed on:\n%s", name, str:sub(1,20)))
+ return writer.error(
+ format("Parser `%s` failed to process the input text.", name),
+ format("Here are the first 20 characters of the remaining "
+ .. "unprocessed text: `%s`.", str:sub(1,20))
+ )
else
return res
end
@@ -28021,7 +29714,6 @@ function M.reader.new(writer, options)
return parsers.inlines_no_link_or_emphasis
end, false)
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Parsers Used for Indentation (local)
@@ -28030,35 +29722,47 @@ function M.reader.new(writer, options)
%
% \end{markdown}
% \begin{macrocode}
- parsers.minimally_indented_blankline = parsers.check_minimal_indent * (parsers.blankline / "")
+ parsers.minimally_indented_blankline
+ = parsers.check_minimal_indent * (parsers.blankline / "")
- parsers.minimally_indented_block = parsers.check_minimal_indent * V("Block")
+ parsers.minimally_indented_block
+ = parsers.check_minimal_indent * V("Block")
- parsers.minimally_indented_block_or_paragraph = parsers.check_minimal_indent * V("BlockOrParagraph")
+ parsers.minimally_indented_block_or_paragraph
+ = parsers.check_minimal_indent * V("BlockOrParagraph")
- parsers.minimally_indented_paragraph = parsers.check_minimal_indent * V("Paragraph")
+ parsers.minimally_indented_paragraph
+ = parsers.check_minimal_indent * V("Paragraph")
- parsers.minimally_indented_plain = parsers.check_minimal_indent * V("Plain")
+ parsers.minimally_indented_plain
+ = parsers.check_minimal_indent * V("Plain")
- parsers.minimally_indented_par_or_plain = parsers.minimally_indented_paragraph
- + parsers.minimally_indented_plain
+ parsers.minimally_indented_par_or_plain
+ = parsers.minimally_indented_paragraph
+ + parsers.minimally_indented_plain
- parsers.minimally_indented_par_or_plain_no_blank = parsers.minimally_indented_par_or_plain
- - parsers.minimally_indented_blankline
+ parsers.minimally_indented_par_or_plain_no_blank
+ = parsers.minimally_indented_par_or_plain
+ - parsers.minimally_indented_blankline
- parsers.minimally_indented_ref = parsers.check_minimal_indent * V("Reference")
+ parsers.minimally_indented_ref
+ = parsers.check_minimal_indent * V("Reference")
- parsers.minimally_indented_blank = parsers.check_minimal_indent * V("Blank")
+ parsers.minimally_indented_blank
+ = parsers.check_minimal_indent * V("Blank")
- parsers.conditionally_indented_blankline = parsers.check_minimal_blank_indent * (parsers.blankline / "")
+ parsers.conditionally_indented_blankline
+ = parsers.check_minimal_blank_indent * (parsers.blankline / "")
- parsers.minimally_indented_ref_or_block = parsers.minimally_indented_ref
- + parsers.minimally_indented_block
- - parsers.minimally_indented_blankline
+ parsers.minimally_indented_ref_or_block
+ = parsers.minimally_indented_ref
+ + parsers.minimally_indented_block
+ - parsers.minimally_indented_blankline
- parsers.minimally_indented_ref_or_block_or_par = parsers.minimally_indented_ref
- + parsers.minimally_indented_block_or_paragraph
- - parsers.minimally_indented_blankline
+ parsers.minimally_indented_ref_or_block_or_par
+ = parsers.minimally_indented_ref
+ + parsers.minimally_indented_block_or_paragraph
+ - parsers.minimally_indented_blankline
% \end{macrocode}
% \begin{markdown}
@@ -28068,7 +29772,8 @@ function M.reader.new(writer, options)
% \end{markdown}
% \begin{macrocode}
- parsers.separator_loop = function(separated_block, paragraph, block_separator, paragraph_separator)
+ function parsers.separator_loop(separated_block, paragraph,
+ block_separator, paragraph_separator)
return separated_block
+ block_separator
* paragraph
@@ -28077,10 +29782,14 @@ function M.reader.new(writer, options)
* paragraph
end
- parsers.create_loop_body_pair = function(separated_block, paragraph, block_separator, paragraph_separator)
+ function parsers.create_loop_body_pair(separated_block, paragraph,
+ block_separator,
+ paragraph_separator)
return {
- block = parsers.separator_loop(separated_block, paragraph, block_separator, block_separator),
- par = parsers.separator_loop(separated_block, paragraph, block_separator, paragraph_separator)
+ block = parsers.separator_loop(separated_block, paragraph,
+ block_separator, block_separator),
+ par = parsers.separator_loop(separated_block, paragraph,
+ block_separator, paragraph_separator)
}
end
@@ -28103,18 +29812,20 @@ function M.reader.new(writer, options)
parsers.content_blank = parsers.minimally_indented_blankline
- parsers.ref_or_block_separated = parsers.sep_group_no_output(parsers.content_blank)
- * ( parsers.minimally_indented_ref
- - parsers.content_blank)
- + parsers.block_sep_group(parsers.content_blank)
- * ( parsers.minimally_indented_block
- - parsers.content_blank)
+ parsers.ref_or_block_separated
+ = parsers.sep_group_no_output(parsers.content_blank)
+ * ( parsers.minimally_indented_ref
+ - parsers.content_blank)
+ + parsers.block_sep_group(parsers.content_blank)
+ * ( parsers.minimally_indented_block
+ - parsers.content_blank)
parsers.loop_body_pair =
- parsers.create_loop_body_pair(parsers.ref_or_block_separated,
- parsers.minimally_indented_par_or_plain_no_blank,
- parsers.block_sep_group(parsers.content_blank),
- parsers.par_sep_group(parsers.content_blank))
+ parsers.create_loop_body_pair(
+ parsers.ref_or_block_separated,
+ parsers.minimally_indented_par_or_plain_no_blank,
+ parsers.block_sep_group(parsers.content_blank),
+ parsers.par_sep_group(parsers.content_blank))
parsers.content_loop = ( V("Block")
* parsers.loop_body_pair.block^0
@@ -28138,14 +29849,14 @@ function M.reader.new(writer, options)
parsers.add_indent = function(pattern, name, breakable)
return Cg(Cmt( Cb("indent_info")
* Ct(pattern)
- * (#parsers.linechar * Cc(false) + Cc(true)) -- check if starter is blank
+ * ( #parsers.linechar -- check if starter is blank
+ * Cc(false) + Cc(true))
* Cc(name)
* Cc(breakable),
process_starter_indent), "indent_info")
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Parsers Used for Markdown Lists (local)
@@ -28166,7 +29877,8 @@ function M.reader.new(writer, options)
allowed_end = C(parsers.spacechar^1) * #parsers.linechar
else
delimiter_range = parsers.dig * parsers.dig^-8
- allowed_end = C(parsers.spacechar^1) + #(parsers.newline + parsers.eof)
+ allowed_end = C(parsers.spacechar^1)
+ + #(parsers.newline + parsers.eof)
end
return parsers.check_trail
@@ -28181,26 +29893,29 @@ function M.reader.new(writer, options)
+ parsers.enumerator(parsers.rparent)
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Parsers Used for Blockquotes (local)
%
% \end{markdown}
% \begin{macrocode}
- parsers.blockquote_start = parsers.check_trail * C(parsers.more) * C(parsers.spacechar^0)
+ parsers.blockquote_start
+ = parsers.check_trail
+ * C(parsers.more)
+ * C(parsers.spacechar^0)
- parsers.blockquote_body = parsers.add_indent(parsers.blockquote_start, "bq", true)
- * parsers.indented_content()
- * remove_indent("bq")
+ parsers.blockquote_body
+ = parsers.add_indent(parsers.blockquote_start, "bq", true)
+ * parsers.indented_content()
+ * remove_indent("bq")
if not options.breakableBlockquotes then
- parsers.blockquote_body = parsers.add_indent(parsers.blockquote_start, "bq", false)
- * parsers.indented_content()
- * remove_indent("bq")
+ parsers.blockquote_body
+ = parsers.add_indent(parsers.blockquote_start, "bq", false)
+ * parsers.indented_content()
+ * remove_indent("bq")
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Helpers for Emphasis and Strong Emphasis (local)
@@ -28211,7 +29926,8 @@ function M.reader.new(writer, options)
% \begin{macrocode}
local function parse_content_part(content_part)
local rope = util.rope_to_string(content_part)
- local parsed = self.parser_functions.parse_inlines_no_link_or_emphasis(rope)
+ local parsed
+ = self.parser_functions.parse_inlines_no_link_or_emphasis(rope)
parsed.indent_info = nil
return parsed
end
@@ -28223,37 +29939,40 @@ function M.reader.new(writer, options)
%
% \end{markdown}
% \begin{macrocode}
- local function collect_emphasis_content(t, opening_index, closing_index)
- local content = {}
+ local collect_emphasis_content =
+ function(t, opening_index, closing_index)
+ local content = {}
- local content_part = {}
- for i = opening_index, closing_index do
- local value = t[i]
+ local content_part = {}
+ for i = opening_index, closing_index do
+ local value = t[i]
- if value.rendered ~= nil then
- content[#content + 1] = parse_content_part(content_part)
- content_part = {}
- content[#content + 1] = value.rendered
- value.rendered = nil
- else
- if value.type == "delimiter" and value.element == "emphasis" then
- if value.is_active then
- content_part[#content_part + 1] = string.rep(value.character, value.current_count)
- end
+ if value.rendered ~= nil then
+ content[#content + 1] = parse_content_part(content_part)
+ content_part = {}
+ content[#content + 1] = value.rendered
+ value.rendered = nil
else
- content_part[#content_part + 1] = value.content
+ if value.type == "delimiter"
+ and value.element == "emphasis" then
+ if value.is_active then
+ content_part[#content_part + 1]
+ = string.rep(value.character, value.current_count)
+ end
+ else
+ content_part[#content_part + 1] = value.content
+ end
+ value.content = ''
+ value.is_active = false
end
- value.content = ''
- value.is_active = false
end
- end
- if next(content_part) ~= nil then
- content[#content + 1] = parse_content_part(content_part)
- end
+ if next(content_part) ~= nil then
+ content[#content + 1] = parse_content_part(content_part)
+ end
- return content
- end
+ return content
+ end
% \end{macrocode}
% \begin{markdown}
@@ -28264,7 +29983,9 @@ function M.reader.new(writer, options)
% \end{markdown}
% \begin{macrocode}
local function fill_emph(t, opening_index, closing_index)
- local content = collect_emphasis_content(t, opening_index + 1, closing_index - 1)
+ local content
+ = collect_emphasis_content(t, opening_index + 1,
+ closing_index - 1)
t[opening_index + 1].is_active = true
t[opening_index + 1].rendered = writer.emphasis(content)
end
@@ -28278,7 +29999,9 @@ function M.reader.new(writer, options)
% \end{markdown}
% \begin{macrocode}
local function fill_strong(t, opening_index, closing_index)
- local content = collect_emphasis_content(t, opening_index + 1, closing_index - 1)
+ local content
+ = collect_emphasis_content(t, opening_index + 1,
+ closing_index - 1)
t[opening_index + 1].is_active = true
t[opening_index + 1].rendered = writer.strong(content)
end
@@ -28292,9 +30015,12 @@ function M.reader.new(writer, options)
% \end{markdown}
% \begin{macrocode}
local function breaks_three_rule(opening_delimiter, closing_delimiter)
- return (opening_delimiter.is_closing or closing_delimiter.is_opening) and
- ((opening_delimiter.original_count + closing_delimiter.original_count) % 3 == 0) and
- (opening_delimiter.original_count % 3 ~= 0 or closing_delimiter.original_count % 3 ~= 0)
+ return ( opening_delimiter.is_closing
+ or closing_delimiter.is_opening)
+ and (( opening_delimiter.original_count
+ + closing_delimiter.original_count) % 3 == 0)
+ and ( opening_delimiter.original_count % 3 ~= 0
+ or closing_delimiter.original_count % 3 ~= 0)
end
% \end{macrocode}
@@ -28306,7 +30032,8 @@ function M.reader.new(writer, options)
%
% \end{markdown}
% \begin{macrocode}
- local function find_emphasis_opener(t, bottom_index, latest_index, character, closing_delimiter)
+ local find_emphasis_opener = function(t, bottom_index, latest_index,
+ character, closing_delimiter)
for i = latest_index, bottom_index, -1 do
local value = t[i]
if value.is_active and
@@ -28370,12 +30097,18 @@ function M.reader.new(writer, options)
local is_opening = value.is_opening
local closing_length_modulo_three = value.original_count % 3
- local current_openers_bottom = openers_bottom[character][is_opening][closing_length_modulo_three + 1]
+ local current_openers_bottom
+ = openers_bottom[character][is_opening]
+ [closing_length_modulo_three + 1]
- local opener_position = find_emphasis_opener(t, current_openers_bottom, current_position - 1, character, value)
+ local opener_position
+ = find_emphasis_opener(t, current_openers_bottom,
+ current_position - 1, character, value)
if (opener_position == nil) then
- openers_bottom[character][is_opening][closing_length_modulo_three + 1] = current_position
+ openers_bottom[character][is_opening]
+ [closing_length_modulo_three + 1]
+ = current_position
current_position = current_position + 1
goto continue
end
@@ -28385,7 +30118,8 @@ function M.reader.new(writer, options)
local current_opening_count = opening_delimiter.current_count
local current_closing_count = t[current_position].current_count
- if (current_opening_count >= 2) and (current_closing_count >= 2) then
+ if (current_opening_count >= 2)
+ and (current_closing_count >= 2) then
opening_delimiter.current_count = current_opening_count - 2
t[current_position].current_count = current_closing_count - 2
fill_strong(t, opener_position, current_position)
@@ -28469,15 +30203,19 @@ function M.reader.new(writer, options)
return check_unicode_type(s, i, 0, 3, "%s")
end
- parsers.unicode_preceding_punctuation = B(parsers.escapable)
- + Cmt(parsers.succeed, check_preceding_unicode_punctuation)
+ parsers.unicode_preceding_punctuation
+ = B(parsers.escapable)
+ + Cmt(parsers.succeed, check_preceding_unicode_punctuation)
- parsers.unicode_preceding_whitespace = Cmt(parsers.succeed, check_preceding_unicode_whitespace)
+ parsers.unicode_preceding_whitespace
+ = Cmt(parsers.succeed, check_preceding_unicode_whitespace)
- parsers.unicode_following_punctuation = #parsers.escapable
- + Cmt(parsers.succeed, check_following_unicode_punctuation)
+ parsers.unicode_following_punctuation
+ = #parsers.escapable
+ + Cmt(parsers.succeed, check_following_unicode_punctuation)
- parsers.unicode_following_whitespace = Cmt(parsers.succeed, check_following_unicode_whitespace)
+ parsers.unicode_following_whitespace
+ = Cmt(parsers.succeed, check_following_unicode_whitespace)
parsers.delimiter_run = function(character)
return (B(parsers.backslash * character) + -B(character))
@@ -28487,49 +30225,58 @@ function M.reader.new(writer, options)
parsers.left_flanking_delimiter_run = function(character)
return (B( parsers.any)
- * (parsers.unicode_preceding_punctuation + parsers.unicode_preceding_whitespace)
+ * ( parsers.unicode_preceding_punctuation
+ + parsers.unicode_preceding_whitespace)
+ -B(parsers.any))
* parsers.delimiter_run(character)
* parsers.unicode_following_punctuation
+ parsers.delimiter_run(character)
- * -#(parsers.unicode_following_punctuation + parsers.unicode_following_whitespace
+ * -#( parsers.unicode_following_punctuation
+ + parsers.unicode_following_whitespace
+ parsers.eof)
end
parsers.right_flanking_delimiter_run = function(character)
return parsers.unicode_preceding_punctuation
* parsers.delimiter_run(character)
- * (parsers.unicode_following_punctuation + parsers.unicode_following_whitespace
+ * ( parsers.unicode_following_punctuation
+ + parsers.unicode_following_whitespace
+ parsers.eof)
+ (B(parsers.any)
- * -(parsers.unicode_preceding_punctuation + parsers.unicode_preceding_whitespace))
+ * -( parsers.unicode_preceding_punctuation
+ + parsers.unicode_preceding_whitespace))
* parsers.delimiter_run(character)
end
if options.underscores then
- parsers.emph_start = parsers.left_flanking_delimiter_run(parsers.asterisk)
- + (-#parsers.right_flanking_delimiter_run(parsers.underscore)
- + (parsers.unicode_preceding_punctuation
- * #parsers.right_flanking_delimiter_run(parsers.underscore)))
- * parsers.left_flanking_delimiter_run(parsers.underscore)
-
- parsers.emph_end = parsers.right_flanking_delimiter_run(parsers.asterisk)
- + (-#parsers.left_flanking_delimiter_run(parsers.underscore)
- + #(parsers.left_flanking_delimiter_run(parsers.underscore)
- * parsers.unicode_following_punctuation))
- * parsers.right_flanking_delimiter_run(parsers.underscore)
+ parsers.emph_start
+ = parsers.left_flanking_delimiter_run(parsers.asterisk)
+ + ( -#parsers.right_flanking_delimiter_run(parsers.underscore)
+ + ( parsers.unicode_preceding_punctuation
+ * #parsers.right_flanking_delimiter_run(parsers.underscore)))
+ * parsers.left_flanking_delimiter_run(parsers.underscore)
+
+ parsers.emph_end
+ = parsers.right_flanking_delimiter_run(parsers.asterisk)
+ + ( -#parsers.left_flanking_delimiter_run(parsers.underscore)
+ + #( parsers.left_flanking_delimiter_run(parsers.underscore)
+ * parsers.unicode_following_punctuation))
+ * parsers.right_flanking_delimiter_run(parsers.underscore)
else
- parsers.emph_start = parsers.left_flanking_delimiter_run(parsers.asterisk)
+ parsers.emph_start
+ = parsers.left_flanking_delimiter_run(parsers.asterisk)
- parsers.emph_end = parsers.right_flanking_delimiter_run(parsers.asterisk)
+ parsers.emph_end
+ = parsers.right_flanking_delimiter_run(parsers.asterisk)
end
- parsers.emph_capturing_open_and_close = #parsers.emph_start * #parsers.emph_end
- * Ct( Cg(Cc("delimiter"), "type")
- * Cg(Cc("emphasis"), "element")
- * Cg(C(parsers.emph_start), "content")
- * Cg(Cc(true), "is_opening")
- * Cg(Cc(true), "is_closing"))
+ parsers.emph_capturing_open_and_close
+ = #parsers.emph_start * #parsers.emph_end
+ * Ct( Cg(Cc("delimiter"), "type")
+ * Cg(Cc("emphasis"), "element")
+ * Cg(C(parsers.emph_start), "content")
+ * Cg(Cc(true), "is_opening")
+ * Cg(Cc(true), "is_closing"))
parsers.emph_capturing_open = Ct( Cg(Cc("delimiter"), "type")
* Cg(Cc("emphasis"), "element")
@@ -28554,7 +30301,6 @@ function M.reader.new(writer, options)
+ parsers.emph_capturing_close
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Helpers for Links and Link Reference Definitions (local)
@@ -28568,7 +30314,6 @@ function M.reader.new(writer, options)
parsers.rawnotes = {}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{reader->register_link} method registers
@@ -28592,7 +30337,6 @@ function M.reader.new(writer, options)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{reader->lookup_reference} method looks up a
@@ -28605,7 +30349,6 @@ function M.reader.new(writer, options)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{reader->lookup_note_reference} method looks up a
@@ -28619,17 +30362,24 @@ function M.reader.new(writer, options)
parsers.title_s_direct_ref = parsers.squote
* Cs((parsers.html_entities
- + (parsers.anyescaped - parsers.squote - parsers.blankline^2))^0)
+ + ( parsers.anyescaped
+ - parsers.squote
+ - parsers.blankline^2))^0)
* parsers.squote
parsers.title_d_direct_ref = parsers.dquote
* Cs((parsers.html_entities
- + (parsers.anyescaped - parsers.dquote - parsers.blankline^2))^0)
+ + ( parsers.anyescaped
+ - parsers.dquote
+ - parsers.blankline^2))^0)
* parsers.dquote
parsers.title_p_direct_ref = parsers.lparent
* Cs((parsers.html_entities
- + (parsers.anyescaped - parsers.lparent - parsers.rparent - parsers.blankline^2))^0)
+ + ( parsers.anyescaped
+ - parsers.lparent
+ - parsers.rparent
+ - parsers.blankline^2))^0)
* parsers.rparent
parsers.title_direct_ref = parsers.title_s_direct_ref
@@ -28639,7 +30389,8 @@ function M.reader.new(writer, options)
parsers.inline_direct_ref_inside = parsers.lparent * parsers.spnl
* Cg(parsers.url + Cc(""), "url")
* parsers.spnl
- * Cg(parsers.title_direct_ref + Cc(""), "title")
+ * Cg( parsers.title_direct_ref
+ + Cc(""), "title")
* parsers.spnl * parsers.rparent
parsers.inline_direct_ref = parsers.lparent * parsers.spnlc
@@ -28667,7 +30418,8 @@ function M.reader.new(writer, options)
* Cg(Cc("inline"), "link_type")
+ #(parsers.exclamation * parsers.full_link)
* Cg(Cc("full"), "link_type")
- + #(parsers.exclamation * parsers.collapsed_link)
+ + #( parsers.exclamation
+ * parsers.collapsed_link)
* Cg(Cc("collapsed"), "link_type")
+ #(parsers.exclamation * parsers.shortcut_link)
* Cg(Cc("shortcut"), "link_type")
@@ -28687,7 +30439,7 @@ function M.reader.new(writer, options)
+ #parsers.link_text
* Cg(Cc("link_text"), "link_type")
- parsers.note_opening = #(parsers.circumflex * parsers.shortcut_link)
+ parsers.note_opening = #(parsers.circumflex * parsers.link_text)
* Cg(Cc("note_inline"), "link_type")
parsers.raw_note_opening = #( parsers.lbracket
@@ -28698,15 +30450,18 @@ function M.reader.new(writer, options)
local inline_note_element = Cg(Cc("note"), "element")
* parsers.note_opening
- * Cg(parsers.circumflex * parsers.lbracket, "content")
+ * Cg( parsers.circumflex
+ * parsers.lbracket, "content")
local image_element = Cg(Cc("image"), "element")
* parsers.image_opening
- * Cg(parsers.exclamation * parsers.lbracket, "content")
+ * Cg( parsers.exclamation
+ * parsers.lbracket, "content")
local note_element = Cg(Cc("note"), "element")
* parsers.raw_note_opening
- * Cg(parsers.lbracket * parsers.circumflex, "content")
+ * Cg( parsers.lbracket
+ * parsers.circumflex, "content")
local link_element = Cg(Cc("link"), "element")
* parsers.link_opening
@@ -28736,7 +30491,9 @@ function M.reader.new(writer, options)
* Cg(Cc(false), "is_opening")
* Cg(Cc(true), "is_closing")
* ( Cg(Cc(true), "is_direct")
- * Cg(parsers.rbracket * #parsers.inline_direct_ref, "content")
+ * Cg( parsers.rbracket
+ * #parsers.inline_direct_ref,
+ "content")
+ Cg(Cc(false), "is_direct")
* Cg(parsers.rbracket, "content")))
@@ -28757,22 +30514,24 @@ function M.reader.new(writer, options)
* -V("EndlineExceptions")
+ parsers.check_optional_indent
* -V("EndlineExceptions")
- * -parsers.starter) / "")
+ * -V("ListStarter")) / "")
* parsers.spacechar^0 / "\n"
- parsers.link_and_emph_content = Ct( Cg(Cc("content"), "type")
- * Cg(Cs(( parsers.link_emph_precedence
- + parsers.backslash * parsers.any
- + parsers.link_and_emph_endline
- + (parsers.linechar
- - parsers.blankline^2
- - parsers.link_image_open_or_close
- - parsers.emph_open_or_close))^0), "content"))
+ parsers.link_and_emph_content
+ = Ct( Cg(Cc("content"), "type")
+ * Cg(Cs(( parsers.link_emph_precedence
+ + parsers.backslash * parsers.linechar
+ + parsers.link_and_emph_endline
+ + (parsers.linechar
+ - parsers.blankline^2
+ - parsers.link_image_open_or_close
+ - parsers.emph_open_or_close))^0), "content"))
- parsers.link_and_emph_table = (parsers.link_image_opening + parsers.emph_open)
- * parsers.link_and_emph_content
- * ((parsers.link_image_open_or_close + parsers.emph_open_or_close)
- * parsers.link_and_emph_content)^1
+ parsers.link_and_emph_table
+ = (parsers.link_image_opening + parsers.emph_open)
+ * parsers.link_and_emph_content
+ * ((parsers.link_image_open_or_close + parsers.emph_open_or_close)
+ * parsers.link_and_emph_content)^1
% \end{macrocode}
% \begin{markdown}
@@ -28802,7 +30561,9 @@ function M.reader.new(writer, options)
local value = t[i]
if value.type == "delimiter" and
value.is_opening and
- (value.element == "link" or value.element == "image" or value.element == "note")
+ ( value.element == "link"
+ or value.element == "image"
+ or value.element == "note")
and not value.removed then
if value.is_active then
return i
@@ -28883,11 +30644,12 @@ function M.reader.new(writer, options)
%
% \end{markdown}
% \begin{macrocode}
- local function delete_parsed_content_in_range(t, opening_index, closing_index)
- for i = opening_index, closing_index do
- t[i].rendered = nil
+ local delete_parsed_content_in_range =
+ function(t, opening_index, closing_index)
+ for i = opening_index, closing_index do
+ t[i].rendered = nil
+ end
end
- end
% \end{macrocode}
% \begin{markdown}
@@ -28932,34 +30694,40 @@ function M.reader.new(writer, options)
%
% \end{markdown}
% \begin{macrocode}
- local function render_link_or_image(t, opening_index, closing_index, content_end_index, reference)
- process_emphasis(t, opening_index, content_end_index)
- local mapped = collect_emphasis_content(t, opening_index + 1, content_end_index - 1)
-
- local rendered = {}
- if (t[opening_index].element == "link") then
- rendered = writer.link(mapped, reference.url, reference.title, reference.attributes)
- end
+ local render_link_or_image =
+ function(t, opening_index, closing_index, content_end_index,
+ reference)
+ process_emphasis(t, opening_index, content_end_index)
+ local mapped = collect_emphasis_content(t, opening_index + 1,
+ content_end_index - 1)
- if (t[opening_index].element == "image") then
- rendered = writer.image(mapped, reference.url, reference.title, reference.attributes)
- end
+ local rendered = {}
+ if (t[opening_index].element == "link") then
+ rendered = writer.link(mapped, reference.url,
+ reference.title, reference.attributes)
+ end
- if (t[opening_index].element == "note") then
- if (t[opening_index].link_type == "note_inline") then
- rendered = writer.note(mapped)
+ if (t[opening_index].element == "image") then
+ rendered = writer.image(mapped, reference.url, reference.title,
+ reference.attributes)
end
- if (t[opening_index].link_type == "raw_note") then
- rendered = writer.note(reference)
+
+ if (t[opening_index].element == "note") then
+ if (t[opening_index].link_type == "note_inline") then
+ rendered = writer.note(mapped)
+ end
+ if (t[opening_index].link_type == "raw_note") then
+ rendered = writer.note(reference)
+ end
end
- end
- t[opening_index].rendered = rendered
- delete_parsed_content_in_range(t, opening_index + 1, closing_index)
- empty_content_in_range(t, opening_index, closing_index)
- disable_previous_link_openers(t, opening_index)
- disable_range(t, opening_index, closing_index)
- end
+ t[opening_index].rendered = rendered
+ delete_parsed_content_in_range(t, opening_index + 1,
+ closing_index)
+ empty_content_in_range(t, opening_index, closing_index)
+ disable_previous_link_openers(t, opening_index)
+ disable_range(t, opening_index, closing_index)
+ end
% \end{macrocode}
% \begin{markdown}
@@ -28970,52 +30738,56 @@ function M.reader.new(writer, options)
%
% \end{markdown}
% \begin{macrocode}
- local function resolve_inline_following_content(t, closing_index, match_reference, match_link_attributes)
- local content = ""
- for i = closing_index + 1, #t do
- content = content .. t[i].content
- end
+ local resolve_inline_following_content =
+ function(t, closing_index, match_reference, match_link_attributes)
+ local content = ""
+ for i = closing_index + 1, #t do
+ content = content .. t[i].content
+ end
- local matching_content = parsers.succeed
+ local matching_content = parsers.succeed
- if match_reference then
- matching_content = matching_content * parsers.inline_direct_ref_inside
- end
+ if match_reference then
+ matching_content = matching_content
+ * parsers.inline_direct_ref_inside
+ end
- if match_link_attributes then
- matching_content = matching_content * Cg(Ct(parsers.attributes^-1), "attributes")
- end
+ if match_link_attributes then
+ matching_content = matching_content
+ * Cg(Ct(parsers.attributes^-1), "attributes")
+ end
- local matched = lpeg.match(Ct(matching_content * Cg(Cp(), "end_position")), content)
+ local matched = lpeg.match(Ct( matching_content
+ * Cg(Cp(), "end_position")), content)
- local matched_count = matched.end_position - 1
- for i = closing_index + 1, #t do
- local value = t[i]
+ local matched_count = matched.end_position - 1
+ for i = closing_index + 1, #t do
+ local value = t[i]
- local chars_left = matched_count
- matched_count = matched_count - #value.content
+ local chars_left = matched_count
+ matched_count = matched_count - #value.content
- if matched_count <= 0 then
- value.content = value.content:sub(chars_left + 1)
- break
+ if matched_count <= 0 then
+ value.content = value.content:sub(chars_left + 1)
+ break
+ end
+
+ value.content = ''
+ value.is_active = false
end
- value.content = ''
- value.is_active = false
- end
+ local attributes = matched.attributes
+ if attributes == nil or next(attributes) == nil then
+ attributes = nil
+ end
- local attributes = matched.attributes
- if attributes == nil or next(attributes) == nil then
- attributes = nil
+ return {
+ url = matched.url or "",
+ title = matched.title or "",
+ attributes = attributes
+ }
end
- return {
- url = matched.url or "",
- title = matched.title or "",
- attributes = attributes
- }
- end
-
% \end{macrocode}
% \begin{markdown}
%
@@ -29025,8 +30797,11 @@ function M.reader.new(writer, options)
% \end{markdown}
% \begin{macrocode}
local function resolve_inline_link(t, opening_index, closing_index)
- local inline_content = resolve_inline_following_content(t, closing_index, true, t.match_link_attributes)
- render_link_or_image(t, opening_index, closing_index, closing_index, inline_content)
+ local inline_content
+ = resolve_inline_following_content(t, closing_index, true,
+ t.match_link_attributes)
+ render_link_or_image(t, opening_index, closing_index,
+ closing_index, inline_content)
end
% \end{macrocode}
@@ -29037,10 +30812,14 @@ function M.reader.new(writer, options)
%
% \end{markdown}
% \begin{macrocode}
- local function resolve_note_inline_link(t, opening_index, closing_index)
- local inline_content = resolve_inline_following_content(t, closing_index, false, false)
- render_link_or_image(t, opening_index, closing_index, closing_index, inline_content)
- end
+ local resolve_note_inline_link =
+ function(t, opening_index, closing_index)
+ local inline_content
+ = resolve_inline_following_content(t, closing_index,
+ false, false)
+ render_link_or_image(t, opening_index, closing_index,
+ closing_index, inline_content)
+ end
% \end{macrocode}
% \begin{markdown}
@@ -29051,13 +30830,18 @@ function M.reader.new(writer, options)
% \end{markdown}
% \begin{macrocode}
local function resolve_shortcut_link(t, opening_index, closing_index)
- local content = collect_link_content(t, opening_index + 1, closing_index - 1)
+ local content
+ = collect_link_content(t, opening_index + 1, closing_index - 1)
local r = self.lookup_reference(content)
if r then
- local inline_content = resolve_inline_following_content(t, closing_index, false, t.match_link_attributes)
- r.attributes = join_attributes(r.attributes, inline_content.attributes)
- render_link_or_image(t, opening_index, closing_index, closing_index, r)
+ local inline_content
+ = resolve_inline_following_content(t, closing_index, false,
+ t.match_link_attributes)
+ r.attributes
+ = join_attributes(r.attributes, inline_content.attributes)
+ render_link_or_image(t, opening_index, closing_index,
+ closing_index, r)
end
end
@@ -29070,12 +30854,14 @@ function M.reader.new(writer, options)
% \end{markdown}
% \begin{macrocode}
local function resolve_raw_note_link(t, opening_index, closing_index)
- local content = collect_link_content(t, opening_index + 1, closing_index - 1)
+ local content
+ = collect_link_content(t, opening_index + 1, closing_index - 1)
local r = self.lookup_note_reference(content)
if r then
local parsed_ref = self.parser_functions.parse_blocks_nested(r)
- render_link_or_image(t, opening_index, closing_index, closing_index, parsed_ref)
+ render_link_or_image(t, opening_index, closing_index,
+ closing_index, parsed_ref)
end
end
@@ -29088,15 +30874,22 @@ function M.reader.new(writer, options)
% \end{markdown}
% \begin{macrocode}
local function resolve_full_link(t, opening_index, closing_index)
- local next_link_closing_index = find_next_link_closing_index(t, closing_index + 4)
- local next_link_content = collect_link_content(t, closing_index + 3, next_link_closing_index - 1)
+ local next_link_closing_index
+ = find_next_link_closing_index(t, closing_index + 4)
+ local next_link_content
+ = collect_link_content(t, closing_index + 3,
+ next_link_closing_index - 1)
local r = self.lookup_reference(next_link_content)
if r then
- local inline_content = resolve_inline_following_content(t, next_link_closing_index, false,
- t.match_link_attributes)
- r.attributes = join_attributes(r.attributes, inline_content.attributes)
- render_link_or_image(t, opening_index, next_link_closing_index, closing_index, r)
+ local inline_content
+ = resolve_inline_following_content(t, next_link_closing_index,
+ false,
+ t.match_link_attributes)
+ r.attributes
+ = join_attributes(r.attributes, inline_content.attributes)
+ render_link_or_image(t, opening_index, next_link_closing_index,
+ closing_index, r)
end
end
@@ -29110,14 +30903,20 @@ function M.reader.new(writer, options)
% \end{markdown}
% \begin{macrocode}
local function resolve_collapsed_link(t, opening_index, closing_index)
- local next_link_closing_index = find_next_link_closing_index(t, closing_index + 4)
- local content = collect_link_content(t, opening_index + 1, closing_index - 1)
+ local next_link_closing_index
+ = find_next_link_closing_index(t, closing_index + 4)
+ local content
+ = collect_link_content(t, opening_index + 1, closing_index - 1)
local r = self.lookup_reference(content)
if r then
- local inline_content = resolve_inline_following_content(t, closing_index, false, t.match_link_attributes)
- r.attributes = join_attributes(r.attributes, inline_content.attributes)
- render_link_or_image(t, opening_index, next_link_closing_index, closing_index, r)
+ local inline_content
+ = resolve_inline_following_content(t, closing_index, false,
+ t.match_link_attributes)
+ r.attributes
+ = join_attributes(r.attributes, inline_content.attributes)
+ render_link_or_image(t, opening_index, next_link_closing_index,
+ closing_index, r)
end
end
@@ -29137,9 +30936,12 @@ function M.reader.new(writer, options)
end
for i,value in ipairs(t) do
- if not value.is_closing or
- value.type ~= "delimiter" or
- not (value.element == "link" or value.element == "image" or value.element == "note") then
+ if not value.is_closing
+ or value.type ~= "delimiter"
+ or not ( value.element == "link"
+ or value.element == "image"
+ or value.element == "note")
+ or value.removed then
goto continue
end
@@ -29189,14 +30991,14 @@ function M.reader.new(writer, options)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Inline Elements (local)
%
% \end{markdown}
% \begin{macrocode}
- parsers.Str = (parsers.normalchar * (parsers.normalchar + parsers.at)^0)
+ parsers.Str = ( parsers.normalchar
+ * (parsers.normalchar + parsers.at)^0)
/ writer.string
parsers.Symbol = (parsers.backtick^1 + V("SpecialChar"))
@@ -29224,29 +31026,34 @@ function M.reader.new(writer, options)
parsers.interrupting_bullets = parsers.fail
parsers.interrupting_enumerators = parsers.fail
else
- parsers.interrupting_bullets = parsers.bullet(parsers.dash, true)
- + parsers.bullet(parsers.asterisk, true)
- + parsers.bullet(parsers.plus, true)
-
- parsers.interrupting_enumerators = parsers.enumerator(parsers.period, true)
- + parsers.enumerator(parsers.rparent, true)
+ parsers.interrupting_bullets
+ = parsers.bullet(parsers.dash, true)
+ + parsers.bullet(parsers.asterisk, true)
+ + parsers.bullet(parsers.plus, true)
+
+ parsers.interrupting_enumerators
+ = parsers.enumerator(parsers.period, true)
+ + parsers.enumerator(parsers.rparent, true)
end
if options.html then
- parsers.html_interrupting = parsers.check_trail
- * ( parsers.html_incomplete_open_tag
- + parsers.html_incomplete_close_tag
- + parsers.html_incomplete_open_special_tag
- + parsers.html_comment_start
- + parsers.html_cdatasection_start
- + parsers.html_declaration_start
- + parsers.html_instruction_start
- - parsers.html_close_special_tag
- - parsers.html_empty_special_tag)
+ parsers.html_interrupting
+ = parsers.check_trail
+ * ( parsers.html_incomplete_open_tag
+ + parsers.html_incomplete_close_tag
+ + parsers.html_incomplete_open_special_tag
+ + parsers.html_comment_start
+ + parsers.html_cdatasection_start
+ + parsers.html_declaration_start
+ + parsers.html_instruction_start
+ - parsers.html_close_special_tag
+ - parsers.html_empty_special_tag)
else
parsers.html_interrupting = parsers.fail
end
+ parsers.ListStarter = parsers.starter
+
parsers.EndlineExceptions
= parsers.blankline -- paragraph break
+ parsers.eof -- end of document
@@ -29264,7 +31071,7 @@ function M.reader.new(writer, options)
* -V("EndlineExceptions")
+ parsers.check_optional_indent
* -V("EndlineExceptions")
- * -parsers.starter)
+ * -V("ListStarter")) / function(_) return end
* parsers.spacechar^0
parsers.Endline = parsers.endline
@@ -29278,47 +31085,55 @@ function M.reader.new(writer, options)
* -V("NoSoftLineBreakEndlineExceptions")
+ parsers.check_optional_indent
* -V("NoSoftLineBreakEndlineExceptions")
- * -parsers.starter)
+ * -V("ListStarter"))
* parsers.spacechar^0
/ writer.space
- parsers.EndlineBreak = parsers.backslash * parsers.Endline
+ parsers.EndlineBreak = parsers.backslash * parsers.endline
/ writer.hard_line_break
parsers.OptionalIndent
= parsers.spacechar^1 / writer.space
- parsers.Space = parsers.spacechar^2 * parsers.Endline
+ parsers.Space = parsers.spacechar^2 * parsers.endline
/ writer.hard_line_break
- + parsers.spacechar^1 * parsers.Endline^-1 * parsers.eof / self.expandtabs
- + parsers.spacechar^1 * parsers.Endline
+ + parsers.spacechar^1
+ * parsers.endline^-1
+ * parsers.eof / self.expandtabs
+ + parsers.spacechar^1 * parsers.endline
/ writer.soft_line_break
- + parsers.spacechar^1 * -parsers.newline / self.expandtabs
+ + parsers.spacechar^1
+ * -parsers.newline / self.expandtabs
+ + parsers.spacechar^1
parsers.NoSoftLineBreakSpace
- = parsers.spacechar^2 * parsers.Endline
+ = parsers.spacechar^2 * parsers.endline
/ writer.hard_line_break
- + parsers.spacechar^1 * parsers.Endline^-1 * parsers.eof / self.expandtabs
- + parsers.spacechar^1 * parsers.Endline
+ + parsers.spacechar^1
+ * parsers.endline^-1
+ * parsers.eof / self.expandtabs
+ + parsers.spacechar^1 * parsers.endline
/ writer.soft_line_break
- + parsers.spacechar^1 * -parsers.newline / self.expandtabs
+ + parsers.spacechar^1
+ * -parsers.newline / self.expandtabs
+ + parsers.spacechar^1
parsers.NonbreakingEndline
= parsers.endline
- / writer.soft_line_break
+ / writer.nbsp
parsers.NonbreakingSpace
- = parsers.spacechar^2 * parsers.Endline
- / writer.hard_line_break
- + parsers.spacechar^1 * parsers.Endline^-1 * parsers.eof / ""
- + parsers.spacechar^1 * parsers.Endline
+ = parsers.spacechar^2 * parsers.endline
+ / writer.nbsp
+ + parsers.spacechar^1
+ * parsers.endline^-1 * parsers.eof / ""
+ + parsers.spacechar^1 * parsers.endline
* parsers.optionalspace
- / writer.soft_line_break
+ / writer.nbsp
+ parsers.spacechar^1 * parsers.optionalspace
/ writer.nbsp
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{reader->auto_link_url} method produces an
@@ -29333,7 +31148,6 @@ function self.auto_link_url(url, attributes)
url, nil, attributes)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{reader->auto_link_email} method produces an
@@ -29362,20 +31176,21 @@ end
parsers.LinkAndEmph = Ct(parsers.link_and_emph_table)
/ self.defer_link_and_emphasis_processing
- parsers.EscapedChar = parsers.backslash * C(parsers.escapable) / writer.string
+ parsers.EscapedChar = parsers.backslash
+ * C(parsers.escapable) / writer.string
- parsers.InlineHtml = Cs(parsers.html_inline_comment) / writer.inline_html_comment
- + Cs(parsers.html_any_empty_inline_tag
- + parsers.html_inline_instruction
- + parsers.html_inline_cdatasection
- + parsers.html_inline_declaration
- + parsers.html_any_open_inline_tag
- + parsers.html_any_close_tag)
- / writer.inline_html_tag
+ parsers.InlineHtml = Cs(parsers.html_inline_comment)
+ / writer.inline_html_comment
+ + Cs(parsers.html_any_empty_inline_tag
+ + parsers.html_inline_instruction
+ + parsers.html_inline_cdatasection
+ + parsers.html_inline_declaration
+ + parsers.html_any_open_inline_tag
+ + parsers.html_any_close_tag)
+ / writer.inline_html_tag
- parsers.HtmlEntity = parsers.html_entities / writer.string
+ parsers.HtmlEntity = parsers.html_entities / writer.string
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Block Elements (local)
@@ -29392,15 +31207,18 @@ end
+ parsers.html_declaration))
/ writer.block_html_element
- parsers.indented_non_blank_line = parsers.indentedline - parsers.blankline
+ parsers.indented_non_blank_line = parsers.indentedline
+ - parsers.blankline
- parsers.Verbatim = Cs(
- parsers.check_code_trail
- * (parsers.line - parsers.blankline)
- * ((parsers.check_minimal_blank_indent_and_full_code_trail * parsers.blankline)^0
- * ((parsers.check_minimal_indent / "") * parsers.check_code_trail
- * (parsers.line - parsers.blankline))^1)^0
- ) / self.expandtabs / writer.verbatim
+ parsers.Verbatim
+ = Cs( parsers.check_code_trail
+ * (parsers.line - parsers.blankline)
+ * (( parsers.check_minimal_blank_indent_and_full_code_trail
+ * parsers.blankline)^0
+ * ( (parsers.check_minimal_indent / "")
+ * parsers.check_code_trail
+ * (parsers.line - parsers.blankline))^1)^0)
+ / self.expandtabs / writer.verbatim
parsers.Blockquote = parsers.blockquote_body
/ writer.blockquote
@@ -29420,7 +31238,6 @@ end
parsers.Plain = parsers.nonindentspace * Ct(parsers.Inline^1)
/ writer.plain
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Lists (local)
@@ -29439,73 +31256,79 @@ end
parsers.list_blank = parsers.conditionally_indented_blankline
- parsers.ref_or_block_list_separated = parsers.sep_group_no_output(parsers.list_blank)
- * parsers.minimally_indented_ref
- + parsers.block_sep_group(parsers.list_blank)
- * parsers.minimally_indented_block
-
- parsers.ref_or_block_non_separated = parsers.minimally_indented_ref
- + (parsers.succeed / writer.interblocksep)
- * parsers.minimally_indented_block
- - parsers.minimally_indented_blankline
-
- parsers.tight_list_loop_body_pair =
- parsers.create_loop_body_pair(parsers.ref_or_block_non_separated,
- parsers.minimally_indented_par_or_plain_no_blank,
- (parsers.succeed / writer.interblocksep),
- (parsers.succeed / writer.paragraphsep))
-
- parsers.loose_list_loop_body_pair =
- parsers.create_loop_body_pair(parsers.ref_or_block_list_separated,
- parsers.minimally_indented_par_or_plain,
- parsers.block_sep_group(parsers.list_blank),
- parsers.par_sep_group(parsers.list_blank))
-
- parsers.tight_list_content_loop = V("Block")
- * parsers.tight_list_loop_body_pair.block^0
- + (V("Paragraph") + V("Plain"))
- * parsers.ref_or_block_non_separated
- * parsers.tight_list_loop_body_pair.block^0
- + (V("Paragraph") + V("Plain"))
- * parsers.tight_list_loop_body_pair.par^0
-
- parsers.loose_list_content_loop = V("Block")
- * parsers.loose_list_loop_body_pair.block^0
- + (V("Paragraph") + V("Plain"))
- * parsers.ref_or_block_list_separated
- * parsers.loose_list_loop_body_pair.block^0
- + (V("Paragraph") + V("Plain"))
- * parsers.loose_list_loop_body_pair.par^0
-
- parsers.list_item_tightness_condition = -#( parsers.list_blank^0
- * parsers.minimally_indented_ref_or_block_or_par)
- * remove_indent("li")
- + remove_indent("li")
- * parsers.fail
-
- parsers.indented_content_tight = Ct( (parsers.blankline / "")
- * #parsers.list_blank
- * remove_indent("li")
- + ( (V("Reference") + (parsers.blankline / ""))
- * parsers.check_minimal_indent
- * parsers.tight_list_content_loop
- + (V("Reference") + (parsers.blankline / ""))
- + (parsers.tickbox^-1 / writer.escape)
- * parsers.tight_list_content_loop
- )
- * parsers.list_item_tightness_condition
- )
-
- parsers.indented_content_loose = Ct( (parsers.blankline / "")
- * #parsers.list_blank
- + ( (V("Reference") + (parsers.blankline / ""))
- * parsers.check_minimal_indent
- * parsers.loose_list_content_loop
- + (V("Reference") + (parsers.blankline / ""))
- + (parsers.tickbox^-1 / writer.escape)
- * parsers.loose_list_content_loop
- )
- )
+ parsers.ref_or_block_list_separated
+ = parsers.sep_group_no_output(parsers.list_blank)
+ * parsers.minimally_indented_ref
+ + parsers.block_sep_group(parsers.list_blank)
+ * parsers.minimally_indented_block
+
+ parsers.ref_or_block_non_separated
+ = parsers.minimally_indented_ref
+ + (parsers.succeed / writer.interblocksep)
+ * parsers.minimally_indented_block
+ - parsers.minimally_indented_blankline
+
+ parsers.tight_list_loop_body_pair =
+ parsers.create_loop_body_pair(
+ parsers.ref_or_block_non_separated,
+ parsers.minimally_indented_par_or_plain_no_blank,
+ (parsers.succeed / writer.interblocksep),
+ (parsers.succeed / writer.paragraphsep))
+
+ parsers.loose_list_loop_body_pair =
+ parsers.create_loop_body_pair(
+ parsers.ref_or_block_list_separated,
+ parsers.minimally_indented_par_or_plain,
+ parsers.block_sep_group(parsers.list_blank),
+ parsers.par_sep_group(parsers.list_blank))
+
+ parsers.tight_list_content_loop
+ = V("Block")
+ * parsers.tight_list_loop_body_pair.block^0
+ + (V("Paragraph") + V("Plain"))
+ * parsers.ref_or_block_non_separated
+ * parsers.tight_list_loop_body_pair.block^0
+ + (V("Paragraph") + V("Plain"))
+ * parsers.tight_list_loop_body_pair.par^0
+
+ parsers.loose_list_content_loop
+ = V("Block")
+ * parsers.loose_list_loop_body_pair.block^0
+ + (V("Paragraph") + V("Plain"))
+ * parsers.ref_or_block_list_separated
+ * parsers.loose_list_loop_body_pair.block^0
+ + (V("Paragraph") + V("Plain"))
+ * parsers.loose_list_loop_body_pair.par^0
+
+ parsers.list_item_tightness_condition
+ = -#( parsers.list_blank^0
+ * parsers.minimally_indented_ref_or_block_or_par)
+ * remove_indent("li")
+ + remove_indent("li")
+ * parsers.fail
+
+ parsers.indented_content_tight
+ = Ct( (parsers.blankline / "")
+ * #parsers.list_blank
+ * remove_indent("li")
+ + ( (V("Reference") + (parsers.blankline / ""))
+ * parsers.check_minimal_indent
+ * parsers.tight_list_content_loop
+ + (V("Reference") + (parsers.blankline / ""))
+ + (parsers.tickbox^-1 / writer.escape)
+ * parsers.tight_list_content_loop
+ )
+ * parsers.list_item_tightness_condition)
+
+ parsers.indented_content_loose
+ = Ct( (parsers.blankline / "")
+ * #parsers.list_blank
+ + ( (V("Reference") + (parsers.blankline / ""))
+ * parsers.check_minimal_indent
+ * parsers.loose_list_content_loop
+ + (V("Reference") + (parsers.blankline / ""))
+ + (parsers.tickbox^-1 / writer.escape)
+ * parsers.loose_list_content_loop))
parsers.TightListItem = function(starter)
return -parsers.ThematicBreak
@@ -29563,13 +31386,15 @@ end
local enumerator = parsers.enumerator(delimiter_type)
return Cg(enumerator, "listtype")
* (Ct( parsers.TightListItem(Cb("listtype"))
- * ((parsers.check_minimal_indent / "") * parsers.TightListItem(enumerator))^0)
+ * ( (parsers.check_minimal_indent / "")
+ * parsers.TightListItem(enumerator))^0)
* Cc(true)
* -#((parsers.list_blank^0 / "")
* parsers.check_minimal_indent * enumerator)
+ Ct( parsers.LooseListItem(Cb("listtype"))
* ((parsers.list_blank^0 / "")
- * (parsers.check_minimal_indent / "") * parsers.LooseListItem(enumerator))^0)
+ * (parsers.check_minimal_indent / "")
+ * parsers.LooseListItem(enumerator))^0)
* Cc(false)
) * Ct(Cb("listtype")) / ordered_list
end
@@ -29577,7 +31402,6 @@ end
parsers.OrderedList = parsers.OrderedListOfType(parsers.period)
+ parsers.OrderedListOfType(parsers.rparent)
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Blank (local)
@@ -29587,7 +31411,6 @@ end
parsers.Blank = parsers.blankline / ""
+ V("Reference")
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Headings (local)
@@ -29622,22 +31445,27 @@ end
- parsers.thematic_break_lines
parsers.heading_text = parsers.heading_line
- * ((V("Endline") / "\n") * (parsers.heading_line - parsers.heading_level))^0
+ * ( (V("Endline") / "\n")
+ * ( parsers.heading_line
+ - parsers.heading_level))^0
* parsers.newline^-1
- parsers.SetextHeading = parsers.freeze_trail * parsers.check_trail_no_rem
- * #(parsers.heading_text
- * parsers.check_minimal_indent * parsers.check_trail * parsers.heading_level)
+ parsers.SetextHeading = parsers.freeze_trail
+ * parsers.check_trail_no_rem
+ * #( parsers.heading_text
+ * parsers.check_minimal_indent
+ * parsers.check_trail
+ * parsers.heading_level)
* Cs(parsers.heading_text)
/ parsers.parse_heading_text
- * parsers.check_minimal_indent_and_trail * parsers.heading_level
+ * parsers.check_minimal_indent_and_trail
+ * parsers.heading_level
* parsers.newline
* parsers.unfreeze_trail
/ writer.heading
parsers.Heading = parsers.AtxHeading + parsers.SetextHeading
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Syntax Specification
@@ -29670,7 +31498,6 @@ end
return local_walkable_syntax
end)(walkable_syntax)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamref{reader->insert_pattern} method adds a pattern to
@@ -29682,14 +31509,18 @@ end
local current_extension_name = nil
self.insert_pattern = function(selector, pattern, pattern_name)
assert(pattern_name == nil or type(pattern_name) == "string")
- local _, _, lhs, pos, rhs = selector:find("^(%a+)%s+([%a%s]+%a+)%s+(%a+)$")
+ local _, _, lhs, pos, rhs
+ = selector:find("^(%a+)%s+([%a%s]+%a+)%s+(%a+)$")
assert(lhs ~= nil,
- [[Expected selector in form "LHS (before|after|instead of) RHS", not "]]
+ [[Expected selector in form ]]
+ .. [["LHS (before|after|instead of) RHS", not "]]
.. selector .. [["]])
assert(walkable_syntax[lhs] ~= nil,
- [[Rule ]] .. lhs .. [[ -> ... does not exist in markdown grammar]])
+ [[Rule ]] .. lhs
+ .. [[ -> ... does not exist in markdown grammar]])
assert(pos == "before" or pos == "after" or pos == "instead of",
- [[Expected positional specifier "before", "after", or "instead of", not "]]
+ [[Expected positional specifier "before", "after", ]]
+ .. [[or "instead of", not "]]
.. pos .. [["]])
local rule = walkable_syntax[lhs]
local index = nil
@@ -29707,10 +31538,12 @@ end
.. [[ does not exist in markdown grammar]])
local accountable_pattern
if current_extension_name then
- accountable_pattern = { pattern, current_extension_name, pattern_name }
+ accountable_pattern
+ = {pattern, current_extension_name, pattern_name}
else
assert(type(pattern) == "string",
- [[reader->insert_pattern() was called outside an extension with ]]
+ [[reader->insert_pattern() was called outside ]]
+ .. [[an extension with ]]
.. [[a PEG pattern instead of a rule name]])
accountable_pattern = pattern
end
@@ -29721,7 +31554,6 @@ end
end
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Create a local \luamdef{syntax} hash table that stores those rules of the
@@ -29733,13 +31565,10 @@ end
local syntax =
{ "Blocks",
- Blocks = V("InitializeState")
- * ( V("ExpectedJekyllData")
- * (V("Blank")^0 / writer.interblocksep)
- )^-1
- * V("Blank")^0
+ Blocks = V("InitializeState")
+ * V("ExpectedJekyllData")
+ * V("Blank")^0
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Only create interblock separators between pairs of blocks that are not
@@ -29748,74 +31577,75 @@ end
%
% \end{markdown}
% \begin{macrocode}
- * ( V("Block")
- * ( V("Blank")^0 * parsers.eof
- + ( V("Blank")^2 / writer.paragraphsep
- + V("Blank")^0 / writer.interblocksep
- )
- )
- + ( V("Paragraph") + V("Plain") )
- * ( V("Blank")^0 * parsers.eof
- + ( V("Blank")^2 / writer.paragraphsep
- + V("Blank")^0 / writer.interblocksep
- )
- )
- * V("Block")
- * ( V("Blank")^0 * parsers.eof
- + ( V("Blank")^2 / writer.paragraphsep
- + V("Blank")^0 / writer.interblocksep
- )
- )
- + ( V("Paragraph") + V("Plain") )
- * ( V("Blank")^0 * parsers.eof
- + V("Blank")^0 / writer.paragraphsep
- )
- )^0,
-
- ExpectedJekyllData = parsers.fail,
-
- Blank = parsers.Blank,
- Reference = parsers.Reference,
-
- Blockquote = parsers.Blockquote,
- Verbatim = parsers.Verbatim,
- ThematicBreak = parsers.ThematicBreak,
- BulletList = parsers.BulletList,
- OrderedList = parsers.OrderedList,
- DisplayHtml = parsers.DisplayHtml,
- Heading = parsers.Heading,
- Paragraph = parsers.Paragraph,
- Plain = parsers.Plain,
-
- EndlineExceptions = parsers.EndlineExceptions,
+ * ( V("Block")
+ * ( V("Blank")^0 * parsers.eof
+ + ( V("Blank")^2 / writer.paragraphsep
+ + V("Blank")^0 / writer.interblocksep
+ )
+ )
+ + ( V("Paragraph") + V("Plain") )
+ * ( V("Blank")^0 * parsers.eof
+ + ( V("Blank")^2 / writer.paragraphsep
+ + V("Blank")^0 / writer.interblocksep
+ )
+ )
+ * V("Block")
+ * ( V("Blank")^0 * parsers.eof
+ + ( V("Blank")^2 / writer.paragraphsep
+ + V("Blank")^0 / writer.interblocksep
+ )
+ )
+ + ( V("Paragraph") + V("Plain") )
+ * ( V("Blank")^0 * parsers.eof
+ + V("Blank")^0 / writer.paragraphsep
+ )
+ )^0,
+
+ ExpectedJekyllData = parsers.succeed,
+
+ Blank = parsers.Blank,
+ Reference = parsers.Reference,
+
+ Blockquote = parsers.Blockquote,
+ Verbatim = parsers.Verbatim,
+ ThematicBreak = parsers.ThematicBreak,
+ BulletList = parsers.BulletList,
+ OrderedList = parsers.OrderedList,
+ DisplayHtml = parsers.DisplayHtml,
+ Heading = parsers.Heading,
+ Paragraph = parsers.Paragraph,
+ Plain = parsers.Plain,
+
+ ListStarter = parsers.ListStarter,
+ EndlineExceptions = parsers.EndlineExceptions,
NoSoftLineBreakEndlineExceptions
- = parsers.NoSoftLineBreakEndlineExceptions,
-
- Str = parsers.Str,
- Space = parsers.Space,
- NoSoftLineBreakSpace = parsers.NoSoftLineBreakSpace,
- OptionalIndent = parsers.OptionalIndent,
- Endline = parsers.Endline,
- EndlineNoSub = parsers.EndlineNoSub,
+ = parsers.NoSoftLineBreakEndlineExceptions,
+
+ Str = parsers.Str,
+ Space = parsers.Space,
+ NoSoftLineBreakSpace
+ = parsers.NoSoftLineBreakSpace,
+ OptionalIndent = parsers.OptionalIndent,
+ Endline = parsers.Endline,
+ EndlineNoSub = parsers.EndlineNoSub,
NoSoftLineBreakEndline
- = parsers.NoSoftLineBreakEndline,
- EndlineBreak = parsers.EndlineBreak,
- LinkAndEmph = parsers.LinkAndEmph,
- Code = parsers.Code,
- AutoLinkUrl = parsers.AutoLinkUrl,
- AutoLinkEmail = parsers.AutoLinkEmail,
+ = parsers.NoSoftLineBreakEndline,
+ EndlineBreak = parsers.EndlineBreak,
+ LinkAndEmph = parsers.LinkAndEmph,
+ Code = parsers.Code,
+ AutoLinkUrl = parsers.AutoLinkUrl,
+ AutoLinkEmail = parsers.AutoLinkEmail,
AutoLinkRelativeReference
- = parsers.AutoLinkRelativeReference,
- InlineHtml = parsers.InlineHtml,
- HtmlEntity = parsers.HtmlEntity,
- EscapedChar = parsers.EscapedChar,
- Smart = parsers.Smart,
- Symbol = parsers.Symbol,
- SpecialChar = parsers.fail,
- InitializeState = parsers.succeed,
+ = parsers.AutoLinkRelativeReference,
+ InlineHtml = parsers.InlineHtml,
+ HtmlEntity = parsers.HtmlEntity,
+ EscapedChar = parsers.EscapedChar,
+ Smart = parsers.Smart,
+ Symbol = parsers.Symbol,
+ SpecialChar = parsers.fail,
+ InitializeState = parsers.succeed,
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamref{reader->update_rule} as a function that receives two
@@ -29830,20 +31660,23 @@ end
self.update_rule = function(rule_name, get_pattern)
assert(current_extension_name ~= nil)
assert(syntax[rule_name] ~= nil,
- [[Rule ]] .. rule_name .. [[ -> ... does not exist in markdown grammar]])
+ [[Rule ]] .. rule_name
+ .. [[ -> ... does not exist in markdown grammar]])
local previous_pattern
local extension_name
if walkable_syntax[rule_name] then
- local previous_accountable_pattern = walkable_syntax[rule_name][1]
+ local previous_accountable_pattern
+ = walkable_syntax[rule_name][1]
previous_pattern = previous_accountable_pattern[1]
- extension_name = previous_accountable_pattern[2] .. ", " .. current_extension_name
+ extension_name
+ = previous_accountable_pattern[2]
+ .. ", " .. current_extension_name
else
previous_pattern = nil
extension_name = current_extension_name
end
local pattern
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Instead of a function, a \acro{peg} pattern `pattern` may also be
@@ -29872,7 +31705,6 @@ end
walkable_syntax[rule_name] = { accountable_pattern }
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define a hash table of all characters with special meaning and add method
@@ -29894,7 +31726,6 @@ end
self.add_special_character("!")
self.add_special_character("\\")
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Add method \luamdef{reader->initialize_named_group} that defines named groups
@@ -29911,7 +31742,6 @@ end
* Cg(pattern, name)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Add a named group for indentation.
@@ -29920,7 +31750,6 @@ end
% \begin{macrocode}
self.initialize_named_group("indent_info")
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Apply syntax extensions.
@@ -29934,7 +31763,6 @@ end
end
current_extension_name = nil
% \end{macrocode}
-% \par
% \begin{markdown}
%
% If the \Opt{debugExtensions} option is enabled, serialize
@@ -29966,9 +31794,11 @@ end
pattern_name = "Anonymous Pattern"
end
local extension_name = rhs[2]
- human_readable_rhs = pattern_name .. [[ (]] .. extension_name .. [[)]]
+ human_readable_rhs = pattern_name .. [[ (]]
+ .. extension_name .. [[)]]
end
- local encoded_rhs = util.encode_json_string(human_readable_rhs)
+ local encoded_rhs
+ = util.encode_json_string(human_readable_rhs)
local output_line = [[ ]] .. encoded_rhs
if rhs_index < #rule then
output_line = output_line .. ","
@@ -29986,12 +31816,12 @@ end
local output = table.concat(output_lines, "\n")
local output_filename = options.debugExtensionsFileName
local output_file = assert(io.open(output_filename, "w"),
- [[Could not open file "]] .. output_filename .. [[" for writing]])
+ [[Could not open file "]] .. output_filename
+ .. [[" for writing]])
assert(output_file:write(output))
assert(output_file:close())
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Materialize \luamref{walkable_syntax} and merge it into \luamref{syntax} to
@@ -30028,7 +31858,6 @@ end
end
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Finalize the parser by reacting to options and by producing special parsers
@@ -30079,7 +31908,7 @@ end
end
local blocks_nested_t = util.table_copy(syntax)
- blocks_nested_t.ExpectedJekyllData = parsers.fail
+ blocks_nested_t.ExpectedJekyllData = parsers.succeed
parsers.blocks_nested = Ct(blocks_nested_t)
parsers.blocks = Ct(syntax)
@@ -30109,10 +31938,11 @@ end
local inlines_no_link_or_emphasis_t = util.table_copy(inlines_t)
inlines_no_link_or_emphasis_t.LinkAndEmph = parsers.fail
- inlines_no_link_or_emphasis_t.EndlineExceptions = parsers.EndlineExceptions - parsers.eof
- parsers.inlines_no_link_or_emphasis = Ct(inlines_no_link_or_emphasis_t)
+ inlines_no_link_or_emphasis_t.EndlineExceptions
+ = parsers.EndlineExceptions - parsers.eof
+ parsers.inlines_no_link_or_emphasis
+ = Ct(inlines_no_link_or_emphasis_t)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Return a function that converts markdown string `input` into a plain \TeX{}
@@ -30137,7 +31967,8 @@ end
elseif form == "nfkd" then
input = uni_algos.normalize.NFKD(input)
else
- error(format("Unknown normalization form %s", form))
+ return writer.error(
+ format("Unknown normalization form %s.", form))
end
end
% \end{macrocode}
@@ -30153,30 +31984,12 @@ end
end
% \end{macrocode}
% \begin{markdown}
-% When determining the name of the cache file, create salt for the hashing
-% function out of the package version and the passed options recognized by the
-% Lua interface (see Section <#sec:lua-options>). The \Opt{cacheDir} option
-% is disregarded.
+% Clear the table of references.
% \end{markdown}
% \begin{macrocode}
references = {}
- local opt_string = {}
- for k, _ in pairs(defaultOptions) do
- local v = options[k]
- if type(v) == "table" then
- for _, i in ipairs(v) do
- opt_string[#opt_string+1] = k .. "=" .. tostring(i)
- end
- elseif k ~= "cacheDir" then
- opt_string[#opt_string+1] = k .. "=" .. tostring(v)
- end
- end
- table.sort(opt_string)
- local salt = table.concat(opt_string, ",") .. "," .. metadata.version
- local output
- local function convert(input)
- local document = self.parser_functions.parse_blocks(input)
- local output = util.rope_to_string(writer.document(document))
+ local document = self.parser_functions.parse_blocks(input)
+ local output = util.rope_to_string(writer.document(document))
% \end{macrocode}
% \begin{markdown}
% Remove block element / paragraph separators immediately followed by the
@@ -30184,82 +31997,49 @@ end
% Then, remove any leftover output of \luamref{writer->undosep}.
% \end{markdown}
% \begin{macrocode}
- local undosep_start, undosep_end
- local potential_secend_start, secend_start
- local potential_sep_start, sep_start
+ local undosep_start, undosep_end
+ local potential_secend_start, secend_start
+ local potential_sep_start, sep_start
+ while true do
+ -- find a `writer->undosep`
+ undosep_start, undosep_end
+ = output:find(writer.undosep_text, 1, true)
+ if undosep_start == nil then break end
+ -- skip any preceding section ends
+ secend_start = undosep_start
while true do
- -- find a `writer->undosep`
- undosep_start, undosep_end = output:find(writer.undosep_text, 1, true)
- if undosep_start == nil then break end
- -- skip any preceding section ends
- secend_start = undosep_start
- while true do
- potential_secend_start = secend_start - #writer.secend_text
- if potential_secend_start < 1
- or output:sub(potential_secend_start, secend_start - 1) ~= writer.secend_text then
- break
- end
- secend_start = potential_secend_start
+ potential_secend_start = secend_start - #writer.secend_text
+ if potential_secend_start < 1
+ or output:sub(potential_secend_start,
+ secend_start - 1) ~= writer.secend_text
+ then
+ break
end
- -- find an immediately preceding block element / paragraph separator
- sep_start = secend_start
- potential_sep_start = sep_start - #writer.interblocksep_text
+ secend_start = potential_secend_start
+ end
+ -- find an immediately preceding
+ -- block element / paragraph separator
+ sep_start = secend_start
+ potential_sep_start = sep_start - #writer.interblocksep_text
+ if potential_sep_start >= 1
+ and output:sub(potential_sep_start,
+ sep_start - 1) == writer.interblocksep_text
+ then
+ sep_start = potential_sep_start
+ else
+ potential_sep_start = sep_start - #writer.paragraphsep_text
if potential_sep_start >= 1
- and output:sub(potential_sep_start, sep_start - 1) == writer.interblocksep_text then
+ and output:sub(potential_sep_start,
+ sep_start - 1) == writer.paragraphsep_text
+ then
sep_start = potential_sep_start
- else
- potential_sep_start = sep_start - #writer.paragraphsep_text
- if potential_sep_start >= 1
- and output:sub(potential_sep_start, sep_start - 1) == writer.paragraphsep_text then
- sep_start = potential_sep_start
- end
end
- -- remove `writer->undosep` and immediately preceding block element / paragraph separator
- output = output:sub(1, sep_start - 1)
- .. output:sub(secend_start, undosep_start - 1)
- .. output:sub(undosep_end + 1)
end
- return output
- end
-% \end{macrocode}
-% \begin{markdown}
-% If we cache markdown documents, produce the cache file and transform its
-% filename to plain \TeX{} output via the \luamref{writer->pack} method.
-% \end{markdown}
-% \begin{macrocode}
- if options.eagerCache or options.finalizeCache then
- local name = util.cache(options.cacheDir, input, salt, convert,
- ".md" .. writer.suffix)
- output = writer.pack(name)
-% \end{macrocode}
-% \begin{markdown}
-% Otherwise, return the result of the conversion directly.
-% \end{markdown}
-% \begin{macrocode}
- else
- output = convert(input)
- end
-% \end{macrocode}
-% \begin{markdown}
-% If the \Opt{finalizeCache} option is enabled, populate the frozen cache in
-% the file \Opt{frozenCacheFileName} with an entry for markdown document
-% number \Opt{frozenCacheCounter}.
-% \end{markdown}
-% \begin{macrocode}
- if options.finalizeCache then
- local file, mode
- if options.frozenCacheCounter > 0 then
- mode = "a"
- else
- mode = "w"
- end
- file = assert(io.open(options.frozenCacheFileName, mode),
- [[Could not open file "]] .. options.frozenCacheFileName
- .. [[" for writing]])
- assert(file:write([[\expandafter\global\expandafter\def\csname ]]
- .. [[markdownFrozenCache]] .. options.frozenCacheCounter
- .. [[\endcsname{]] .. output .. [[}]] .. "\n"))
- assert(file:close())
+ -- remove `writer->undosep` and immediately preceding
+ -- block element / paragraph separator
+ output = output:sub(1, sep_start - 1)
+ .. output:sub(secend_start, undosep_start - 1)
+ .. output:sub(undosep_end + 1)
end
return output
end
@@ -30296,7 +32076,6 @@ M.extensions.bracketed_spans = function()
name = "built-in bracketed_spans syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->span} as a function that will transform an input
@@ -30321,10 +32100,13 @@ M.extensions.bracketed_spans = function()
+ parsers.autolink
+ V("InlineHtml")
+ ( parsers.backslash * parsers.backslash)
- + ( parsers.backslash * (parsers.lbracket + parsers.rbracket)
+ + ( parsers.backslash
+ * (parsers.lbracket + parsers.rbracket)
+ V("Space") + V("Endline")
+ (parsers.any
- - (parsers.newline + parsers.lbracket + parsers.rbracket
+ - ( parsers.newline
+ + parsers.lbracket
+ + parsers.rbracket
+ parsers.blankline^2))))^1)
/ self.parser_functions.parse_inlines)
* parsers.rbracket
@@ -30355,7 +32137,6 @@ M.extensions.citations = function(citation_nbsps)
name = "built-in citations syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->citations} as a function that will transform an
@@ -30387,11 +32168,15 @@ M.extensions.citations = function(citation_nbsps)
end
end
else
- table.insert(buffer, {"\\markdownRenderer", text_cites and "TextCite" or "Cite",
- "{", #cites, "}"})
+ table.insert(buffer,
+ {"\\markdownRenderer",
+ text_cites and "TextCite" or "Cite",
+ "{", #cites, "}"})
for _,cite in ipairs(cites) do
- table.insert(buffer, {cite.suppress_author and "-" or "+", "{",
- cite.prenote or "", "}{", cite.postnote or "", "}{", cite.name, "}"})
+ table.insert(buffer,
+ {cite.suppress_author and "-" or "+", "{",
+ cite.prenote or "", "}{",
+ cite.postnote or "", "}{", cite.name, "}"})
end
end
return buffer
@@ -30407,12 +32192,16 @@ M.extensions.citations = function(citation_nbsps)
local citation_name
= Cs(parsers.dash^-1) * parsers.at
* Cs(citation_chars
- * (((citation_chars + parsers.internal_punctuation
+ * ((( citation_chars
+ + parsers.internal_punctuation
- parsers.comma - parsers.semicolon)
- * -#((parsers.internal_punctuation - parsers.comma
+ * -#(( parsers.internal_punctuation
+ - parsers.comma
- parsers.semicolon)^0
- * -(citation_chars + parsers.internal_punctuation
- - parsers.comma - parsers.semicolon)))^0
+ * -( citation_chars
+ + parsers.internal_punctuation
+ - parsers.comma
+ - parsers.semicolon)))^0
* citation_chars)^-1)
local citation_body_prenote
@@ -30421,10 +32210,14 @@ M.extensions.citations = function(citation_nbsps)
+ parsers.inticks
+ parsers.autolink
+ V("InlineHtml")
- + V("Space") + V("Endline")
+ + V("Space") + V("EndlineNoSub")
+ (parsers.anyescaped
- - (parsers.newline + parsers.rbracket + parsers.blankline^2))
- - (parsers.spnl * parsers.dash^-1 * parsers.at))^1)
+ - ( parsers.newline
+ + parsers.rbracket
+ + parsers.blankline^2))
+ - ( parsers.spnl
+ * parsers.dash^-1
+ * parsers.at))^1)
local citation_body_postnote
= Cs((parsers.alphanumeric^1
@@ -30432,9 +32225,11 @@ M.extensions.citations = function(citation_nbsps)
+ parsers.inticks
+ parsers.autolink
+ V("InlineHtml")
- + V("Space") + V("Endline")
+ + V("Space") + V("EndlineNoSub")
+ (parsers.anyescaped
- - (parsers.newline + parsers.rbracket + parsers.semicolon
+ - ( parsers.newline
+ + parsers.rbracket
+ + parsers.semicolon
+ parsers.blankline^2))
- (parsers.spnl * parsers.rbracket))^1)
@@ -30445,8 +32240,9 @@ M.extensions.citations = function(citation_nbsps)
* parsers.spnlc
)
* citation_name
- * (parsers.internal_punctuation - parsers.semicolon)^-1
- * ( parsers.spnlc
+ * ( parsers.internal_punctuation
+ - parsers.semicolon)^-1
+ * ( parsers.spnlc / function(_) return end
* citation_body_postnote
+ Cc("")
* parsers.spnlc
@@ -30467,7 +32263,9 @@ M.extensions.citations = function(citation_nbsps)
+ V("InlineHtml")
+ V("Space") + V("Endline")
+ (parsers.anyescaped
- - (parsers.newline + parsers.rbracket + parsers.at
+ - ( parsers.newline
+ + parsers.rbracket
+ + parsers.at
+ parsers.semicolon + parsers.blankline^2))
- (parsers.spnl * parsers.rbracket))^0)
@@ -30548,7 +32346,6 @@ end
% \begin{macrocode}
M.extensions.content_blocks = function(language_map)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \luamdef{languages_json} table maps programming language filename
@@ -30561,7 +32358,8 @@ M.extensions.content_blocks = function(language_map)
% \begin{macrocode}
local languages_json = (function()
local base, prev, curr
- for _, pathname in ipairs{kpse.lookup(language_map, { all=true })} do
+ for _, pathname in ipairs{kpse.lookup(language_map,
+ {all=true})} do
local file = io.open(pathname, "r")
if not file then goto continue end
local input = assert(file:read("*a"))
@@ -30585,7 +32383,6 @@ M.extensions.content_blocks = function(language_map)
name = "built-in content_blocks syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->contentblock} as a function that will transform an
@@ -30602,20 +32399,20 @@ M.extensions.content_blocks = function(language_map)
suf = suf:lower()
if type == "onlineimage" then
return {"\\markdownRendererContentBlockOnlineImage{",suf,"}",
- "{",self.string(src),"}",
- "{",self.uri(src),"}",
- "{",self.string(tit or ""),"}"}
+ "{",self.string(src),"}",
+ "{",self.uri(src),"}",
+ "{",self.string(tit or ""),"}"}
elseif languages_json[suf] then
return {"\\markdownRendererContentBlockCode{",suf,"}",
- "{",self.string(languages_json[suf]),"}",
- "{",self.string(src),"}",
- "{",self.uri(src),"}",
- "{",self.string(tit or ""),"}"}
+ "{",self.string(languages_json[suf]),"}",
+ "{",self.string(src),"}",
+ "{",self.uri(src),"}",
+ "{",self.string(tit or ""),"}"}
else
return {"\\markdownRendererContentBlock{",suf,"}",
- "{",self.string(src),"}",
- "{",self.uri(src),"}",
- "{",self.string(tit or ""),"}"}
+ "{",self.string(src),"}",
+ "{",self.uri(src),"}",
+ "{",self.string(tit or ""),"}"}
end
end
end, extend_reader = function(self)
@@ -30650,8 +32447,8 @@ M.extensions.content_blocks = function(language_map)
return parser
end)("png", "jpg", "jpeg", "gif", "tif", "tiff")
- -- online image url for iA Writer content blocks with mandatory suffix,
- -- allowing nested brackets:
+ -- online image url for iA Writer content blocks with
+ -- mandatory suffix, allowing nested brackets:
local onlineimageurl
= (parsers.less
* Cs((parsers.anyescaped
@@ -30715,7 +32512,6 @@ M.extensions.definition_lists = function(tight_lists)
name = "built-in definition_lists syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->definitionlist} as a function that will transform an
@@ -30729,8 +32525,9 @@ M.extensions.definition_lists = function(tight_lists)
local function dlitem(term, defs)
local retVal = {"\\markdownRendererDlItem{",term,"}"}
for _, def in ipairs(defs) do
- retVal[#retVal+1] = {"\\markdownRendererDlDefinitionBegin ",def,
- "\\markdownRendererDlDefinitionEnd "}
+ retVal[#retVal+1]
+ = {"\\markdownRendererDlDefinitionBegin ",def,
+ "\\markdownRendererDlDefinitionEnd "}
end
retVal[#retVal+1] = "\\markdownRendererDlItemEnd "
return retVal
@@ -30756,17 +32553,26 @@ M.extensions.definition_lists = function(tight_lists)
local defstartchar = S("~:")
- local defstart = parsers.check_trail_length(0) * defstartchar * #parsers.spacing
- * (parsers.tab + parsers.space^-3)
- + parsers.check_trail_length(1) * defstartchar * #parsers.spacing
- * (parsers.tab + parsers.space^-2)
- + parsers.check_trail_length(2) * defstartchar * #parsers.spacing
- * (parsers.tab + parsers.space^-1)
- + parsers.check_trail_length(3) * defstartchar * #parsers.spacing
-
- local indented_line = (parsers.check_minimal_indent / "") * parsers.check_code_trail * parsers.line
-
- local blank = parsers.check_minimal_blank_indent_and_any_trail * parsers.optionalspace * parsers.newline
+ local defstart
+ = parsers.check_trail_length(0) * defstartchar
+ * #parsers.spacing
+ * (parsers.tab + parsers.space^-3)
+ + parsers.check_trail_length(1)
+ * defstartchar * #parsers.spacing
+ * (parsers.tab + parsers.space^-2)
+ + parsers.check_trail_length(2)
+ * defstartchar * #parsers.spacing
+ * (parsers.tab + parsers.space^-1)
+ + parsers.check_trail_length(3)
+ * defstartchar * #parsers.spacing
+
+ local indented_line
+ = (parsers.check_minimal_indent / "")
+ * parsers.check_code_trail * parsers.line
+
+ local blank
+ = parsers.check_minimal_blank_indent_and_any_trail
+ * parsers.optionalspace * parsers.newline
local dlchunk = Cs(parsers.line * (indented_line - blank)^0)
@@ -30783,24 +32589,24 @@ M.extensions.definition_lists = function(tight_lists)
end
local DefinitionListItemLoose
- = C(parsers.line) * blank^0
- * Ct((parsers.check_minimal_indent * (defstart
- * indented_blocks(dlchunk)
- / self.parser_functions.parse_blocks_nested))^1)
- * Cc(false) / definition_list_item
+ = C(parsers.line) * blank^0
+ * Ct((parsers.check_minimal_indent * (defstart
+ * indented_blocks(dlchunk)
+ / self.parser_functions.parse_blocks_nested))^1)
+ * Cc(false) / definition_list_item
local DefinitionListItemTight
- = C(parsers.line)
- * Ct((parsers.check_minimal_indent * (defstart * dlchunk
- / self.parser_functions.parse_blocks_nested))^1)
- * Cc(true) / definition_list_item
+ = C(parsers.line)
+ * Ct((parsers.check_minimal_indent * (defstart * dlchunk
+ / self.parser_functions.parse_blocks_nested))^1)
+ * Cc(true) / definition_list_item
local DefinitionList
- = ( Ct(DefinitionListItemLoose^1) * Cc(false)
- + Ct(DefinitionListItemTight^1)
- * (blank^0
- * -DefinitionListItemLoose * Cc(true))
- ) / writer.definitionlist
+ = ( Ct(DefinitionListItemLoose^1) * Cc(false)
+ + Ct(DefinitionListItemTight^1)
+ * (blank^0
+ * -DefinitionListItemLoose * Cc(true))
+ ) / writer.definitionlist
self.insert_pattern("Block after Heading",
DefinitionList, "DefinitionList")
@@ -30824,7 +32630,6 @@ M.extensions.fancy_lists = function()
local options = self.options
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->fancylist} as a function that will transform an
@@ -30885,7 +32690,8 @@ M.extensions.fancy_lists = function()
return {"\\markdownRendererFancyOlItemWithNumber{",num,"}",s,
"\\markdownRendererFancyOlItemEnd "}
else
- return {"\\markdownRendererFancyOlItem ",s,"\\markdownRendererFancyOlItemEnd "}
+ return {"\\markdownRendererFancyOlItem ",s,
+ "\\markdownRendererFancyOlItemEnd "}
end
end
end, extend_reader = function(self)
@@ -30906,7 +32712,8 @@ M.extensions.fancy_lists = function()
continuation_marker = marker
end
for _,delim in ipairs(delims) do
- table.insert(markers_table, {start_marker, continuation_marker, delim})
+ table.insert(markers_table,
+ {start_marker, continuation_marker, delim})
end
end
return markers_table
@@ -30925,15 +32732,18 @@ M.extensions.fancy_lists = function()
local roman_marker = function(chars)
local m, d, c = P(chars[1]), P(chars[2]), P(chars[3])
- local l, x, v, i = P(chars[4]), P(chars[5]), P(chars[6]), P(chars[7])
+ local l, x, v, i
+ = P(chars[4]), P(chars[5]), P(chars[6]), P(chars[7])
return m^-3
* (c*m + c*d + d^-1 * c^-3)
* (x*c + x*l + l^-1 * x^-3)
* (i*x + i*v + v^-1 * i^-3)
end
- local lowercase_roman_marker = roman_marker({"m", "d", "c", "l", "x", "v", "i"})
- local uppercase_roman_marker = roman_marker({"M", "D", "C", "L", "X", "V", "I"})
+ local lowercase_roman_marker
+ = roman_marker({"m", "d", "c", "l", "x", "v", "i"})
+ local uppercase_roman_marker
+ = roman_marker({"M", "D", "C", "L", "X", "V", "I"})
local lowercase_opening_roman_marker = P("i")
local uppercase_opening_roman_marker = P("I")
@@ -30957,7 +32767,8 @@ M.extensions.fancy_lists = function()
local markers_table = combine_markers_and_delims(markers, delims)
- local function enumerator(start_marker, _, delimiter_type, interrupting)
+ local function enumerator(start_marker, _,
+ delimiter_type, interrupting)
local delimiter_range
local allowed_end
if interrupting then
@@ -30965,7 +32776,8 @@ M.extensions.fancy_lists = function()
allowed_end = C(parsers.spacechar^1) * #parsers.linechar
else
delimiter_range = start_marker
- allowed_end = C(parsers.spacechar^1) + #(parsers.newline + parsers.eof)
+ allowed_end = C(parsers.spacechar^1)
+ + #(parsers.newline + parsers.eof)
end
return parsers.check_trail
@@ -30987,13 +32799,15 @@ M.extensions.fancy_lists = function()
end
local function roman2number(roman)
- local romans = { ["M"] = 1000, ["D"] = 500, ["C"] = 100, ["L"] = 50, ["X"] = 10, ["V"] = 5, ["I"] = 1 }
+ local romans = { ["M"] = 1000, ["D"] = 500, ["C"] = 100,
+ ["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) ]
+ 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
@@ -31002,7 +32816,9 @@ M.extensions.fancy_lists = function()
i = i + 1
end
end
- if i <= len then numeral = numeral + romans[ string.sub(roman,i,i) ] end
+ if i <= len then
+ numeral = numeral + romans[ string.sub(roman,i,i) ]
+ end
return numeral
end
@@ -31027,11 +32843,13 @@ M.extensions.fancy_lists = function()
end
num = numstr:match("^([A-Z])$")
if num then
- return string.byte(num) - string.byte("A") + 1, "UpperAlpha", numdelim
+ 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
+ return string.byte(num) - string.byte("a") + 1,
+ "LowerAlpha", numdelim
end
num = numstr:match("^([IVXLCDM]+)")
if num then
@@ -31045,42 +32863,44 @@ M.extensions.fancy_lists = function()
end
local function fancylist(items,tight,start)
- local startnum, numstyle, numdelim = sniffstyle(start[2][1], start[2][2])
+ local startnum, numstyle, numdelim
+ = sniffstyle(start[2][1], start[2][2])
return writer.fancylist(items,tight,
options.startNumber and startnum or 1,
numstyle or "Decimal",
numdelim or "Default")
end
- local FancyListOfType = function(start_marker, continuation_marker, delimiter_type)
- local enumerator_start = enumerator(start_marker, continuation_marker, delimiter_type)
- local enumerator_cont = enumerator(continuation_marker, continuation_marker, delimiter_type)
- return Cg(enumerator_start, "listtype")
- * (Ct( TightListItem(Cb("listtype"))
- * ((parsers.check_minimal_indent / "") * TightListItem(enumerator_cont))^0)
- * Cc(true)
- * -#((parsers.conditionally_indented_blankline^0 / "")
- * parsers.check_minimal_indent * enumerator_cont)
- + Ct( LooseListItem(Cb("listtype"))
- * ((parsers.conditionally_indented_blankline^0 / "")
- * (parsers.check_minimal_indent / "") * LooseListItem(enumerator_cont))^0)
- * Cc(false)
- ) * Ct(Cb("listtype")) / fancylist
- end
+ local FancyListOfType
+ = function(start_marker, continuation_marker, delimiter_type)
+ local enumerator_start
+ = enumerator(start_marker, continuation_marker,
+ delimiter_type)
+ local enumerator_cont
+ = enumerator(continuation_marker, continuation_marker,
+ delimiter_type)
+ return Cg(enumerator_start, "listtype")
+ * (Ct( TightListItem(Cb("listtype"))
+ * ((parsers.check_minimal_indent / "")
+ * TightListItem(enumerator_cont))^0)
+ * Cc(true)
+ * -#((parsers.conditionally_indented_blankline^0 / "")
+ * parsers.check_minimal_indent * enumerator_cont)
+ + Ct( LooseListItem(Cb("listtype"))
+ * ((parsers.conditionally_indented_blankline^0 / "")
+ * (parsers.check_minimal_indent / "")
+ * LooseListItem(enumerator_cont))^0)
+ * Cc(false)
+ ) * Ct(Cb("listtype")) / fancylist
+ end
- local FancyList = join_table_with_func(FancyListOfType, markers_table)
+ local FancyList
+ = join_table_with_func(FancyListOfType, markers_table)
- local Endline = parsers.newline
- * (parsers.check_minimal_indent
- * -parsers.EndlineExceptions
- + parsers.check_optional_indent
- * -parsers.EndlineExceptions
- * -starter)
- * parsers.spacechar^0
- / writer.soft_line_break
+ local ListStarter = starter
self.update_rule("OrderedList", FancyList)
- self.update_rule("Endline", Endline)
+ self.update_rule("ListStarter", ListStarter)
end
}
end
@@ -31110,7 +32930,6 @@ M.extensions.fenced_code = function(blank_before_code_fence,
local options = self.options
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->fencedCode} as a function that will transform an
@@ -31124,20 +32943,22 @@ M.extensions.fenced_code = function(blank_before_code_fence,
s = s:gsub("\n$", "")
local buf = {}
if attr ~= nil then
- table.insert(buf, {"\\markdownRendererFencedCodeAttributeContextBegin",
- self.attributes(attr)})
+ table.insert(buf,
+ {"\\markdownRendererFencedCodeAttributeContextBegin",
+ self.attributes(attr)})
end
local name = util.cache_verbatim(options.cacheDir, s)
- table.insert(buf, {"\\markdownRendererInputFencedCode{",
- name,"}{",self.string(i),"}{",self.infostring(i),"}"})
+ table.insert(buf,
+ {"\\markdownRendererInputFencedCode{",
+ name,"}{",self.string(i),"}{",self.infostring(i),"}"})
if attr ~= nil then
- table.insert(buf, "\\markdownRendererFencedCodeAttributeContextEnd{}")
+ table.insert(buf,
+ "\\markdownRendererFencedCodeAttributeContextEnd{}")
end
return buf
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->rawBlock} as a function that will transform an
@@ -31171,11 +32992,13 @@ M.extensions.fenced_code = function(blank_before_code_fence,
- parsers.newline)^0)
/ strip_enclosing_whitespaces)
- local backtick_infostring = Cs(Cs((V("HtmlEntity")
- + (-#(parsers.backslash * parsers.backtick) * parsers.anyescaped)
- - parsers.newline
- - parsers.backtick)^0)
- / strip_enclosing_whitespaces)
+ local backtick_infostring
+ = Cs( Cs((V("HtmlEntity")
+ + ( -#(parsers.backslash * parsers.backtick)
+ * parsers.anyescaped)
+ - parsers.newline
+ - parsers.backtick)^0)
+ / strip_enclosing_whitespaces)
local fenceindent
@@ -31197,77 +33020,93 @@ M.extensions.fenced_code = function(blank_before_code_fence,
end
end
- local function count_fenced_start_indent(_, _, indent_table, trail)
- local last_indent_name = get_last_indent_name(indent_table)
- fenceindent = 0
- if last_indent_name ~= "li" then
- fenceindent = #trail
+ local count_fenced_start_indent =
+ function(_, _, indent_table, trail)
+ local last_indent_name = get_last_indent_name(indent_table)
+ fenceindent = 0
+ if last_indent_name ~= "li" then
+ fenceindent = #trail
+ end
+ return true
end
- return true
- end
- local fencehead = function(char, infostring)
- return Cmt(Cb("indent_info") * parsers.check_trail, count_fenced_start_indent)
- * Cg(char^3, "fencelength")
- * parsers.optionalspace
- * infostring
- * (parsers.newline + parsers.eof)
+ local fencehead = function(char, infostring)
+ return Cmt( Cb("indent_info")
+ * parsers.check_trail, count_fenced_start_indent)
+ * Cg(char^3, "fencelength")
+ * parsers.optionalspace
+ * infostring
+ * (parsers.newline + parsers.eof)
end
- local fencetail = function(char)
- return parsers.check_trail_no_rem
- * Cmt(C(char^3) * Cb("fencelength"), captures_geq_length)
- * parsers.optionalspace * (parsers.newline + parsers.eof)
- + parsers.eof
+ local fencetail = function(char)
+ return parsers.check_trail_no_rem
+ * Cmt(C(char^3) * Cb("fencelength"), captures_geq_length)
+ * parsers.optionalspace * (parsers.newline + parsers.eof)
+ + parsers.eof
end
- local function process_fenced_line(s, i, indent_table, line_content, is_blank) -- luacheck: ignore s i
- local remainder = ""
- if has_trail(indent_table) then
- remainder = indent_table.trail.internal_remainder
- end
+ local process_fenced_line =
+ function(s, i, -- luacheck: ignore s i
+ indent_table, line_content, is_blank)
+ local remainder = ""
+ if has_trail(indent_table) then
+ remainder = indent_table.trail.internal_remainder
+ end
- if is_blank and get_last_indent_name(indent_table) == "li" then
- remainder = ""
- end
+ if is_blank
+ and get_last_indent_name(indent_table) == "li" then
+ remainder = ""
+ end
- local str = remainder .. line_content
- local index = 1
- local remaining = fenceindent
+ local str = remainder .. line_content
+ local index = 1
+ local remaining = fenceindent
- while true do
- local c = str:sub(index, index)
- if c == " " and remaining > 0 then
- remaining = remaining - 1
- index = index + 1
- elseif c == "\t" and remaining > 3 then
- remaining = remaining - 4
- index = index + 1
- else
- break
+ while true do
+ local c = str:sub(index, index)
+ if c == " " and remaining > 0 then
+ remaining = remaining - 1
+ index = index + 1
+ elseif c == "\t" and remaining > 3 then
+ remaining = remaining - 4
+ index = index + 1
+ else
+ break
+ end
end
- end
- return true, str:sub(index)
- end
+ return true, str:sub(index)
+ end
local fencedline = function(char)
- return Cmt(Cb("indent_info") * C(parsers.line - fencetail(char)) * Cc(false), process_fenced_line)
+ return Cmt( Cb("indent_info")
+ * C(parsers.line - fencetail(char))
+ * Cc(false), process_fenced_line)
end
- local blankfencedline = Cmt(Cb("indent_info") * C(parsers.blankline) * Cc(true), process_fenced_line)
+ local blankfencedline
+ = Cmt( Cb("indent_info")
+ * C(parsers.blankline)
+ * Cc(true), process_fenced_line)
local TildeFencedCode
- = fencehead(parsers.tilde, tilde_infostring)
- * Cs(((parsers.check_minimal_blank_indent / "") * blankfencedline
- + (parsers.check_minimal_indent / "") * fencedline(parsers.tilde))^0)
- * ((parsers.check_minimal_indent / "") * fencetail(parsers.tilde) + parsers.succeed)
+ = fencehead(parsers.tilde, tilde_infostring)
+ * Cs(( (parsers.check_minimal_blank_indent / "")
+ * blankfencedline
+ + ( parsers.check_minimal_indent / "")
+ * fencedline(parsers.tilde))^0)
+ * ( (parsers.check_minimal_indent / "")
+ * fencetail(parsers.tilde) + parsers.succeed)
local BacktickFencedCode
= fencehead(parsers.backtick, backtick_infostring)
- * Cs(((parsers.check_minimal_blank_indent / "") * blankfencedline
- + (parsers.check_minimal_indent / "") * fencedline(parsers.backtick))^0)
- * ((parsers.check_minimal_indent / "") * fencetail(parsers.backtick) + parsers.succeed)
+ * Cs(( (parsers.check_minimal_blank_indent / "")
+ * blankfencedline
+ + (parsers.check_minimal_indent / "")
+ * fencedline(parsers.backtick))^0)
+ * ( (parsers.check_minimal_indent / "")
+ * fencetail(parsers.backtick) + parsers.succeed)
local infostring_with_attributes
= Ct(C((parsers.linechar
@@ -31277,28 +33116,28 @@ M.extensions.fenced_code = function(blank_before_code_fence,
* 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)
+ = ((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")
@@ -31340,7 +33179,6 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
name = "built-in fenced_divs syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->div_begin} as a function that will transform the
@@ -31350,13 +33188,15 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
% \end{markdown}
% \begin{macrocode}
function self.div_begin(attributes)
- local start_output = {"\\markdownRendererFencedDivAttributeContextBegin\n",
- self.attributes(attributes)}
- local end_output = {"\\markdownRendererFencedDivAttributeContextEnd{}"}
- return self.push_attributes("div", attributes, start_output, end_output)
+ local start_output
+ = {"\\markdownRendererFencedDivAttributeContextBegin\n",
+ self.attributes(attributes)}
+ local end_output
+ = {"\\markdownRendererFencedDivAttributeContextEnd{}"}
+ return self.push_attributes(
+ "div", attributes, start_output, end_output)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->div_end} as a function that will produce the end of a
@@ -31371,7 +33211,6 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
local parsers = self.parsers
local writer = self.writer
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define basic patterns for matching the opening and the closing tag of a div.
@@ -31397,7 +33236,6 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
* parsers.optionalspace
* (parsers.newline + parsers.eof)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Initialize a named group named `fenced_div_level` for tracking how deep
@@ -31414,21 +33252,24 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
self.initialize_named_group("fenced_div_num_opening_indents")
local function increment_div_level()
- local function push_indent_table(s, i, indent_table, -- luacheck: ignore s i
- fenced_div_num_opening_indents, fenced_div_level)
- fenced_div_level = tonumber(fenced_div_level) + 1
- local num_opening_indents = 0
- if indent_table.indents ~= nil then
- num_opening_indents = #indent_table.indents
+ local push_indent_table =
+ function(s, i, indent_table, -- luacheck: ignore s i
+ fenced_div_num_opening_indents, fenced_div_level)
+ fenced_div_level = tonumber(fenced_div_level) + 1
+ local num_opening_indents = 0
+ if indent_table.indents ~= nil then
+ num_opening_indents = #indent_table.indents
+ end
+ fenced_div_num_opening_indents[fenced_div_level]
+ = num_opening_indents
+ return true, fenced_div_num_opening_indents
end
- fenced_div_num_opening_indents[fenced_div_level] = num_opening_indents
- return true, fenced_div_num_opening_indents
- end
- local function increment_level(s, i, fenced_div_level) -- luacheck: ignore s i
- fenced_div_level = tonumber(fenced_div_level) + 1
- return true, tostring(fenced_div_level)
- end
+ local increment_level =
+ function(s, i, fenced_div_level) -- luacheck: ignore s i
+ fenced_div_level = tonumber(fenced_div_level) + 1
+ return true, tostring(fenced_div_level)
+ end
return Cg( Cmt( Cb("indent_info")
* Cb("fenced_div_num_opening_indents")
@@ -31439,11 +33280,13 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
end
local function decrement_div_level()
- local function pop_indent_table(s, i, fenced_div_indent_table, fenced_div_level) -- luacheck: ignore s i
- fenced_div_level = tonumber(fenced_div_level)
- fenced_div_indent_table[fenced_div_level] = nil
- return true, tostring(fenced_div_level - 1)
- end
+ local pop_indent_table =
+ function(s, i, -- luacheck: ignore s i
+ fenced_div_indent_table, fenced_div_level)
+ fenced_div_level = tonumber(fenced_div_level)
+ fenced_div_indent_table[fenced_div_level] = nil
+ return true, tostring(fenced_div_level - 1)
+ end
return Cg( Cmt( Cb("fenced_div_num_opening_indents")
* Cb("fenced_div_level"), pop_indent_table)
@@ -31451,21 +33294,24 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
end
- local non_fenced_div_block = parsers.check_minimal_indent * V("Block")
- - parsers.check_minimal_indent_and_trail * fenced_div_end
+ local non_fenced_div_block
+ = parsers.check_minimal_indent * V("Block")
+ - parsers.check_minimal_indent_and_trail * fenced_div_end
- local non_fenced_div_paragraph = parsers.check_minimal_indent * V("Paragraph")
- - parsers.check_minimal_indent_and_trail * fenced_div_end
+ local non_fenced_div_paragraph
+ = parsers.check_minimal_indent * V("Paragraph")
+ - parsers.check_minimal_indent_and_trail * fenced_div_end
local blank = parsers.minimally_indented_blank
- local block_separated = parsers.block_sep_group(blank)
- * non_fenced_div_block
+ local block_separated = parsers.block_sep_group(blank)
+ * non_fenced_div_block
- local loop_body_pair = parsers.create_loop_body_pair(block_separated,
- non_fenced_div_paragraph,
- parsers.block_sep_group(blank),
- parsers.par_sep_group(blank))
+ local loop_body_pair
+ = parsers.create_loop_body_pair(block_separated,
+ non_fenced_div_paragraph,
+ parsers.block_sep_group(blank),
+ parsers.par_sep_group(blank))
local content_loop = ( non_fenced_div_block
* loop_body_pair.block^0
@@ -31478,7 +33324,9 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
local FencedDiv = fenced_div_begin
/ function (infostring)
- local attr = lpeg.match(Ct(parsers.attributes), infostring)
+ local attr
+ = lpeg.match(Ct(parsers.attributes),
+ infostring)
if attr == nil then
attr = {"." .. infostring}
end
@@ -31489,7 +33337,8 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
* parsers.skipblanklines
* Ct(content_loop)
* parsers.minimally_indented_blank^0
- * parsers.check_minimal_indent_and_trail * fenced_div_end
+ * parsers.check_minimal_indent_and_trail
+ * fenced_div_end
* decrement_div_level()
* (Cc("") / writer.div_end)
@@ -31499,7 +33348,6 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
self.add_special_character(":")
% \end{macrocode}
-% \par
% \begin{markdown}
%
% If the `blank_before_div_fence` parameter is `false`, we will have the
@@ -31510,23 +33358,27 @@ M.extensions.fenced_divs = function(blank_before_div_fence)
% \end{markdown}
% \begin{macrocode}
local function is_inside_div()
- local function check_div_level(s, i, fenced_div_level) -- luacheck: ignore s i
- fenced_div_level = tonumber(fenced_div_level)
- return fenced_div_level > 0
- end
+ local check_div_level =
+ function(s, i, fenced_div_level) -- luacheck: ignore s i
+ fenced_div_level = tonumber(fenced_div_level)
+ return fenced_div_level > 0
+ end
return Cmt(Cb("fenced_div_level"), check_div_level)
end
local function check_indent()
- local function compare_indent(s, i, indent_table, -- luacheck: ignore s i
- fenced_div_num_opening_indents, fenced_div_level)
- fenced_div_level = tonumber(fenced_div_level)
- local num_current_indents = (indent_table.current_line_indents ~= nil and
- #indent_table.current_line_indents) or 0
- local num_opening_indents = fenced_div_num_opening_indents[fenced_div_level]
- return num_current_indents == num_opening_indents
- end
+ local compare_indent =
+ function(s, i, indent_table, -- luacheck: ignore s i
+ fenced_div_num_opening_indents, fenced_div_level)
+ fenced_div_level = tonumber(fenced_div_level)
+ local num_current_indents
+ = ( indent_table.current_line_indents ~= nil and
+ #indent_table.current_line_indents) or 0
+ local num_opening_indents
+ = fenced_div_num_opening_indents[fenced_div_level]
+ return num_current_indents == num_opening_indents
+ end
return Cmt( Cb("indent_info")
* Cb("fenced_div_num_opening_indents")
@@ -31598,26 +33450,31 @@ M.extensions.header_attributes = function()
* parsers.newline))^1
- parsers.thematic_break_lines
- local heading_text = heading_line
- * ((V("Endline") / "\n") * (heading_line - parsers.heading_level))^0
- * parsers.newline^-1
-
- local SetextHeading = parsers.freeze_trail * parsers.check_trail_no_rem
- * #(heading_text
- * (parsers.attributes
- * parsers.optionalspace
- * parsers.newline)^-1
- * parsers.check_minimal_indent * parsers.check_trail * parsers.heading_level)
- * Cs(heading_text) / strip_trailing_spaces
- / parsers.parse_heading_text
- * Cg(Ct((parsers.attributes
- * parsers.optionalspace
- * parsers.newline)^-1), "attributes")
- * parsers.check_minimal_indent_and_trail * parsers.heading_level
- * Cb("attributes")
- * parsers.newline
- * parsers.unfreeze_trail
- / writer.heading
+ local heading_text
+ = heading_line
+ * ( (V("Endline") / "\n")
+ * (heading_line - parsers.heading_level))^0
+ * parsers.newline^-1
+
+ local SetextHeading
+ = parsers.freeze_trail * parsers.check_trail_no_rem
+ * #(heading_text
+ * (parsers.attributes
+ * parsers.optionalspace
+ * parsers.newline)^-1
+ * parsers.check_minimal_indent
+ * parsers.check_trail
+ * parsers.heading_level)
+ * Cs(heading_text) / strip_trailing_spaces
+ / parsers.parse_heading_text
+ * Cg(Ct((parsers.attributes
+ * parsers.optionalspace
+ * parsers.newline)^-1), "attributes")
+ * parsers.check_minimal_indent_and_trail * parsers.heading_level
+ * Cb("attributes")
+ * parsers.newline
+ * parsers.unfreeze_trail
+ / writer.heading
local Heading = AtxHeading + SetextHeading
self.update_rule("Heading", Heading)
@@ -31666,7 +33523,6 @@ M.extensions.line_blocks = function()
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
@@ -31691,18 +33547,18 @@ M.extensions.line_blocks = function()
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
+ 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")
@@ -31724,7 +33580,6 @@ M.extensions.mark = function()
name = "built-in mark syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->mark} as a function that will transform an input
@@ -31742,8 +33597,9 @@ M.extensions.mark = function()
local doubleequals = P("==")
- local Mark = parsers.between(V("Inline"), doubleequals, doubleequals)
- / function (inlines) return writer.mark(inlines) end
+ local Mark
+ = parsers.between(V("Inline"), doubleequals, doubleequals)
+ / function (inlines) return writer.mark(inlines) end
self.add_special_character("=")
self.insert_pattern("Inline before LinkAndEmph",
@@ -31776,13 +33632,18 @@ M.extensions.link_attributes = function()
%
% \end{markdown}
% \begin{macrocode}
- local define_reference_parser = (parsers.check_trail / "") * parsers.link_label * parsers.colon
- * parsers.spnlc * parsers.url
- * ( parsers.spnlc_sep * parsers.title * (parsers.spnlc * Ct(parsers.attributes))
- * parsers.only_blank
- + parsers.spnlc_sep * parsers.title * parsers.only_blank
- + Cc("") * (parsers.spnlc * Ct(parsers.attributes)) * parsers.only_blank
- + Cc("") * parsers.only_blank)
+ local define_reference_parser
+ = (parsers.check_trail / "")
+ * parsers.link_label
+ * parsers.colon
+ * parsers.spnlc * parsers.url
+ * ( parsers.spnlc_sep * parsers.title
+ * (parsers.spnlc * Ct(parsers.attributes))
+ * parsers.only_blank
+ + parsers.spnlc_sep * parsers.title * parsers.only_blank
+ + Cc("") * (parsers.spnlc * Ct(parsers.attributes))
+ * parsers.only_blank
+ + Cc("") * parsers.only_blank)
local ReferenceWithAttributes = define_reference_parser
/ self.register_link
@@ -31797,8 +33658,10 @@ M.extensions.link_attributes = function()
% \end{markdown}
% \begin{macrocode}
- local LinkWithAttributesAndEmph = Ct(parsers.link_and_emph_table * Cg(Cc(true), "match_link_attributes"))
- / self.defer_link_and_emphasis_processing
+ local LinkWithAttributesAndEmph
+ = Ct(parsers.link_and_emph_table * Cg(Cc(true),
+ "match_link_attributes"))
+ / self.defer_link_and_emphasis_processing
self.update_rule("LinkAndEmph", LinkWithAttributesAndEmph)
@@ -31863,7 +33726,6 @@ M.extensions.notes = function(notes, inline_notes)
name = "built-in notes syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->note} as a function that will transform an
@@ -31883,9 +33745,10 @@ M.extensions.notes = function(notes, inline_notes)
if inline_notes then
local InlineNote
- = parsers.circumflex
- * (parsers.link_label / self.parser_functions.parse_inlines_no_inline_note)
- / writer.note
+ = parsers.circumflex
+ * ( parsers.link_label
+ / self.parser_functions.parse_inlines_no_inline_note)
+ / writer.note
self.insert_pattern("Inline after LinkAndEmph",
InlineNote, "InlineNote")
@@ -31923,26 +33786,37 @@ M.extensions.notes = function(notes, inline_notes)
local NoteRef = RawNoteRef / lookup_note
- local optionally_indented_line = parsers.check_optional_indent_and_any_trail * parsers.line
+ local optionally_indented_line
+ = parsers.check_optional_indent_and_any_trail * parsers.line
- local blank = parsers.check_optional_blank_indent_and_any_trail * parsers.optionalspace * parsers.newline
+ local blank
+ = parsers.check_optional_blank_indent_and_any_trail
+ * parsers.optionalspace * parsers.newline
- local chunk = Cs(parsers.line * (optionally_indented_line - blank)^0)
+ local chunk
+ = Cs(parsers.line
+ * (optionally_indented_line - blank)^0)
local indented_blocks = function(bl)
return Cs( bl
- * (blank^1 * (parsers.check_optional_indent / "")
- * parsers.check_code_trail * -parsers.blankline * bl)^0)
+ * ( blank^1 * (parsers.check_optional_indent / "")
+ * parsers.check_code_trail
+ * -parsers.blankline * bl)^0)
end
local NoteBlock
- = parsers.check_trail_no_rem * RawNoteRef * parsers.colon
+ = parsers.check_trail_no_rem
+ * RawNoteRef * parsers.colon
* parsers.spnlc * indented_blocks(chunk)
/ register_note
- local Reference = NoteBlock + parsers.Reference
+ self.update_rule("Reference", function(previous_pattern)
+ if previous_pattern == nil then
+ previous_pattern = parsers.Reference
+ end
+ return NoteBlock + previous_pattern
+ end)
- self.update_rule("Reference", Reference)
self.insert_pattern("Inline before LinkAndEmph",
NoteRef, "NoteRef")
end
@@ -32024,7 +33898,6 @@ M.extensions.pipe_tables = function(table_captions, table_attributes)
name = "built-in pipe_tables syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->table} as a function that will transform an input
@@ -32094,24 +33967,26 @@ M.extensions.pipe_tables = function(table_captions, table_attributes)
, table_hline_separator
, table_hline_column)
- local table_caption_beginning = (parsers.check_minimal_blank_indent_and_any_trail_no_rem
- * parsers.optionalspace * parsers.newline)^0
- * parsers.check_minimal_indent_and_trail
- * (P("Table")^-1 * parsers.colon)
- * parsers.optionalspace
+ local table_caption_beginning
+ = ( parsers.check_minimal_blank_indent_and_any_trail_no_rem
+ * parsers.optionalspace * parsers.newline)^0
+ * parsers.check_minimal_indent_and_trail
+ * (P("Table")^-1 * parsers.colon)
+ * parsers.optionalspace
local function strip_trailing_spaces(s)
return s:gsub("%s*$","")
end
- local table_row = pipe_table_row(true
- , (C((parsers.linechar - parsers.pipe)^1)
- / strip_trailing_spaces
- / self.parser_functions.parse_inlines)
- , parsers.pipe
- , (C((parsers.linechar - parsers.pipe)^0)
- / strip_trailing_spaces
- / self.parser_functions.parse_inlines))
+ local table_row
+ = pipe_table_row(true
+ , (C((parsers.linechar - parsers.pipe)^1)
+ / strip_trailing_spaces
+ / self.parser_functions.parse_inlines)
+ , parsers.pipe
+ , (C((parsers.linechar - parsers.pipe)^0)
+ / strip_trailing_spaces
+ / self.parser_functions.parse_inlines))
local table_caption
if table_captions then
@@ -32128,7 +34003,8 @@ M.extensions.pipe_tables = function(table_captions, table_attributes)
+ ( parsers.newline
* #( parsers.optionalspace
* parsers.linechar)
- * C(parsers.optionalspace) / writer.space))
+ * C(parsers.optionalspace)
+ / writer.space))
* (parsers.linechar
- parsers.lbrace)^0)^1)
/ self.parser_functions.parse_inlines)
@@ -32142,7 +34018,8 @@ M.extensions.pipe_tables = function(table_captions, table_attributes)
+ ( parsers.newline
* #( parsers.optionalspace
* parsers.linechar)
- * C(parsers.optionalspace) / writer.space))^1)
+ * C(parsers.optionalspace)
+ / writer.space))^1)
/ self.parser_functions.parse_inlines
* parsers.newline
end
@@ -32150,12 +34027,15 @@ M.extensions.pipe_tables = function(table_captions, table_attributes)
table_caption = parsers.fail
end
- local PipeTable = Ct(table_row * parsers.newline * (parsers.check_minimal_indent_and_trail / {})
- * table_hline * parsers.newline
- * ((parsers.check_minimal_indent / {}) * table_row * parsers.newline)^0)
- / make_pipe_table_rectangular
- * table_caption^-1
- / writer.table
+ local PipeTable
+ = Ct( table_row * parsers.newline
+ * (parsers.check_minimal_indent_and_trail / {})
+ * table_hline * parsers.newline
+ * ( (parsers.check_minimal_indent / {})
+ * table_row * parsers.newline)^0)
+ / make_pipe_table_rectangular
+ * table_caption^-1
+ / writer.table
self.insert_pattern("Block after Blockquote",
PipeTable, "PipeTable")
@@ -32179,7 +34059,6 @@ M.extensions.raw_inline = function()
local options = self.options
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->rawInline} as a function that will transform an
@@ -32221,7 +34100,6 @@ M.extensions.strike_through = function()
name = "built-in strike_through syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->strike_through} as a function that will transform
@@ -32264,7 +34142,6 @@ M.extensions.subscripts = function()
name = "built-in subscripts syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->subscript} as a function that will transform
@@ -32306,7 +34183,6 @@ M.extensions.superscripts = function()
name = "built-in superscripts syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->superscript} as a function that will transform
@@ -32323,7 +34199,8 @@ M.extensions.superscripts = function()
local writer = self.writer
local Superscript = (
- parsers.between(parsers.Str, parsers.circumflex, parsers.circumflex)
+ parsers.between(parsers.Str, parsers.circumflex,
+ parsers.circumflex)
) / writer.superscript
self.insert_pattern("Inline after LinkAndEmph",
@@ -32350,7 +34227,6 @@ M.extensions.tex_math = function(tex_math_dollars,
name = "built-in tex_math syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->display_math} as a function that will transform
@@ -32386,11 +34262,13 @@ M.extensions.tex_math = function(tex_math_dollars,
return str:gsub("^%s*(.-)$", "%1")
end
- local allowed_before_closing = B( parsers.backslash * parsers.any
- + parsers.any * (parsers.any - parsers.backslash))
+ local allowed_before_closing
+ = B( parsers.backslash * parsers.any
+ + parsers.any * (parsers.any - parsers.backslash))
- local allowed_before_closing_no_space = B( parsers.backslash * parsers.any
- + parsers.any * (parsers.nonspacechar - parsers.backslash))
+ local allowed_before_closing_no_space
+ = B( parsers.backslash * parsers.any
+ + parsers.any * (parsers.nonspacechar - parsers.backslash))
% \end{macrocode}
% \begin{markdown}
@@ -32399,18 +34277,20 @@ M.extensions.tex_math = function(tex_math_dollars,
%
% \end{markdown}
% \begin{macrocode}
- local dollar_math_content = (parsers.newline * (parsers.check_optional_indent / "")
- + parsers.backslash^-1
- * parsers.linechar)
- - parsers.blankline^2
- - parsers.dollar
+ local dollar_math_content
+ = (parsers.newline * (parsers.check_optional_indent / "")
+ + parsers.backslash^-1
+ * parsers.linechar)
+ - parsers.blankline^2
+ - parsers.dollar
local inline_math_opening_dollars = parsers.dollar
* #(parsers.nonspacechar)
- local inline_math_closing_dollars = allowed_before_closing_no_space
- * parsers.dollar
- * -#(parsers.digit)
+ local inline_math_closing_dollars
+ = allowed_before_closing_no_space
+ * parsers.dollar
+ * -#(parsers.digit)
local inline_math_dollars = between(Cs( dollar_math_content),
inline_math_opening_dollars,
@@ -32433,9 +34313,10 @@ M.extensions.tex_math = function(tex_math_dollars,
%
% \end{markdown}
% \begin{macrocode}
- local backslash_math_content = (parsers.newline * (parsers.check_optional_indent / "")
- + parsers.linechar)
- - parsers.blankline^2
+ local backslash_math_content
+ = (parsers.newline * (parsers.check_optional_indent / "")
+ + parsers.linechar)
+ - parsers.blankline^2
% \end{macrocode}
% \begin{markdown}
%
@@ -32555,16 +34436,19 @@ end
% \acro{yaml} metadata block syntax extension. 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.
+% but \acro{yaml} metadata. When both `expect_jekyll_data` and
+% `ensure_jekyll_data` parameters are `true`, then a a markdown document must
+% begin directly with \acro{yaml} metadata and must contain nothing but
+% \acro{yaml} metadata.
%
% \end{markdown}
% \begin{macrocode}
-M.extensions.jekyll_data = function(expect_jekyll_data)
+M.extensions.jekyll_data = function(expect_jekyll_data,
+ ensure_jekyll_data)
return {
name = "built-in jekyll_data syntax extension",
extend_writer = function(self)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Define \luamdef{writer->jekyllData} as a function that will transform an
@@ -32572,7 +34456,8 @@ M.extensions.jekyll_data = function(expect_jekyll_data)
% the key `p` in the parent table; if `p` is nil, then the table has no parent.
% All scalar keys and values encountered in the table will be cast to a string
% following \acro{yaml} serialization rules. String values will also be
-% transformed using the function `t`.
+% transformed using the function `t` for the typographic output format used by
+% the \mref{markdownRendererJekyllDataTypographicString} macro.
%
% \end{markdown}
% \begin{macrocode}
@@ -32617,17 +34502,18 @@ M.extensions.jekyll_data = function(expect_jekyll_data)
::not_a_sequence::
if is_sequence then
- table.insert(buf, "\\markdownRendererJekyllDataSequenceBegin{")
- table.insert(buf, self.identifier(p or "null"))
- table.insert(buf, "}{")
- table.insert(buf, #keys)
- table.insert(buf, "}")
+ table.insert(buf,
+ "\\markdownRendererJekyllDataSequenceBegin{")
+ table.insert(buf, self.identifier(p or "null"))
+ table.insert(buf, "}{")
+ table.insert(buf, #keys)
+ table.insert(buf, "}")
else
- table.insert(buf, "\\markdownRendererJekyllDataMappingBegin{")
- table.insert(buf, self.identifier(p or "null"))
- table.insert(buf, "}{")
- table.insert(buf, #keys)
- table.insert(buf, "}")
+ table.insert(buf, "\\markdownRendererJekyllDataMappingBegin{")
+ table.insert(buf, self.identifier(p or "null"))
+ table.insert(buf, "}{")
+ table.insert(buf, #keys)
+ table.insert(buf, "}")
end
for _, k in ipairs(keys) do
@@ -32655,7 +34541,14 @@ M.extensions.jekyll_data = function(expect_jekyll_data)
table.insert(buf, v)
table.insert(buf, "}")
elseif typ == "string" then
- table.insert(buf, "\\markdownRendererJekyllDataString{")
+ table.insert(buf,
+ "\\markdownRendererJekyllDataProgrammaticString{")
+ table.insert(buf, k)
+ table.insert(buf, "}{")
+ table.insert(buf, self.identifier(v))
+ table.insert(buf, "}")
+ table.insert(buf,
+ "\\markdownRendererJekyllDataTypographicString{")
table.insert(buf, k)
table.insert(buf, "}{")
table.insert(buf, t(v))
@@ -32665,8 +34558,10 @@ M.extensions.jekyll_data = function(expect_jekyll_data)
table.insert(buf, k)
table.insert(buf, "}")
else
- error(format("Unexpected type %s for value of " ..
- "YAML key %s", typ, k))
+ local error = self.error(format(
+ "Unexpected type %s for value of "
+ .. "YAML key %s.", typ, k))
+ table.insert(buf, error)
end
end
end
@@ -32688,38 +34583,48 @@ M.extensions.jekyll_data = function(expect_jekyll_data)
local writer = self.writer
local JekyllData
- = Cmt( C((parsers.line - P("---") - P("..."))^0)
- , function(s, i, text) -- luacheck: ignore s i
- local data
- local ran_ok, _ = pcall(function()
- -- TODO: Replace with `require("tinyyaml")` in TeX Live 2023
- local tinyyaml = require("markdown-tinyyaml")
- data = tinyyaml.parse(text, {timestamps=false})
- end)
- if ran_ok and data ~= nil then
- return true, writer.jekyllData(data, function(s)
- return self.parser_functions.parse_blocks_nested(s)
- end, nil)
- else
- return false
- end
- end
- )
+ = Cmt( C((parsers.line - P("---") - P("..."))^0)
+ , function(s, i, text) -- luacheck: ignore s i
+ local data
+ local ran_ok, _ = pcall(function()
+ local tinyyaml = require("tinyyaml")
+ data = tinyyaml.parse(text, {timestamps=false})
+ end)
+ if ran_ok and data ~= nil then
+ return true, writer.jekyllData(data, function(s)
+ return self.parser_functions.parse_blocks_nested(s)
+ end, nil)
+ else
+ return false
+ end
+ end
+ )
local UnexpectedJekyllData
- = P("---")
- * parsers.blankline / 0
- * #(-parsers.blankline) -- if followed by blank, it's thematic break
- * JekyllData
- * (P("---") + P("..."))
+ = P("---")
+ * parsers.blankline / 0
+ -- if followed by blank, it's thematic break
+ * #(-parsers.blankline)
+ * JekyllData
+ * (P("---") + P("..."))
local ExpectedJekyllData
- = ( P("---")
- * parsers.blankline / 0
- * #(-parsers.blankline) -- if followed by blank, it's thematic break
- )^-1
- * JekyllData
- * (P("---") + P("..."))^-1
+ = ( P("---")
+ * parsers.blankline / 0
+ -- if followed by blank, it's thematic break
+ * #(-parsers.blankline)
+ )^-1
+ * JekyllData
+ * (P("---") + P("..."))^-1
+
+ if ensure_jekyll_data then
+ ExpectedJekyllData = ExpectedJekyllData
+ * parsers.eof
+ else
+ ExpectedJekyllData = ( ExpectedJekyllData
+ * (V("Blank")^0 / writer.interblocksep)
+ )^-1
+ end
self.insert_pattern("Block before Blockquote",
UnexpectedJekyllData, "UnexpectedJekyllData")
@@ -32734,15 +34639,124 @@ end
%
%### Conversion from Markdown to Plain \TeX{}
%
-% The \luamref{new} function returns a conversion function that takes a
-% markdown string and turns it into a plain \TeX{} output. See Section
-% <#sec:lua-conversion>.
+% The \luamref{new} function of file `markdown.lua` loads file
+% `markdown-parser.lua` and calls its own function \luamref{new} unless option
+% \Opt{eagerCache} or \Opt{finalizeCache} has been enabled and a cached
+% conversion output exists, in which case it is returned without loading file
+% `markdown-parser.lua`.
+%
+% \end{markdown}
+% \iffalse
+%</lua>
+%<*lua-loader>
+% \fi
+% \begin{macrocode}
+function M.new(options)
+% \end{macrocode}
+% \begin{markdown}
+%
+% Make the `options` table inherit from the \luamref{defaultOptions} table.
+%
+% \end{markdown}
+% \begin{macrocode}
+ options = options or {}
+ setmetatable(options, { __index = function (_, key)
+ return defaultOptions[key] end })
+% \end{macrocode}
+% \begin{markdown}
+%
+% Return a conversion function that tries to produce a cached conversion output
+% exists. If no cached conversion output exists, we load the file
+% `markdown-parser.lua` and use it to convert the input.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local parser_convert = nil
+ return function(input)
+ local function convert(input)
+ if parser_convert == nil then
+% \end{macrocode}
+% \begin{markdown}
+%
+% Lazy-load `markdown-parser.lua` and check that it originates from the same
+% version of the Markdown package.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local parser = require("markdown-parser")
+ if metadata.version ~= parser.metadata.version then
+ warn("markdown.lua " .. metadata.version .. " used with " ..
+ "markdown-parser.lua " .. parser.metadata.version .. ".")
+ end
+ parser_convert = parser.new(options)
+ end
+ return parser_convert(input)
+ end
+% \end{macrocode}
+% \begin{markdown}
+% If we cache markdown documents, produce the cache file and transform its
+% filename to plain \TeX{} output.
+%
+% When determining the name of the cache file, create salt for the hashing
+% function out of the package version and the passed options recognized by the
+% Lua interface (see Section <#sec:lua-options>).
+% \end{markdown}
+% \begin{macrocode}
+ local output
+ if options.eagerCache or options.finalizeCache then
+ local salt = util.salt(options)
+ local name = util.cache(options.cacheDir, input, salt, convert,
+ ".md.tex")
+ output = [[\input{]] .. name .. [[}\relax]]
+% \end{macrocode}
+% \begin{markdown}
+% Otherwise, return the result of the conversion directly.
+% \end{markdown}
+% \begin{macrocode}
+ else
+ output = convert(input)
+ end
+% \end{macrocode}
+% \begin{markdown}
+% If the \Opt{finalizeCache} option is enabled, populate the frozen cache in
+% the file \Opt{frozenCacheFileName} with an entry for markdown document
+% number \Opt{frozenCacheCounter}.
+% \end{markdown}
+% \begin{macrocode}
+ if options.finalizeCache then
+ local file, mode
+ if options.frozenCacheCounter > 0 then
+ mode = "a"
+ else
+ mode = "w"
+ end
+ file = assert(io.open(options.frozenCacheFileName, mode),
+ [[Could not open file "]] .. options.frozenCacheFileName
+ .. [[" for writing]])
+ assert(file:write(
+ [[\expandafter\global\expandafter\def\csname ]]
+ .. [[markdownFrozenCache]] .. options.frozenCacheCounter
+ .. [[\endcsname{]] .. output .. [[}]] .. "\n"))
+ assert(file:close())
+ end
+ return output
+ end
+end
+% \end{macrocode}
+% \iffalse
+%</lua-loader>
+%<*lua>
+% \fi
+% \begin{markdown}
+%
+% The \luamref{new} function from file `markdown-parser.lua` returns a
+% conversion function that takes a markdown string and turns it into a plain
+% \TeX{} output. See Section <#sec:lua-conversion>.
%
% \end{markdown}
% \begin{macrocode}
function M.new(options)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Make the `options` table inherit from the \luamref{defaultOptions} table.
@@ -32753,7 +34767,6 @@ function M.new(options)
setmetatable(options, { __index = function (_, key)
return defaultOptions[key] end })
% \end{macrocode}
-% \par
% \begin{markdown}
%
% If the singleton cache contains a conversion function for the same `options`,
@@ -32769,7 +34782,15 @@ function M.new(options)
goto miss
end
end
- elseif singletonCache.options[k] ~= options[k] then
+% \end{macrocode}
+% \begin{markdown}
+%
+% The \Opt{cacheDir} option is disregarded.
+%
+% \end{markdown}
+% \begin{macrocode}
+ elseif k ~= "cacheDir"
+ and singletonCache.options[k] ~= options[k] then
goto miss
end
end
@@ -32777,7 +34798,6 @@ function M.new(options)
end
::miss::
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Apply built-in syntax extensions based on `options`.
@@ -32830,7 +34850,7 @@ function M.new(options)
if options.jekyllData then
local jekyll_data_extension = M.extensions.jekyll_data(
- options.expectJekyllData)
+ options.expectJekyllData, options.ensureJekyllData)
table.insert(extensions, jekyll_data_extension)
end
@@ -32893,7 +34913,8 @@ function M.new(options)
end
if options.citations then
- local citations_extension = M.extensions.citations(options.citationNbsps)
+ local citations_extension
+ = M.extensions.citations(options.citationNbsps)
table.insert(extensions, citations_extension)
end
@@ -32902,7 +34923,6 @@ function M.new(options)
table.insert(extensions, fancy_lists_extension)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Apply user-defined syntax extensions based on `options.extensions`.
@@ -32918,7 +34938,9 @@ function M.new(options)
%
% \end{markdown}
% \begin{macrocode}
- local pathname = kpse.lookup(filename)
+ local pathname = assert(kpse.find_file(filename),
+ [[Could not locate user-defined syntax extension "]]
+ .. filename)
local input_file = assert(io.open(pathname, "r"),
[[Could not open user-defined syntax extension "]]
.. pathname .. [[" for reading]])
@@ -32948,7 +34970,8 @@ function M.new(options)
.. type(user_extension.api_version)
.. [[" but "number" was expected]])
assert(user_extension.api_version > 0
- and user_extension.api_version <= metadata.user_extension_api_version,
+ and user_extension.api_version
+ <= metadata.user_extension_api_version,
[[User-defined syntax extension "]] .. pathname
.. [[" uses syntax extension API version "]]
.. user_extension.api_version .. [[ but markdown.lua ]]
@@ -32966,7 +34989,8 @@ function M.new(options)
.. [[" but "number" was expected]])
assert(user_extension.grammar_version == metadata.grammar_version,
[[User-defined syntax extension "]] .. pathname
- .. [[" uses grammar version "]] .. user_extension.grammar_version
+ .. [[" uses grammar version "]]
+ .. user_extension.grammar_version
.. [[ but markdown.lua ]] .. metadata.version
.. [[ uses grammar version ]] .. metadata.grammar_version
.. [[, which is incompatible]])
@@ -32998,7 +35022,6 @@ function M.new(options)
table.insert(extensions, user_extension)
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Produce a conversion function from markdown to plain \TeX.
@@ -33009,7 +35032,6 @@ function M.new(options)
local reader = M.reader.new(writer, options)
local convert = reader.finalize_grammar(extensions)
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Force garbage collection to reclaim memory for temporary
@@ -33020,7 +35042,6 @@ function M.new(options)
% \begin{macrocode}
collectgarbage("collect")
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Update the singleton cache.
@@ -33039,7 +35060,6 @@ function M.new(options)
singletonCache.convert = convert
end
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Return the conversion function from markdown to plain \TeX.
@@ -33048,14 +35068,18 @@ function M.new(options)
% \begin{macrocode}
return convert
end
-
-return M
% \end{macrocode}
% \iffalse
%</lua>
+%<*lua,lua-loader>
+% \fi
+% \begin{macrocode}
+return M
+% \end{macrocode}
+% \iffalse
+%</lua,lua-loader>
%<*lua-cli>
% \fi
-% \par
% \begin{markdown}
%
%### Command-Line Implementation {#lua-cli-implementation}
@@ -33131,14 +35155,13 @@ end
% \end{markdown}
% \begin{macrocode}
if options.cacheDir then
- lfs.rmdir(options["cacheDir"])
+ lfs.rmdir(options.cacheDir)
end
% \end{macrocode}
% \iffalse
%</lua-cli>
%<*tex>
% \fi
-% \par
% \begin{markdown}
%
% Plain \TeX{} Implementation {#teximplementation}
@@ -33211,66 +35234,130 @@ end
{ nnee }
\ExplSyntaxOff
% \end{macrocode}
-% \par
% \begin{markdown}
%
%### Themes {#themes-implementation}
%
% This section implements the theme-loading mechanism and the built-in themes
-% provided with the Markdown package. Futhermore, this section also implements
+% provided with the Markdown package. Furthermore, this section also implements
% the built-in plain \TeX{} themes provided with the Markdown package.
%
% \end{markdown}
% \begin{macrocode}
\ExplSyntaxOn
\prop_new:N \g_@@_plain_tex_loaded_themes_linenos_prop
+\prop_new:N \g_@@_plain_tex_loaded_themes_versions_prop
\cs_new:Nn
- \@@_plain_tex_load_theme:nn
+ \@@_plain_tex_load_theme:nnn
{
\prop_get:NnNTF
\g_@@_plain_tex_loaded_themes_linenos_prop
{ #1 }
\l_tmpa_tl
{
- \msg_warning:nnnV
- { markdown }
- { repeatedly-loaded-plain-tex-theme }
+ \prop_get:NnN
+ \g_@@_plain_tex_loaded_themes_versions_prop
{ #1 }
- \l_tmpa_tl
+ \l_tmpb_tl
+ \str_if_eq:nVTF
+ { #2 }
+ \l_tmpb_tl
+ {
+ \msg_warning:nnnVn
+ { markdown }
+ { repeatedly-loaded-plain-tex-theme }
+ { #1 }
+ \l_tmpa_tl
+ { #2 }
+ }
+ {
+ \msg_error:nnnnVV
+ { markdown }
+ { different-versions-of-plain-tex-theme }
+ { #1 }
+ { #2 }
+ \l_tmpb_tl
+ \l_tmpa_tl
+ }
}
{
- \msg_info:nnn
- { markdown }
- { loading-plain-tex-theme }
- { #1 }
\prop_gput:Nnx
\g_@@_plain_tex_loaded_themes_linenos_prop
{ #1 }
- { \tex_the:D \tex_inputlineno:D }
- \file_input:n
- { markdown theme #2 }
+ { \tex_the:D \tex_inputlineno:D } % noqa: W200
+ \prop_gput:Nnn
+ \g_@@_plain_tex_loaded_themes_versions_prop
+ { #1 }
+ { #2 }
+% \end{macrocode}
+% \begin{markdown}
+%
+% Load built-in plain \TeX{} themes from the prop
+% \mref{g_@@_plain_tex_built_in_themes_prop} and from the filesystem otherwise.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \prop_if_in:NnTF
+ \g_@@_plain_tex_built_in_themes_prop
+ { #1 }
+ {
+ \msg_info:nnnn
+ { markdown }
+ { loading-built-in-plain-tex-theme }
+ { #1 }
+ { #2 }
+ \prop_item:Nn
+ \g_@@_plain_tex_built_in_themes_prop
+ { #1 }
+ }
+ {
+ \msg_info:nnnn
+ { markdown }
+ { loading-plain-tex-theme }
+ { #1 }
+ { #2 }
+ \file_input:n
+ { markdown theme #3 }
+ }
}
}
\msg_new:nnn
{ markdown }
{ loading-plain-tex-theme }
- { Loading~plain~TeX~Markdown~theme~#1 }
+ { Loading~version~#2~of~plain~TeX~Markdown~theme~#1 }
+\msg_new:nnn
+ { markdown }
+ { loading-built-in-plain-tex-theme }
+ { Loading~version~#2~of~built-in~plain~TeX~Markdown~theme~#1 }
\msg_new:nnn
{ markdown }
{ repeatedly-loaded-plain-tex-theme }
{
- Plain~TeX~Markdown~theme~#1~was~previously~
+ Version~#3~of~plain~TeX~Markdown~theme~#1~was~previously~
loaded~on~line~#2,~not~loading~it~again
}
+\msg_new:nnn
+ { markdown }
+ { different-versions-of-plain-tex-theme }
+ {
+ Tried~to~load~version~#2~of~plain~TeX~Markdown~theme~#1~
+ but~version~#3~has~already~been~loaded~on~line~#4
+ }
\cs_generate_variant:Nn
\prop_gput:Nnn
{ Nnx }
\cs_gset_eq:NN
- \@@_load_theme:nn
- \@@_plain_tex_load_theme:nn
+ \@@_load_theme:nnn
+ \@@_plain_tex_load_theme:nnn
\cs_generate_variant:Nn
- \@@_load_theme:nn
- { nV }
+ \@@_load_theme:nnn
+ { VeV }
+\cs_generate_variant:Nn
+ \msg_error:nnnnnn
+ { nnnnVV }
+\cs_generate_variant:Nn
+ \msg_warning:nnnnn
+ { nnnVn }
% \end{macrocode}
% \begin{markdown}
%
@@ -33325,23 +35412,623 @@ end
%
% \end{markdown}
% \begin{macrocode}
- \@@_plain_tex_load_theme:VV
+ \@@_plain_tex_load_theme:VeV
\l_tmpb_tl
+ { \markdownThemeVersion }
\l_tmpa_str
}
\cs_generate_variant:Nn
\tl_set:Nn
{ Ne }
\cs_generate_variant:Nn
- \@@_plain_tex_load_theme:nn
- { VV }
-\ExplSyntaxOff
+ \@@_plain_tex_load_theme:nnn
+ { VeV }
+% \end{macrocode}
+% \begin{markdown}
+%
+% The `witiko/dot` theme nags users that they should use the name
+% `witiko/diagrams@v1` instead.
+%
+% \end{markdown}
+% \begin{macrocode}
+\prop_gput:Nnn
+ \g_@@_plain_tex_built_in_themes_prop
+ { witiko / dot }
+ {
+ \str_if_eq:enF
+ { \markdownThemeVersion }
+ { silent }
+ {
+ \markdownWarning
+ {
+ The~theme~name~"witiko/dot"~has~been~soft-deprecated.
+ \iow_newline:
+ Consider~changing~the~name~to~"witiko/diagrams@v1".
+ }
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% We enable the \Opt{fencedCode} Lua option.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \markdownSetup { fencedCode }
+% \end{macrocode}
+% \begin{markdown}
+%
+% We store the previous definition of the fenced code token renderer prototype:
+%
+% \end{markdown}
+% \begin{macrocode}
+ \cs_set_eq:NN
+ \@@_dot_previous_definition:nnn
+ \markdownRendererInputFencedCodePrototype
+% \end{macrocode}
+% \begin{markdown}
+%
+% If the infostring starts with `dot …`, we redefine the fenced code block
+% token renderer prototype, so that it typesets the code block via Graphviz
+% tools if and only if the \Opt{frozenCache} plain \TeX{} option is
+% disabled and the code block has not been previously typeset:
+%
+% \end{markdown}
+% \begin{macrocode}
+ \regex_const:Nn
+ \c_@@_dot_infostring_regex
+ { ^dot(\s+(.+))? }
+ \seq_new:N
+ \l_@@_dot_matches_seq
+ \markdownSetup {
+ rendererPrototypes = {
+ inputFencedCode = {
+ \regex_extract_once:NnNTF
+ \c_@@_dot_infostring_regex
+ { #2 }
+ \l_@@_dot_matches_seq
+ {
+ \@@_if_option:nF
+ { frozenCache }
+ {
+ \sys_shell_now:n
+ {
+ if~!~test~-e~#1.pdf.source~
+ ||~!~diff~#1~#1.pdf.source;
+ then~
+ dot~-Tpdf~-o~#1.pdf~#1;
+ cp~#1~#1.pdf.source;
+ fi
+ }
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% We include the typeset image using the image token renderer:
+%
+% \end{markdown}
+% \begin{macrocode}
+ \exp_args:NNne
+ \exp_last_unbraced:No
+ \markdownRendererImage
+ {
+ { Graphviz~image }
+ { #1.pdf }
+ { #1.pdf }
+ }
+ {
+ \seq_item:Nn
+ \l_@@_dot_matches_seq
+ { 3 }
+ }
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% If the infostring does not start with `dot …`, we use the previous definition
+% of the fenced code token renderer prototype:
+%
+% \end{markdown}
+% \begin{macrocode}
+ {
+ \@@_dot_previous_definition:nnn
+ { #1 }
+ { #2 }
+ { #3 }
+ }
+ },
+ },
+ }
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% The theme `witiko/diagrams` loads either the theme `witiko/dot` for version
+% `v1` or the theme `witiko/diagrams/v2` for version `v2`.
+%
+% \end{markdown}
+% \begin{macrocode}
+\prop_gput:Nnn
+ \g_@@_plain_tex_built_in_themes_prop
+ { witiko / diagrams }
+ {
+ \str_case:enF
+ { \markdownThemeVersion }
+ {
+ { latest }
+ {
+ \markdownWarning
+ {
+ Write~"witiko/diagrams@v2"~to~pin~version~"v2"~of~the~
+ theme~"witiko/diagrams".~This~will~keep~your~documents~
+ from~suddenly~breaking~when~we~have~released~future~
+ versions~of~the~theme~with~backwards-incompatible~
+ syntax~and~behavior.
+ }
+ \markdownSetup
+ {
+ import = witiko/diagrams/v2,
+ }
+ }
+ { v2 }
+ {
+ \markdownSetup
+ {
+ import = witiko/diagrams/v2,
+ }
+ }
+ { v1 }
+ {
+ \markdownSetup
+ {
+ import = witiko/dot@silent,
+ }
+ }
+ }
+ {
+ \msg_error:nnnen
+ { markdown }
+ { unknown-theme-version }
+ { witiko/diagrams }
+ { \markdownThemeVersion }
+ { v1 }
+ }
+ }
+\cs_generate_variant:Nn
+ \msg_error:nnnnn
+ { nnnen }
+\msg_new:nnnn
+ { markdown }
+ { unknown-theme-version }
+ { Unknown~version~"#2"~of~theme~"#1"~has~been~requested. }
+ { Known~versions~are:~#3 }
+% \end{macrocode}
+% \begin{markdown}
+%
+% Next, we implement the theme `witiko/diagrams/v2`.
+%
+% \end{markdown}
+% \begin{macrocode}
+\prop_gput:Nnn
+ \g_@@_plain_tex_built_in_themes_prop
+ { witiko / diagrams / v2 }
+ {
+% \end{macrocode}
+% \begin{markdown}
+%
+% We enable the \Opt{fencedCode} and \Opt{fencedCodeAttributes} Lua
+% option.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \@@_setup:n
+ {
+ fencedCode = true,
+ fencedCodeAttributes = true,
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% Store the previous fenced code token renderer prototype.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \cs_set_eq:NN
+ \@@_diagrams_previous_fenced_code:nnn
+ \markdownRendererInputFencedCodePrototype
+% \end{macrocode}
+% \begin{markdown}
+%
+% Store the caption of the diagram.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \tl_new:N
+ \l_@@_diagrams_caption_tl
+ \@@_setup:n
+ {
+ rendererPrototypes = {
+% \end{macrocode}
+% \begin{markdown}
+%
+% Route attributes on fenced code blocks to the image attribute renderer
+% prototypes.
+%
+% \end{markdown}
+% \begin{macrocode}
+ fencedCodeAttributeContextBegin = {
+ \group_begin:
+ \markdownRendererImageAttributeContextBegin
+ \cs_set_eq:NN
+ \@@_diagrams_previous_key_value:nn
+ \markdownRendererAttributeKeyValuePrototype
+ \@@_setup:n
+ {
+ rendererPrototypes = {
+ attributeKeyValue = {
+ \str_if_eq:nnTF
+ { ##1 }
+ { caption }
+ {
+ \tl_set:Nn
+ \l_@@_diagrams_caption_tl
+ { ##2 }
+ }
+ {
+ \@@_diagrams_previous_key_value:nn
+ { ##1 }
+ { ##2 }
+ }
+ },
+ },
+ }
+ },
+ fencedCodeAttributeContextEnd = {
+ \markdownRendererImageAttributeContextEnd
+ \group_end:
+ },
+ },
+ }
+ \cs_new:Nn
+ \@@_diagrams_render_diagram:nnnn
+ {
+ \@@_if_option:nF
+ { frozenCache }
+ {
+ \sys_shell_now:n
+ {
+ if~!~test~-e~#2.source~
+ ||~!~diff~#1~#2.source;
+ then~
+ (#3);
+ cp~#1~#2.source;
+ fi
+ }
+ \exp_args:NNnV
+ \exp_last_unbraced:No
+ \markdownRendererImage
+ {
+ { #4 }
+ { #2 }
+ { #2 }
+ }
+ \l_@@_diagrams_caption_tl
+ }
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% Use the prop \mdef{g_markdown_diagrams_infostrings_prop} to determine how the
+% code with a given infostring should be processed and routed to the token
+% renderer prototype(s) for images.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \prop_new:N
+ \g_markdown_diagrams_infostrings_prop
+% \end{macrocode}
+% \begin{markdown}
+%
+% If we know a processing function for a given infostring, use it.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \@@_setup:n
+ {
+ rendererPrototypes = {
+ inputFencedCode = {
+ \prop_get:NnNTF
+ \g_markdown_diagrams_infostrings_prop
+ { #2 }
+ \l_tmpa_tl
+ {
+ \cs_set:NV
+ \@@_diagrams_infostrings_current:n
+ \l_tmpa_tl
+ \@@_diagrams_infostrings_current:n
+ { #1 }
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% Otherwise, use the previous fenced code token renderer prototype.
+%
+% \end{markdown}
+% \begin{macrocode}
+ {
+ \@@_diagrams_previous_fenced_code:nnn
+ { #1 }
+ { #2 }
+ { #3 }
+ }
+ },
+ },
+ }
+ \cs_generate_variant:Nn
+ \cs_set:Nn
+ { NV }
+% \end{macrocode}
+% \begin{markdown}
+%
+% Typeset fenced code with infostring `dot` using the command `dot` from
+% the package Graphviz.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \cs_set:Nn
+ \@@_diagrams_infostrings_current:n
+ {
+ \@@_diagrams_render_diagram:nnnn
+ { #1 }
+ { #1.pdf }
+ { dot~-Tpdf~-o~#1.pdf~#1 }
+ { Graphviz~image }
+ }
+ \@@_tl_set_from_cs:NNn
+ \l_tmpa_tl
+ \@@_diagrams_infostrings_current:n
+ { 1 }
+ \prop_gput:NnV
+ \g_markdown_diagrams_infostrings_prop
+ { dot }
+ \l_tmpa_tl
+% \end{macrocode}
+% \begin{markdown}
+%
+% Typeset fenced code with infostring `mermaid` using the command `mmdc` from
+% the npm package `@mermaid-js/mermaid-cli`.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \cs_set:Nn
+ \@@_diagrams_infostrings_current:n
+ {
+ \@@_diagrams_render_diagram:nnnn
+ { #1 }
+ { #1.pdf }
+ { mmdc~--pdfFit~-i~#1~-o~#1.pdf }
+ { Mermaid~image }
+ }
+ \@@_tl_set_from_cs:NNn
+ \l_tmpa_tl
+ \@@_diagrams_infostrings_current:n
+ { 1 }
+ \prop_gput:NnV
+ \g_markdown_diagrams_infostrings_prop
+ { mermaid }
+ \l_tmpa_tl
+% \end{macrocode}
+% \begin{markdown}
+%
+% Typeset fenced code with infostring `plantuml` using the command `plantuml`
+% from the package PlantUML.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \regex_const:Nn
+ \c_@@_diagrams_filename_suffix_regex
+ { \.[^.]*$ }
+ \cs_set:Nn
+ \@@_diagrams_infostrings_current:n
+ {
+ \tl_set:Nn
+ \l_tmpa_tl
+ { #1 }
+ \regex_replace_once:NnN
+ \c_@@_diagrams_filename_suffix_regex
+ { .pdf }
+ \l_tmpa_tl
+ \@@_diagrams_render_diagram:nVnn
+ { #1 }
+ \l_tmpa_tl
+ { plantuml~-tpdf~#1 }
+ { PlantUML~image }
+ }
+ \cs_generate_variant:Nn
+ \@@_diagrams_render_diagram:nnnn
+ { nVnn }
+ \@@_tl_set_from_cs:NNn
+ \l_tmpa_tl
+ \@@_diagrams_infostrings_current:n
+ { 1 }
+ \prop_gput:NnV
+ \g_markdown_diagrams_infostrings_prop
+ { plantuml }
+ \l_tmpa_tl
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% We locally change the category code of percent signs, so that we
+% can use them in the shell code:
+%
+% \end{markdown}
+% \begin{macrocode}
+\group_begin:
+\char_set_catcode_other:N \%
+% \end{macrocode}
+% \begin{markdown}
+%
+% The `witiko/graphicx/http` theme stores the previous definition of the image
+% token renderer prototype:
+%
+% \end{markdown}
+% \begin{macrocode}
+\prop_gput:Nnn
+ \g_@@_plain_tex_built_in_themes_prop
+ { witiko / graphicx / http }
+ {
+ \cs_set_eq:NN
+ \@@_graphicx_http_previous_definition:nnnn
+ \markdownRendererImagePrototype
+% \end{macrocode}
+% \begin{markdown}
+%
+% We define variables and functions to enumerate the images for caching and to
+% store the pathname of the file containing the pathname of the downloaded
+% image file.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \int_new:N
+ \g_@@_graphicx_http_image_number_int
+ \int_gset:Nn
+ \g_@@_graphicx_http_image_number_int
+ { 0 }
+ \cs_new:Nn
+ \@@_graphicx_http_filename:
+ {
+ \markdownOptionCacheDir
+ / witiko_graphicx_http .
+ \int_use:N
+ \g_@@_graphicx_http_image_number_int
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% We define a function that will receive two arguments that correspond to the
+% URL of the online image and to the pathname, where the online image should
+% be downloaded. The function produces a shell command that tries to
+% downloads the online image to the pathname.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \cs_new:Nn
+ \@@_graphicx_http_download:nn
+ {
+ wget~-O~#2~#1~
+ ||~curl~--location~-o~#2~#1~
+ ||~rm~-f~#2
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% We redefine the image token renderer prototype, so that it tries to download
+% an online image.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \str_new:N
+ \l_@@_graphicx_http_filename_str
+ \ior_new:N
+ \g_@@_graphicx_http_filename_ior
+ \markdownSetup {
+ rendererPrototypes = {
+ image = {
+ \@@_if_option:nF
+ { frozenCache }
+ {
+% \end{macrocode}
+% \begin{markdown}
+%
+% The image will be downloaded only if the image URL has the http or https
+% protocols and the \Opt{frozenCache} plain \TeX{} option is disabled:
+%
+% \end{markdown}
+% \begin{macrocode}
+ \sys_shell_now:e
+ {
+ mkdir~-p~" \markdownOptionCacheDir ";
+ if~printf~'%s'~"#3"~|~grep~-q~-E~'^https?:';
+ then~
+% \end{macrocode}
+% \begin{markdown}
+%
+% The image will be downloaded to the pathname \Opt{cacheDir}<!--
+% -->`/`\meta{the MD5 digest of the image URL}`.`\meta{the suffix of the
+% image URL}:
+%
+% \end{markdown}
+% \begin{macrocode}
+ OUTPUT_PREFIX=" \markdownOptionCacheDir ";
+ OUTPUT_BODY="$(printf~'%s'~'#3'
+ |~md5sum~|~cut~-d'~'~-f1)";
+ OUTPUT_SUFFIX="$(printf~'%s'~'#3'
+ |~sed~'s/.*[.]//')";
+ OUTPUT="$OUTPUT_PREFIX/$OUTPUT_BODY.$OUTPUT_SUFFIX";
+% \end{macrocode}
+% \begin{markdown}
+%
+% The image will be downloaded only if it has not already been downloaded:
+%
+% \end{markdown}
+% \begin{macrocode}
+ if~!~[~-e~"$OUTPUT"~];
+ then~
+ \@@_graphicx_http_download:nn
+ { '#3' }
+ { "$OUTPUT" } ;
+ printf~'%s'~"$OUTPUT"~
+ >~" \@@_graphicx_http_filename: ";
+ fi;
+% \end{macrocode}
+% \begin{markdown}
+%
+% If the image does not have the http or https protocols or the image has
+% already been downloaded, the URL will be stored as-is:
+%
+% \end{markdown}
+% \begin{macrocode}
+ else~
+ printf~'%s'~'#3'~
+ >~" \@@_graphicx_http_filename: ";
+ fi
+ }
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% We load the pathname of the downloaded image and we typeset the image using
+% the previous definition of the image renderer prototype:
+%
+% \end{markdown}
+% \begin{macrocode}
+ \ior_open:Ne
+ \g_@@_graphicx_http_filename_ior
+ { \@@_graphicx_http_filename: }
+ \ior_str_get:NN
+ \g_@@_graphicx_http_filename_ior
+ \l_@@_graphicx_http_filename_str
+ \ior_close:N
+ \g_@@_graphicx_http_filename_ior
+ \@@_graphicx_http_previous_definition:nnVn
+ { #1 }
+ { #2 }
+ \l_@@_graphicx_http_filename_str
+ { #4 }
+ \int_gincr:N
+ \g_@@_graphicx_http_image_number_int
+ }
+ }
+ }
+ \cs_generate_variant:Nn
+ \ior_open:Nn
+ { Ne }
+ \cs_generate_variant:Nn
+ \@@_graphicx_http_previous_definition:nnnn
+ { nnVn }
+ }
+\group_end:
% \end{macrocode}
-% \iffalse
-%</tex>
-%<*themes-witiko-tilde>
-% \fi
-% \par
% \begin{markdown}
%
% The `witiko/tilde` theme redefines the tilde token renderer prototype,
@@ -33349,14 +36036,43 @@ end
%
% \end{markdown}
% \begin{macrocode}
-\markdownSetup {
- rendererPrototypes = {
- tilde = {~},
- },
-}
+\prop_gput:Nnn
+ \g_@@_plain_tex_built_in_themes_prop
+ { witiko / tilde }
+ {
+ \markdownSetup {
+ rendererPrototypes = {
+ tilde = {~},
+ },
+ }
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% The themes `witiko/example/foo` and `witiko/example/bar` are supposed to be
+% used in code examples. They don't do anything.
+%
+% \end{markdown}
+% \begin{macrocode}
+\clist_map_inline:nn
+ { foo, bar }
+ {
+ \prop_gput:Nnn
+ \g_@@_plain_tex_built_in_themes_prop
+ { witiko / example / #1 }
+ {
+ \markdownWarning
+ {
+ The~theme~witiko/example/#1~is~supposed~to~be~used~in~code~
+ examples.~Using~it~in~actual~code~has~no~effect,~except~
+ this~warning~message,~and~is~usually~a~mistake.
+ }
+ }
+ }
+\ExplSyntaxOff
% \end{macrocode}
% \iffalse
-%</themes-witiko-tilde>
+%</tex>
%<*themes-witiko-markdown-defaults-tex>
% \fi
% \begin{markdown}
@@ -33406,18 +36122,22 @@ end
\def\markdownRendererUlEndTightPrototype{}%
\def\markdownRendererOlBeginPrototype{}%
\def\markdownRendererOlBeginTightPrototype{}%
-\def\markdownRendererFancyOlBeginPrototype#1#2{\markdownRendererOlBegin}%
-\def\markdownRendererFancyOlBeginTightPrototype#1#2{\markdownRendererOlBeginTight}%
+\def\markdownRendererFancyOlBeginPrototype#1#2{%
+ \markdownRendererOlBegin}%
+\def\markdownRendererFancyOlBeginTightPrototype#1#2{%
+ \markdownRendererOlBeginTight}%
\def\markdownRendererOlItemPrototype{}%
\def\markdownRendererOlItemWithNumberPrototype#1{}%
\def\markdownRendererOlItemEndPrototype{}%
\def\markdownRendererFancyOlItemPrototype{\markdownRendererOlItem}%
-\def\markdownRendererFancyOlItemWithNumberPrototype{\markdownRendererOlItemWithNumber}%
+\def\markdownRendererFancyOlItemWithNumberPrototype{%
+ \markdownRendererOlItemWithNumber}%
\def\markdownRendererFancyOlItemEndPrototype{}%
\def\markdownRendererOlEndPrototype{}%
\def\markdownRendererOlEndTightPrototype{}%
\def\markdownRendererFancyOlEndPrototype{\markdownRendererOlEnd}%
-\def\markdownRendererFancyOlEndTightPrototype{\markdownRendererOlEndTight}%
+\def\markdownRendererFancyOlEndTightPrototype{%
+ \markdownRendererOlEndTight}%
\def\markdownRendererDlBeginPrototype{}%
\def\markdownRendererDlBeginTightPrototype{}%
\def\markdownRendererDlItemPrototype#1{#1}%
@@ -33491,8 +36211,29 @@ end
\ExplSyntaxOff
\def\markdownRendererSectionBeginPrototype{}%
\def\markdownRendererSectionEndPrototype{}%
+\ExplSyntaxOn
+\cs_gset:Npn
+ \markdownRendererWarningPrototype
+ #1#2#3#4
+ {
+ \tl_set:Nn
+ \l_tmpa_tl
+ { #2 }
+ \tl_if_empty:nF
+ { #4 }
+ {
+ \tl_put_right:Nn
+ \l_tmpa_tl
+ { \iow_newline: #4 }
+ }
+ \exp_args:NV
+ \markdownWarning
+ \l_tmpa_tl
+ }
+\ExplSyntaxOff
+\def\markdownRendererErrorPrototype#1#2#3#4{%
+ \markdownError{#2}{#4}}%
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Raw Attributes
@@ -33505,7 +36246,7 @@ end
% \begin{macrocode}
\ExplSyntaxOn
\cs_new:Nn
- \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_inline:nn
{
\str_case:nn
{ #2 }
@@ -33515,7 +36256,7 @@ end
}
}
\cs_new:Nn
- \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_block:nn
{
\str_case:nn
{ #2 }
@@ -33527,23 +36268,25 @@ end
\cs_gset:Npn
\markdownRendererInputRawInlinePrototype#1#2
{
- \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_inline:nn
{ #1 }
{ #2 }
}
\cs_gset:Npn
\markdownRendererInputRawBlockPrototype#1#2
{
- \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_block:nn
{ #1 }
{ #2 }
}
\ExplSyntaxOff
% \end{macrocode}
-% \par
% \begin{markdown}
%
-%#### YAML Metadata Renderer Prototypes
+%#### Simple YAML Metadata Renderer Prototypes
+% In this section, we implement the simple high-level interface for processing
+% simple \acro{YAML} metadata using the key--value `markdown/jekyllData`. See
+% also Section <#sec:expl3yamlmetadata>.
%
% To keep track of the current type of structure we inhabit when we are
% traversing a \acro{yaml} document, we will maintain the
@@ -33573,18 +36316,17 @@ end
\tl_const:Nn \c_@@_jekyll_data_mapping_tl { mapping }
\tl_const:Nn \c_@@_jekyll_data_scalar_tl { scalar }
% \end{macrocode}
-% \par
% \begin{markdown}
%
% To keep track of our current place when we are traversing a \acro{yaml}
% document, we will maintain the
% \mdef{g_\@\@_jekyll_data_wildcard_absolute_address_seq} stack of keys using
-% the \mdef{markdown_jekyll_data_push_address_segment:n} macro.
+% the \mdef{\@\@_jekyll_data_push_address_segment:n} macro.
%
% \end{markdown}
% \begin{macrocode}
\seq_new:N \g_@@_jekyll_data_wildcard_absolute_address_seq
-\cs_new:Nn \markdown_jekyll_data_push_address_segment:n
+\cs_new:Nn \@@_jekyll_data_push_address_segment:n
{
\seq_if_empty:NF
\g_@@_jekyll_data_datatypes_seq
@@ -33619,7 +36361,6 @@ end
}
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Out of \mref{g_\@\@_jekyll_data_wildcard_absolute_address_seq}, we will
@@ -33650,23 +36391,23 @@ end
% ```
%
% We will construct \mref{g_\@\@_jekyll_data_wildcard_absolute_address_tl}
-% using the \mdef{markdown_jekyll_data_concatenate_address:NN} macro and
+% using the \mdef{\@\@_jekyll_data_concatenate_address:NN} macro and
% we will construct both token lists using the
-% \mdef{markdown_jekyll_data_update_address_tls:} macro.
+% \mdef{\@\@_jekyll_data_update_address_tls:} macro.
%
% \end{markdown}
% \begin{macrocode}
\tl_new:N \g_@@_jekyll_data_wildcard_absolute_address_tl
\tl_new:N \g_@@_jekyll_data_wildcard_relative_address_tl
-\cs_new:Nn \markdown_jekyll_data_concatenate_address:NN
+\cs_new:Nn \@@_jekyll_data_concatenate_address:NN
{
\seq_pop_left:NN #1 \l_tmpa_tl
\tl_set:Nx #2 { / \seq_use:Nn #1 { / } }
\seq_put_left:NV #1 \l_tmpa_tl
}
-\cs_new:Nn \markdown_jekyll_data_update_address_tls:
+\cs_new:Nn \@@_jekyll_data_update_address_tls:
{
- \markdown_jekyll_data_concatenate_address:NN
+ \@@_jekyll_data_concatenate_address:NN
\g_@@_jekyll_data_wildcard_absolute_address_seq
\g_@@_jekyll_data_wildcard_absolute_address_tl
\seq_get_right:NN
@@ -33674,25 +36415,24 @@ end
\g_@@_jekyll_data_wildcard_relative_address_tl
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% To make sure that the stacks and token lists stay in sync, we will use the
-% \mdef{markdown_jekyll_data_push:nN} and \mdef{markdown_jekyll_data_pop:}
+% \mdef{\@\@_jekyll_data_push:nN} and \mdef{\@\@_jekyll_data_pop:}
% macros.
%
% \end{markdown}
% \begin{macrocode}
-\cs_new:Nn \markdown_jekyll_data_push:nN
+\cs_new:Nn \@@_jekyll_data_push:nN
{
- \markdown_jekyll_data_push_address_segment:n
+ \@@_jekyll_data_push_address_segment:n
{ #1 }
\seq_put_right:NV
\g_@@_jekyll_data_datatypes_seq
#2
- \markdown_jekyll_data_update_address_tls:
+ \@@_jekyll_data_update_address_tls:
}
-\cs_new:Nn \markdown_jekyll_data_pop:
+\cs_new:Nn \@@_jekyll_data_pop:
{
\seq_pop_right:NN
\g_@@_jekyll_data_wildcard_absolute_address_seq
@@ -33700,43 +36440,41 @@ end
\seq_pop_right:NN
\g_@@_jekyll_data_datatypes_seq
\l_tmpa_tl
- \markdown_jekyll_data_update_address_tls:
+ \@@_jekyll_data_update_address_tls:
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% To set a single key--value, we will use the
-% \mdef{markdown_jekyll_data_set_keyval:Nn} macro, ignoring unknown keys.
+% \mdef{\@\@_jekyll_data_set_keyval_known:nn} macro, ignoring unknown keys.
% To set key--values for both absolute and relative wildcards, we will use the
-% \mdef{markdown_jekyll_data_set_keyvals:nn} macro.
+% \mdef{\@\@_jekyll_data_set_keyvals_known:nn} macro.
%
% \end{markdown}
% \begin{macrocode}
-\cs_new:Nn \markdown_jekyll_data_set_keyval:nn
+\cs_new:Nn \@@_jekyll_data_set_keyval_known:nn
{
\keys_set_known:nn
{ markdown/jekyllData }
{ { #1 } = { #2 } }
}
\cs_generate_variant:Nn
- \markdown_jekyll_data_set_keyval:nn
+ \@@_jekyll_data_set_keyval_known:nn
{ Vn }
-\cs_new:Nn \markdown_jekyll_data_set_keyvals:nn
+\cs_new:Nn \@@_jekyll_data_set_keyvals_known:nn
{
- \markdown_jekyll_data_push:nN
+ \@@_jekyll_data_push:nN
{ #1 }
\c_@@_jekyll_data_scalar_tl
- \markdown_jekyll_data_set_keyval:Vn
+ \@@_jekyll_data_set_keyval_known:Vn
\g_@@_jekyll_data_wildcard_absolute_address_tl
{ #2 }
- \markdown_jekyll_data_set_keyval:Vn
+ \@@_jekyll_data_set_keyval_known:Vn
\g_@@_jekyll_data_wildcard_relative_address_tl
{ #2 }
- \markdown_jekyll_data_pop:
+ \@@_jekyll_data_pop:
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Finally, we will register our macros as token renderer prototypes
@@ -33745,39 +36483,338 @@ end
% \end{markdown}
% \begin{macrocode}
\def\markdownRendererJekyllDataSequenceBeginPrototype#1#2{
- \markdown_jekyll_data_push:nN
+ \@@_jekyll_data_push:nN
{ #1 }
\c_@@_jekyll_data_sequence_tl
}
\def\markdownRendererJekyllDataMappingBeginPrototype#1#2{
- \markdown_jekyll_data_push:nN
+ \@@_jekyll_data_push:nN
{ #1 }
\c_@@_jekyll_data_mapping_tl
}
\def\markdownRendererJekyllDataSequenceEndPrototype{
- \markdown_jekyll_data_pop:
+ \@@_jekyll_data_pop:
}
\def\markdownRendererJekyllDataMappingEndPrototype{
- \markdown_jekyll_data_pop:
+ \@@_jekyll_data_pop:
}
\def\markdownRendererJekyllDataBooleanPrototype#1#2{
- \markdown_jekyll_data_set_keyvals:nn
+ \@@_jekyll_data_set_keyvals_known:nn
{ #1 }
{ #2 }
}
\def\markdownRendererJekyllDataEmptyPrototype#1{}
\def\markdownRendererJekyllDataNumberPrototype#1#2{
- \markdown_jekyll_data_set_keyvals:nn
+ \@@_jekyll_data_set_keyvals_known:nn
{ #1 }
{ #2 }
}
-\def\markdownRendererJekyllDataStringPrototype#1#2{
- \markdown_jekyll_data_set_keyvals:nn
+% \end{macrocode}
+% \begin{markdown}
+%
+% We will process all string scalar values assuming that they may contain
+% markdown markup and are intended for typesetting.
+%
+% \end{markdown}
+% \begin{macrocode}
+\def\markdownRendererJekyllDataProgrammaticStringPrototype#1#2{}
+\def\markdownRendererJekyllDataTypographicStringPrototype#1#2{
+ \@@_jekyll_data_set_keyvals_known:nn
{ #1 }
{ #2 }
}
\ExplSyntaxOff
% \end{macrocode}
+% \begin{markdown}
+%
+%#### Complex YAML Metadata Renderer Prototypes
+% In this section, we implement the high-level interface for routing complex
+% \acro{YAML} metadata to expl3 key--values using the option
+% `jekyllDataKeyValue`=\meta{module}. See also Section <#sec:expl3yamlmetadata>.
+%
+% \end{markdown}
+% \begin{macrocode}
+\ExplSyntaxOn
+\@@_with_various_cases:nn
+ { jekyllDataKeyValue }
+ {
+ \keys_define:nn
+ { markdown/options }
+ {
+ #1 .code:n = {
+ \@@_route_jekyll_data_to_key_values:n
+ { ##1 }
+ },
+% \end{macrocode}
+% \begin{markdown}
+%
+% When no \meta{module} has been provided, assume that the \acro{YAML} metadata
+% specify absolute paths to key--values.
+%
+% \end{markdown}
+% \begin{macrocode}
+ #1 .default:n = { },
+ }
+ }
+\seq_new:N
+ \l_@@_jekyll_data_current_position_seq
+\tl_new:N
+ \l_@@_jekyll_data_current_position_tl
+\cs_new:Nn
+ \@@_route_jekyll_data_to_key_values:n
+ {
+ \markdownSetup
+ {
+ renderers = {
+ jekyllData(Sequence|Mapping)Begin = {
+ \bool_lazy_and:nnTF
+ {
+ \seq_if_empty_p:N
+ \l_@@_jekyll_data_current_position_seq
+ }
+ {
+ \str_if_eq_p:nn
+ { ##1 }
+ { null }
+ }
+ {
+ \tl_if_empty:nF
+ { #1 }
+ {
+ \seq_put_right:Nn
+ \l_@@_jekyll_data_current_position_seq
+ { #1 }
+ }
+ }
+ {
+ \seq_put_right:Nn
+ \l_@@_jekyll_data_current_position_seq
+ { ##1 }
+ }
+ },
+ jekyllData(Sequence|Mapping)End = {
+ \seq_pop_right:NN
+ \l_@@_jekyll_data_current_position_seq
+ \l_tmpa_tl
+ },
+% \end{macrocode}
+% \begin{markdown}
+%
+% For every \acro{YAML} key `path.to.`\meta{key} with a value of type
+% \meta{non-string type}, set the key \meta{non-string type} of the key–value
+% \meta{module}`/path/to/`\meta{key} if it is known and the key \meta{key} of
+% the key–value \meta{module}`/path/to` otherwise. \meta{Non-string type} is
+% one of `boolean`, `number`, and `empty`.
+%
+% \end{markdown}
+% \begin{macrocode}
+ jekyllDataBoolean = {
+ \tl_set:Nx
+ \l_@@_jekyll_data_current_position_tl
+ {
+ \seq_use:Nn
+ \l_@@_jekyll_data_current_position_seq
+ { / }
+ }
+ \keys_if_exist:VnTF
+ \l_@@_jekyll_data_current_position_tl
+ { ##1 / boolean }
+ {
+ \@@_keys_set:xn
+ {
+ \tl_use:N
+ \l_@@_jekyll_data_current_position_tl
+ / ##1 / boolean
+ }
+ { ##2 }
+ }
+ {
+ \@@_keys_set:xn
+ {
+ \tl_use:N
+ \l_@@_jekyll_data_current_position_tl
+ / ##1
+ }
+ { ##2 }
+ }
+ },
+ jekyllDataNumber = {
+ \tl_set:Nx
+ \l_@@_jekyll_data_current_position_tl
+ {
+ \seq_use:Nn
+ \l_@@_jekyll_data_current_position_seq
+ { / }
+ }
+ \keys_if_exist:VnTF
+ \l_@@_jekyll_data_current_position_tl
+ { ##1 / number }
+ {
+ \@@_keys_set:xn
+ {
+ \tl_use:N
+ \l_@@_jekyll_data_current_position_tl
+ / ##1 / number
+ }
+ { ##2 }
+ }
+ {
+ \@@_keys_set:xn
+ {
+ \tl_use:N
+ \l_@@_jekyll_data_current_position_tl
+ / ##1
+ }
+ { ##2 }
+ }
+ },
+% \end{macrocode}
+% \begin{markdown}
+%
+% For the \meta{non-string type} of `empty`, no value is passed to the
+% key–value. Therefore, a default value should always be defined for nullable
+% keys using the key property `.default:n`.
+%
+% \end{markdown}
+% \begin{macrocode}
+ jekyllDataEmpty = {
+ \tl_set:Nx
+ \l_@@_jekyll_data_current_position_tl
+ {
+ \seq_use:Nn
+ \l_@@_jekyll_data_current_position_seq
+ { / }
+ }
+ \keys_if_exist:VnTF
+ \l_@@_jekyll_data_current_position_tl
+ { ##1 / empty }
+ {
+ \keys_set:xn
+ {
+ \tl_use:N
+ \l_@@_jekyll_data_current_position_tl
+ / ##1
+ }
+ { empty }
+ }
+ {
+ \keys_set:Vn
+ \l_@@_jekyll_data_current_position_tl
+ { ##1 }
+ }
+ },
+% \end{macrocode}
+% \begin{markdown}
+%
+% For every \acro{YAML} key `path.to.`\meta{key} with a value of type `string`,
+% set the keys `typographicString` and `programmaticString` of the key–value
+% \meta{module}`/path/to/`\meta{key} if they are known with the typographic and
+% programmatic strings of the value, respectively. Furthermore, set the key
+% \meta{key} of the key–value \meta{module}`/path/to` with the typographic
+% string of the value unless the key `typographicString` is known. If the key
+% `programmaticString` is known, only set the key \meta{key} if it is known. In
+% contrast, if neither `typographicString` nor `programmaticString` are known,
+% set \meta{key} normally, i.e. regardless of whether it is known or unknown.
+%
+% \end{markdown}
+% \begin{macrocode}
+ jekyllDataTypographicString = {
+ \tl_set:Nx
+ \l_@@_jekyll_data_current_position_tl
+ {
+ \seq_use:Nn
+ \l_@@_jekyll_data_current_position_seq
+ { / }
+ }
+ \keys_if_exist:VnTF
+ \l_@@_jekyll_data_current_position_tl
+ { ##1 / typographicString }
+ {
+ \@@_keys_set:xn
+ {
+ \tl_use:N
+ \l_@@_jekyll_data_current_position_tl
+ / ##1 / typographicString
+ }
+ { ##2 }
+ }
+ {
+ \keys_if_exist:VnTF
+ \l_@@_jekyll_data_current_position_tl
+ { ##1 / programmaticString }
+ {
+ \@@_keys_set_known:xn
+ {
+ \tl_use:N
+ \l_@@_jekyll_data_current_position_tl
+ / ##1
+ }
+ { ##2 }
+ }
+ {
+ \@@_keys_set:xn
+ {
+ \tl_use:N
+ \l_@@_jekyll_data_current_position_tl
+ / ##1
+ }
+ { ##2 }
+ }
+ }
+ },
+ jekyllDataProgrammaticString = {
+ \tl_set:Nx
+ \l_@@_jekyll_data_current_position_tl
+ {
+ \seq_use:Nn
+ \l_@@_jekyll_data_current_position_seq
+ { / }
+ }
+ \keys_if_exist:VnT
+ \l_@@_jekyll_data_current_position_tl
+ { ##1 / programmaticString }
+ {
+ \@@_keys_set:xn
+ {
+ \tl_use:N
+ \l_@@_jekyll_data_current_position_tl
+ / ##1 / programmaticString
+ }
+ { ##2 }
+ }
+ },
+ },
+ }
+ }
+\cs_new:Nn
+ \@@_keys_set:nn
+ {
+ \keys_set:nn
+ { }
+ { { #1 } = { #2 } }
+ }
+\cs_new:Nn
+ \@@_keys_set_known:nn
+ {
+ \keys_set_known:nn
+ { }
+ { { #1 } = { #2 } }
+ }
+\cs_generate_variant:Nn
+ \@@_keys_set:nn
+ { xn }
+\cs_generate_variant:Nn
+ \@@_keys_set_known:nn
+ { xn }
+\cs_generate_variant:Nn
+ \keys_set:nn
+ { xn, Vn }
+\prg_generate_conditional_variant:Nnn
+ \keys_if_exist:nn
+ { Vn }
+ { T, TF }
+\ExplSyntaxOff
+% \end{macrocode}
% \iffalse
%</themes-witiko-markdown-defaults-tex>
%<*tex>
@@ -33796,14 +36833,24 @@ end
\c_@@_top_layer_tl
\c_@@_option_layer_plain_tex_tl
{
- \ExplSyntaxOff
+ \use:c
+ { ExplSyntaxOff }
\@@_if_option:nF
{ noDefaults }
{
- \@@_setup:n
- {theme = witiko/markdown/defaults}
+ \@@_if_option:nTF
+ { experimental }
+ {
+ \@@_setup:n
+ { theme = witiko/markdown/defaults@experimental }
+ }
+ {
+ \@@_setup:n
+ { theme = witiko/markdown/defaults }
+ }
}
- \ExplSyntaxOn
+ \use:c
+ { ExplSyntaxOn }
}
\ExplSyntaxOff
% \end{macrocode}
@@ -33853,7 +36900,7 @@ end
\l_tmpa_tl
\tl_gput_right:Nx
\g_@@_formatted_lua_options_tl
- { #1~=~ \l_tmpa_tl ,~ }
+ { #1~=~ \l_tmpa_tl ,~ }
}
{
\str_if_eq_p:VV
@@ -33870,9 +36917,18 @@ end
\clist_map_inline:Vn
\l_tmpa_tl
{
- \tl_gput_right:Nx
+ \@@_lua_escape:xN
+ { ##1 }
+ \l_tmpb_tl
+ \tl_gput_right:Nn
\g_@@_formatted_lua_options_tl
- { "##1" ,~ }
+ { " }
+ \tl_gput_right:NV
+ \g_@@_formatted_lua_options_tl
+ \l_tmpb_tl
+ \tl_gput_right:Nn
+ \g_@@_formatted_lua_options_tl
+ { " ,~ }
}
\tl_gput_right:Nx
\g_@@_formatted_lua_options_tl
@@ -33883,19 +36939,89 @@ end
\@@_get_option_value:nN
{ #1 }
\l_tmpa_tl
- \tl_gput_right:Nx
+ \@@_lua_escape:xN
+ { \l_tmpa_tl }
+ \l_tmpb_tl
+ \tl_gput_right:Nn
+ \g_@@_formatted_lua_options_tl
+ { #1~=~ " }
+ \tl_gput_right:NV
+ \g_@@_formatted_lua_options_tl
+ \l_tmpb_tl
+ \tl_gput_right:Nn
\g_@@_formatted_lua_options_tl
- { #1~=~ " \l_tmpa_tl " ,~ }
+ { " ,~ }
}
}
\cs_generate_variant:Nn
\clist_map_inline:nn
{ Vn }
-\let\markdownPrepareLuaOptions=\@@_format_lua_options:
-\def\markdownLuaOptions{{ \g_@@_formatted_lua_options_tl }}
-\ExplSyntaxOff
+\let
+ \markdownPrepareLuaOptions
+ \@@_format_lua_options:
+\def
+ \markdownLuaOptions
+ {
+ {
+ \g_@@_formatted_lua_options_tl
+ }
+ }
+\sys_if_engine_luatex:TF
+ {
+ \cs_new:Nn
+ \@@_lua_escape:nN
+ {
+ \tl_set:Nx
+ #2
+ {
+ \lua_escape:n
+ { #1 }
+ }
+ }
+ }
+ {
+ \regex_const:Nn
+ \c_@@_lua_escape_regex
+ { [\\"'] }
+ \cs_new:Nn
+ \@@_lua_escape:nN
+ {
+ \tl_set:Nn
+ #2
+ { #1 }
+ \regex_replace_all:NnN
+ \c_@@_lua_escape_regex
+ { \u { c_backslash_str } \0 }
+ #2
+ }
+ }
+\cs_generate_variant:Nn
+ \@@_lua_escape:nN
+ { xN }
+% \end{macrocode}
+% \begin{markdown}
+%
+% After the \mdef{markdownPrepareInputFilename} macro has been
+% fully expanded, the \mdef{markdownInputFilename} macro will
+% expands to a Lua string that contains the input filename passed
+% as the first argument.
+%
+% \end{markdown}
+% \begin{macrocode}
+\tl_new:N
+ \markdownInputFilename
+\cs_new:Npn
+ \markdownPrepareInputFilename
+ #1
+ {
+ \@@_lua_escape:xN
+ { #1 }
+ \markdownInputFilename
+ \tl_gset:Nx
+ \markdownInputFilename
+ { " \markdownInputFilename " }
+ }
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \mdef{markdownPrepare} macro contains the Lua code that is executed prior
@@ -33904,17 +37030,19 @@ end
%
% \end{markdown}
% \begin{macrocode}
-\def\markdownPrepare{%
+\cs_new:Npn
+ \markdownPrepare
+ {
% \end{macrocode}
% \begin{markdown}
% First, ensure that the \Opt{cacheDir} directory exists.
% \end{markdown}
% \begin{macrocode}
- local lfs = require("lfs")
- local cacheDir = "\markdownOptionCacheDir"
- if not lfs.isdir(cacheDir) then
- assert(lfs.mkdir(cacheDir))
- end
+ local~lfs = require("lfs")
+ local~options = \markdownLuaOptions
+ if~not~lfs.isdir(options.cacheDir) then~
+ assert(lfs.mkdir(options.cacheDir))
+ end~
% \end{macrocode}
% \begin{markdown}
% Next, load the `markdown` module and create a converter function using
@@ -33922,11 +37050,30 @@ end
% \mref{markdownLuaOptions} macro.
% \end{markdown}
% \begin{macrocode}
- local md = require("markdown")
- local convert = md.new(\markdownLuaOptions)
-}%
+ local~md = require("markdown")
+ local~convert = md.new(options)
+ }
+% \end{macrocode}
+% \begin{markdown}
+%
+% The \mdef{markdownConvert} macro contains the Lua code that is executed
+% during the conversion from markdown to plain \TeX{}. It opens the
+% input file, converts it, and prints the conversion result.
+%
+% \end{markdown}
+% \begin{macrocode}
+\cs_new:Npn
+ \markdownConvert
+ {
+ local~filename = \markdownInputFilename
+ local~file = assert(io.open(filename, "r"),
+ [[Could~not~open~file~"]] .. filename .. [["~for~reading]])
+ local~input = assert(file:read("*a"))
+ assert(file:close())
+ print(convert(input))
+ }
+\ExplSyntaxOff
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \mdef{markdownCleanup} macro contains the Lua code that is executed
@@ -33940,10 +37087,11 @@ end
% Remove the `options.cacheDir` directory if it is empty.
% \end{markdown}
% \begin{macrocode}
- lfs.rmdir(cacheDir)
+ if options.cacheDir then
+ lfs.rmdir(options.cacheDir)
+ end
}%
% \end{macrocode}
-% \par
% \begin{markdown}
%
%### Buffering Block-Level Markdown Input {#buffering-block}
@@ -33957,7 +37105,6 @@ end
\csname newread\endcsname\markdownInputFileStream
\csname newwrite\endcsname\markdownOutputFileStream
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \mdef{markdownReadAndConvertTab} macro contains the tab character literal.
@@ -33969,7 +37116,6 @@ end
\gdef\markdownReadAndConvertTab{^^I}%
\endgroup
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \mref{markdownReadAndConvert} macro is largely a rewrite of the
@@ -34127,7 +37273,6 @@ end
% \begin{macrocode}
|endgroup
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Use the \pkg{lt3luabridge} library to define the \mdef{markdownLuaExecute}
@@ -34161,6 +37306,9 @@ end
}
}
}
+ \str_gset:NV
+ \g_luabridge_output_dirname_str
+ \markdownOptionOutputDir
\luabridge_now:e
{ #1 }
}
@@ -34297,12 +37445,14 @@ end
\msg_new:nnn
{ markdown }
{ buffering-markinline }
- { Buffering~inline~markdown~input~into~the~temporary~input~file~"#1". }
+ { Buffering~inline~markdown~input~into~
+ the~temporary~input~file~"#1". }
\msg_new:nnnn
{ markdown }
{ markinline-peek-failure }
{ Use~of~\iow_char:N \\ markinline~doesn't~match~its~definition }
- { The~macro~should~be~followed~by~inline~markdown~text~in~curly~braces }
+ { The~macro~should~be~followed~by~inline~
+ markdown~text~in~curly~braces }
\ExplSyntaxOff
% \end{macrocode}
% \begin{markdown}
@@ -34321,6 +37471,13 @@ end
\markdownInput
#1
{
+ \@@_if_option:nTF
+ { frozenCache }
+ {
+ \markdownInputRaw
+ { #1 }
+ }
+ {
% \end{macrocode}
% \begin{markdown}
%
@@ -34330,19 +37487,23 @@ end
%
% \end{markdown}
% \begin{macrocode}
- \file_get_full_name:nNTF
- { #1 }
- \l_tmpa_tl
- {
- \exp_args:NV
- \markdownInputRaw
+ \tl_set:Nx
\l_tmpa_tl
- }
- {
- \msg_error:nnnV
- { markdown }
- { markdown-file-does-not-exist }
{ #1 }
+ \file_get_full_name:VNTF
+ \l_tmpa_tl
+ \l_tmpb_tl
+ {
+ \exp_args:NV
+ \markdownInputRaw
+ \l_tmpb_tl
+ }
+ {
+ \msg_error:nnV
+ { markdown }
+ { markdown-file-does-not-exist }
+ \l_tmpa_tl
+ }
}
}
\msg_new:nnn
@@ -34396,7 +37557,8 @@ end
|fi
|markdownInfo{Including markdown document number
"|the|markdownOptionFrozenCacheCounter" from frozen cache}%
- |csname markdownFrozenCache|the|markdownOptionFrozenCacheCounter|endcsname
+ |csname markdownFrozenCache%
+ |the|markdownOptionFrozenCacheCounter|endcsname
|global|advance|markdownOptionFrozenCacheCounter by 1|relax
}{%
|markdownInfo{Including markdown document "&1"}%
@@ -34410,13 +37572,10 @@ end
|openin|markdownInputFileStream&1
|closein|markdownInputFileStream
|markdownPrepareLuaOptions
+ |markdownPrepareInputFilename{&1}%
|markdownLuaExecute{%
|markdownPrepare
- local file = assert(io.open("&1", "r"),
- [[Could not open file "&1" for reading]])
- local input = assert(file:read("*a"))
- assert(file:close())
- print(convert(input))
+ |markdownConvert
|markdownCleanup}%
% \end{macrocode}
% \begin{markdown}
@@ -34430,7 +37589,6 @@ end
}%
|endgroup
% \end{macrocode}
-% \par
% \begin{markdown}
% The \mref{markdownEscape} macro resets the category codes of the percent sign
% and the hash sign back to comment and parameter, respectively, before using
@@ -34450,13 +37608,12 @@ end
%</tex>
%<*latex>
% \fi
-% \par
% \begin{markdown}
%
% \LaTeX{} Implementation {#lateximplementation}
%-------------------------
%
-% The \LaTeX{} implemenation makes use of the fact that, apart from some subtle
+% The \LaTeX{} implementation makes use of the fact that, apart from some subtle
% differences, \LaTeX{} implements the majority of the plain \TeX{}
% format~[@latex17, Section 9]. As a consequence, we can directly reuse the
% existing plain \TeX{} implementation.
@@ -34467,7 +37624,6 @@ end
\ProvidesPackage{markdown}[\markdownLastModified\markdownVersionSpace v%
\markdownVersion\markdownVersionSpace markdown renderer]%
% \end{macrocode}
-% \par
% \begin{markdown}
%
%### Typesetting Markdown
@@ -34489,7 +37645,6 @@ end
{ ( \[ (.*?) \] ) ? }
{
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Apply the options locally.
@@ -34507,13 +37662,13 @@ end
}
\ExplSyntaxOff
% \end{macrocode}
-% \par
% \begin{markdown}
%
% The \mdef{markdownInputPlainTeX} macro is used to store the original plain
-% \TeX{} implementation of the \mref{markdownInput} macro. The \mref{markdownInput}
-% macro is then redefined to accept an optional argument with options recognized by
-% the \LaTeX{} interface (see Section <#sec:latex-options>).
+% \TeX{} implementation of the \mref{yamlInput} macro. The \mref{markdownInput}
+% and \mref{yamlInput} macros are then redefined to accept an optional argument
+% with options recognized by the \LaTeX{} interface (see Section
+% <#sec:latex-options>).
%
% \end{markdown}
% \begin{macrocode}
@@ -34523,12 +37678,16 @@ end
\markdownSetup{#1}%
\markdownInputPlainTeX{#2}%
\endgroup}%
+\renewcommand\yamlInput[2][]{%
+ \begingroup
+ \yamlSetup{jekyllData, expectJekyllData, ensureJekyllData, #1}%
+ \markdownInputPlainTeX{#2}%
+ \endgroup}%
% \end{macrocode}
-% \par
% \begin{markdown}
%
-% The \envmref{markdown}, and \envmref{markdown*} \LaTeX{} environments are
-% implemented using the \mref{markdownReadAndConvert} macro.
+% The \envmref{markdown}, \envmref{markdown*}, and \envmref{yaml} \LaTeX{}
+% environments are implemented using the \mref{markdownReadAndConvert} macro.
%
% \end{markdown}
% \begin{macrocode}
@@ -34620,13 +37779,26 @@ end
% we let the \mref{markdownReadAndConvert} macro process the rest of the
% \LaTeX{} environment.
%
+% We also make provision for using the \mref{markdown} command as a part of a
+% different \LaTeX{} environment as follows:
+%
+% ``` tex
+% \newenvironment{foo}\%
+% {code before \markdown[some, options]}\%
+% {\markdownEnd code after}
+% ```
+%
% \end{markdown}
% \begin{macrocode}
- \c { markdownReadAndConvert@markdown } { }
+ \c { exp_args:NV }
+ \c { markdownReadAndConvert@ }
+ \c { @currenvir }
}
{
\group_end:
- \markdownReadAndConvert@markdown { }
+ \exp_args:NV
+ \markdownReadAndConvert@
+ \@currenvir
}
}
{ \markdownEnd }
@@ -34634,15 +37806,35 @@ end
{ markdown* }
[ 1 ]
{
- \msg_warning:nnn
- { markdown }
- { latex-markdown-star-deprecated }
- { #1 }
+ \@@_if_option:nTF
+ { experimental }
+ {
+ \msg_error:nnn
+ { markdown }
+ { latex-markdown-star-deprecated }
+ { #1 }
+ }
+ {
+ \msg_warning:nnn
+ { markdown }
+ { latex-markdown-star-deprecated }
+ { #1 }
+ }
\@@_setup:n
{ #1 }
- \markdownReadAndConvert@markdown *
+ \markdownReadAndConvert@
+ { markdown* }
}
{ \markdownEnd }
+\renewenvironment
+ { yaml }
+ {
+ \group_begin:
+ \yamlSetup
+ { jekyllData, expectJekyllData, ensureJekyllData }
+ \markdown
+ }
+ { \yamlEnd }
\msg_new:nnn
{ markdown }
{ latex-markdown-star-deprecated }
@@ -34650,6 +37842,9 @@ end
The~markdown*~LaTeX~environment~has~been~deprecated~and~will~
be~removed~in~the~next~major~version~of~the~Markdown~package.
}
+\cs_generate_variant:Nn
+ \@@_setup:n
+ { V }
\ExplSyntaxOff
\begingroup
% \end{macrocode}
@@ -34663,44 +37858,35 @@ end
% \begin{macrocode}
\catcode`\|=0\catcode`\<=1\catcode`\>=2%
\catcode`\\=12|catcode`|{=12|catcode`|}=12%
- |gdef|markdownReadAndConvert@markdown#1<%
- |markdownReadAndConvert<\end{markdown#1}>%
- <|end<markdown#1>>>%
+ |gdef|markdownReadAndConvert@#1<%
+ |markdownReadAndConvert<\end{#1}>%
+ <|end<#1>>>%
|endgroup
% \end{macrocode}
-% \par
-% \begin{markdown}
-%
-%### Options
-% The supplied package options are processed using the \mref{markdownSetup} macro.
-%
-% \end{markdown}
-% \begin{macrocode}
-\DeclareOption*{%
- \expandafter\markdownSetup\expandafter{\CurrentOption}}%
-\ProcessOptions\relax
-% \end{macrocode}
% \begin{markdown}
%
%### Themes {#latex-themes-implementation}
%
% This section overrides the plain \TeX{} implementation of the theme-loading
-% mechanism from Section <#sec:themes-implementation>. Futhermore, this section
+% mechanism from Section <#sec:themes-implementation>. Furthermore, this section
% also implements the built-in \LaTeX{} themes provided with the Markdown package.
%
% \end{markdown}
% \begin{macrocode}
\ExplSyntaxOn
+\prop_new:N \g_@@_latex_loaded_themes_linenos_prop
+\prop_new:N \g_@@_latex_loaded_themes_versions_prop
\cs_gset:Nn
- \@@_load_theme:nn
+ \@@_load_theme:nnn
{
% \end{macrocode}
-% \par
% \begin{markdown}
%
-% If the Markdown package has already been loaded, determine whether
-% a file named `markdowntheme`\meta{munged theme name}`.sty` exists
-% and whether we are still in the preamble.
+% If the Markdown package has not yet been loaded, determine whether
+% either this is a built-in theme according to the prop
+% \mref{g_@@_latex_built_in_themes_prop} or a file named
+% `markdowntheme`\meta{munged theme name}`.sty` exists and whether we are still
+% in the preamble.
%
% \end{markdown}
% \begin{macrocode}
@@ -34709,24 +37895,42 @@ end
% \end{macrocode}
% \begin{markdown}
%
-% If both conditions are true does, end with an error, since we cannot load
-% \LaTeX{} themes after the preamble. Otherwise, try loading a plain \TeX{}
-% theme instead.
+% If both conditions are true, end with an error, since we cannot load
+% \LaTeX{} themes after the preamble.
%
% \end{markdown}
% \begin{macrocode}
- \file_if_exist:nTF
- { markdown theme #2.sty }
+ \bool_if:nTF
+ {
+ \bool_lazy_or_p:nn
+ {
+ \prop_if_in_p:Nn
+ \g_@@_latex_built_in_themes_prop
+ { #1 }
+ }
+ {
+ \file_if_exist_p:n
+ { markdown theme #3.sty }
+ }
+ }
{
\msg_error:nnn
{ markdown }
{ latex-theme-after-preamble }
{ #1 }
}
+% \end{macrocode}
+% \begin{markdown}
+%
+% Otherwise, try loading a plain \TeX{} theme instead.
+%
+% \end{markdown}
+% \begin{macrocode}
{
- \@@_plain_tex_load_theme:nn
+ \@@_plain_tex_load_theme:nnn
{ #1 }
{ #2 }
+ { #3 }
}
\else
% \end{macrocode}
@@ -34738,20 +37942,96 @@ end
%
% \end{markdown}
% \begin{macrocode}
- \file_if_exist:nTF
- { markdown theme #2.sty }
+ \bool_if:nTF
{
- \msg_info:nnn
- { markdown }
- { loading-latex-theme }
+ \bool_lazy_or_p:nn
+ {
+ \prop_if_in_p:Nn
+ \g_@@_latex_built_in_themes_prop
+ { #1 }
+ }
+ {
+ \file_if_exist_p:n
+ { markdown theme #3.sty }
+ }
+ }
+ {
+ \prop_get:NnNTF
+ \g_@@_latex_loaded_themes_linenos_prop
{ #1 }
- \RequirePackage
- { markdown theme #2 }
+ \l_tmpa_tl
+ {
+ \prop_get:NnN
+ \g_@@_latex_loaded_themes_versions_prop
+ { #1 }
+ \l_tmpb_tl
+ \str_if_eq:nVTF
+ { #2 }
+ \l_tmpb_tl
+ {
+ \msg_warning:nnnVn
+ { markdown }
+ { repeatedly-loaded-latex-theme }
+ { #1 }
+ \l_tmpa_tl
+ { #2 }
+ }
+ {
+ \msg_error:nnnnVV
+ { markdown }
+ { different-versions-of-latex-theme }
+ { #1 }
+ { #2 }
+ \l_tmpb_tl
+ \l_tmpa_tl
+ }
+ }
+ {
+ \prop_gput:Nnx
+ \g_@@_latex_loaded_themes_linenos_prop
+ { #1 }
+ { \tex_the:D \tex_inputlineno:D } % noqa: W200
+ \prop_gput:Nnn
+ \g_@@_latex_loaded_themes_versions_prop
+ { #1 }
+ { #2 }
+% \end{macrocode}
+% \begin{markdown}
+%
+% Load built-in plain \TeX{} themes from the prop
+% \mref{g_@@_latex_built_in_themes_prop} and from the filesystem otherwise.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \prop_if_in:NnTF
+ \g_@@_latex_built_in_themes_prop
+ { #1 }
+ {
+ \msg_info:nnnn
+ { markdown }
+ { loading-built-in-latex-theme }
+ { #1 }
+ { #2 }
+ \prop_item:Nn
+ \g_@@_latex_built_in_themes_prop
+ { #1 }
+ }
+ {
+ \msg_info:nnnn
+ { markdown }
+ { loading-latex-theme }
+ { #1 }
+ { #2 }
+ \RequirePackage
+ { markdown theme #3 }
+ }
+ }
}
{
- \@@_plain_tex_load_theme:nn
+ \@@_plain_tex_load_theme:nnn
{ #1 }
{ #2 }
+ { #3 }
}
\fi
\else
@@ -34763,15 +38043,15 @@ end
%
% \end{markdown}
% \begin{macrocode}
- \msg_info:nnn
+ \msg_info:nnnn
{ markdown }
{ theme-loading-postponed }
{ #1 }
+ { #2 }
\AtEndOfPackage
{
- \@@_load_theme:nn
- { #1 }
- { #2 }
+ \@@_set_theme:n
+ { #1 @ #2 }
}
\fi
}
@@ -34779,13 +38059,31 @@ end
{ markdown }
{ theme-loading-postponed }
{
- Postponing~loading~Markdown~theme~#1~until~
+ Postponing~loading~version~#2~of~Markdown~theme~#1~until~
Markdown~package~has~finished~loading
}
\msg_new:nnn
{ markdown }
+ { loading-built-in-latex-theme }
+ { Loading~version~#2~of~built-in~LaTeX~Markdown~theme~#1 }
+\msg_new:nnn
+ { markdown }
{ loading-latex-theme }
- { Loading~LaTeX~Markdown~theme~#1 }
+ { Loading~version~#2~of~LaTeX~Markdown~theme~#1 }
+\msg_new:nnn
+ { markdown }
+ { repeatedly-loaded-latex-theme }
+ {
+ Version~#3~of~LaTeX~Markdown~theme~#1~was~previously~
+ loaded~on~line~#2,~not~loading~it~again
+ }
+\msg_new:nnn
+ { markdown }
+ { different-versions-of-latex-theme }
+ {
+ Tried~to~load~version~#2~of~LaTeX~Markdown~theme~#1~
+ but~version~#3~has~already~been~loaded~on~line~#4
+ }
\cs_generate_variant:Nn
\msg_new:nnnn
{ nnVV }
@@ -34797,7 +38095,7 @@ end
\c_backslash_str
\tl_put_right:Nn
\l_tmpa_tl
- { begin{document} }
+ { begin { document } }
\tl_set:Nn
\l_tmpb_tl
{ Load~Markdown~theme~#1~before~ }
@@ -34806,333 +38104,350 @@ end
\c_backslash_str
\tl_put_right:Nn
\l_tmpb_tl
- { begin{document} }
+ { begin { document } }
\msg_new:nnVV
{ markdown }
{ latex-theme-after-preamble }
\l_tmpa_tl
\l_tmpb_tl
-\ExplSyntaxOff
% \end{macrocode}
% \begin{markdown}
%
-% The `witiko/dot` theme enables the \Opt{fencedCode} Lua option:
+% The `witiko/dot` and `witiko/graphicx/http` \LaTeX{} themes load the package
+% \pkg{graphicx}, see also Section <#sec:latex-prerequisites>. Then, they
+% load the corresponding plain \TeX{} themes.
%
% \end{markdown}
+% \begin{macrocode}
+\tl_set:Nn
+ \l_tmpa_tl
+ {
+ \RequirePackage
+ { graphicx }
+ \markdownLoadPlainTeXTheme
+ }
+\prop_gput:NnV
+ \g_@@_latex_built_in_themes_prop
+ { witiko / dot }
+ \l_tmpa_tl
+\prop_gput:NnV
+ \g_@@_latex_built_in_themes_prop
+ { witiko / graphicx / http }
+ \l_tmpa_tl
+\ExplSyntaxOff
+% \end{macrocode}
% \iffalse
%</latex>
-%<*themes-witiko-dot>
+%<*themes-witiko-markdown-defaults-latex>
% \fi
-% \begin{macrocode}
-\markdownSetup{fencedCode}%
-% \end{macrocode}
% \begin{markdown}
%
-% We load the \pkg{ifthen} and \pkg{grffile} packages, see also
-% Section <#sec:latex-prerequisites>:
+% The `witiko/markdown/defaults` \LaTeX{} theme also loads the corresponding
+% plain \TeX{} theme.
%
% \end{markdown}
% \begin{macrocode}
-\RequirePackage{ifthen,grffile}
-% \end{macrocode}
-% \begin{markdown}
-%
-% We store the previous definition of the fenced code token renderer prototype:
-%
-% \end{markdown}
-% \begin{macrocode}
-\let\markdown@witiko@dot@oldRendererInputFencedCodePrototype
- \markdownRendererInputFencedCodePrototype
-% \end{macrocode}
-% \begin{markdown}
-%
-% If the infostring starts with `dot …`, we redefine the fenced code block
-% token renderer prototype, so that it typesets the code block via Graphviz
-% tools if and only if the \Opt{frozenCache} plain \TeX{} option is
-% disabled and the code block has not been previously typeset:
-%
-% \end{markdown}
-% \begin{macrocode}
-\renewcommand\markdownRendererInputFencedCodePrototype[3]{%
- \def\next##1 ##2\relax{%
- \ifthenelse{\equal{##1}{dot}}{%
- \markdownIfOption{frozenCache}{}{%
- \immediate\write18{%
- if ! test -e #1.pdf.source || ! diff #1 #1.pdf.source;
- then
- dot -Tpdf -o #1.pdf #1;
- cp #1 #1.pdf.source;
- fi}}%
+\markdownLoadPlainTeXTheme
% \end{macrocode}
% \begin{markdown}
%
-% We include the typeset image using the image token renderer:
-%
-% \end{markdown}
-% \begin{macrocode}
- \markdownRendererImage{Graphviz image}{#1.pdf}{#1.pdf}{##2}%
-% \end{macrocode}
-% \begin{markdown}
+% Next, the \LaTeX{} theme overrides some of the plain \TeX{} definitions.
+% See Section <#sec:latex-token-renderer-prototypes> for the actual
+% definitions.
%
-% If the infostring does not start with `dot …`, we use the previous definition
-% of the fenced code token renderer prototype:
+%### Options
+% The supplied package options are processed using the \mref{markdownSetup} macro.
%
% \end{markdown}
-% \begin{macrocode}
- }{%
- \markdown@witiko@dot@oldRendererInputFencedCodePrototype{#1}{#2}{#3}%
- }%
- }%
- \next#2 \relax}%
-% \end{macrocode}
% \iffalse
-%</themes-witiko-dot>
-%<*themes-witiko-graphicx-http>
+%</themes-witiko-markdown-defaults-latex>
+%<*latex>
% \fi
-% \par
-% \begin{markdown}
-%
-% The `witiko/graphicx/http` theme stores the previous definition of the image
-% token renderer prototype:
-%
-% \end{markdown}
-% \begin{macrocode}
-\let\markdown@witiko@graphicx@http@oldRendererImagePrototype
- \markdownRendererImagePrototype
-% \end{macrocode}
-% \begin{markdown}
-%
-% We load the \pkg{catchfile} and \pkg{grffile} packages, see also
-% Section <#sec:latex-prerequisites>:
-%
-% \end{markdown}
-% \begin{macrocode}
-\RequirePackage{catchfile,grffile}
-% \end{macrocode}
-% \begin{markdown}
-%
-% We define the \mdef{markdown@witiko@graphicx@http@counter} counter to enumerate
-% the images for caching and the \mdef{markdown@witiko@graphicx@http@filename}
-% command, which will store the pathname of the file containing the pathname
-% of the downloaded image file.
-%
-% \end{markdown}
-% \begin{macrocode}
-\newcount\markdown@witiko@graphicx@http@counter
-\markdown@witiko@graphicx@http@counter=0
-\newcommand\markdown@witiko@graphicx@http@filename{%
- \markdownOptionCacheDir/witiko_graphicx_http%
- .\the\markdown@witiko@graphicx@http@counter}%
-% \end{macrocode}
-% \begin{markdown}
-%
-% We define the \mdef{markdown@witiko@graphicx@http@download} command, which will
-% receive two arguments that correspond to the URL of the online image and to
-% the pathname, where the online image should be downloaded. The command will
-% produce a shell command that tries to downloads the online image to the
-% pathname.
-%
-% \end{markdown}
-% \begin{macrocode}
-\newcommand\markdown@witiko@graphicx@http@download[2]{%
- wget -O #2 #1 || curl --location -o #2 #1 || rm -f #2}
-% \end{macrocode}
-% \begin{markdown}
-%
-% We locally swap the category code of the percentage sign with the line feed
-% control character, so that we can use percentage signs in the shell code:
-%
-% \end{markdown}
% \begin{macrocode}
-\begingroup
-\catcode`\%=12
-\catcode`\^^A=14
-% \end{macrocode}
-% \begin{markdown}
-%
-% We redefine the image token renderer prototype, so that it tries to download
-% an online image.
-%
-% \end{markdown}
-% \begin{macrocode}
-\global\def\markdownRendererImagePrototype#1#2#3#4{^^A
- \begingroup
- \edef\filename{\markdown@witiko@graphicx@http@filename}^^A
+\DeclareOption*{%
+ \expandafter\markdownSetup\expandafter{\CurrentOption}}%
+\ProcessOptions\relax
% \end{macrocode}
+% \iffalse
+%</latex>
+%<*themes-witiko-markdown-defaults-latex>
+% \fi
% \begin{markdown}
%
-% The image will be downloaded only if the image URL has the http or https
-% protocols and the \Opt{frozenCache} plain \TeX{} option is disabled:
+%### Token Renderer Prototypes {#latex-token-renderer-prototypes}
%
+% The following configuration should be considered placeholder. If the option
+% `plain` has been enabled (see Section <#sec:plain>), none of the definitions
+% will take effect.
% \end{markdown}
% \begin{macrocode}
- \markdownIfOption{frozenCache}{}{^^A
- \immediate\write18{^^A
- mkdir -p "\markdownOptionCacheDir";
- if printf '%s' "#3" | grep -q -E '^https?:';
- then
+\markdownIfOption{plain}{\iffalse}{\iftrue}
% \end{macrocode}
% \begin{markdown}
%
-% The image will be downloaded to the pathname \Opt{cacheDir}<!--
-% -->`/`\meta{the MD5 digest of the image URL}`.`\meta{the suffix of the
-% image URL}:
+%#### Lists
%
-% \end{markdown}
-% \begin{macrocode}
- OUTPUT_PREFIX="\markdownOptionCacheDir";
- OUTPUT_BODY="$(printf '%s' '#3' | md5sum | cut -d' ' -f1)";
- OUTPUT_SUFFIX="$(printf '%s' '#3' | sed 's/.*[.]//')";
- OUTPUT="$OUTPUT_PREFIX/$OUTPUT_BODY.$OUTPUT_SUFFIX";
-% \end{macrocode}
-% \begin{markdown}
+% If either the \Opt{tightLists} or the \Opt{fancyLists} Lua option is enabled
+% and the current document class is not \pkg{beamer}, use a package that
+% provides support for tight and fancy lists.
%
-% The image will be downloaded only if it has not already been downloaded:
+% If either the package \pkg{paralist} or the package \pkg{enumitem} have already
+% been loaded, use them. Otherwise, if the option \Opt{experimental} or any test
+% phase has been enabled, use the package \pkg{enumitem}. Otherwise, use the
+% package \pkg{paralist}.
%
% \end{markdown}
% \begin{macrocode}
- if ! [ -e "$OUTPUT" ];
- then
- \markdown@witiko@graphicx@http@download{'#3'}{"$OUTPUT"};
- printf '%s' "$OUTPUT" > "\filename";
- fi;
+\ExplSyntaxOn
+\bool_new:N
+ \g_@@_tight_or_fancy_lists_bool
+\bool_gset_false:N
+ \g_@@_tight_or_fancy_lists_bool
+\@@_if_option:nTF
+ { tightLists }
+ {
+ \bool_gset_true:N
+ \g_@@_tight_or_fancy_lists_bool
+ }
+ {
+ \@@_if_option:nT
+ { fancyLists }
+ {
+ \bool_gset_true:N
+ \g_@@_tight_or_fancy_lists_bool
+ }
+ }
+\bool_new:N
+ \g_@@_beamer_paralist_or_enumitem_bool
+\bool_gset_true:N
+ \g_@@_beamer_paralist_or_enumitem_bool
+\@ifclassloaded
+ { beamer }
+ { }
+ {
+ \@ifpackageloaded
+ { paralist }
+ { }
+ {
+ \@ifpackageloaded
+ { enumitem }
+ { }
+ {
+ \bool_gset_false:N
+ \g_@@_beamer_paralist_or_enumitem_bool
+ }
+ }
+ }
+\bool_if:nT
+ {
+ \g_@@_tight_or_fancy_lists_bool &&
+ ! \g_@@_beamer_paralist_or_enumitem_bool
+ }
+ {
+ \bool_if:nTF
+ {
+ \bool_lazy_or_p:nn
+ {
+ \str_if_eq_p:en
+ { \markdownThemeVersion }
+ { experimental }
+ }
+ {
+ \bool_lazy_and_p:nn
+ {
+ \prop_if_exist_p:N
+ \g__pdfmanagement_documentproperties_prop
+ }
+ {
+ \bool_lazy_any_p:n
+ {
+ {
+ \prop_if_in_p:Nn
+ \g__pdfmanagement_documentproperties_prop
+ { document / testphase / phase-I }
+ }
+ {
+ \prop_if_in_p:Nn
+ \g__pdfmanagement_documentproperties_prop
+ { document / testphase / phase-II }
+ }
+ {
+ \prop_if_in_p:Nn
+ \g__pdfmanagement_documentproperties_prop
+ { document / testphase / phase-III }
+ }
+ {
+ \prop_if_in_p:Nn
+ \g__pdfmanagement_documentproperties_prop
+ { document / testphase / phase-IV }
+ }
+ {
+ \prop_if_in_p:Nn
+ \g__pdfmanagement_documentproperties_prop
+ { document / testphase / phase-V }
+ }
+ {
+ \prop_if_in_p:Nn
+ \g__pdfmanagement_documentproperties_prop
+ { document / testphase / phase-VI }
+ }
+ }
+ }
+ }
+ }
+ {
+ \RequirePackage
+ { enumitem }
+ }
+ {
+ \RequirePackage
+ { paralist }
+ }
+ }
+\ExplSyntaxOff
% \end{macrocode}
% \begin{markdown}
%
-% If the image does not have the http or https protocols or the image has
-% already been downloaded, the URL will be stored as-is:
+% If we loaded the \pkg{enumitem} package, define the tight and
+% fancy list renderer prototypes to make use of the capabilities of
+% the package.
%
% \end{markdown}
% \begin{macrocode}
- else
- printf '%s' '#3' > "\filename";
- fi}}^^A
+\ExplSyntaxOn
+\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_number:nn
+ { #1 }
+ { #3 }
+ \@@_latex_fancy_list_item_label_delimiter:n
+ { #2 }
+ }
+\cs_generate_variant:Nn
+ \@@_latex_fancy_list_item_label:nnn
+ { VVn }
+\tl_new:N
+ \l_@@_latex_fancy_list_item_label_number_style_tl
+\tl_new:N
+ \l_@@_latex_fancy_list_item_label_delimiter_style_tl
+\@ifpackageloaded { enumitem } {
+ \markdownSetup { rendererPrototypes = {
% \end{macrocode}
% \begin{markdown}
%
-% We load the pathname of the downloaded image and we typeset the image using
-% the previous definition of the image renderer prototype:
+% First, let's define the tight list item renderer prototypes.
%
% \end{markdown}
% \begin{macrocode}
- \CatchFileDef{\filename}{\filename}{\endlinechar=-1}^^A
- \markdown@witiko@graphicx@http@oldRendererImagePrototype^^A
- {#1}{#2}{\filename}{#4}^^A
- \endgroup
- \global\advance\markdown@witiko@graphicx@http@counter by 1\relax}^^A
-\endgroup
+ ulBeginTight = {
+ \begin
+ { itemize }
+ [ noitemsep ]
+ },
+ ulEndTight = {
+ \end
+ { itemize }
+ },
+ olBeginTight = {
+ \begin
+ { enumerate }
+ [ noitemsep ]
+ },
+ olEndTight = {
+ \end
+ { enumerate }
+ },
+ dlBeginTight = {
+ \begin
+ { description }
+ [ noitemsep ]
+ },
+ dlEndTight = {
+ \end
+ { description }
+ },
% \end{macrocode}
-% \iffalse
-%</themes-witiko-graphicx-http>
-%<*themes-witiko-markdown-defaults-latex>
-% \fi
-% \par
% \begin{markdown}
%
-% The `witiko/markdown/defaults` \LaTeX{} theme provides default definitions
-% for token renderer prototypes. First, the \LaTeX{} theme loads the plain
-% \TeX{} theme with the default definitions for plain \TeX{}:
+% Second, let's define the fancy list item renderer prototypes.
%
% \end{markdown}
% \begin{macrocode}
-\markdownLoadPlainTeXTheme
+ 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 }
+ },
+ 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
+ { enumerate }
+ [ noitemsep ]
+ },
+ fancyOlEnd(|Tight) = {
+ \end { enumerate }
+ \group_end:
+ },
+ fancyOlItemWithNumber = {
+ \item
+ [
+ \@@_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 }
+ ]
+ },
+ } }
% \end{macrocode}
-% \par
% \begin{markdown}
%
-% Next, the \LaTeX{} theme overrides some of the plain \TeX{} definitions.
-% See Section <#sec:latex-token-renderer-prototypes> for the actual
-% definitions.
-%
-%### Token Renderer Prototypes {#latex-token-renderer-prototypes}
-%
-% The following configuration should be considered placeholder. If the option
-% `plain` has been enabled (see Section <#sec:plain>), none of the definitions
-% will take effect.
-% \end{markdown}
-% \begin{macrocode}
-\markdownIfOption{plain}{\iffalse}{\iftrue}
-% \end{macrocode}
-% \par
-% \begin{markdown}%
-% 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.
+% Otherwise, if we loaded the \pkg{paralist} package, define the
+% tight and fancy list renderer prototypes to make use of the
+% capabilities of the package.
%
% \end{markdown}
% \begin{macrocode}
-\@ifclassloaded{beamer}{}{%
- \markdownIfOption{tightLists}{\RequirePackage{paralist}}{}%
- \markdownIfOption{fancyLists}{\RequirePackage{paralist}}{}%
}
+{ \@ifpackageloaded { paralist } {
+ \markdownSetup { rendererPrototypes = {
% \end{macrocode}
-% \par
-% \begin{markdown}
-%
-% If we loaded the \pkg{paralist} package, define the respective renderer
-% prototypes to make use of the capabilities of the package. Otherwise,
-% define the renderer prototypes to fall back on the corresponding renderers
-% for the non-tight lists.
-%
-% \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_number:nn
- { #1 }
- { #3 }
- \@@_latex_fancy_list_item_label_delimiter:n
- { #2 }
- }
- \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={
-% \end{macrocode}
-% \par
% \begin{markdown}
%
% Make tight bullet lists a little less compact by adding extra vertical space
@@ -35140,14 +38455,14 @@ end
%
% \end{markdown}
% \begin{macrocode}
- ulBeginTight = {%
+ ulBeginTight = {
\group_begin:
\pltopsep=\topsep
\plpartopsep=\partopsep
- \begin{compactitem}
+ \begin { compactitem }
},
ulEndTight = {
- \end{compactitem}
+ \end { compactitem }
\group_end:
},
fancyOlBegin = {
@@ -35158,33 +38473,13 @@ end
\tl_set:Nn
\l_@@_latex_fancy_list_item_label_delimiter_style_tl
{ #2 }
- \@@_if_option:nTF
- { startNumber }
- {
- \tl_set:Nn
- \l_tmpa_tl
- { \begin{enumerate} }
- }
- {
- \tl_set:Nn
- \l_tmpa_tl
- { \begin{enumerate}[ }
- \tl_put_right:Nx
- \l_tmpa_tl
- { \@@_latex_paralist_style:nn { #1 } { #2 } }
- \tl_put_right:Nn
- \l_tmpa_tl
- { ] }
- }
- \tl_use:N
- \l_tmpa_tl
+ \begin { enumerate }
},
fancyOlEnd = {
- \end{enumerate}
+ \end { enumerate }
\group_end:
},
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Make tight ordered lists a little less compact by adding extra vertical
@@ -35192,14 +38487,14 @@ end
%
% \end{markdown}
% \begin{macrocode}
- olBeginTight = {%
+ olBeginTight = {
\group_begin:
\plpartopsep=\partopsep
\pltopsep=\topsep
- \begin{compactenum}
+ \begin { compactenum }
},
olEndTight = {
- \end{compactenum}
+ \end { compactenum }
\group_end:
},
fancyOlBeginTight = {
@@ -35210,35 +38505,12 @@ end
\tl_set:Nn
\l_@@_latex_fancy_list_item_label_delimiter_style_tl
{ #2 }
- \@@_if_option:nTF
- { startNumber }
- {
- \tl_set:Nn
- \l_tmpa_tl
- { \begin{compactenum} }
- }
- {
- \tl_set:Nn
- \l_tmpa_tl
- { \begin{compactenum}[ }
- \tl_put_right:Nx
- \l_tmpa_tl
- { \@@_latex_paralist_style:nn { #1 } { #2 } }
- \tl_put_right:Nn
- \l_tmpa_tl
- { ] }
- }
- \tl_put_left:Nn
- \l_tmpa_tl
- {
- \plpartopsep=\partopsep
- \pltopsep=\topsep
- }
- \tl_use:N
- \l_tmpa_tl
+ \plpartopsep=\partopsep
+ \pltopsep=\topsep
+ \begin { compactenum }
},
fancyOlEndTight = {
- \end{compactenum}
+ \end { compactenum }
\group_end:
},
fancyOlItemWithNumber = {
@@ -35251,7 +38523,6 @@ end
]
},
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Make tight definition lists a little less compact by adding extra
@@ -35263,32 +38534,44 @@ end
\group_begin:
\plpartopsep=\partopsep
\pltopsep=\topsep
- \begin{compactdesc}
+ \begin { compactdesc }
},
dlEndTight = {
- \end{compactdesc}
+ \end { compactdesc }
\group_end:
- }}}
- \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}}}
+ }
+ } }
}
+{
+% \end{macrocode}
+% \begin{markdown}
+%
+% Otherwise, if we loaded neither the \pkg{enumitem} package nor the
+% \pkg{paralist} package, define the tight and fancy list renderer
+% prototypes to fall back on the corresponding renderers for the
+% non-tight lists.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \markdownSetup
+ {
+ rendererPrototypes = {
+ ulBeginTight = \markdownRendererUlBegin,
+ ulEndTight = \markdownRendererUlEnd,
+ fancyOlBegin = \markdownRendererOlBegin,
+ fancyOlEnd = \markdownRendererOlEnd,
+ olBeginTight = \markdownRendererOlBegin,
+ olEndTight = \markdownRendererOlEnd,
+ fancyOlBeginTight = \markdownRendererOlBegin,
+ fancyOlEndTight = \markdownRendererOlEnd,
+ dlBeginTight = \markdownRendererDlBegin,
+ dlEndTight = \markdownRendererDlEnd,
+ },
+ }
+} }
\ExplSyntaxOff
\RequirePackage{amsmath}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Unless the \pkg{unicode-math} package has been loaded, load the \pkg{amssymb}
@@ -35320,7 +38603,6 @@ end
tilde = {\textasciitilde},
pipe = {\textbar},
% \end{macrocode}
-% \par
% \begin{markdown}
%
% We can capitalize on the fact that the expansion of renderers is performed by
@@ -35344,6 +38626,19 @@ end
\texttt{#1}%
\fi
}}}
+% \end{macrocode}
+% \begin{markdown}
+%
+%#### Content Blocks
+%
+% In content block renderer prototypes, display the content as a table using
+% the package \pkg{csvsimple} when the raw attribute is `csv`, display the
+% content using the default templates of the package \pkg{luaxml} when the
+% raw attribute is `html`, execute the content with TeX when the raw attribute
+% is `tex`, and display the content as markdown otherwise.
+%
+% \end{markdown}
+% \begin{macrocode}
\ExplSyntaxOn
\markdownSetup{
rendererPrototypes = {
@@ -35353,32 +38648,59 @@ end
{
{ csv }
{
- \begin{table}
- \begin{center}
- \csvautotabular{#3}
- \end{center}
+ \begin { table }
+ \begin { center }
+ \csvautotabular { #3 }
+ \end{ center }
\tl_if_empty:nF
{ #4 }
- { \caption{#4} }
- \end{table}
+ { \caption { #4 } }
+ \end { table }
+ }
+ { html }
+ {
+% \end{macrocode}
+% \begin{markdown}
+%
+% If we are using [\TeX{}4ht][1], we will pass HTML elements to the
+% output HTML document unchanged.
+%
+% [1]: https://tug.org/tex4ht/
+%
+% \end{markdown}
+% \begin{macrocode}
+ \cs_if_exist:NTF
+ \HCode
+ {
+ \if_mode_vertical:
+ \IgnorePar
+ \fi:
+ \EndP
+ \special
+ { t4ht* < #3 }
+ \par
+ \ShowPar
+ }
+ {
+ \@@_luaxml_print_html:n
+ { #3 }
+ }
+ }
+ { tex }
+ {
+ \markdownEscape
+ { #3 }
}
- { tex } { \markdownEscape{#3} }
}
- { \markdownInput{#3} }
+ {
+ \markdownInput
+ { #3 }
+ }
},
},
}
\ExplSyntaxOff
\markdownSetup{rendererPrototypes={
- image = {%
- \begin{figure}%
- \begin{center}%
- \includegraphics[alt={#1}]{#3}%
- \end{center}%
- \ifx\empty#4\empty\else
- \caption{#4}%
- \fi
- \end{figure}},
ulBegin = {\begin{itemize}},
ulEnd = {\end{itemize}},
olBegin = {\begin{enumerate}},
@@ -35392,7 +38714,6 @@ end
tickedBox = {$\boxtimes$},
halfTickedBox = {$\boxdot$}}}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% If \acro{HTML} identifiers appear after a heading, we make them
@@ -35402,7 +38723,7 @@ end
% \begin{macrocode}
\ExplSyntaxOn
\seq_new:N
- \l_@@_header_identifiers_seq
+ \g_@@_header_identifiers_seq
\markdownSetup
{
rendererPrototypes = {
@@ -35411,8 +38732,8 @@ end
{
rendererPrototypes = {
attributeIdentifier = {
- \seq_put_right:Nn
- \l_@@_header_identifiers_seq
+ \seq_gput_right:Nn
+ \g_@@_header_identifiers_seq
{ ##1 }
},
},
@@ -35420,10 +38741,10 @@ end
},
headerAttributeContextEnd = {
\seq_map_inline:Nn
- \l_@@_header_identifiers_seq
+ \g_@@_header_identifiers_seq
{ \label { ##1 } }
- \seq_clear:N
- \l_@@_header_identifiers_seq
+ \seq_gclear:N
+ \g_@@_header_identifiers_seq
},
},
}
@@ -35485,7 +38806,6 @@ end
thematicBreak = {\noindent\rule[0.5ex]{\linewidth}{1pt}},
note = {\footnote{#1}}}}
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Fenced Code
@@ -35496,7 +38816,7 @@ end
% \begin{macrocode}
\RequirePackage{ltxcmds}
\ExplSyntaxOn
-\cs_gset:Npn
+\cs_gset_protected:Npn
\markdownRendererInputFencedCodePrototype#1#2#3
{
\tl_if_empty:nTF
@@ -35519,7 +38839,6 @@ end
\l_tmpa_seq
\l_tmpa_tl
% \end{macrocode}
-% \par
% \begin{markdown}
%
% When the \pkg{minted} package is loaded, use it for syntax highlighting.
@@ -35529,16 +38848,17 @@ end
\ltx@ifpackageloaded
{ minted }
{
+ \catcode`\%=14\relax
\catcode`\#=6\relax
\exp_args:NV
\inputminted
\l_tmpa_tl
{ #1 }
+ \catcode`\%=12\relax
\catcode`\#=12\relax
}
{
% \end{macrocode}
-% \par
% \begin{markdown}
%
% When the \pkg{listings} package is loaded, use it for syntax highlighting.
@@ -35547,9 +38867,8 @@ end
% \begin{macrocode}
\ltx@ifpackageloaded
{ listings }
- { \lstinputlisting[language=\l_tmpa_tl]{#1} }
+ { \lstinputlisting [ language = \l_tmpa_tl ] { #1 } }
% \end{macrocode}
-% \par
% \begin{markdown}
%
% When neither the \pkg{listings} package nor the \pkg{minted} package is
@@ -35557,13 +38876,12 @@ end
%
% \end{markdown}
% \begin{macrocode}
- { \markdownRendererInputFencedCode{#1}{}{} }
+ { \markdownRendererInputFencedCode { #1 } { } { } }
}
}
}
\ExplSyntaxOff
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Support the nesting of strong emphasis.
@@ -35571,7 +38889,7 @@ end
% \end{markdown}
% \begin{macrocode}
\ExplSyntaxOn
-\def\markdownLATEXStrongEmphasis#1{%
+\def\markdownLATEXStrongEmphasis#1{
\str_if_in:NnTF
\f@series
{ b }
@@ -35582,7 +38900,6 @@ end
\markdownSetup{rendererPrototypes={strongEmphasis={%
\protect\markdownLATEXStrongEmphasis{#1}}}}
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Support \LaTeX{} document classes that do not provide chapters.
@@ -35606,7 +38923,6 @@ end
headingSix = {\subparagraph{#1}}}}
}%
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Tickboxes
@@ -35642,7 +38958,6 @@ end
\fi
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### HTML elements
@@ -35676,7 +38991,6 @@ end
}
}
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Citations
@@ -35691,13 +39005,14 @@ end
\newcount\markdownLaTeXCitationsCounter
% Basic implementation
-\RequirePackage{gobble}
+\long\def\@gobblethree#1#2#3{}%
\def\markdownLaTeXBasicCitations#1#2#3#4#5#6{%
\advance\markdownLaTeXCitationsCounter by 1\relax
\ifx\relax#4\relax
\ifx\relax#5\relax
- \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax
- \cite{#1#2#6}% Without prenotes and postnotes, just accumulate cites
+ \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal
+ \relax
+ \cite{#1#2#6}% No prenotes/postnotes, just accumulate cites
\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\@gobblethree
@@ -35707,7 +39022,8 @@ end
\cite{#1}%
\fi
\cite[#5]{#6}%
- \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax
+ \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal
+ \relax
\else
\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
@@ -35734,7 +39050,8 @@ end
\space % Insert a space before the prenote in later citations
\fi
#4~\expandafter\cite\ifx\relax#5\relax{#6}\else[#5]{#6}\fi
- \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax
+ \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal
+ \relax
\else
\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
@@ -35754,8 +39071,9 @@ end
\advance\markdownLaTeXCitationsCounter by 1\relax
\ifx\relax#3\relax
\ifx\relax#4\relax
- \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax
- \citep{#1,#5}% Without prenotes and postnotes, just accumulate cites
+ \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal
+ \relax
+ \citep{#1,#5}% No prenotes/postnotes, just accumulate cites
\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\@gobbletwo
@@ -35765,7 +39083,8 @@ end
\citep{#1}%
\fi
\citep[][#4]{#5}%
- \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax
+ \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal
+ \relax
\else
\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
@@ -35785,7 +39104,8 @@ end
\citep{#1}%
\fi
\citep[#3][#4]{#5}%
- \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax
+ \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal
+ \relax
\else
\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
@@ -35800,8 +39120,9 @@ end
\advance\markdownLaTeXCitationsCounter by 1\relax
\ifx\relax#3\relax
\ifx\relax#4\relax
- \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax
- \citet{#1,#5}% Without prenotes and postnotes, just accumulate cites
+ \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal
+ \relax
+ \citet{#1,#5}% No prenotes/postnotes, just accumulate cites
\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter\expandafter
\@gobbletwo
@@ -35811,10 +39132,13 @@ end
\citet{#1}%
\fi
, \citet[#3][#4]{#5}%
- \ifnum\markdownLaTeXCitationsCounter<\markdownLaTeXCitationsTotal\relax
+ \ifnum\markdownLaTeXCitationsCounter<\markdownLaTeXCitationsTotal
+ \relax
,
\else
- \ifnum\markdownLaTeXCitationsCounter=\markdownLaTeXCitationsTotal\relax
+ \ifnum
+ \markdownLaTeXCitationsCounter=\markdownLaTeXCitationsTotal
+ \relax
,
\fi
\fi
@@ -35833,10 +39157,13 @@ end
\citet{#1}%
\fi
, \citet[#3][#4]{#5}%
- \ifnum\markdownLaTeXCitationsCounter<\markdownLaTeXCitationsTotal\relax
+ \ifnum\markdownLaTeXCitationsCounter<\markdownLaTeXCitationsTotal
+ \relax
,
\else
- \ifnum\markdownLaTeXCitationsCounter=\markdownLaTeXCitationsTotal\relax
+ \ifnum
+ \markdownLaTeXCitationsCounter=\markdownLaTeXCitationsTotal
+ \relax
,
\fi
\fi
@@ -35851,13 +39178,15 @@ end
% BibLaTeX implementation
\def\markdownLaTeXBibLaTeXCitations#1#2#3#4#5{%
\advance\markdownLaTeXCitationsCounter by 1\relax
- \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax
+ \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal
+ \relax
\autocites#1[#3][#4]{#5}%
\expandafter\@gobbletwo
\fi\markdownLaTeXBibLaTeXCitations{#1[#3][#4]{#5}}}
\def\markdownLaTeXBibLaTeXTextCitations#1#2#3#4#5{%
\advance\markdownLaTeXCitationsCounter by 1\relax
- \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax
+ \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal
+ \relax
\textcites#1[#3][#4]{#5}%
\expandafter\@gobbletwo
\fi\markdownLaTeXBibLaTeXTextCitations{#1[#3][#4]{#5}}}
@@ -35908,7 +39237,6 @@ end
\expandafter{\expandafter}%
}}}}
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Links
@@ -35919,23 +39247,26 @@ end
\RequirePackage{url}
\RequirePackage{expl3}
\ExplSyntaxOn
-\def\markdownRendererLinkPrototype#1#2#3#4{
- \tl_set:Nn \l_tmpa_tl { #1 }
- \tl_set:Nn \l_tmpb_tl { #2 }
- \bool_set:Nn
- \l_tmpa_bool
- {
- \tl_if_eq_p:NN
- \l_tmpa_tl
- \l_tmpb_tl
- }
- \tl_set:Nn \l_tmpa_tl { #4 }
- \bool_set:Nn
- \l_tmpb_bool
- {
- \tl_if_empty_p:N
- \l_tmpa_tl
- }
+\cs_gset_protected:Npn
+ \markdownRendererLinkPrototype
+ #1#2#3#4
+ {
+ \tl_set:Nn \l_tmpa_tl { #1 }
+ \tl_set:Nn \l_tmpb_tl { #2 }
+ \bool_set:Nn
+ \l_tmpa_bool
+ {
+ \tl_if_eq_p:NN
+ \l_tmpa_tl
+ \l_tmpb_tl
+ }
+ \tl_set:Nn \l_tmpa_tl { #4 }
+ \bool_set:Nn
+ \l_tmpb_bool
+ {
+ \tl_if_empty_p:N
+ \l_tmpa_tl
+ }
% \end{macrocode}
% \begin{markdown}
% If the label and the fully-escaped URI are equivalent and the title is
@@ -35943,17 +39274,19 @@ end
% link is either direct or indirect.
% \end{markdown}
% \begin{macrocode}
- \bool_if:nTF
- {
- \l_tmpa_bool && \l_tmpb_bool
- }
- {
- \markdownLaTeXRendererAutolink { #2 } { #3 }
- }{
- \markdownLaTeXRendererDirectOrIndirectLink { #1 } { #2 } { #3 } { #4 }
- }
-}
-\def\markdownLaTeXRendererAutolink#1#2{%
+ \bool_if:nTF
+ {
+ \l_tmpa_bool && \l_tmpb_bool
+ }
+ {
+ \markdownLaTeXRendererAutolink { #2 } { #3 }
+ }
+ {
+ \markdownLaTeXRendererDirectOrIndirectLink
+ { #1 } { #2 } { #3 } { #4 }
+ }
+ }
+\def\markdownLaTeXRendererAutolink#1#2{
% \end{macrocode}
% \begin{markdown}
% If the URL begins with a hash sign, then we assume that it is a relative
@@ -35988,7 +39321,8 @@ end
\exp_args:NV
\ref
\l_tmpb_tl
- }{
+ }
+ {
\url { #2 }
}
}
@@ -35996,7 +39330,6 @@ end
\def\markdownLaTeXRendererDirectOrIndirectLink#1#2#3#4{%
#1\footnote{\ifx\empty#4\empty\else#4: \fi\url{#3}}}
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Tables
@@ -36035,7 +39368,59 @@ end
\begin{table}
\centering}%
\addto@hook\markdownLaTeXTableEnd{%
- \caption{#1}
+ \caption{#1}}%
+ \fi
+ }
+}}
+% \end{macrocode}
+% \begin{markdown}
+%
+% If the \Opt{tableAttributes} option is enabled, we will register any
+% identifiers, so that they can be used as \LaTeX{} labels for referencing
+% tables.
+%
+% \end{markdown}
+% \begin{macrocode}
+\ExplSyntaxOn
+\seq_new:N
+ \l_@@_table_identifiers_seq
+\markdownSetup {
+ rendererPrototypes = {
+ table += {
+ \seq_map_inline:Nn
+ \l_@@_table_identifiers_seq
+ {
+ \addto@hook
+ \markdownLaTeXTableEnd
+ { \label { ##1 } }
+ }
+ },
+ }
+}
+\markdownSetup {
+ rendererPrototypes = {
+ tableAttributeContextBegin = {
+ \group_begin:
+ \markdownSetup {
+ rendererPrototypes = {
+ attributeIdentifier = {
+ \seq_put_right:Nn
+ \l_@@_table_identifiers_seq
+ { ##1 }
+ },
+ },
+ }
+ },
+ tableAttributeContextEnd = {
+ \group_end:
+ },
+ },
+}
+\ExplSyntaxOff
+\markdownSetup{rendererPrototypes={
+ table += {%
+ \ifx\empty#1\empty\else
+ \addto@hook\markdownLaTeXTableEnd{%
\end{table}}%
\fi
\addto@hook\markdownLaTeXTable{\begin{tabular}}%
@@ -36084,7 +39469,6 @@ end
\expandafter\@gobble
\fi\markdownLaTeXRenderTableCell}
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Line Blocks
@@ -36110,7 +39494,6 @@ end
}{}
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### YAML Metadata {#latex-yaml-metadata}
@@ -36124,12 +39507,19 @@ end
% \begin{macrocode}
\ExplSyntaxOn
\keys_define:nn
- { markdown/jekyllData }
+ { markdown / jekyllData }
{
- author .code:n = { \author{#1} },
- date .code:n = { \date{#1} },
- title .code:n = { \title{#1} },
- }
+ author .code:n = {
+ \author
+ { #1 }
+ },
+ date .code:n = {
+ \date
+ { #1 }
+ },
+ title .code:n = {
+ \title
+ { #1 }
% \end{macrocode}
% \begin{markdown}
%
@@ -36141,107 +39531,201 @@ end
%
% \end{markdown}
% \begin{macrocode}
-\markdownSetup{
- rendererPrototypes = {
- jekyllDataEnd = {
- \AddToHook{begindocument/end}{\maketitle}
+ \AddToHook
+ { begindocument / end }
+ { \maketitle }
},
- },
-}
-\ExplSyntaxOff
+ }
% \end{macrocode}
-% \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.
+%#### Marked Text
+% If the \Opt{mark} option is enabled, we will load either the \pkg{soul}
+% package or the \pkg{lua-ul} package and use it to implement marked text.
%
% \end{markdown}
% \begin{macrocode}
-\markdownIfOption{strikeThrough}{%
- \RequirePackage{soulutf8}%
- \markdownSetup{
- rendererPrototypes = {
- strikeThrough = {%
- \st{#1}%
- },
- }
+\@@_if_option:nT
+ { mark }
+ {
+ \sys_if_engine_luatex:TF
+ {
+ \RequirePackage
+ { luacolor }
+ \RequirePackage
+ { lua-ul }
+ \markdownSetup
+ {
+ rendererPrototypes = {
+ mark = {
+ \highLight
+ { #1 }
+ },
+ }
+ }
+ }
+ {
+ \RequirePackage
+ { xcolor }
+ \RequirePackage
+ { soul }
+ \markdownSetup
+ {
+ rendererPrototypes = {
+ mark = {
+ \hl
+ { #1 }
+ },
+ }
+ }
+ }
}
-}{}
% \end{macrocode}
-% \par
% \begin{markdown}
%
-%#### Marked Text
-% If the \Opt{mark} option is enabled, we will load the \pkg{soulutf8} package
-% and use it to implement marked text.
+%#### Strike-Through
+% If the \Opt{strikeThrough} option is enabled, we will load either the
+% \pkg{soul} package or the \pkg{lua-ul} package and use it to implement
+% strike-throughs.
%
% \end{markdown}
% \begin{macrocode}
-\markdownIfOption{mark}{%
- \RequirePackage{soulutf8}%
- \markdownSetup{
- rendererPrototypes = {
- mark = {%
- \hl{#1}%
- },
- }
+\@@_if_option:nT
+ { strikeThrough }
+ {
+ \sys_if_engine_luatex:TF
+ {
+ \RequirePackage
+ { lua-ul }
+ \markdownSetup
+ {
+ rendererPrototypes = {
+ strikeThrough = {
+ \strikeThrough
+ { #1 }
+ },
+ }
+ }
+ }
+ {
+ \RequirePackage
+ { soul }
+ \markdownSetup
+ {
+ rendererPrototypes = {
+ strikeThrough = {
+ \st
+ { #1 }
+ },
+ }
+ }
+ }
}
-}{}
% \end{macrocode}
-% \par
% \begin{markdown}
%
-%#### Image Attributes
+%#### Images and their attributes
%
-% If the \Opt{linkAttributes} option is enabled, we will load
-% the \pkg{graphicx} package. Furthermore, in image attribute contexts,
-% we will make attributes in the form \meta{key}`=`\meta{value} set the
-% corresponding keys of the \pkg{graphicx} package to the corresponding
-% values.
+% We define images to be rendered as floating figures using the command
+% `\includegraphics`, where the image label is the alt text and the image
+% title is the caption of the figure.
+%
+% If the \Opt{linkAttributes} option is enabled, we will make attributes in the
+% form \meta{key}`=`\meta{value} set the corresponding keys of the
+% \pkg{graphicx} package to the corresponding values and we will register any
+% identifiers, so that they can be used as \LaTeX{} labels for referencing
+% figures.
%
% \end{markdown}
% \begin{macrocode}
-\ExplSyntaxOn
+\seq_new:N
+ \l_@@_image_identifiers_seq
+\markdownSetup {
+ rendererPrototypes = {
+ image = {
+ \tl_if_empty:nTF
+ { #4 }
+ {
+ \begin { center }
+ \includegraphics
+ [ alt = { #1 } ]
+ { #3 }
+ \end { center }
+ }
+ {
+ \begin { figure }
+ \begin { center }
+ \includegraphics
+ [ alt = { #1 } ]
+ { #3 }
+ \caption { #4 }
+ \seq_map_inline:Nn
+ \l_@@_image_identifiers_seq
+ { \label { ##1 } }
+ \end { center }
+ \end { figure }
+ }
+ },
+ }
+}
\@@_if_option:nT
{ linkAttributes }
{
- \RequirePackage{graphicx}
- \markdownSetup{
- rendererPrototypes = {
- imageAttributeContextBegin = {
- \group_begin:
- \markdownSetup{
- rendererPrototypes = {
- attributeKeyValue = {
- \setkeys
- { Gin }
- { { ##1 } = { ##2 } }
- },
- },
- }
- },
- imageAttributeContextEnd = {
- \group_end:
- },
- },
- }
+ \RequirePackage { graphicx }
}
+\markdownSetup {
+ rendererPrototypes = {
+ imageAttributeContextBegin = {
+ \group_begin:
+ \markdownSetup {
+ rendererPrototypes = {
+ attributeIdentifier = {
+ \seq_put_right:Nn
+ \l_@@_image_identifiers_seq
+ { ##1 }
+ },
+ attributeKeyValue = {
+ \setkeys
+ { Gin }
+ { { ##1 } = { ##2 } }
+ },
+ },
+ }
+ },
+ imageAttributeContextEnd = {
+ \group_end:
+ },
+ },
+}
\ExplSyntaxOff
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Raw Attributes
%
-% In the raw block and inline raw span renderer prototypes, default to the
-% plain TeX renderer prototypes, translating raw attribute `latex` to `tex`.
+% In the raw block and inline raw span renderer prototypes, display the content
+% using the default templates of the package \pkg{luaxml} when the raw
+% attribute is `html` and default to the plain TeX renderer prototypes
+% otherwise, translating raw attribute `latex` to `tex`.
%
% \end{markdown}
% \begin{macrocode}
\ExplSyntaxOn
-\cs_gset:Npn
+\cs_new:Nn
+ \@@_luaxml_print_html:n
+ {
+ \luabridge_now:n
+ {
+ local~input_file = assert(io.open(" #1 ", "r"))
+ local~input = assert(input_file:read("*a"))
+ assert(input_file:close())
+ input = "<body>" .. input .. "</body>"
+ local~dom = require("luaxml-domobject").html_parse(input)
+ local~output = require("luaxml-htmltemplates"):process_dom(dom)
+ print(output)
+ }
+ }
+\cs_gset_protected:Npn
\markdownRendererInputRawInlinePrototype#1#2
{
\str_case:nnF
@@ -36249,18 +39733,45 @@ end
{
{ latex }
{
- \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_inline:nn
{ #1 }
{ tex }
}
+ { html }
+ {
+% \end{macrocode}
+% \begin{markdown}
+%
+% If we are using [\TeX{}4ht][1], we will pass HTML elements to the
+% output HTML document unchanged.
+%
+% [1]: https://tug.org/tex4ht/
+%
+% \end{markdown}
+% \begin{macrocode}
+ \cs_if_exist:NTF
+ \HCode
+ {
+ \if_mode_vertical:
+ \IgnorePar
+ \EndP
+ \fi:
+ \special
+ { t4ht* < #1 }
+ }
+ {
+ \@@_luaxml_print_html:n
+ { #1 }
+ }
+ }
}
{
- \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_inline:nn
{ #1 }
{ #2 }
}
}
-\cs_gset:Npn
+\cs_gset_protected:Npn
\markdownRendererInputRawBlockPrototype#1#2
{
\str_case:nnF
@@ -36268,17 +39779,81 @@ end
{
{ latex }
{
- \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_block:nn
{ #1 }
{ tex }
}
+ { html }
+ {
+% \end{macrocode}
+% \begin{markdown}
+%
+% If we are using [\TeX{}4ht][1], we will pass HTML elements to the
+% output HTML document unchanged.
+%
+% [1]: https://tug.org/tex4ht/
+%
+% \end{markdown}
+% \begin{macrocode}
+ \cs_if_exist:NTF
+ \HCode
+ {
+ \if_mode_vertical:
+ \IgnorePar
+ \fi:
+ \EndP
+ \special
+ { t4ht* < #1 }
+ \par
+ \ShowPar
+ }
+ {
+ \@@_luaxml_print_html:n
+ { #1 }
+ }
+ }
}
{
- \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_block:nn
{ #1 }
{ #2 }
}
}
+% \end{macrocode}
+% \begin{markdown}
+%
+%#### Bracketed spans
+%
+% If the \Opt{bracketedSpans} option is enabled, we will register any
+% identifiers, so that they can be used as \LaTeX{} labels for referencing
+% the last \LaTeX{} counter that has been incremented in e.g. ordered lists.
+%
+% \end{markdown}
+% \begin{macrocode}
+\seq_new:N
+ \l_@@_bracketed_span_identifiers_seq
+\markdownSetup {
+ rendererPrototypes = {
+ bracketedSpanAttributeContextBegin = {
+ \group_begin:
+ \markdownSetup {
+ rendererPrototypes = {
+ attributeIdentifier = {
+ \seq_put_right:Nn
+ \l_@@_bracketed_span_identifiers_seq
+ { ##1 }
+ },
+ },
+ }
+ },
+ bracketedSpanAttributeContextEnd = {
+ \seq_map_inline:Nn
+ \l_@@_bracketed_span_identifiers_seq
+ { \label { ##1 } }
+ \group_end:
+ },
+ },
+}
\ExplSyntaxOff
\fi % Closes `\markdownIfOption{plain}{\iffalse}{\iftrue}`
% \end{macrocode}
@@ -36286,7 +39861,6 @@ end
%</themes-witiko-markdown-defaults-latex>
%<*latex>
% \fi
-% \par
% \begin{markdown}
%
%### Miscellanea
@@ -36308,7 +39882,6 @@ end
%</latex>
%<*context>
% \fi
-% \par
% \begin{markdown}
%
% \Hologo{ConTeXt} Implementation {#contextimplementation}
@@ -36336,7 +39909,6 @@ end
\advance\count0 by 1\relax
\ifnum\count0<256\repeat
% \end{macrocode}
-% \par
% \begin{markdown}
%
% On top of that, make the pipe character (`|`) inactive during the scanning.
@@ -36346,13 +39918,12 @@ end
% \begin{macrocode}
\catcode`|=12}%
% \end{macrocode}
-% \par
% \begin{markdown}
%
%### Typesetting Markdown
-% The \mref{inputmarkdown} macro is defined to accept an optional argument with
-% options recognized by the \Hologo{ConTeXt} interface (see Section
-% <#sec:context-options>).
+% The \mref{inputmarkdown} and \mref{inputyaml} macros are defined to accept an
+% optional argument with options recognized by the \Hologo{ConTeXt} interface
+% (see Section <#sec:context-options>).
%
% \end{markdown}
% \begin{macrocode}
@@ -36366,11 +39937,17 @@ end
\fi
\markdownInput{#2}%
\endgroup}%
+\long\def\inputyaml{%
+ \dosingleempty
+ \doinputyaml}%
+\long\def\doinputyaml[#1]#2{%
+ \doinputmarkdown
+ [jekyllData, expectJekyllData, ensureJekyllData, #1]{#2}}%
% \end{macrocode}
-% \par
% \begin{markdown}
%
-% The \mref{startmarkdown} and \mref{stopmarkdown} macros are implemented using the
+% The \mref{startmarkdown}, \mref{stopmarkdown}, \mref{startyaml}, and
+% \mref{stopyaml} macros are implemented using the
% \mref{markdownReadAndConvert} macro.
%
% In Knuth's \TeX, trailing spaces are removed very early on when a line is
@@ -36404,62 +39981,165 @@ end
|gdef|stopmarkdown{%
|ctxlua{document.markdown_buffering = false}%
|markdownEnd}%
+ |gdef|startyaml{%
+ |begingroup
+ |ctxlua{document.markdown_buffering = true}%
+ |setupyaml[jekyllData, expectJekyllData, ensureJekyllData]%
+ |markdownReadAndConvert{\stopyaml}%
+ {|stopyaml}}%
+ |gdef|stopyaml{%
+ |ctxlua{document.markdown_buffering = false}%
+ |yamlEnd}%
|endgroup
% \end{macrocode}
-% \par
% \begin{markdown}
%
%### Themes {#context-themes-implementation}
%
% This section overrides the plain \TeX{} implementation of the theme-loading
-% mechanism from Section <#sec:themes-implementation>. Futhermore, this section
+% mechanism from Section <#sec:themes-implementation>. Furthermore, this section
% also implements the built-in \Hologo{ConTeXt} themes provided with the
% Markdown package.
%
% \end{markdown}
% \begin{macrocode}
\ExplSyntaxOn
+\prop_new:N \g_@@_context_loaded_themes_linenos_prop
+\prop_new:N \g_@@_context_loaded_themes_versions_prop
\cs_gset:Nn
- \@@_load_theme:nn
+ \@@_load_theme:nnn
{
% \end{macrocode}
-% \par
% \begin{markdown}
%
-% Determine whether a file named `t-markdowntheme`\meta{munged theme
-% name}`.tex` exists. If it does, load it. Otherwise, try loading a plain
-% \TeX{} theme instead.
+% Determine whether either this is a built-in theme according to the prop
+% \mref{g_@@_context_built_in_themes_prop} or a file named
+% `t-markdowntheme`\meta{munged theme name}`.tex` exists. If it does, load it.
+% Otherwise, try loading a plain \TeX{} theme instead.
%
% \end{markdown}
% \begin{macrocode}
- \file_if_exist:nTF
- { t - markdown theme #2.tex }
+ \bool_if:nTF
{
- \msg_info:nnn
- { markdown }
- { loading-context-theme }
+ \bool_lazy_or_p:nn
+ {
+ \prop_if_in_p:Nn
+ \g_@@_context_built_in_themes_prop
+ { #1 }
+ }
+ {
+ \file_if_exist_p:n
+ { t - markdown theme #3.tex }
+ }
+ }
+ {
+ \prop_get:NnNTF
+ \g_@@_context_loaded_themes_linenos_prop
{ #1 }
- \usemodule
- [ t ]
- [ markdown theme #2 ]
+ \l_tmpa_tl
+ {
+ \prop_get:NnN
+ \g_@@_context_loaded_themes_versions_prop
+ { #1 }
+ \l_tmpb_tl
+ \str_if_eq:nVTF
+ { #2 }
+ \l_tmpb_tl
+ {
+ \msg_warning:nnnVn
+ { markdown }
+ { repeatedly-loaded-context-theme }
+ { #1 }
+ \l_tmpa_tl
+ { #2 }
+ }
+ {
+ \msg_error:nnnnVV
+ { markdown }
+ { different-versions-of-context-theme }
+ { #1 }
+ { #2 }
+ \l_tmpb_tl
+ \l_tmpa_tl
+ }
+ }
+ {
+ \prop_gput:Nnx
+ \g_@@_context_loaded_themes_linenos_prop
+ { #1 }
+ { \tex_the:D \tex_inputlineno:D } % noqa: W200
+ \prop_gput:Nnn
+ \g_@@_context_loaded_themes_versions_prop
+ { #1 }
+ { #2 }
+% \end{macrocode}
+% \begin{markdown}
+%
+% Load built-in plain \TeX{} themes from the prop
+% \mref{g_@@_context_built_in_themes_prop} and from the filesystem otherwise.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \prop_if_in:NnTF
+ \g_@@_context_built_in_themes_prop
+ { #1 }
+ {
+ \msg_info:nnnn
+ { markdown }
+ { loading-built-in-context-theme }
+ { #1 }
+ { #2 }
+ \prop_item:Nn
+ \g_@@_context_built_in_themes_prop
+ { #1 }
+ }
+ {
+ \msg_info:nnnn
+ { markdown }
+ { loading-context-theme }
+ { #1 }
+ { #2 }
+ \usemodule
+ [ t ]
+ [ markdown theme #3 ]
+ }
+ }
}
{
- \@@_plain_tex_load_theme:nn
+ \@@_plain_tex_load_theme:nnn
{ #1 }
{ #2 }
+ { #3 }
}
}
\msg_new:nnn
{ markdown }
+ { loading-built-in-context-theme }
+ { Loading~version~#2~of~built-in~ConTeXt~Markdown~theme~#1 }
+\msg_new:nnn
+ { markdown }
{ loading-context-theme }
- { Loading~ConTeXt~Markdown~theme~#1 }
+ { Loading~version~#2~of~ConTeXt~Markdown~theme~#1 }
+\msg_new:nnn
+ { markdown }
+ { repeatedly-loaded-context-theme }
+ {
+ Version~#3~of~ConTeXt~Markdown~theme~#1~was~previously~
+ loaded~on~line~#2,~not~loading~it~again
+ }
+\msg_new:nnn
+ { markdown }
+ { different-versions-of-context-theme }
+ {
+ Tried~to~load~version~#2~of~ConTeXt~Markdown~theme~#1~
+ but~version~#3~has~already~been~loaded~on~line~#4
+ }
\ExplSyntaxOff
% \end{macrocode}
% \iffalse
%</context>
-%<*themes-witiko-markdown-defaults-context>
+%<*themes-witiko-markdown-defaults-ctx>
% \fi
-% \par
% \begin{markdown}
%
% The `witiko/markdown/defaults` \Hologo{ConTeXt} theme provides default
@@ -36470,7 +40150,6 @@ end
% \begin{macrocode}
\markdownLoadPlainTeXTheme
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Next, the \Hologo{ConTeXt} theme overrides some of the plain \TeX{} definitions.
@@ -36569,7 +40248,6 @@ end
}%
\def\markdownRendererInputVerbatimPrototype#1{\typefile{#1}}%
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Fenced Code
@@ -36586,7 +40264,6 @@ end
{ #2 }
{ \markdownRendererInputVerbatim{#1} }
% \end{macrocode}
-% \par
% \begin{markdown}
%
% Otherwise, extract the first word of the infostring and treat it as the name
@@ -36620,7 +40297,7 @@ end
\seq_pop_left:NN
\l_tmpa_seq
\l_tmpa_tl
- \typefile[\l_tmpa_tl][]{#1}
+ \typefile[ \l_tmpa_tl ][] {#1}
}
}
\ExplSyntaxOff
@@ -36639,9 +40316,9 @@ end
\def\markdownRendererStrikeThroughPrototype#1{\overstrikes{#1}}
\def\markdownRendererSuperscriptPrototype#1{\high{#1}}
\def\markdownRendererSubscriptPrototype#1{\low{#1}}
-\def\markdownRendererDisplayMathPrototype#1{\startformula#1\stopformula}%
+\def\markdownRendererDisplayMathPrototype#1{%
+ \startformula#1\stopformula}%
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Tables
@@ -36665,8 +40342,10 @@ end
\placetable{#1}{\the\markdownConTeXtTable}}%
\fi
\begingroup
- \setupTABLE[r][each][topframe=off, bottomframe=off, leftframe=off, rightframe=off]
- \setupTABLE[c][each][topframe=off, bottomframe=off, leftframe=off, rightframe=off]
+ \setupTABLE[r][each][topframe=off, bottomframe=off,
+ leftframe=off, rightframe=off]
+ \setupTABLE[c][each][topframe=off, bottomframe=off,
+ leftframe=off, rightframe=off]
\setupTABLE[r][1][topframe=on, bottomframe=on]
\setupTABLE[r][#1][bottomframe=on]
\markdownConTeXtRowCounter=0%
@@ -36704,18 +40383,19 @@ end
\fi\if#1r%
\setupTABLE[c][\the\markdownConTeXtColumnCounter][align=left]
\fi
- \ifnum\markdownConTeXtColumnCounter<\markdownConTeXtColumnTotal\relax\else
+ \ifnum\markdownConTeXtColumnCounter<\markdownConTeXtColumnTotal\relax
+ \else
\expandafter\gobbleoneargument
\fi\markdownConTeXtReadAlignments}
\def\markdownConTeXtRenderTableCell#1{%
\advance\markdownConTeXtColumnCounter by 1\relax
\markdownConTeXtTable=\expandafter{%
\the\markdownConTeXtTable\bTD#1\eTD}%
- \ifnum\markdownConTeXtColumnCounter<\markdownConTeXtColumnTotal\relax\else
+ \ifnum\markdownConTeXtColumnCounter<\markdownConTeXtColumnTotal\relax
+ \else
\expandafter\gobbleoneargument
\fi\markdownConTeXtRenderTableCell}
% \end{macrocode}
-% \par
% \begin{markdown}
%
%#### Raw Attributes
@@ -36734,13 +40414,13 @@ end
{
{ latex }
{
- \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_inline:nn
{ #1 }
{ context }
}
}
{
- \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_inline:nn
{ #1 }
{ #2 }
}
@@ -36753,13 +40433,13 @@ end
{
{ context }
{
- \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_block:nn
{ #1 }
{ tex }
}
}
{
- \@@_plain_tex_default_input_raw_block_renderer_prototype:nn
+ \@@_plain_tex_default_input_raw_block:nn
{ #1 }
{ #2 }
}
@@ -36773,10 +40453,9 @@ end
\protect
% \end{macrocode}
% \iffalse
-%</themes-witiko-markdown-defaults-context>
+%</themes-witiko-markdown-defaults-ctx>
%<*context>
% \fi
-% \par
% \begin{markdown}
%
% At the end of the \Hologo{ConTeXt} module, we load the
@@ -36786,9 +40465,31 @@ end
%
% \end{markdown}
% \begin{macrocode}
-\markdownIfOption{noDefaults}{}{
- \setupmarkdown[theme=witiko/markdown/defaults]
-}
+\ExplSyntaxOn
+\str_if_eq:VVT
+ \c_@@_top_layer_tl
+ \c_@@_option_layer_context_tl
+ {
+ \use:c
+ { ExplSyntaxOff }
+ \@@_if_option:nF
+ { noDefaults }
+ {
+ \@@_if_option:nTF
+ { experimental }
+ {
+ \@@_setup:n
+ { theme = witiko/markdown/defaults@experimental }
+ }
+ {
+ \@@_setup:n
+ { theme = witiko/markdown/defaults }
+ }
+ }
+ \use:c
+ { ExplSyntaxOn }
+ }
+\ExplSyntaxOff
\stopmodule
\protect
% \end{macrocode}