From e9f267fd4c8414d6146c5fee0dbe459613dd0f3b Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Tue, 4 Apr 2023 03:01:33 +0000 Subject: CTAN sync 202304040301 --- macros/generic/markdown/CHANGES.md | 35 +- macros/generic/markdown/VERSION | 2 +- macros/generic/markdown/examples/context-mkii.tex | 2 + macros/generic/markdown/examples/context-mkiv.tex | 6 + macros/generic/markdown/examples/example.md | 18 + macros/generic/markdown/examples/latex.tex | 2 + macros/generic/markdown/markdown.dtx | 2424 +++++- macros/generic/markdown/markdown.html | 8807 +++++++++++---------- macros/generic/markdown/markdown.pdf | Bin 957775 -> 998227 bytes 9 files changed, 6892 insertions(+), 4404 deletions(-) (limited to 'macros/generic') diff --git a/macros/generic/markdown/CHANGES.md b/macros/generic/markdown/CHANGES.md index 250ec4f8df..3eef881e72 100644 --- a/macros/generic/markdown/CHANGES.md +++ b/macros/generic/markdown/CHANGES.md @@ -1,6 +1,32 @@ # Changes -## 2.21.0 +## 2.22.0 (2023-04-03) + +Development: + +- Add support for TeX math surrounded by backslash-escaped + parens and brackets. (contributed by @lostenderman, #61, + #235, #236, #270) +- Add support for attributes on links, images, and inline + code spans. (jgm#36, jgm#43, #50, #123, #256, #280) +- Add `import` LaTeX option. (#107, #285) + +Documentation: + +- Unify how Pandoc syntax extensions are named and cited in + documentation. (#274, #284) + +Refactoring: + +- Only configure the Kpathsea library if it has not already + been configured. (#268, #283) + +Deprecation: + +- Deprecate `theme` LaTeX option in favor of the new + `import` LaTeX option. (#107, #285) + +## 2.21.0 (2023-02-28) Development: @@ -17,6 +43,9 @@ Fixes: [CommonMark](https://spec.commonmark.org/0.30/#matches). (lostenderman#56, #265) - Fail gracefully when CLI receives unknown options. (eddcb18) + +Documentation: + - Rename `writer->encode_*()` methods to clarify their purpose. (lostenderman#101, #271, #272) @@ -24,9 +53,9 @@ Deprecation: - Deprecate the current semantics of header attribute contexts. (#258, #264) -- Deprecate `hardLineBreaks` option. (#227, #263) +- Deprecate `hardLineBreaks` Lua option. (#227, #263) -## 2.20.0 (2022-02-01) +## 2.20.0 (2023-02-01) Development: diff --git a/macros/generic/markdown/VERSION b/macros/generic/markdown/VERSION index 617f937934..dc259f020e 100644 --- a/macros/generic/markdown/VERSION +++ b/macros/generic/markdown/VERSION @@ -1 +1 @@ -2.21.0-0-gee15b88 (2023-02-28) +2.22.0-0-g5a3d0fe (2023-04-02) diff --git a/macros/generic/markdown/examples/context-mkii.tex b/macros/generic/markdown/examples/context-mkii.tex index fcd6784eaf..e4f953c9a2 100644 --- a/macros/generic/markdown/examples/context-mkii.tex +++ b/macros/generic/markdown/examples/context-mkii.tex @@ -27,6 +27,8 @@ tableCaptions = yes, taskLists = yes, texMathDollars = yes, + texMathDoubleBackslash = yes, + texMathSingleBackslash = yes, ] % Set renderers of the Markdown module. diff --git a/macros/generic/markdown/examples/context-mkiv.tex b/macros/generic/markdown/examples/context-mkiv.tex index a4b9fd9472..9d485820cf 100644 --- a/macros/generic/markdown/examples/context-mkiv.tex +++ b/macros/generic/markdown/examples/context-mkiv.tex @@ -4,6 +4,10 @@ \setupexternalfigures[location={local,global,default}] % Load the Markdown module. +\startluacode +local kpse = require("kpse") +kpse.set_program_name("luatex") +\stopluacode \usemodule[t][markdown] % Set options of the Markdown module. @@ -27,6 +31,8 @@ tableCaptions = yes, taskLists = yes, texMathDollars = yes, + texMathDoubleBackslash = yes, + texMathSingleBackslash = yes, ] % Set renderers of the Markdown module. diff --git a/macros/generic/markdown/examples/example.md b/macros/generic/markdown/examples/example.md index 16d32368d9..8819ef5b67 100644 --- a/macros/generic/markdown/examples/example.md +++ b/macros/generic/markdown/examples/example.md @@ -177,3 +177,21 @@ $$ x^n + y^n = z^n $$ | even discontinuous | lines + +This is inline and display TeX math created using dollars signs: + +$E=mc^2$ + +$$E=mc^2$$ + +This is inline and display TeX math created using single backslashes: + +\(E=mc^2\) + +\[E=mc^2\] + +This is inline and display TeX math created using double backslashes: + +\\(E=mc^2\\) + +\\[E=mc^2\\] diff --git a/macros/generic/markdown/examples/latex.tex b/macros/generic/markdown/examples/latex.tex index fc7d6a0a2a..44736c61dc 100644 --- a/macros/generic/markdown/examples/latex.tex +++ b/macros/generic/markdown/examples/latex.tex @@ -35,6 +35,8 @@ tableCaptions, taskLists, texMathDollars, + texMathDoubleBackslash, + texMathSingleBackslash, ]{markdown} \begin{markdown*}{hybrid} --- diff --git a/macros/generic/markdown/markdown.dtx b/macros/generic/markdown/markdown.dtx index 86d1d68fed..ee878acc72 100644 --- a/macros/generic/markdown/markdown.dtx +++ b/macros/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 % @@ -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 % %<*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 `colored text`. + +% +%<*tex> +% \fi +% \begin{macrocode} +\@@_add_lua_option:nnn + { inlineCodeAttributes } + { boolean } + { false } +% \end{macrocode} +% \iffalse +% +%<*lua,lua-cli> +% \fi +% \begin{macrocode} +defaultOptions.inlineCodeAttributes = false +% \end{macrocode} +% \par +% \iffalse +% +%<*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 % %<*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) + +% +%<*tex> +% \fi +% \begin{macrocode} +\@@_add_lua_option:nnn + { linkAttributes } + { boolean } + { false } +% \end{macrocode} +% \iffalse +% +%<*lua,lua-cli> +% \fi +% \begin{macrocode} +defaultOptions.linkAttributes = false +% \end{macrocode} +% \par +% \iffalse +% +%<*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,55 +9509,461 @@ defaultOptions.texMathDollars = false % %<*manual-options> -#### Option `tightLists` +#### Option `texMathDoubleBackslash` -`tightLists` (default value: `true`) +`texMathDoubleBackslash` (default value: `false`) % \fi % \begin{markdown} % -% \Optitem[true]{tightLists}{\opt{true}, \opt{false}} +% \Optitem[false]{texMathDoubleBackslash}{\opt{true}, \opt{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: - - ``` md - - This is - - a tight - - unordered list. + : Enable the Pandoc [double backslash math syntax + extension][pandoc-tex-math-double-backslash]: - - This is - - not a tight + ``` md + inline math: \\(E=mc^2\\) - - unordered list. - ``` + display math: \\[E=mc^2\\] + ``` : false - : Unordered and ordered lists whose items consist of multiple paragraphs - will be treated the same way as lists that consist of multiple paragraphs. + : 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 -##### \LaTeX{} Example {.unnumbered} +##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex -\documentclass{article} -\usepackage{markdown} -\begin{document} +\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: -\begin{markdown} -The following list is tight: +> \\(E=mc^2\\) +> +> \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\] -- first item +##### 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\\] + +% +%<*tex> +% \fi +% \begin{macrocode} +\@@_add_lua_option:nnn + { texMathDoubleBackslash } + { boolean } + { false } +% \end{macrocode} +% \iffalse +% +%<*lua,lua-cli> +% \fi +% \begin{macrocode} +defaultOptions.texMathDoubleBackslash = false +% \end{macrocode} +% \par +% \iffalse +% +%<*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\] + +% +%<*tex> +% \fi +% \begin{macrocode} +\@@_add_lua_option:nnn + { texMathSingleBackslash } + { boolean } + { false } +% \end{macrocode} +% \iffalse +% +%<*lua,lua-cli> +% \fi +% \begin{macrocode} +defaultOptions.texMathSingleBackslash = false +% \end{macrocode} +% \par +% \iffalse +% +%<*manual-options> + +#### Option `tightLists` + +`tightLists` (default value: `true`) + +% \fi +% \begin{markdown} +% +% \Optitem[true]{tightLists}{\opt{true}, \opt{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: + + ``` md + - This is + - a tight + - unordered list. + + - This is + + not a tight + + - 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. + +% \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{markdown} +\begin{document} + +\begin{markdown} +The following list is tight: + +- first item - second item - third item @@ -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 + +% +%<*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 +% +%<*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 + +% +%<*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 +% +%<*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} @@ -14116,36 +14968,117 @@ following content: \startmarkdown Please visit [the link][ctan]. - [ctan]: https://ctan.org/ - (the Comprehensive TeX Archive Network) -\stopmarkdown -\stoptext + [ctan]: https://ctan.org/ + (the Comprehensive TeX Archive Network) +\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: + +> Please visit the link titled *the Comprehensive TeX +> Archive Network*. + +% +%<*tex> +% \fi +% +% \begin{macrocode} +\def\markdownRendererLink{% + \markdownRendererLinkPrototype}% +\ExplSyntaxOn +\seq_gput_right:Nn + \g_@@_renderers_seq + { link } +\prop_gput:Nnn + \g_@@_renderer_arities_prop + { link } + { 4 } +\ExplSyntaxOff +% \end{macrocode} +% \par +% +% \iffalse +% +%<*manual-tokens> +% \fi +% +% \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 -context document.tex +lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: -> Please visit the link titled *the Comprehensive TeX -> Archive Network*. +> foo (bar) baz % %<*tex> % \fi % % \begin{macrocode} -\def\markdownRendererLink{% - \markdownRendererLinkPrototype}% +\def\markdownRendererLinkAttributeContextBegin{% + \markdownRendererLinkAttributeContextBeginPrototype}% \ExplSyntaxOn \seq_gput_right:Nn \g_@@_renderers_seq - { link } + { linkAttributeContextBegin } \prop_gput:Nnn \g_@@_renderer_arities_prop - { link } - { 4 } + { 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 @@ -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} ``````` @@ -18117,6 +19064,44 @@ would use the following code in the preamble of your document: \expandafter\markdownLaTeXThemeLoad\expandafter{ \markdownLaTeXThemePackageName}{#1/} } +\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 } { @@ -18126,13 +19111,12 @@ would use the following code in the preamble of your document: % \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 % %<*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} @@ -23477,60 +24740,68 @@ function M.reader.new(writer, options) parsers.doubleasterisks) ) / writer.strong - parsers.Emph = ( parsers.between(parsers.Inline, parsers.asterisk, - parsers.asterisk) - ) / writer.emphasis - end + parsers.Emph = ( parsers.between(parsers.Inline, parsers.asterisk, + parsers.asterisk) + ) / writer.emphasis + 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 + +% \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.less - * C(parsers.alphanumeric^1 * P("://") * parsers.urlchar^1) - * parsers.more - / function(url) - return writer.link(writer.escape(url), url) - end + parsers.AutoLinkUrl = parsers.auto_link_url + / self.auto_link_url - 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 + 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 inlinemath = between(C( parsers.backslash^-1 - * parsers.any - - parsers.blankline^2 - - parsers.dollar), - parsers.dollar * #(parsers.nonspacechar), - inlinemathtail) + local display_math_opening_single = parsers.backslash + * parsers.lbracket - local displaymathdelim = parsers.dollar - * parsers.dollar + local display_math_closing_single = allowed_before_closing + * parsers.backslash + * parsers.rbracket - local displaymath = between(C( parsers.backslash^-1 - * parsers.any - - parsers.blankline^2 - - parsers.dollar), - displaymathdelim, - displaymathdelim) + local display_math_single = between(C( backslash_math_content), + display_math_opening_single, + display_math_closing_single) + + local display_math = parsers.fail + + 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 TexMathDollars = displaymath / writer.display_math - + inlinemath / writer.inline_math + 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`. diff --git a/macros/generic/markdown/markdown.html b/macros/generic/markdown/markdown.html index 98c6a51fe3..b31144bfe9 100644 --- a/macros/generic/markdown/markdown.html +++ b/macros/generic/markdown/markdown.html @@ -84,7 +84,7 @@

Markdown Package User Manual

Vít Novotný

-

2.21.0-0-gee15b88 2023-02-28

+

2.22.0-0-g5a3d0fe 2023-04-02