summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/generic/markdown/markdown.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/generic/markdown/markdown.dtx')
-rw-r--r--Master/texmf-dist/source/generic/markdown/markdown.dtx2368
1 files changed, 2046 insertions, 322 deletions
diff --git a/Master/texmf-dist/source/generic/markdown/markdown.dtx b/Master/texmf-dist/source/generic/markdown/markdown.dtx
index 86d1d68fed6..ee878acc728 100644
--- a/Master/texmf-dist/source/generic/markdown/markdown.dtx
+++ b/Master/texmf-dist/source/generic/markdown/markdown.dtx
@@ -88,10 +88,16 @@
relativeReferences,
stripPercentSigns,
underscores = false,
- theme = witiko/dot,
- theme = witiko/graphicx/http,
- theme = witiko/markdown/techdoc,
]{markdown}
+\markdownSetup{
+ import = {
+ witiko/dot,
+ witiko/graphicx/http,
+ witiko/markdown/techdoc = {
+ options as lua-options
+ },
+ },
+}
% Set up Unicode characters.
\usepackage{newunicodechar}
@@ -1042,7 +1048,8 @@ a directory named `markdown` due to [issue #74][issue-74].
%### Lua Requirements {#luaprerequisites}
%
% The Lua part of the package requires that the following Lua modules are
-% available from within the Lua\TeX{} engine:
+% available from within the Lua\TeX{} engine (though not necessarily in the
+% LuaMeta\TeX{} engine).
%
% \pkg{LPeg${}\geq{}$0.10}
%
@@ -1075,8 +1082,9 @@ local unicode
% \end{macrocode}
% \begin{markdown}
%
-% If the Selene Unicode library is unavailable and we are using
-% Lua${}\geq{}$5.3, we will use the built-in support for Unicode.
+% If the Selene Unicode library is unavailable (could be because we are using
+% LuaMeta\TeX) and we are using Lua${}\geq{}$5.3, we will use the built-in
+% support for Unicode.
%
% \end{markdown}
% \begin{macrocode}
@@ -1097,7 +1105,49 @@ end)()
%
% \end{markdown}
% \begin{macrocode}
-local md5 = require("md5")
+local md5 = require("md5");
+% \end{macrocode}
+% \begin{markdown}
+%
+% \pkg{Kpathsea}
+%
+%: A package that implements the loading of third-party Lua libraries
+% and looking up files in the \TeX{} directory structure.
+%
+% \end{markdown}
+% \begin{macrocode}
+(function()
+% \end{macrocode}
+% \begin{markdown}
+%
+% If \pkg{Kpathsea} has not been loaded before or if Lua\TeX{} has not yet
+% been initialized, configure \pkg{Kpathsea} on top of loading it. Since
+% \Hologo{ConTeXt} MkIV provides a `kpse` global that acts as a
+% stub for \pkg{Kpathsea} and the \pkg{lua-uni-case} library expects that
+% `kpse` is a reference to the full \pkg{Kpathsea} library, we load
+% \pkg{Kpathsea} to the `kpse` global.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local should_initialize = package.loaded.kpse == nil
+ or tex.initialize ~= nil
+ local ran_ok
+ ran_ok, kpse = pcall(require, "kpse")
+ if ran_ok and should_initialize then
+ kpse.set_program_name("luatex")
+ end
+% \end{macrocode}
+% \begin{markdown}
+%
+% If the \pkg{Kpathsea} library is unavailable, we will look up files only
+% in the current working directory.
+%
+% \end{markdown}
+% \begin{macrocode}
+ if not ran_ok then
+ kpse = {lookup = function(f, _) return f end}
+ end
+end)()
% \end{macrocode}
% \par
% \begin{markdown}
@@ -1115,14 +1165,7 @@ local md5 = require("md5")
local uni_case
(function()
local ran_ok
- -- TODO: Stop loading kpse module to a global kpse variable
- -- after https://github.com/latex3/lua-uni-algos/issues/3 has been fixed.
- -- Remove kpse global also from file .luacheckrc.
- ran_ok, kpse = pcall(require, "kpse")
- if ran_ok then
- kpse.set_program_name("luatex")
- ran_ok, uni_case = pcall(require, "lua-uni-case")
- end
+ ran_ok, uni_case = pcall(require, "lua-uni-case")
% \end{macrocode}
% \begin{markdown}
%
@@ -1307,13 +1350,19 @@ end)()
% is used in the `witiko/graphicx/http` \LaTeX{} theme, see Section
% <#sec:latexthemes>.
%
+% \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.
+%
% \pkg{grffile}
%
-%: A package that extends the name processing of package graphics 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
+%: 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>.
%
% \pkg{etoolbox}
@@ -1939,7 +1988,7 @@ package.
local defaultOptions = {}
% \end{macrocode}
% \begingroup
-% \markdownSetup{snippet=witiko/markdown/techdoc/options}
+% \markdownSetup{snippet=lua-options}
% \par
% \iffalse
%</lua,lua-cli>
@@ -3660,15 +3709,17 @@ defaultOptions.blankBeforeHeading = false
%
: true
- : Enable the Pandoc bracketed spans extension:
+ : Enable the Pandoc [bracketed span syntax extension][pandoc-bracketed-spans]:
``` md
- [This is *some text*]{.class key="val"}
+ [This is *some text*]{.class key=val}
``````
: false
- : Disable the Pandoc bracketed spans extension:
+ : Disable the Pandoc bracketed span syntax extension.
+
+ [pandoc-bracketed-spans]: https://pandoc.org/MANUAL.html#extension-bracketed_spans
% \end{markdown}
% \iffalse
@@ -4072,7 +4123,7 @@ defaultOptions.citationNbsps = true
%
: true
- : Enable the Pandoc citation syntax extension:
+ : Enable the Pandoc [citation syntax extension][pandoc-citations]:
``` md
Here is a simple parenthetical citation [@doe99] and here
@@ -4094,6 +4145,8 @@ defaultOptions.citationNbsps = true
: Disable the Pandoc citation syntax extension.
+ [pandoc-citations]: https://pandoc.org/MANUAL.html#extension-citations
+
% \end{markdown}
% \iffalse
@@ -4391,11 +4444,11 @@ defaultOptions.codeSpans = true
%
: true
- : Enable the
-% iA\,Writer content blocks syntax extension~[@sotkov17]:
-% \iffalse
- iA\,Writer content blocks syntax extension:
-% \fi
+ : Enable the
+% iA\,Writer content blocks syntax extension~[@sotkov17]:
+% \iffalse
+ iA\,Writer content blocks syntax extension:
+% \fi
``` md
http://example.com/minard.jpg (Napoleon's
@@ -4408,8 +4461,8 @@ defaultOptions.codeSpans = true
: false
- : Disable the
- iA\,Writer content blocks syntax extension.
+ : Disable the
+ iA\,Writer content blocks syntax extension.
% \end{markdown}
% \iffalse
@@ -5231,7 +5284,7 @@ defaultOptions.extensions = {}
%
: true
- : Enable the Pandoc fancy list extension:
+ : Enable the Pandoc [fancy list syntax extension][pandoc-fancy-lists]:
``` md
a) first item
@@ -5241,7 +5294,9 @@ defaultOptions.extensions = {}
: false
- : Disable the Pandoc fancy list extension.
+ : Disable the Pandoc fancy list syntax extension.
+
+ [pandoc-fancy-lists]: https://pandoc.org/MANUAL.html#org-fancy-lists
% \end{markdown}
% \iffalse
@@ -5499,10 +5554,10 @@ defaultOptions.fencedCode = false
%
: true
- : Enable the Pandoc fenced code attribute extension:
+ : Enable the Pandoc [fenced code attribute syntax extension][pandoc-fenced-code-attributes]:
```````` md
- ~~~~ {#mycode .haskell .numberLines startFrom="100"}
+ ~~~~ {#mycode .haskell .numberLines startFrom=100}
qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++
qsort (filter (>= x) xs)
@@ -5511,7 +5566,9 @@ defaultOptions.fencedCode = false
: false
- : Disable the Pandoc fenced code attribute extension.
+ : Disable the Pandoc fenced code attribute syntax extension.
+
+ [pandoc-fenced-code-attributes]: https://pandoc.org/MANUAL.html#extension-fenced_code_attributes
% \end{markdown}
% \iffalse
@@ -5544,11 +5601,11 @@ following content:
}
\begin{document}
\begin{markdown}
-``` js {linenos=true}
+~~~ js {linenos=true}
if (a > 3) {
moveShip(5 * gravity, DOWN);
}
-``````
+~~~~~~
\end{markdown}
\end{document}
```````
@@ -5597,7 +5654,7 @@ defaultOptions.fencedCodeAttributes = false
%
: true
- : Enable the Pandoc fenced divs extension:
+ : Enable the Pandoc [fenced div syntax extension][pandoc-fenced-divs]:
``` md
::::: {#special .sidebar}
@@ -5609,7 +5666,9 @@ defaultOptions.fencedCodeAttributes = false
: false
- : Disable the Pandoc fenced divs extension:
+ : Disable the Pandoc fenced div syntax extension.
+
+ [pandoc-fenced-divs]: https://pandoc.org/MANUAL.html#extension-fenced_divs
% \end{markdown}
% \iffalse
@@ -6125,20 +6184,20 @@ defaultOptions.hashEnumerators = false
%
: true
- : Enable the assignment of HTML attributes to headings:
+ : Enable the assignment of HTML attributes to headings:
- ``` md
- # My first heading {#foo}
+ ``` md
+ # My first heading {#foo}
- ## My second heading ## {#bar .baz}
+ ## My second heading ## {#bar .baz}
- Yet another heading {key=value}
- ===================
- ``````
+ Yet another heading {key=value}
+ ===================
+ ``````
: false
- : Disable the assignment of HTML attributes to headings.
+ : Disable the assignment of HTML attributes to headings.
% \end{markdown}
% \iffalse
@@ -6646,6 +6705,102 @@ defaultOptions.hybrid = false
%</lua,lua-cli>
%<*manual-options>
+#### Option `inlineCodeAttributes`
+
+`inlineCodeAttributes` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{inlineCodeAttributes}{\opt{true}, \opt{false}}
+%
+: true
+
+ : Enable the Pandoc [inline code span attribute extension][pandoc-inline-code-attributes]:
+
+ ``` md
+ `<$>`{.haskell}
+ ``````
+
+: false
+
+ : Enable the Pandoc inline code span attribute extension.
+
+ [pandoc-inline-code-attributes]: https://pandoc.org/MANUAL.html#extension-inline_code_attributes
+
+% \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[inlineCodeAttributes]{markdown}
+\usepackage{expl3}
+\ExplSyntaxOn
+\markdownSetup{
+ renderers = {
+ codeSpanAttributeContextBegin = {
+ \group_begin:
+ \color_group_begin:
+ \markdownSetup{
+ renderers = {
+ attributeKeyValue = {
+ \str_if_eq:nnT
+ { ##1 }
+ { color }
+ {
+ \color_select:n { ##2 }
+ }
+ },
+ },
+ }
+ },
+ codeSpanAttributeContextEnd = {
+ \color_group_end:
+ \group_end:
+ },
+ },
+}
+\ExplSyntaxOff
+\begin{document}
+\begin{markdown}
+Here is some `colored text`{color=red}.
+\end{markdown}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> Here is some <span style="color: red">`colored text`</span>.
+
+%</manual-options>
+%<*tex>
+% \fi
+% \begin{macrocode}
+\@@_add_lua_option:nnn
+ { inlineCodeAttributes }
+ { boolean }
+ { false }
+% \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli>
+% \fi
+% \begin{macrocode}
+defaultOptions.inlineCodeAttributes = false
+% \end{macrocode}
+% \par
+% \iffalse
+%</lua,lua-cli>
+%<*manual-options>
+
#### Option `inlineNotes`
`inlineNotes` (default value: `false`)
@@ -6657,7 +6812,7 @@ defaultOptions.hybrid = false
%
: true
- : Enable the Pandoc inline note syntax extension:
+ : Enable the Pandoc [inline note syntax extension][pandoc-inline-notes]:
``` md
Here is an inline note.^[Inlines notes are easier to
@@ -6669,6 +6824,8 @@ defaultOptions.hybrid = false
: Disable the Pandoc inline note syntax extension.
+ [pandoc-inline-notes]: https://pandoc.org/MANUAL.html#extension-inline_notes
+
% \end{markdown}
% \iffalse
@@ -6767,7 +6924,8 @@ defaultOptions.inlineNotes = false
%
: true
- : Enable the Pandoc `yaml_metadata_block` syntax extension for entering
+ : Enable the Pandoc [\acro{yaml} metadata block syntax
+ extension][pandoc-yaml-metadata-block] for entering
metadata in \acro{yaml}:
~~~~~~ yaml
@@ -6786,8 +6944,10 @@ defaultOptions.inlineNotes = false
: false
- : Disable the Pandoc `yaml_metadata_block` syntax extension for entering
- metadata in \acro{yaml}.
+ : Disable the Pandoc \acro{yaml} metadata block syntax extension
+ for entering metadata in \acro{yaml}.
+
+ [pandoc-yaml-metadata-block]: https://pandoc.org/MANUAL.html#extension-yaml_metadata_block
% \end{markdown}
% \iffalse
@@ -6920,6 +7080,103 @@ defaultOptions.jekyllData = false
%</lua,lua-cli>
%<*manual-options>
+#### Option `linkAttributes`
+
+`linkAttributes` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{linkAttributes}{\opt{true}, \opt{false}}
+%
+: true
+
+ : Enable the Pandoc [link and image attribute syntax
+ extension][pandoc-link-attributes]:
+
+ ``` md
+ An inline ![image](foo.jpg){#id .class width=30 height=20px}
+ and a reference ![image][ref] with attributes.
+
+ [ref]: foo.jpg "optional title" {#id .class key=val key2=val2}
+ ``````
+
+: false
+
+ : Enable the Pandoc link and image attribute syntax extension.
+
+ [pandoc-link-attributes]: https://pandoc.org/MANUAL.html#extension-link_attributes
+
+% \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[linkAttributes]{markdown}
+\usepackage{expl3, graphicx}
+\ExplSyntaxOn
+\markdownSetup{
+ renderers = {
+ imageAttributeContextBegin = {
+ \group_begin:
+ \markdownSetup{
+ renderers = {
+ attributeKeyValue = {
+ \setkeys
+ { Gin }
+ { { ##1 } = { ##2 } }
+ },
+ },
+ }
+ },
+ imageAttributeContextEnd = {
+ \group_end:
+ },
+ },
+}
+\ExplSyntaxOff
+\begin{document}
+\begin{markdown}
+Here is an example image:
+
+ ![example image](example-image){width=5cm height=4cm}
+\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 an example
+image (from [Martin Scharrer's mwe package][mwe]) displayed at size 5cm × 4cm.
+
+ [mwe]: https://ctan.org/pkg/mwe (mwe – Packages and image files for MWEs)
+
+%</manual-options>
+%<*tex>
+% \fi
+% \begin{macrocode}
+\@@_add_lua_option:nnn
+ { linkAttributes }
+ { boolean }
+ { false }
+% \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli>
+% \fi
+% \begin{macrocode}
+defaultOptions.linkAttributes = false
+% \end{macrocode}
+% \par
+% \iffalse
+%</lua,lua-cli>
+%<*manual-options>
+
#### Option `lineBlocks`
`lineBlocks` (default value: `false`)
@@ -6931,7 +7188,8 @@ defaultOptions.jekyllData = false
%
: true
- : Enable the Pandoc line block syntax extension.
+ : Enable the Pandoc [line block syntax
+ extension][pandoc-line-blocks]:
``` md
| this is a line block that
@@ -6943,7 +7201,9 @@ defaultOptions.jekyllData = false
: false
- : Disable the Pandoc line block syntax extension.
+ : Disable the Pandoc line block syntax extension.
+
+ [pandoc-line-blocks]: https://pandoc.org/MANUAL.html#extension-line_blocks
% \end{markdown}
% \iffalse
@@ -7063,7 +7323,7 @@ defaultOptions.lineBlocks = false
%
: true
- : Enable the Pandoc note syntax extension:
+ : Enable the Pandoc [note syntax extension][pandoc-footnotes]:
``` md
Here is a note reference,[^1] and another.[^longnote]
@@ -7087,7 +7347,9 @@ defaultOptions.lineBlocks = false
: false
- : Disable the Pandoc note syntax extension.
+ : Disable the Pandoc note syntax extension.
+
+ [pandoc-footnotes]: https://pandoc.org/MANUAL.html#extension-footnotes
% \end{markdown}
% \iffalse
@@ -7392,13 +7654,15 @@ defaultOptions.preserveTabs = false
%
: true
- : Enable the Pandoc raw attribute syntax extension:
+ : Enable the Pandoc [raw attribute syntax
+ extension][pandoc-raw-attribute]:
``` md
`$H_2 O$`{=tex} is a liquid.
```
- To enable raw blocks, the \Opt{fencedCode} option must also be enabled:
+ To enable raw blocks, the \Opt{fencedCode} option must also
+ be enabled:
~~~~~~~~ md
Here is a mathematical formula:
@@ -7421,6 +7685,8 @@ defaultOptions.preserveTabs = false
: Disable the Pandoc raw attribute syntax extension.
+ [pandoc-raw-attribute]: https://pandoc.org/MANUAL.html#extension-raw_attribute
+
% \end{markdown}
% \iffalse
@@ -8273,15 +8539,18 @@ defaultOptions.startNumber = true
%
: true
- : Enable the Pandoc strike-through syntax extension:
+ : Enable the Pandoc [strike-through syntax
+ extension][pandoc-strikeout]:
- ``` md
- This ~~is deleted text.~~
- ``````
+ ``` md
+ This ~~is deleted text.~~
+ ``````
: false
- : Disable the Pandoc strike-through syntax extension.
+ : Disable the Pandoc strike-through syntax extension.
+
+ [pandoc-strikeout]: https://pandoc.org/MANUAL.html#extension-strikeout
% \end{markdown}
% \iffalse
@@ -8505,15 +8774,18 @@ defaultOptions.stripIndent = false
%
: true
- : Enable the Pandoc subscript syntax extension:
+ : Enable the Pandoc [subscript syntax
+ extension][pandoc-subscript]:
- ``` md
- H~2~O is a liquid.
- ``````
+ ``` md
+ H~2~O is a liquid.
+ ``````
: false
- : Disable the Pandoc subscript syntax extension.
+ : Disable the Pandoc subscript syntax extension.
+
+ [pandoc-subscript]: https://pandoc.org/MANUAL.html#extension-superscript-subscript
% \end{markdown}
% \iffalse
@@ -8594,15 +8866,18 @@ defaultOptions.subscripts = false
%
: true
- : Enable the Pandoc superscript syntax extension:
+ : Enable the Pandoc [superscript syntax
+ extension][pandoc-superscript]:
- ``` md
- 2^10^ is 1024.
- ``````
+ ``` md
+ 2^10^ is 1024.
+ ``````
: false
- : Disable the Pandoc superscript syntax extension.
+ : Disable the Pandoc superscript syntax extension.
+
+ [pandoc-superscript]: https://pandoc.org/MANUAL.html#extension-superscript-subscript
% \end{markdown}
% \iffalse
@@ -8683,11 +8958,12 @@ defaultOptions.superscripts = false
%
: true
- : Enable the Pandoc `table_captions` syntax extension for
-% pipe tables (see the \Opt{pipeTables} option).
-% \iffalse
- [pipe tables](#pipe-tables).
-% \fi
+ : Enable the Pandoc [table caption syntax
+ extension][pandoc-table-captions] for
+% pipe tables (see the \Opt{pipeTables} option).
+% \iffalse
+ [pipe tables](#pipe-tables).
+% \fi
``` md
| Right | Left | Default | Center |
@@ -8701,7 +8977,9 @@ defaultOptions.superscripts = false
: false
- : Disable the Pandoc `table_captions` syntax extension.
+ : Disable the Pandoc table caption syntax extension.
+
+ [pandoc-table-captions]: https://pandoc.org/MANUAL.html#extension-table_captions
% \end{markdown}
% \iffalse
@@ -8810,7 +9088,8 @@ defaultOptions.tableCaptions = false
%
: true
- : Enable the Pandoc `task_lists` syntax extension.
+ : Enable the Pandoc [task list syntax
+ extension][pandoc-task-lists]:
``` md
@@ -8821,7 +9100,9 @@ defaultOptions.tableCaptions = false
: false
- : Disable the Pandoc `task_lists` syntax extension.
+ : Disable the Pandoc task list syntax extension.
+
+ [pandoc-task-lists]: https://pandoc.org/MANUAL.html#extension-task_lists
% \end{markdown}
% \iffalse
@@ -9036,9 +9317,10 @@ defaultOptions.texComments = false
%
: true
- : Enable the Pandoc `tex_math_dollars` syntax extension.
+ : Enable the Pandoc [dollar math syntax
+ extension][pandoc-tex-math-dollars]:
- ```
+ ``` md
inline math: $E=mc^2$
display math: $$E=mc^2$$
@@ -9046,7 +9328,9 @@ defaultOptions.texComments = false
: false
- : Disable the Pandoc `tex_math_dollars` syntax extension.
+ : Disable the Pandoc dollar math syntax extension.
+
+ [pandoc-tex-math-dollars]: https://pandoc.org/MANUAL.html#extension-tex_math_dollars
% \end{markdown}
% \iffalse
@@ -9225,6 +9509,412 @@ defaultOptions.texMathDollars = false
%</lua,lua-cli>
%<*manual-options>
+#### Option `texMathDoubleBackslash`
+
+`texMathDoubleBackslash` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{texMathDoubleBackslash}{\opt{true}, \opt{false}}
+%
+: true
+
+ : Enable the Pandoc [double backslash math syntax
+ extension][pandoc-tex-math-double-backslash]:
+
+ ``` md
+ inline math: \\(E=mc^2\\)
+
+ display math: \\[E=mc^2\\]
+ ```
+
+: false
+
+ : Disable the Pandoc double backslash math syntax extension.
+
+ [pandoc-tex-math-double-backslash]: https://pandoc.org/MANUAL.html#extension-tex_math_double_backslash
+
+% \end{markdown}
+% \iffalse
+
+##### Lua Module Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+\input lmfonts
+\directlua{
+ local markdown = require("markdown")
+ local newline = [[^^J^^J]]
+ local convert = markdown.new({texMathDoubleBackslash = true})
+ local input =
+ [[\\(E=mc^2\\)]] .. newline .. newline ..
+ [[\\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]]]
+ tex.sprint(convert(input)) }
+\bye
+```````
+Then, invoke LuaTeX from the terminal:
+``` sh
+luatex document.tex
+```````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> \\(E=mc^2\\)
+>
+> \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]
+
+##### Lua CLI Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+\input lmfonts
+\input optionfalse
+\par
+\input optiontrue
+\bye
+```````
+Using a text editor, create a text document named `content.md` with the
+following content:
+``` md
+\\(E=mc^2\\)
+
+\\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]
+``````
+Next, invoke LuaTeX from the terminal:
+``` sh
+texlua ⟨CLI pathname⟩ -- content.md optionfalse.tex
+texlua ⟨CLI pathname⟩ 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:
+
+> \\\(E=mc^2\\)
+>
+> \\\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]
+>
+> \\(E=mc^2\\)
+>
+> \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]
+
+##### Plain \TeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+
+\def\markdownOptionTexMathDoubleBackslash{true}
+\markdownBegin
+\\(E=mc^2\\)
+
+\\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]
+\markdownEnd
+
+\bye
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+luatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> \\(E=mc^2\\)
+>
+> \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[texMathDoubleBackslash]{markdown}
+\begin{document}
+
+\begin{markdown}
+\\(E=mc^2\\)
+
+\\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]
+\end{markdown}
+
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> \\(E=mc^2\\)
+>
+> \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\usemodule[t][markdown]
+\setupmarkdown[texMathDoubleBackslash = yes]
+\starttext
+
+\startmarkdown
+\\(E=mc^2\\)
+
+\\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]
+\stopmarkdown
+
+\stoptext
+````````
+Next, invoke LuaTeX from the terminal:
+``` sh
+context document.tex
+`````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> \\(E=mc^2\\)
+>
+> \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]
+
+%</manual-options>
+%<*tex>
+% \fi
+% \begin{macrocode}
+\@@_add_lua_option:nnn
+ { texMathDoubleBackslash }
+ { boolean }
+ { false }
+% \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli>
+% \fi
+% \begin{macrocode}
+defaultOptions.texMathDoubleBackslash = false
+% \end{macrocode}
+% \par
+% \iffalse
+%</lua,lua-cli>
+%<*manual-options>
+
+#### Option `texMathSingleBackslash`
+
+`texMathSingleBackslash` (default value: `false`)
+
+% \fi
+% \begin{markdown}
+%
+% \Optitem[false]{texMathSingleBackslash}{\opt{true}, \opt{false}}
+%
+: true
+
+ : Enable the Pandoc [single backslash math syntax
+ extension][pandoc-tex-math-single-backslash]:
+
+ ``` md
+ inline math: \(E=mc^2\)
+
+ display math: \[E=mc^2\]
+ ```
+
+: false
+
+ : Disable the Pandoc single backslash math syntax extension.
+
+ [pandoc-tex-math-single-backslash]: https://pandoc.org/MANUAL.html#extension-tex_math_single_backslash
+
+% \end{markdown}
+% \iffalse
+
+##### Lua Module Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+\input lmfonts
+\directlua{
+ local markdown = require("markdown")
+ local newline = [[^^J^^J]]
+ local convert = markdown.new({texMathSingleBackslash = true})
+ local input =
+ [[\(E=mc^2\)]] .. newline .. newline ..
+ [[\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]]]
+ tex.sprint(convert(input)) }
+\bye
+```````
+Then, invoke LuaTeX from the terminal:
+``` sh
+luatex document.tex
+```````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> \(E=mc^2\)
+>
+> \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]
+
+##### Lua CLI Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+\input lmfonts
+\input optionfalse
+\par
+\input optiontrue
+\bye
+```````
+Using a text editor, create a text document named `content.md` with the
+following content:
+``` md
+\(E=mc^2\)
+
+\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]
+``````
+Next, invoke LuaTeX from the terminal:
+``` sh
+texlua ⟨CLI pathname⟩ -- content.md optionfalse.tex
+texlua ⟨CLI pathname⟩ 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:
+
+> (E=mc^2)
+>
+> [\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx]
+>
+> \(E=mc^2\)
+>
+> \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]
+
+##### Plain \TeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\input markdown
+
+\def\markdownOptionTexMathSingleBackslash{true}
+\markdownBegin
+\(E=mc^2\)
+
+\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]
+\markdownEnd
+
+\bye
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+luatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> \(E=mc^2\)
+>
+> \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[texMathSingleBackslash]{markdown}
+\begin{document}
+
+\begin{markdown}
+\(E=mc^2\)
+
+\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]
+\end{markdown}
+
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> \(E=mc^2\)
+>
+> \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]
+
+##### \Hologo{ConTeXt} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\usemodule[t][markdown]
+\setupmarkdown[texMathSingleBackslash = yes]
+\starttext
+
+\startmarkdown
+\(E=mc^2\)
+
+\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]
+\stopmarkdown
+
+\stoptext
+````````
+Next, invoke LuaTeX from the terminal:
+``` sh
+context document.tex
+`````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> \(E=mc^2\)
+>
+> \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]
+
+%</manual-options>
+%<*tex>
+% \fi
+% \begin{macrocode}
+\@@_add_lua_option:nnn
+ { texMathSingleBackslash }
+ { boolean }
+ { false }
+% \end{macrocode}
+% \iffalse
+%</tex>
+%<*lua,lua-cli>
+% \fi
+% \begin{macrocode}
+defaultOptions.texMathSingleBackslash = false
+% \end{macrocode}
+% \par
+% \iffalse
+%</lua,lua-cli>
+%<*manual-options>
+
#### Option `tightLists`
`tightLists` (default value: `true`)
@@ -9236,27 +9926,27 @@ defaultOptions.texMathDollars = false
%
: true
- : Unordered and ordered lists whose items do not consist of multiple
- paragraphs will be considered *tight*. Tight lists will produce tight
- renderers that may produce different output than lists that are not
- tight:
+ : Unordered and ordered lists whose items do not consist of multiple
+ paragraphs will be considered *tight*. Tight lists will produce tight
+ renderers that may produce different output than lists that are not
+ tight:
- ``` md
- - This is
- - a tight
- - unordered list.
+ ``` md
+ - This is
+ - a tight
+ - unordered list.
- - This is
+ - This is
- not a tight
+ not a tight
- - unordered list.
- ```
+ - unordered list.
+ ```
: false
- : Unordered and ordered lists whose items consist of multiple paragraphs
- will be treated the same way as lists that consist of multiple paragraphs.
+ : Unordered and ordered lists whose items consist of multiple paragraphs
+ will be treated the same way as lists that consist of multiple paragraphs.
% \end{markdown}
% \iffalse
@@ -11563,6 +12253,87 @@ following text:
%
% \begin{markdown}
+#### Code Span Attribute Context Renderers
+The following macros are only produced, when the \Opt{inlineCodeAttributes}
+option is enabled.
+
+The \mdef{markdownRendererCodeSpanAttributeContextBegin} and
+\mdef{markdownRendererCodeSpanAttributeContextEnd} macros represent the beginning
+and the end of an inline code span in which the attributes of the inline code
+span apply. The macros receive no arguments.
+
+% \end{markdown}
+%
+% \iffalse
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[inlineCodeAttributes]{markdown}
+\markdownSetup{
+ renderers = {
+ codeSpanAttributeContextBegin = {(},
+ codeSpan = {#1},
+ codeSpanAttributeContextEnd = {)},
+ },
+}
+\begin{document}
+\begin{markdown}
+
+foo `bar`{key=value} baz
+
+\end{markdown}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> foo (bar) baz
+
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+% \begin{macrocode}
+\def\markdownRendererCodeSpanAttributeContextBegin{%
+ \markdownRendererCodeSpanAttributeContextBeginPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { codeSpanAttributeContextBegin }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { codeSpanAttributeContextBegin }
+ { 0 }
+\ExplSyntaxOff
+\def\markdownRendererCodeSpanAttributeContextEnd{%
+ \markdownRendererCodeSpanAttributeContextEndPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { codeSpanAttributeContextEnd }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { codeSpanAttributeContextEnd }
+ { 0 }
+\ExplSyntaxOff
+% \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
#### Content Block Renderers {#texcontentblockrenderers}
The \mdef{markdownRendererContentBlock} macro represents an iA\,Writer content
@@ -12737,11 +13508,11 @@ following content:
}
\begin{document}
\begin{markdown}
-``` js {linenos=true}
+~~~ js {linenos=true}
if (a > 3) {
moveShip(5 * gravity, DOWN);
}
-``````
+~~~~~~
\end{markdown}
\end{document}
```````
@@ -13618,6 +14389,87 @@ that the \TeX{} engine has shell access.
%
% \begin{markdown}
+#### Image Attribute Context Renderers
+The following macros are only produced, when the \Opt{linkAttributes} option
+is enabled.
+
+The \mdef{markdownRendererImageAttributeContextBegin} and
+\mdef{markdownRendererImageAttributeContextEnd} macros represent the beginning
+and the end of an image in which the attributes of the image apply. The macros
+receive no arguments.
+
+% \end{markdown}
+%
+% \iffalse
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[linkAttributes]{markdown}
+\markdownSetup{
+ renderers = {
+ imageAttributeContextBegin = {(},
+ image = {#1},
+ imageAttributeContextEnd = {)},
+ },
+}
+\begin{document}
+\begin{markdown}
+
+foo ![bar](#bar){key=value} baz
+
+\end{markdown}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> foo (bar) baz
+
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+% \begin{macrocode}
+\def\markdownRendererImageAttributeContextBegin{%
+ \markdownRendererImageAttributeContextBeginPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { imageAttributeContextBegin }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { imageAttributeContextBegin }
+ { 0 }
+\ExplSyntaxOff
+\def\markdownRendererImageAttributeContextEnd{%
+ \markdownRendererImageAttributeContextEndPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { imageAttributeContextEnd }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { imageAttributeContextEnd }
+ { 0 }
+\ExplSyntaxOff
+% \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
#### Interblock Separator Renderer
The \mdef{markdownRendererInterblockSeparator} macro represents a separator
between two markdown block elements. The macro receives no arguments.
@@ -13756,7 +14608,7 @@ following text:
The following macros are only produced, when the \Opt{lineBlocks} option
is enabled.
-The \mdef{markdownRendererLineBlockBegin} and \mdef{markdownRendererLineBlockEnd} macros
+The \mdef{markdownRendererLineBlockBegin} and \mdef{markdownRendererLineBlockEnd} macros
represent the beginning and the end of a line block. The macros receive no arguments.
% \end{markdown}
@@ -14157,6 +15009,87 @@ following text:
%
% \begin{markdown}
+#### Link Attribute Context Renderers
+The following macros are only produced, when the \Opt{linkAttributes} option
+is enabled.
+
+The \mdef{markdownRendererLinkAttributeContextBegin} and
+\mdef{markdownRendererLinkAttributeContextEnd} macros represent the beginning
+and the end of a hyperlink in which the attributes of the hyperlink apply.
+The macros receive no arguments.
+
+% \end{markdown}
+%
+% \iffalse
+
+##### \LaTeX{} Example {.unnumbered}
+
+Using a text editor, create a text document named `document.tex` with the
+following content:
+``` tex
+\documentclass{article}
+\usepackage[linkAttributes]{markdown}
+\markdownSetup{
+ renderers = {
+ linkAttributeContextBegin = {(},
+ link = {#1},
+ linkAttributeContextEnd = {)},
+ },
+}
+\begin{document}
+\begin{markdown}
+
+foo [bar](#bar){key=value} baz
+
+\end{markdown}
+\end{document}
+```````
+Next, invoke LuaTeX from the terminal:
+``` sh
+lualatex document.tex
+``````
+A PDF document named `document.pdf` should be produced and contain the
+following text:
+
+> foo (bar) baz
+
+%</manual-tokens>
+%<*tex>
+% \fi
+%
+% \begin{macrocode}
+\def\markdownRendererLinkAttributeContextBegin{%
+ \markdownRendererLinkAttributeContextBeginPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { linkAttributeContextBegin }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { linkAttributeContextBegin }
+ { 0 }
+\ExplSyntaxOff
+\def\markdownRendererLinkAttributeContextEnd{%
+ \markdownRendererLinkAttributeContextEndPrototype}%
+\ExplSyntaxOn
+\seq_gput_right:Nn
+ \g_@@_renderers_seq
+ { linkAttributeContextEnd }
+\prop_gput:Nnn
+ \g_@@_renderer_arities_prop
+ { linkAttributeContextEnd }
+ { 0 }
+\ExplSyntaxOff
+% \end{macrocode}
+% \par
+%
+% \iffalse
+%</tex>
+%<*manual-tokens>
+% \fi
+%
+% \begin{markdown}
+
#### Markdown Document Renderers
The \mdef{markdownRendererDocumentBegin} and \mdef{markdownRendererDocumentEnd}
macros represent the beginning and the end of a *markdown* document. The macros
@@ -16277,11 +17210,11 @@ following text:
% \begin{markdown}
#### Tex Math Renderers
-The \mdef{markdownRendererInlineMath} and \mdef{markdownRendererDisplayMath} macros
-represent inline and display \TeX{} math.
+The \mdef{markdownRendererInlineMath} and \mdef{markdownRendererDisplayMath} macros
+represent inline and display \TeX{} math.
Both macros receive a single argument that corresponds to the tex math content.
-These macros will only be produced, when the \Opt{texMathDollars}
-option is enabled.
+These macros will only be produced, when the \Opt{texMathDollars},
+\Opt{texMathSingleBackslash}, or \Opt{texMathDoubleBackslash} option are enabled.
% \end{markdown}
%
@@ -17553,7 +18486,7 @@ following text:
% \end{macrocode}
% \par
% \begin{markdown}
-%
+%
%### Logging Facilities
% The \mdef{markdownInfo}, \mdef{markdownWarning}, and \mdef{markdownError}
% macros perform logging for the Markdown package. Their first argument
@@ -17767,7 +18700,11 @@ pdflatex --shell-escape document.tex
% <#sec:latexoptions>). Note that \meta{options} inside the `\usepackage`
% macro may not set the `markdownRenderers` (see Section
% <#sec:latexrenderers>) and `markdownRendererPrototypes` (see Section
-% <#sec:latexrendererprototypes>) keys. This limitation is due to the way
+% <#sec:latexrendererprototypes>) keys. Furthermore, although the
+% base variant of the `import` key that loads a single \LaTeX{} theme
+% (see Section <#sec:latexthemes>) can be used, the extended variant
+% that can load multiple themes and import snippets from them (see
+% Section <#sec:latexsnippets>). This limitation is due to the way
% \Hologo{LaTeX2e} parses package options.
%
% \end{markdown}
@@ -17843,7 +18780,7 @@ pdflatex --shell-escape document.tex
%
% Except for the `plain` option described in Section <#sec:latexplain>, and
% the \LaTeX{} themes described in Section <#sec:latexthemes>, and the
-% \LaTeX{} setup snippets described in Section <#sec:latexsetupsnippets>,
+% \LaTeX{} snippets described in Section <#sec:latexsetupsnippets>,
% \LaTeX{} options map directly to the options recognized by the plain
% \TeX{} interface (see Section <#sec:texoptions>) and to the markdown token
% renderers and their prototypes recognized by the plain \TeX{} interface (see
@@ -17870,30 +18807,40 @@ pdflatex --shell-escape document.tex
% \end{macrocode}
% \begin{markdown}
%
-% We may also store \LaTeX{} options as *setup snippets* and invoke them later
-% using the \mdef{markdownSetupSnippet} macro. The \mref{markdownSetupSnippet}
-% macro receives two arguments: the name of the setup snippet and the options
-% to store:
+%#### \LaTeX{} snippets {#latexsetupsnippets}
+%
+% We may also set up \LaTeX{} options as *snippets* using the
+% \mdef{markdownSetupSnippet} macro and invoke them later. The
+% \mref{markdownSetupSnippet} macro receives two arguments: the name
+% of the snippet and the options to store:
%
% \end{markdown}
% \begin{macrocode}
-\newcommand\markdownSetupSnippet[2]{%
- \markdownIfSnippetExists{#1}%
- {%
- \markdownWarning
- {Redefined setup snippet \markdownLaTeXThemeName#1}%
- \csname markdownLaTeXSetupSnippet%
- \markdownLaTeXThemeName#1\endcsname={#2}%
- }{%
- \newtoks\next
- \next={#2}%
- \expandafter\let\csname markdownLaTeXSetupSnippet%
- \markdownLaTeXThemeName#1\endcsname=\next
- }}%
+\ExplSyntaxOn
+\cs_new:Nn
+ \@@_latex_setup_snippet:nn
+ {
+ \markdownIfSnippetExists
+ { #1 }
+ {
+ \markdownWarning
+ {Redefined~snippet~\markdownLaTeXThemeName#1}
+ \csname markdownLaTeXSetupSnippet%
+ \markdownLaTeXThemeName#1\endcsname={#2}
+ }
+ {
+ \newtoks\next
+ \next={#2}
+ \expandafter\let\csname markdownLaTeXSetupSnippet%
+ \markdownLaTeXThemeName#1\endcsname=\next
+ }
+ }
+\let\markdownSetupSnippet=\@@_latex_setup_snippet:nn
+\ExplSyntaxOff
% \end{macrocode}
% \begin{markdown}
%
-% To decide whether a setup snippet exists, we can use the
+% To decide whether a snippet exists, we can use the
% \mdef{markdownIfSnippetExists} macro:
%
% \end{markdown}
@@ -17906,8 +18853,8 @@ pdflatex --shell-escape document.tex
% \begin{markdown}
%
% See Section <#sec:latexthemes> for information on interactions between
-% setup snippets and \LaTeX{} themes. See Section <#sec:latexsetupsnippets>
-% for information about invoking the stored setup snippets.
+% snippets and \LaTeX{} themes. See Section <#sec:latexsnippets>
+% for information about invoking the set-up snippets.
%
% \end{markdown}
% \iffalse
@@ -17918,7 +18865,7 @@ pdflatex --shell-escape document.tex
\LaTeX{} options allow us to disable the redefinition of the default renderer
prototypes from plain \TeX{}, load user-defined themes, and invoke user-defined
-setup snippets.
+set-up snippets.
#### Setting Lua and plain \TeX{} options from \LaTeX{}
@@ -18027,14 +18974,14 @@ interpretation of Markdown tokens. Similarly to \LaTeX{} packages, themes
allow the authors to achieve a specific look and other high-level goals
without low-level programming.
-% The \LaTeX{} option `theme`=\meta{theme name} loads a \LaTeX{} package
+% The \LaTeX{} option `import`=\meta{theme name} loads a \LaTeX{} package
% (further referred to as *a theme*) named `markdowntheme`\meta{munged theme
% name}`.sty`, 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, and a value 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].
+% 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 intended for a single \LaTeX{} document class or for a single \LaTeX{}
@@ -18072,8 +19019,8 @@ would use the following code in the preamble of your document:
``` tex
\usepackage[
- theme = witiko/beamer/MU,
- theme = witiko/dot,
+ import=witiko/beamer/MU,
+ import=witiko/dot,
]{markdown}
```````
@@ -18120,19 +19067,56 @@ would use the following code in the preamble of your document:
\keys_define:nn
{ markdown/latex-options }
{
+ import .code:n = {
+ \tl_set:Nn
+ \l_tmpa_tl
+ { #1 }
+% \end{macrocode}
+% \begin{markdown}
+%
+% To ensure that keys containing forward slashes get passed correctly, we
+% replace all forward slashes in the input with backslash tokens with category
+% code letter and then undo the replacement. This means that if any unbraced
+% backslash tokens with category code letter exist in the input, they will be
+% replaced with forward slashes. However, this should be extremely rare.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \tl_replace_all:NnV
+ \l_tmpa_tl
+ { / }
+ \c_backslash_str
+ \keys_set:nV
+ { markdown/latex-options/import }
+ \l_tmpa_tl
+ },
+ }
+\cs_generate_variant:Nn
+ \tl_replace_all:Nnn
+ { NnV }
+% \end{macrocode}
+% \begin{markdown}
+%
+% The \LaTeX{} option `theme` has been deprecated and will be removed in
+% Markdown 3.0.0.
+%
+% \end{markdown}
+% \begin{macrocode}
+\keys_define:nn
+ { markdown/latex-options }
+ {
theme .code:n = { \@@_set_latex_theme:n { #1 } },
}
\ExplSyntaxOff
% \end{macrocode}
% \begin{markdown}
%
-% The \LaTeX{} themes have a useful synergy with the setup snippets (see
-% Section <#sec:latexoptions>): To make it less likely that different
-% themes will define setup snippets with the same name, we will prepend
-% \meta{theme name}`/` before the snippet name and use the result as the
-% snippet name. For example, if the `witiko/dot` theme defines the `product`
-% setup snippet, the setup snippet will be available under the name
-% `witiko/dot/product`.
+% The \LaTeX{} themes have a useful synergy with snippets (see Section
+% <#sec:latexsetupsnippets>): To make it less likely that different themes
+% will set up snippets with the same name, we will prepend \meta{theme
+% name}`/` before the snippet name and use the result as the snippet name.
+% For example, if the `witiko/dot` theme sets up the `product` snippet, the
+% snippet will be available under the name `witiko/dot/product`.
%
% \end{markdown}
% \iffalse
@@ -18171,7 +19155,7 @@ Example themes provided with the Markdown package include:
right tail of the infostring is used as the image title.
% ```` tex
% \documentclass{article}
-% \usepackage[theme=witiko/dot]{markdown}
+% \usepackage[import=witiko/dot]{markdown}
% \setkeys{Gin}{
% width = \columnwidth,
% height = 0.65\paperheight,
@@ -18244,7 +19228,7 @@ Using a text editor, create a text document named `document.tex` with the
following content:
```` tex
\documentclass{article}
-\usepackage[theme=witiko/dot]{markdown}
+\usepackage[import=witiko/dot]{markdown}
\setkeys{Gin}{
width=\columnwidth,
height=0.65\paperheight,
@@ -18311,7 +19295,7 @@ conference article:
http or https protocol.
% ``` tex
% \documentclass{article}
-% \usepackage[theme=witiko/graphicx/http]{markdown}
+% \usepackage[import=witiko/graphicx/http]{markdown}
% \begin{document}
% \begin{markdown}
% ![img](https://github.com/witiko/markdown/raw/main/markdown.png
@@ -18337,7 +19321,7 @@ Using a text editor, create a text document named `document.tex` with the
following content:
``` tex
\documentclass{article}
-\usepackage[theme=witiko/graphicx/http]{markdown}
+\usepackage[import=witiko/graphicx/http]{markdown}
\begin{document}
\begin{markdown}
![img](https://github.com/witiko/markdown/raw/main/markdown.png
@@ -18374,7 +19358,7 @@ following image:
when the \Opt{hybrid} Lua option is disabled.
% ``` tex
% \documentclass{article}
-% \usepackage[theme=witiko/tilde]{markdown}
+% \usepackage[import=witiko/tilde]{markdown}
% \begin{document}
% \begin{markdown}
% Bartel~Leendert van~der~Waerden
@@ -18393,7 +19377,7 @@ Using a text editor, create a text document named `document.tex` with the
following content:
``` tex
\documentclass{article}
-\usepackage[theme=witiko/tilde]{markdown}
+\usepackage[import=witiko/tilde]{markdown}
\begin{document}
\begin{markdown}
Bartel~Leendert van~der~Waerden
@@ -18425,15 +19409,15 @@ following text, where the middot (`·`) denotes a non-breaking space:
% Please, see Section <#sec:latexthemesimplementation> for implementation
% details of the example themes.
-#### \LaTeX{} setup snippets {#latexsetupsnippets}
+#### \LaTeX{} snippets {#latexsnippets}
% \end{markdown}
% \iffalse
User-defined \LaTeX{} themes provide global control over high-level goals.
However, it is often desirable to change only some local aspects of a document.
-\LaTeX{} setup snippets provide syntactic sugar for defining and invoking
-various options locally.
+\LaTeX{} snippets provide syntactic sugar for defining and invoking various
+options locally.
% \fi
% \begin{markdown}
@@ -18470,7 +19454,7 @@ various options locally.
% \par
% \markdownBegin
-Here is how we can use setup snippets to store options and invoke them later:
+Here is how we can use snippets to store options and invoke them later:
``` tex
\markdownSetupSnippet{romanNumerals}{
@@ -18496,14 +19480,171 @@ The following ordered list will be preceded by roman numerals:
4. quattuor
\end{markdown*}
+```````
+
+If the `romanNumerals` snippet were defined in the `jdoe/lists` theme,
+we can import the theme and use the qualified name of the snippet:
+
+``` tex
+\markdownSetup{import=jdoe/lists}
+\begin{markdown*}{snippet=jdoe/lists/romanNumerals}
+
+The following ordered list will be preceded by roman numerals:
+
+3. tres
+4. quattuor
+
+\end{markdown*}
+```````
+
+Alternatively, we can use the extended variant of the `import` \LaTeX{}
+option that allows us to import the `romanNumerals` snippet to the
+current namespace, so that we can invoke the snippet with less typing:
+
+``` tex
+\markdownSetup{
+ import = {
+ jdoe/lists = romanNumerals,
+ },
+}
+\begin{markdown*}{snippet=romanNumerals}
+
+The following ordered list will be preceded by roman numerals:
+
+3. tres
+4. quattuor
+
+\end{markdown*}
+```````
+
+Furthermore, we can also specify the name of the snippet in the current
+namespace, which is different from the name of the snippet in the
+`jdoe/lists` theme:
+
+``` tex
+\markdownSetup{
+ import = {
+ jdoe/lists = romanNumerals as roman,
+ },
+}
+\begin{markdown*}{snippet=roman}
+
+The following ordered list will be preceded by roman numerals:
+
+3. tres
+4. quattuor
+\end{markdown*}
```````
+Several themes and/or snippets can be loaded at once using the extended
+variant of the `import` \LaTeX{} option.
+
% \markdownEnd
% \iffalse
%</manual-options>
%<*latex>
% \fi
+% \begin{macrocode}
+\ExplSyntaxOn
+\tl_new:N
+ \l_@@_latex_import_current_theme_tl
+\keys_define:nn
+ { markdown/latex-options/import }
+ {
+% \end{macrocode}
+% \begin{markdown}
+%
+% If a theme name is given without a list of snippets to import,
+% we assume that an empty list was given.
+%
+% \end{markdown}
+% \begin{macrocode}
+ unknown .default:n = {},
+ unknown .code:n = {
+% \end{macrocode}
+% \begin{markdown}
+%
+% To ensure that keys containing forward slashes get passed correctly, we
+% replace all forward slashes in the input with backslash tokens with category
+% code letter and then undo the replacement. This means that if any unbraced
+% backslash tokens with category code letter exist in the input, they will be
+% replaced with forward slashes. However, this should be extremely rare.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \tl_set_eq:NN
+ \l_@@_latex_import_current_theme_tl
+ \l_keys_key_str
+ \tl_replace_all:NVn
+ \l_@@_latex_import_current_theme_tl
+ \c_backslash_str
+ { / }
+% \end{macrocode}
+% \begin{markdown}
+%
+% Here, we load the \LaTeX{} theme.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \@@_set_latex_theme:V
+ \l_@@_latex_import_current_theme_tl
+% \end{macrocode}
+% \begin{markdown}
+%
+% Here, we import the \LaTeX{} snippets.
+%
+% \end{markdown}
+% \begin{macrocode}
+ \clist_map_inline:nn
+ { #1 }
+ {
+ \regex_extract_once:nnNTF
+ { ^(.*?)\s+as\s+(.*?)$ }
+ { ##1 }
+ \l_tmpa_seq
+ {
+ \seq_pop:NN
+ \l_tmpa_seq
+ \l_tmpa_tl
+ \seq_pop:NN
+ \l_tmpa_seq
+ \l_tmpa_tl
+ \seq_pop:NN
+ \l_tmpa_seq
+ \l_tmpb_tl
+ }
+ {
+ \tl_set:Nn
+ \l_tmpa_tl
+ { ##1 }
+ \tl_set:Nn
+ \l_tmpb_tl
+ { ##1 }
+ }
+ \tl_put_left:Nn
+ \l_tmpa_tl
+ { / }
+ \tl_put_left:NV
+ \l_tmpa_tl
+ \l_@@_latex_import_current_theme_tl
+ \@@_latex_setup_snippet:Vx
+ \l_tmpb_tl
+ { snippet = { \l_tmpa_tl } }
+ }
+ },
+ }
+\cs_generate_variant:Nn
+ \tl_replace_all:Nnn
+ { NVn }
+\cs_generate_variant:Nn
+ \@@_set_latex_theme:n
+ { V }
+\cs_generate_variant:Nn
+ \@@_latex_setup_snippet:nn
+ { Vx }
+\ExplSyntaxOff
+% \end{macrocode}
% \begin{markdown}
%
%#### Plain \TeX{} Interface Options
@@ -19290,27 +20431,14 @@ end
% \begin{markdown}
%
% The \luamdef{util.lookup_files} method looks up files with filename `f`
-% and returns its path. If the \pkg{kpathsea} library is available, it will
-% search for files not only in the current working directory but also in the
-% \TeX{} directory structure. Further options for \pkg{kpathsea} can be
-% specified in table `options`. [@luatex21, Section 10.7.4]
+% and returns their paths. Further options for the \pkg{Kpathsea} library
+% can be specified in table `options`. [@luatex21, Section 10.7.4]
%
% \end{markdown}
% \begin{macrocode}
-util.lookup_files = (function()
- local ran_ok, kpse = pcall(require, "kpse")
- if ran_ok then
- kpse.set_program_name("luatex")
- else
- kpse = { lookup = function(f, _) return f end }
- end
-
- local function lookup_files(f, options)
- return kpse.lookup(f, options)
- end
-
- return lookup_files
-end)()
+function util.lookup_files(f, options)
+ return kpse.lookup(f, options)
+end
% \end{macrocode}
% \par
% \begin{markdown}
@@ -21941,12 +23069,25 @@ function M.writer.new(options)
% \begin{markdown}
%
% Define \luamdef{writer->code} as a function that will transform an input
-% inline code span `s` to the output format.
+% inline code span `s` with optional attributes `attributes` to the output
+% format.
%
% \end{markdown}
% \begin{macrocode}
- function self.code(s)
- return {"\\markdownRendererCodeSpan{",self.escape(s),"}"}
+ function self.code(s, attributes)
+ local buf = {}
+ if attributes ~= nil then
+ table.insert(buf,
+ "\\markdownRendererCodeSpanAttributeContextBegin\n")
+ table.insert(buf, self.attributes(attributes))
+ end
+ table.insert(buf,
+ {"\\markdownRendererCodeSpan{", self.escape(s), "}"})
+ if attributes ~= nil then
+ table.insert(buf,
+ "\n\\markdownRendererCodeSpanAttributeContextEnd ")
+ end
+ return buf
end
% \end{macrocode}
% \par
@@ -21954,15 +23095,27 @@ function M.writer.new(options)
%
% Define \luamdef{writer->link} as a function that will transform an input
% hyperlink to the output format, where `lab` corresponds to the label,
-% `src` to \acro{uri}, and `tit` to the title of the link.
+% `src` to \acro{uri}, `tit` to the title of the link, and `attributes` to
+% optional attributes.
%
% \end{markdown}
% \begin{macrocode}
- function self.link(lab,src,tit)
- return {"\\markdownRendererLink{",lab,"}",
- "{",self.escape(src),"}",
- "{",self.uri(src),"}",
- "{",self.string(tit or ""),"}"}
+ function self.link(lab, src, tit, attributes)
+ local buf = {}
+ if attributes ~= nil then
+ table.insert(buf,
+ "\\markdownRendererLinkAttributeContextBegin\n")
+ table.insert(buf, self.attributes(attributes))
+ end
+ table.insert(buf, {"\\markdownRendererLink{",lab,"}",
+ "{",self.escape(src),"}",
+ "{",self.uri(src),"}",
+ "{",self.string(tit or ""),"}"})
+ if attributes ~= nil then
+ table.insert(buf,
+ "\n\\markdownRendererLinkAttributeContextEnd ")
+ end
+ return buf
end
% \end{macrocode}
% \par
@@ -21970,15 +23123,27 @@ function M.writer.new(options)
%
% Define \luamdef{writer->image} as a function that will transform an input
% image to the output format, where `lab` corresponds to the label, `src`
-% to the \acro{url}, and `tit` to the title of the image.
+% to the \acro{url}, `tit` to the title of the image, and `attributes` to
+% optional attributes.
%
% \end{markdown}
% \begin{macrocode}
- function self.image(lab,src,tit)
- return {"\\markdownRendererImage{",lab,"}",
- "{",self.string(src),"}",
- "{",self.uri(src),"}",
- "{",self.string(tit or ""),"}"}
+ function self.image(lab, src, tit, attributes)
+ local buf = {}
+ if attributes ~= nil then
+ table.insert(buf,
+ "\\markdownRendererImageAttributeContextBegin\n")
+ table.insert(buf, self.attributes(attributes))
+ end
+ table.insert(buf, {"\\markdownRendererImage{",lab,"}",
+ "{",self.string(src),"}",
+ "{",self.uri(src),"}",
+ "{",self.string(tit or ""),"}"})
+ if attributes ~= nil then
+ table.insert(buf,
+ "\n\\markdownRendererImageAttributeContextEnd ")
+ end
+ return buf
end
% \end{macrocode}
% \par
@@ -22228,8 +23393,14 @@ function M.writer.new(options)
local buf = {}
table.sort(attr)
+ local seen = {}
local key, value
for i = 1, #attr do
+ if seen[attr[i]] ~= nil then
+ goto continue -- prevent duplicate attributes
+ else
+ seen[attr[i]] = true
+ end
if attr[i]:sub(1, 1) == "#" then
table.insert(buf, {"\\markdownRendererAttributeIdentifier{",
attr[i]:sub(2), "}"})
@@ -22241,6 +23412,7 @@ function M.writer.new(options)
table.insert(buf, {"\\markdownRendererAttributeKeyValue{",
key, "}{", value, "}"})
end
+ ::continue::
end
return buf
@@ -22862,6 +24034,15 @@ parsers.title = parsers.title_d + parsers.title_s + parsers.title_p
parsers.optionaltitle
= parsers.spnl * parsers.title * parsers.spacechar^0
+ Cc("")
+
+parsers.indirect_link
+ = parsers.tag
+ * ( C(parsers.spnl) * parsers.tag
+ + Cc(nil) * Cc(nil) -- always produce exactly two captures
+ )
+
+parsers.indirect_image
+ = parsers.exclamation * parsers.indirect_link
% \end{macrocode}
% \par
% \begin{markdown}
@@ -22986,14 +24167,14 @@ parsers.tagentity = parsers.ampersand * C(parsers.alphanumeric^1)
% \par
% \begin{markdown}
%
-%#### Helpers for References
+%#### Helpers for Link Reference Definitions
%
% \end{markdown}
% \begin{macrocode}
-- parse a reference definition: [foo]: /bar "title"
parsers.define_reference_parser = parsers.leader * parsers.tag * parsers.colon
* parsers.spacechar^0 * parsers.url
- * parsers.optionaltitle * parsers.blankline^1
+ * parsers.optionaltitle
% \end{macrocode}
% \par
% \begin{markdown}
@@ -23011,7 +24192,26 @@ parsers.between = function(p, starter, ender)
return (starter * #parsers.nonspacechar * Ct(p * (p - ender2)^0) * ender2)
end
-parsers.urlchar = parsers.anyescaped - parsers.newline - parsers.more
+parsers.urlchar = parsers.anyescaped
+ - parsers.newline
+ - parsers.more
+
+parsers.auto_link_url = parsers.less
+ * C( parsers.alphanumeric^1 * P("://")
+ * parsers.urlchar^1)
+ * parsers.more
+
+parsers.auto_link_email
+ = parsers.less
+ * C((parsers.alphanumeric + S("-._+"))^1
+ * P("@") * parsers.urlchar^1)
+ * parsers.more
+
+parsers.auto_link_relative_reference
+ = parsers.less
+ * C(parsers.urlchar^1)
+ * parsers.more
+
% \end{macrocode}
% \par
% \begin{markdown}
@@ -23314,52 +24514,102 @@ function M.reader.new(writer, options)
% \par
% \begin{markdown}
%
-%#### Helpers for Links and References (local)
+%#### Helpers for Links and Link Reference Definitions (local)
%
% \end{markdown}
% \begin{macrocode}
-- List of references defined in the document
local references
- -- add a reference to the list
- local function register_link(tag,url,title)
- references[self.normalize_tag(tag)] = { url = url, title = title }
- return ""
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% The \luamdef{reader->register_link} method registers
+% a link reference, where `tag` is the link label, `url`
+% is the link destination, `title` is the optional link
+% title, and `attributes` are the optional attributes.
+%
+% \end{markdown}
+% \begin{macrocode}
+ function self.register_link(tag, url, title,
+ attributes)
+ tag = self.normalize_tag(tag)
+ references[tag] = {
+ url = url,
+ title = title,
+ attributes = attributes,
+ }
+ return ""
end
- -- lookup link reference and return either
- -- the link or nil and fallback text.
- local function lookup_reference(label,sps,tag)
- local tagpart
- if not tag then
- tag = label
- tagpart = ""
- elseif tag == "" then
- tag = label
- tagpart = "[]"
- else
- tagpart = {"[",
- self.parser_functions.parse_inlines(tag),
- "]"}
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% The \luamdef{reader->lookup_reference} method looks up a
+% reference with link label `tag`. When the reference exists
+% the method returns a link. The attributes of a link are
+% produced by merging the attributes of the link reference
+% and the optional `attributes`. Otherwise, the method returns a
+% two-tuple of `nil` and fallback text constructed from the
+% link text `label` and the optional spaces `sps` between the
+% link text and the link label.
+%
+% \end{markdown}
+% \begin{macrocode}
+ function self.lookup_reference(label, sps, tag,
+ attributes)
+ local tagpart
+ if not tag then
+ tag = label
+ tagpart = ""
+ elseif tag == "" then
+ tag = label
+ tagpart = "[]"
+ else
+ tagpart = {
+ "[",
+ self.parser_functions.parse_inlines(tag),
+ "]"
+ }
+ end
+ if sps then
+ tagpart = {sps, tagpart}
+ end
+ tag = self.normalize_tag(tag)
+ local r = references[tag]
+ if r then
+ local merged_attributes = {}
+ for _, attribute in ipairs(r.attributes or {}) do
+ table.insert(merged_attributes, attribute)
end
- if sps then
- tagpart = {sps, tagpart}
+ for _, attribute in ipairs(attributes or {}) do
+ table.insert(merged_attributes, attribute)
end
- local r = references[self.normalize_tag(tag)]
- if r then
- return r
- else
- return nil, {"[",
- self.parser_functions.parse_inlines(label),
- "]", tagpart}
+ if #merged_attributes == 0 then
+ merged_attributes = nil
end
+ return {
+ url = r.url,
+ title = r.title,
+ attributes = merged_attributes,
+ }
+ else
+ return nil, {
+ "[",
+ self.parser_functions.parse_inlines(label),
+ "]",
+ tagpart
+ }
+ end
end
-- lookup link reference and return a link, if the reference is found,
-- or a bracketed label otherwise.
- local function indirect_link(label,sps,tag)
+ local function indirect_link(label, sps, tag)
return writer.defer_call(function()
- local r,fallback = lookup_reference(label,sps,tag)
+ local r,fallback = self.lookup_reference(label, sps, tag)
if r then
return writer.link(
self.parser_functions.parse_inlines_no_link(label),
@@ -23372,9 +24622,9 @@ function M.reader.new(writer, options)
-- lookup image reference and return an image, if the reference is found,
-- or a bracketed label otherwise.
- local function indirect_image(label,sps,tag)
+ local function indirect_image(label, sps, tag)
return writer.defer_call(function()
- local r,fallback = lookup_reference(label,sps,tag)
+ local r,fallback = self.lookup_reference(label, sps, tag)
if r then
return writer.image(writer.string(label), r.url, r.title)
else
@@ -23382,6 +24632,19 @@ function M.reader.new(writer, options)
end
end)
end
+
+ parsers.direct_link_tail = parsers.spnl
+ * parsers.lparent
+ * (parsers.url + Cc("")) -- link can be empty [foo]()
+ * parsers.optionaltitle
+ * parsers.rparent
+
+ parsers.direct_link = (parsers.tag / self.parser_functions.parse_inlines_no_link)
+ * parsers.direct_link_tail
+
+ parsers.direct_image = parsers.exclamation
+ * (parsers.tag / self.parser_functions.parse_inlines)
+ * parsers.direct_link_tail
% \end{macrocode}
% \par
% \begin{markdown}
@@ -23482,55 +24745,63 @@ function M.reader.new(writer, options)
) / writer.emphasis
end
- parsers.AutoLinkUrl = parsers.less
- * C(parsers.alphanumeric^1 * P("://") * parsers.urlchar^1)
- * parsers.more
- / function(url)
- return writer.link(writer.escape(url), url)
- end
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% The \luamdef{reader->auto_link_url} method produces an
+% autolink to a URL or a relative reference in the output
+% format, where `url` is the link destination and
+% `attributes` are the optional attributes.
+%
+% \end{markdown}
+% \begin{macrocode}
+function self.auto_link_url(url, attributes)
+ return writer.link(writer.escape(url),
+ url, nil, attributes)
+end
- parsers.AutoLinkEmail = parsers.less
- * C((parsers.alphanumeric + S("-._+"))^1
- * P("@") * parsers.urlchar^1)
- * parsers.more
- / function(email)
- return writer.link(writer.escape(email),
- "mailto:"..email)
- end
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% The \luamdef{reader->auto_link_email} method produces an
+% autolink to an e-mail in the output format, where `email` is the email
+% address destination and `attributes` are the optional attributes.
+%
+% \end{markdown}
+% \begin{macrocode}
+function self.auto_link_email(email, attributes)
+ return writer.link(writer.escape(email),
+ "mailto:"..email,
+ nil, attributes)
+end
+
+ parsers.AutoLinkUrl = parsers.auto_link_url
+ / self.auto_link_url
+
+ parsers.AutoLinkEmail
+ = parsers.auto_link_email
+ / self.auto_link_email
parsers.AutoLinkRelativeReference
- = parsers.less
- * C(parsers.urlchar^1)
- * parsers.more
- / function(url)
- return writer.link(writer.escape(url), url)
- end
+ = parsers.auto_link_relative_reference
+ / self.auto_link_url
- parsers.DirectLink = (parsers.tag / self.parser_functions.parse_inlines_no_link)
- * parsers.spnl
- * parsers.lparent
- * (parsers.url + Cc("")) -- link can be empty [foo]()
- * parsers.optionaltitle
- * parsers.rparent
+ parsers.DirectLink = parsers.direct_link
/ writer.link
- parsers.IndirectLink = parsers.tag * (C(parsers.spnl) * parsers.tag)^-1
+ parsers.IndirectLink = parsers.indirect_link
/ indirect_link
-- parse a link or image (direct or indirect)
parsers.Link = parsers.DirectLink + parsers.IndirectLink
- parsers.DirectImage = parsers.exclamation
- * (parsers.tag / self.parser_functions.parse_inlines)
- * parsers.spnl
- * parsers.lparent
- * (parsers.url + Cc("")) -- link can be empty [foo]()
- * parsers.optionaltitle
- * parsers.rparent
+ parsers.DirectImage = parsers.direct_image
/ writer.image
- parsers.IndirectImage = parsers.exclamation * parsers.tag
- * (C(parsers.spnl) * parsers.tag)^-1 / indirect_image
+ parsers.IndirectImage = parsers.indirect_image
+ / indirect_image
parsers.Image = parsers.DirectImage + parsers.IndirectImage
@@ -23581,7 +24852,9 @@ function M.reader.new(writer, options)
+ parsers.lineof(parsers.underscore)
) / writer.thematic_break
- parsers.Reference = parsers.define_reference_parser / register_link
+ parsers.Reference = parsers.define_reference_parser
+ * parsers.blankline^1
+ / self.register_link
parsers.Paragraph = parsers.nonindentspace * Ct(parsers.Inline^1)
* ( parsers.newline
@@ -23677,7 +24950,7 @@ function M.reader.new(writer, options)
% \end{markdown}
% \begin{macrocode}
parsers.Blank = parsers.blankline / ""
- + parsers.Reference
+ + V("Reference")
+ (parsers.tightblocksep / "\n")
% \end{macrocode}
% \par
@@ -23815,6 +25088,7 @@ function M.reader.new(writer, options)
ExpectedJekyllData = parsers.fail,
Blank = parsers.Blank,
+ Reference = parsers.Reference,
Blockquote = parsers.Blockquote,
Verbatim = parsers.Verbatim,
@@ -23878,7 +25152,33 @@ function M.reader.new(writer, options)
previous_pattern = nil
extension_name = current_extension_name
end
- local pattern = get_pattern(previous_pattern)
+ local pattern
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+% Instead of a function, a \acro{peg} pattern `pattern` may also be
+% supplied with roughly the same effect as supplying the following
+% function, which will define \luamref{walkable_syntax}`[`left-hand
+% side terminal symbol`]` unless it has been previously defined.
+%
+% ``` lua
+% function(previous_pattern)
+% assert(previous_pattern == nil)
+% return pattern
+% end
+% ```
+%
+% \end{markdown}
+% \begin{macrocode}
+ if type(get_pattern) == "function" then
+ pattern = get_pattern(previous_pattern)
+ else
+ assert(previous_pattern == nil,
+ [[Rule ]] .. rule_name ..
+ [[ has already been updated by ]] .. extension_name)
+ pattern = get_pattern
+ end
local accountable_pattern = { pattern, extension_name, rule_name }
walkable_syntax[rule_name] = { accountable_pattern }
end
@@ -24227,7 +25527,7 @@ M.extensions = {}
%#### Bracketed Spans
%
% The \luamdef{extensions.bracketed_spans} function implements the Pandoc
-% bracketed spans syntax extension.
+% bracketed span syntax extension.
%
% \end{markdown}
% \begin{macrocode}
@@ -24888,7 +26188,7 @@ M.extensions.fancy_lists = function()
* Cc(false) * parsers.skipblanklines
) * Cb("listtype") / fancylist
- self.update_rule("OrderedList", function() return FancyList end)
+ self.update_rule("OrderedList", FancyList)
end
}
end
@@ -24905,7 +26205,7 @@ end
% When the `allow_attributes` option is `true`, the syntax extension permits
% attributes following the infostring. When the `allow_raw_blocks` option is
% `true`, the syntax extension permits the specification of raw blocks using
-% Pandoc's raw attribute syntax extension.
+% the Pandoc raw attribute syntax extension.
%
% \end{markdown}
% \begin{macrocode}
@@ -25086,7 +26386,7 @@ end
%#### Fenced Divs
%
% The \luamdef{extensions.fenced_divs} function implements the Pandoc fenced
-% divs syntax extension. When the `blank_before_div_fence` parameter is `true`,
+% div syntax extension. When the `blank_before_div_fence` parameter is `true`,
% the syntax extension requires a blank line between a paragraph and the
% following fenced code block.
%
@@ -25252,7 +26552,7 @@ end
%#### Header Attributes
%
% The \luamdef{extensions.header_attributes} function implements the Pandoc
-% header attributes syntax extension.
+% header attribute syntax extension.
%
% \end{markdown}
% \begin{macrocode}
@@ -25307,7 +26607,34 @@ M.extensions.header_attributes = function()
/ writer.heading
local Heading = AtxHeading + SetextHeading
- self.update_rule("Heading", function() return Heading end)
+ self.update_rule("Heading", Heading)
+ end
+ }
+end
+% \end{macrocode}
+% \begin{markdown}
+%
+%#### Inline Code Attributes
+%
+% The \luamdef{extensions.inline_code_attributes} function implements the
+% Pandoc inline code attribute syntax extension.
+%
+% \end{markdown}
+% \begin{macrocode}
+M.extensions.inline_code_attributes = function()
+ return {
+ name = "built-in inline_code_attributes syntax extension",
+ extend_writer = function()
+ end, extend_reader = function(self)
+ local writer = self.writer
+
+ local CodeWithAttributes = parsers.inticks
+ * Ct(parsers.attributes)
+ / writer.code
+
+ self.insert_pattern("Inline before Code",
+ CodeWithAttributes,
+ "CodeWithAttributes")
end
}
end
@@ -25316,7 +26643,7 @@ end
%
%#### Line Blocks
%
-% The \luamdef{extensions.line_blocks} function implements the Pandoc line blocks
+% The \luamdef{extensions.line_blocks} function implements the Pandoc line block
% syntax extension.
%
% \end{markdown}
@@ -25372,6 +26699,182 @@ end
% \end{macrocode}
% \begin{markdown}
%
+%#### Link Attributes
+%
+% The \luamdef{extensions.link_attributes} function implements the Pandoc
+% link attribute syntax extension.
+%
+% \end{markdown}
+% \begin{macrocode}
+M.extensions.link_attributes = function()
+ return {
+ name = "built-in link_attributes syntax extension",
+ extend_writer = function()
+ end, extend_reader = function(self)
+ local parsers = self.parsers
+ local writer = self.writer
+ local options = self.options
+
+% \end{macrocode}
+% \begin{markdown}
+%
+% The following patterns define link reference definitions with attributes.
+%
+% \end{markdown}
+% \begin{macrocode}
+
+ local define_reference_parser = parsers.define_reference_parser
+ * ( parsers.spnl
+ * Ct(parsers.attributes))^-1
+
+ local ReferenceWithAttributes = define_reference_parser
+ * parsers.blankline^1
+ / self.register_link
+
+ self.update_rule("Reference", ReferenceWithAttributes)
+
+% \end{macrocode}
+% \begin{markdown}
+%
+% The following patterns define direct and indirect links with attributes.
+%
+% \end{markdown}
+% \begin{macrocode}
+
+ local function indirect_link(label, sps, tag,
+ attribute_text,
+ attributes)
+ return writer.defer_call(function()
+ local r, fallback = self.lookup_reference(label, sps, tag,
+ attributes)
+ if r then
+ return writer.link(
+ self.parser_functions.parse_inlines_no_link(label),
+ r.url, r.title, r.attributes)
+ else
+ local buf = {fallback}
+ if attributes then
+ table.insert(buf, writer.string(attribute_text))
+ end
+ return buf
+ end
+ end)
+ end
+
+ local DirectLinkWithAttributes = parsers.direct_link
+ * (Ct(parsers.attributes))^-1
+ / writer.link
+
+ local IndirectLinkWithAttributes = parsers.indirect_link
+ * (C(Ct(parsers.attributes)))^-1
+ / indirect_link
+
+ local LinkWithAttributes = DirectLinkWithAttributes
+ + IndirectLinkWithAttributes
+
+% \end{macrocode}
+% \begin{markdown}
+%
+% Here, we directly update the `Link` grammar rule to keep the
+% method \luamref{reader->parser_functions.parse_inlines_no_link}
+% aware of `LinkWithAttributes` and prevent nested links.
+%
+% If we used \luamref{reader->insert_pattern} instead of
+% \luamref{reader->update_rule}, this correspondence would have
+% been lost and link text would be able to contain nested links.
+%
+% \end{markdown}
+% \begin{macrocode}
+ self.update_rule("Link", LinkWithAttributes)
+
+% \end{macrocode}
+% \begin{markdown}
+%
+% The following patterns define direct and indirect images with attributes.
+%
+% \end{markdown}
+% \begin{macrocode}
+
+ local function indirect_image(label, sps, tag,
+ attribute_text,
+ attributes)
+ return writer.defer_call(function()
+ local r, fallback = self.lookup_reference(label, sps, tag,
+ attributes)
+ if r then
+ return writer.image(writer.string(label),
+ r.url, r.title, r.attributes)
+ else
+ local buf = {"!", fallback}
+ if attributes then
+ table.insert(buf, writer.string(attribute_text))
+ end
+ return buf
+ end
+ end)
+ end
+
+ local DirectImageWithAttributes = parsers.direct_image
+ * Ct(parsers.attributes)
+ / writer.image
+
+ local IndirectImageWithAttributes = parsers.indirect_image
+ * C(Ct(parsers.attributes))
+ / indirect_image
+
+ local ImageWithAttributes = DirectImageWithAttributes
+ + IndirectImageWithAttributes
+
+ self.insert_pattern("Inline before Image",
+ ImageWithAttributes,
+ "ImageWithAttributes")
+
+% \end{macrocode}
+% \begin{markdown}
+%
+% The following patterns define autolinks with attributes.
+%
+% \end{markdown}
+% \begin{macrocode}
+
+ local AutoLinkUrlWithAttributes
+ = parsers.auto_link_url
+ * Ct(parsers.attributes)
+ / self.auto_link_url
+
+ self.insert_pattern("Inline before AutoLinkUrl",
+ AutoLinkUrlWithAttributes,
+ "AutoLinkUrlWithAttributes")
+
+ local AutoLinkEmailWithAttributes
+ = parsers.auto_link_email
+ * Ct(parsers.attributes)
+ / self.auto_link_email
+
+ self.insert_pattern("Inline before AutoLinkEmail",
+ AutoLinkEmailWithAttributes,
+ "AutoLinkEmailWithAttributes")
+
+ if options.relativeReferences then
+
+ local AutoLinkRelativeReferenceWithAttributes
+ = parsers.auto_link_relative_reference
+ * Ct(parsers.attributes)
+ / self.auto_link_url
+
+ self.insert_pattern(
+ "Inline before AutoLinkRelativeReference",
+ AutoLinkRelativeReferenceWithAttributes,
+ "AutoLinkRelativeReferenceWithAttributes")
+
+ end
+
+ end
+ }
+end
+% \end{macrocode}
+% \begin{markdown}
+%
%#### Notes
%
% The \luamdef{extensions.notes} function implements the Pandoc note
@@ -25450,7 +26953,7 @@ M.extensions.notes = function(notes, inline_notes)
/ register_note
local Blank = NoteBlock + parsers.Blank
- self.update_rule("Blank", function() return Blank end)
+ self.update_rule("Blank", Blank)
self.insert_pattern("Inline after Emph",
NoteRef, "NoteRef")
@@ -25468,7 +26971,7 @@ end
% The \luamdef{extensions.pipe_table} function implements the \acro{PHP}
% Markdown table syntax extension (also known as pipe tables in Pandoc). When
% the `table_captions` parameter is `true`, the function also implements the
-% Pandoc `table_captions` syntax extension for table captions.
+% Pandoc table caption syntax extension for table captions.
%
% \end{markdown}
% \begin{macrocode}
@@ -25793,16 +27296,18 @@ end
% \end{macrocode}
% \begin{markdown}
%
-%#### Tex Math Dollars
+%#### Tex Math
%
-% The \luamdef{extensions.tex_math_dollars} function implements the Pandoc
-% tex_math_dollars syntax extension.
+% The \luamdef{extensions.tex_math} function implements the Pandoc math
+% syntax extensions.
%
% \end{markdown}
% \begin{macrocode}
-M.extensions.tex_math_dollars = function()
+M.extensions.tex_math = function(tex_math_dollars,
+ tex_math_single_backslash,
+ tex_math_double_backslash)
return {
- name = "built-in tex_math_dollars syntax extension",
+ name = "built-in tex_math syntax extension",
extend_writer = function(self)
% \end{macrocode}
% \par
@@ -25837,35 +27342,151 @@ M.extensions.tex_math_dollars = function()
return (starter * C(p * (p - ender)^0) * ender)
end
- local inlinemathtail = B( parsers.any * parsers.nonspacechar
- + parsers.backslash * parsers.any)
- * parsers.dollar
- * -#(parsers.digit)
+ local allowed_before_closing = B( parsers.backslash * parsers.any
+ + parsers.any * (parsers.nonspacechar - parsers.backslash))
+% \end{macrocode}
+% \begin{markdown}
+%
+% The following patterns implement the Pandoc dollar math syntax extension.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local dollar_math_content = parsers.backslash^-1
+ * parsers.any
+ - parsers.blankline^2
+ - parsers.dollar
+
+ local inline_math_opening_dollars = parsers.dollar
+ * #(parsers.nonspacechar)
+
+ local inline_math_closing_dollars = allowed_before_closing
+ * parsers.dollar
+ * -#(parsers.digit)
+
+ local inline_math_dollars = between(C( dollar_math_content),
+ inline_math_opening_dollars,
+ inline_math_closing_dollars)
+
+ local display_math_opening_dollars = parsers.dollar
+ * parsers.dollar
+
+ local display_math_closing_dollars = parsers.dollar
+ * parsers.dollar
+
+ local display_math_dollars = between(C( dollar_math_content),
+ display_math_opening_dollars,
+ display_math_closing_dollars)
+% \end{macrocode}
+% \begin{markdown}
+%
+% The following patterns implement the Pandoc single and double
+% backslash math syntax extensions.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local backslash_math_content = parsers.any
+ - parsers.blankline^2
+% \end{macrocode}
+% \begin{markdown}
+%
+% The following patterns implement the Pandoc double backslash math
+% syntax extension.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local inline_math_opening_double = parsers.backslash
+ * parsers.backslash
+ * parsers.lparent
+ * #(parsers.nonspacechar)
+
+ local inline_math_closing_double = allowed_before_closing
+ * parsers.backslash
+ * parsers.backslash
+ * parsers.rparent
+
+ local inline_math_double = between(C( backslash_math_content),
+ inline_math_opening_double,
+ inline_math_closing_double)
+
+ local display_math_opening_double = parsers.backslash
+ * parsers.backslash
+ * parsers.lbracket
+
+ local display_math_closing_double = allowed_before_closing
+ * parsers.backslash
+ * parsers.backslash
+ * parsers.rbracket
+
+ local display_math_double = between(C( backslash_math_content),
+ display_math_opening_double,
+ display_math_closing_double)
+% \end{macrocode}
+% \begin{markdown}
+%
+% The following patterns implement the Pandoc single backslash math
+% syntax extension.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local inline_math_opening_single = parsers.backslash
+ * parsers.lparent
+ * #(parsers.nonspacechar)
+
+ local inline_math_closing_single = allowed_before_closing
+ * parsers.backslash
+ * parsers.rparent
+
+ local inline_math_single = between(C( backslash_math_content),
+ inline_math_opening_single,
+ inline_math_closing_single)
+
+ local display_math_opening_single = parsers.backslash
+ * parsers.lbracket
- local inlinemath = between(C( parsers.backslash^-1
- * parsers.any
- - parsers.blankline^2
- - parsers.dollar),
- parsers.dollar * #(parsers.nonspacechar),
- inlinemathtail)
+ local display_math_closing_single = allowed_before_closing
+ * parsers.backslash
+ * parsers.rbracket
- local displaymathdelim = parsers.dollar
- * parsers.dollar
+ local display_math_single = between(C( backslash_math_content),
+ display_math_opening_single,
+ display_math_closing_single)
- local displaymath = between(C( parsers.backslash^-1
- * parsers.any
- - parsers.blankline^2
- - parsers.dollar),
- displaymathdelim,
- displaymathdelim)
+ local display_math = parsers.fail
- local TexMathDollars = displaymath / writer.display_math
- + inlinemath / writer.inline_math
+ local inline_math = parsers.fail
+
+ if tex_math_dollars then
+ display_math = display_math + display_math_dollars
+ inline_math = inline_math + inline_math_dollars
+ end
+
+ if tex_math_double_backslash then
+ display_math = display_math + display_math_double
+ inline_math = inline_math + inline_math_double
+ end
+
+ if tex_math_single_backslash then
+ display_math = display_math + display_math_single
+ inline_math = inline_math + inline_math_single
+ end
+
+ local TexMath = display_math / writer.display_math
+ + inline_math / writer.inline_math
self.insert_pattern("Inline after Emph",
- TexMathDollars, "TexMathDollars")
+ TexMath, "TexMath")
- self.add_special_character("$")
+ if tex_math_dollars then
+ self.add_special_character("$")
+ end
+
+ if tex_math_single_backslash or tex_math_double_backslash then
+ self.add_special_character("\\")
+ self.add_special_character("[")
+ self.add_special_character("]")
+ self.add_special_character(")")
+ self.add_special_character("(")
+ end
end
}
end
@@ -25875,9 +27496,10 @@ end
%#### YAML Metadata
%
% The \luamdef{extensions.jekyll_data} function implements the Pandoc
-% `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.
+% \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.
%
% \end{markdown}
% \begin{macrocode}
@@ -26020,7 +27642,7 @@ M.extensions.jekyll_data = function(expect_jekyll_data)
self.insert_pattern("Block before Blockquote",
UnexpectedJekyllData, "UnexpectedJekyllData")
if expect_jekyll_data then
- self.update_rule("ExpectedJekyllData", function() return ExpectedJekyllData end)
+ self.update_rule("ExpectedJekyllData", ExpectedJekyllData)
end
end
}
@@ -26094,12 +27716,24 @@ function M.new(options)
table.insert(extensions, header_attributes_extension)
end
+ if options.inlineCodeAttributes then
+ local inline_code_attributes_extension =
+ M.extensions.inline_code_attributes()
+ table.insert(extensions, inline_code_attributes_extension)
+ end
+
if options.jekyllData then
local jekyll_data_extension = M.extensions.jekyll_data(
options.expectJekyllData)
table.insert(extensions, jekyll_data_extension)
end
+ if options.linkAttributes then
+ local link_attributes_extension =
+ M.extensions.link_attributes()
+ table.insert(extensions, link_attributes_extension)
+ end
+
if options.lineBlocks then
local line_block_extension = M.extensions.line_blocks()
table.insert(extensions, line_block_extension)
@@ -26131,9 +27765,14 @@ function M.new(options)
table.insert(extensions, superscript_extension)
end
- if options.texMathDollars then
- local tex_math_dollars_extension = M.extensions.tex_math_dollars()
- table.insert(extensions, tex_math_dollars_extension)
+ if options.texMathDollars or
+ options.texMathSingleBackslash or
+ options.texMathDoubleBackslash then
+ local tex_math_extension = M.extensions.tex_math(
+ options.texMathDollars,
+ options.texMathSingleBackslash,
+ options.texMathDoubleBackslash)
+ table.insert(extensions, tex_math_extension)
end
% \end{macrocode}
@@ -26308,9 +27947,24 @@ local lfs = require("lfs")
if options.cacheDir and not lfs.isdir(options.cacheDir) then
assert(lfs.mkdir(options["cacheDir"]))
end
-
-local ran_ok, kpse = pcall(require, "kpse")
-if ran_ok then kpse.set_program_name("luatex") end
+% \end{macrocode}
+% \begin{markdown}
+%
+% If \pkg{Kpathsea} has not been loaded before or if Lua\TeX{} has not yet
+% been initialized, configure \pkg{Kpathsea} on top of loading it.
+%
+% \end{markdown}
+% \begin{macrocode}
+local kpse
+(function()
+ local should_initialize = package.loaded.kpse == nil
+ or tex.initialize ~= nil
+ local ran_ok
+ ran_ok, kpse = pcall(require, "kpse")
+ if ran_ok and should_initialize then
+ kpse.set_program_name("luatex")
+ end
+end)()
local md = require("markdown")
% \end{macrocode}
% \begin{markdown}
@@ -26503,7 +28157,7 @@ end
% \par
% \begin{markdown}
%
-%#### Raw Attribute Renderer Prototypes
+%#### Raw Attributes
%
% In the raw block and inline raw span renderer prototypes, execute the content
% with TeX when the raw attribute is `tex`, display the content as markdown when
@@ -27282,8 +28936,24 @@ end
"|markdownOptionHelperScriptFileName"}%
|immediate|write|markdownOutputFileStream{%
local ran_ok, error = pcall(function()
- local ran_ok, kpse = pcall(require, "kpse")
- if ran_ok then kpse.set_program_name("luatex") end
+% \end{macrocode}
+% \begin{markdown}
+%
+% If \pkg{Kpathsea} has not been loaded before or if Lua\TeX{} has not yet
+% been initialized, configure \pkg{Kpathsea} on top of loading it.
+%
+% \end{markdown}
+% \begin{macrocode}
+ local kpse
+ (function()
+ local should_initialize = package.loaded.kpse == nil
+ or tex.initialize
+ local ran_ok
+ ran_ok, kpse = pcall(require, "kpse")
+ if ran_ok and should_initialize then
+ kpse.set_program_name("luatex")
+ end
+ end)()
#1
end)
% \end{macrocode}
@@ -27907,7 +29577,7 @@ end
% \begin{markdown}
%
% The `code` key is used to immediately expand and execute code, which can be
-% especially useful in \LaTeX{} setup snippets.
+% especially useful in \LaTeX{} snippets.
%
% \end{markdown}
% \begin{macrocode}
@@ -27939,7 +29609,7 @@ end
% \begin{markdown}
%
% To ensure that keys containing forward slashes get passed correctly, we
-% replace all forward slashes in the nput with backslash tokens with category
+% replace all forward slashes in the input with backslash tokens with category
% code letter and then undo the replacement. This means that if any unbraced
% backslash tokens with category code letter exist in the input, they will be
% replaced with forward slashes. However, this should be extremely rare.
@@ -27980,12 +29650,6 @@ end
\cs_generate_variant:Nn
\keys_define:nn
{ nV }
-\cs_generate_variant:Nn
- \tl_replace_all:Nnn
- { NVn }
-\cs_generate_variant:Nn
- \tl_replace_all:Nnn
- { NnV }
\ExplSyntaxOff
% \end{macrocode}
% \par
@@ -28730,9 +30394,8 @@ end
% \begin{markdown}
%
%#### Links
-% Before consuming the parameters for the hyperlink renderer, we change the
-% category code of the hash sign (`#`) to other, so that it cannot be
-% mistaken for a parameter character.
+% Here is an implementation for hypertext links and relative references.
+%
% \end{markdown}
% \begin{macrocode}
\RequirePackage{url}
@@ -29007,7 +30670,68 @@ end
% \par
% \begin{markdown}
%
-%#### Raw Attribute Renderer Prototypes
+%#### Strike-Through
+% If the \Opt{strikeThrough} option is enabled, we will load the
+% \pkg{soulutf8} package and use it to implement strike-throughs.
+%
+% \end{markdown}
+% \begin{macrocode}
+\markdownIfOption{strikeThrough}{%
+ \RequirePackage{soulutf8}%
+ \markdownSetup{
+ rendererPrototypes = {
+ strikeThrough = {%
+ \st{#1}%
+ },
+ }
+ }
+}{}
+% \end{macrocode}
+% \par
+% \begin{markdown}
+%
+%#### Image 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.
+%
+% \end{markdown}
+% \begin{macrocode}
+\ExplSyntaxOn
+\@@_if_option:nTF
+ { linkAttributes }
+ {
+ \RequirePackage{graphicx}
+ \markdownSetup{
+ rendererPrototypes = {
+ imageAttributeContextBegin = {
+ \group_begin:
+ \markdownSetup{
+ rendererPrototypes = {
+ 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`.
@@ -29429,7 +31153,7 @@ end
% \par
% \begin{markdown}
%
-%#### Raw Attribute Renderer Prototypes
+%#### Raw Attributes
%
% In the raw block and inline raw span renderer prototypes, default to the
% plain TeX renderer prototypes, translating raw attribute `context` to `tex`.