diff options
Diffstat (limited to 'Master/texmf-dist/source/generic/markdown/markdown.dtx')
-rw-r--r-- | Master/texmf-dist/source/generic/markdown/markdown.dtx | 640 |
1 files changed, 491 insertions, 149 deletions
diff --git a/Master/texmf-dist/source/generic/markdown/markdown.dtx b/Master/texmf-dist/source/generic/markdown/markdown.dtx index ee878acc728..3edb022e15a 100644 --- a/Master/texmf-dist/source/generic/markdown/markdown.dtx +++ b/Master/texmf-dist/source/generic/markdown/markdown.dtx @@ -796,16 +796,18 @@ abbr { \ProvidesPackage{markdownthemewitiko_markdown_techdoc}[2022/02/23] \RequirePackage{etoolbox} \markdownSetup{ - rendererPrototypes = { - codeSpan = {\inline{#1}}, - headingFour = {% + renderers = { + head*Four = {% \paragraph{#1}\leavevmode \def\markdownRendererInterblockSeparator{% \let\markdownRendererInterblockSeparator\par }% \noindent }, - jekyllDataEnd = {% + }, + rendererPrototypes = { + codeSpan = {\inline{#1}}, + jek*llDataEnd = {% \AfterEndPreamble{% \printtitlepage \tableofcontents @@ -1045,7 +1047,7 @@ a directory named `markdown` due to [issue #74][issue-74]. % % This section gives an overview of all resources required by the package. % -%### Lua Requirements {#luaprerequisites} +%### Lua Requirements {#lua-prerequisites} % % The Lua part of the package requires that the following Lua modules are % available from within the Lua\TeX{} engine (though not necessarily in the @@ -1201,7 +1203,8 @@ end)() % (subset) parser that is used to read \acro{yaml} metadata when the % \Opt{jekyllData} option is enabled. We carry a copy of the library % in file `markdown-tinyyaml.lua` distributed together with the Markdown -% package. +% package. <!-- TODO: Stop carrying the copy of the library in TeX Live +% 2023. --> % % \end{markdown} % \iffalse @@ -1211,11 +1214,11 @@ end)() % \par % \begin{markdown} % -%### Plain \TeX{} Requirements {#texprerequisites} +%### Plain \TeX{} Requirements {#tex-prerequisites} % % The plain \TeX{} part of the package requires that the plain \TeX{} % format (or its superset) is loaded, all the Lua prerequisites (see -% Section <#sec:luaprerequisites>), and the following packages: +% Section <#sec:lua-prerequisites>), and the following packages: % % \pkg{expl3} % @@ -1275,7 +1278,7 @@ end)() % \par % \begin{markdown} % -%### \LaTeX{} Requirements {#latexprerequisites} +%### \LaTeX{} Requirements {#latex-prerequisites} % % The \LaTeX{} part of the package requires that the \Hologo{LaTeX2e} format is % loaded, @@ -1291,12 +1294,12 @@ end)() % \fi % \begin{markdown} % a \TeX{} engine that extends \Hologo{eTeX}, and all the plain \TeX{} -% prerequisites (see Section <#sec:texprerequisites>): +% prerequisites (see Section <#sec:tex-prerequisites>): % % The following packages are soft prerequisites. They are only used to provide % default token renderer prototypes (see sections % <#sec:texrendererprototypes> and -% <#sec:latexdefaultrendererprototypes>) or \LaTeX{} themes (see Section +% <#sec:latex-default-renderer-prototypes>) or \LaTeX{} themes (see Section % <#sec:latexthemes>) and will not be loaded if the `plain` package option % has been enabled (see Section <#sec:latexplain>): % @@ -1369,7 +1372,7 @@ end)() % %: A package that is used to polyfill the general hook management system in % the default renderer prototypes for \acro{yaml} metadata, see Section -% <#sec:latexyamlmetadata>, and also in the default renderer prototype +% <#sec:latex-yaml-metadata>, and also in the default renderer prototype % for identifier attributes. % % \pkg{soulutf8} @@ -1402,7 +1405,7 @@ end)() %### \Hologo{ConTeXt} Prerequisites % The \Hologo{ConTeXt} part of the package requires that either the Mark II or % the Mark IV format is loaded, all the plain \TeX{} prerequisites (see -% Section <#sec:texprerequisites>), and the following \Hologo{ConTeXt} +% Section <#sec:tex-prerequisites>), and the following \Hologo{ConTeXt} % modules: % % \pkg{m-database} @@ -1601,13 +1604,14 @@ the Markdown package: ``` sh git clone https://github.com/witiko/markdown cd markdown/examples -lualatex latex.tex +lualatex latex-luatex.tex `````` -A PDF document named `latex.pdf` should be produced. Open the text documents -`latex.tex` and `example.md` in a text editor to see how the example documents -are structured. Try changing the documents and typesetting them as follows: +A PDF document named `latex-luatex.pdf` should be produced. Open the text +documents `latex-luatex.tex` and `example.md` in a text editor to see how the +example documents are structured. Try changing the documents and typesetting +them as follows: ``` sh -lualatex latex.tex +lualatex latex-luatex.tex `````` to see the effect of your changes. @@ -1628,10 +1632,7 @@ Next, invoke LuaTeX from the terminal: context document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello -*world*!” Invoking pdfTeX should have the same effect: -``` sh -texexec --passon=--shell-escape document.tex -`````` +*world*!” *** @@ -1714,12 +1715,12 @@ local M = {metadata = metadata} % \par % \begin{markdown} % -%### Conversion from Markdown to Plain \TeX{} {#luaconversion} +%### Conversion from Markdown to Plain \TeX{} {#lua-conversion} % % The Lua interface exposes the \luamdef{new}`(options)` function. This % function returns a conversion function from markdown to plain \TeX{} according % to the table `options` that contains options recognized by the Lua interface -% (see Section <#sec:luaoptions>). The `options` parameter is optional; when +% (see Section <#sec:lua-options>). The `options` parameter is optional; when % unspecified, the behaviour will be the same as if `options` were an empty % table. % @@ -1732,7 +1733,7 @@ local M = {metadata = metadata} % print(convert("Hello *world*!")) % ``````` % -%### User-Defined Syntax Extensions {#luauserextensions} +%### User-Defined Syntax Extensions {#lua-user-extensions} % % For the purpose of user-defined syntax extensions, the Lua interface also % exposes the \luamdef{reader} object, which performs the lexical and @@ -1966,7 +1967,7 @@ pdftex document.tex % \fi % \begin{markdown} % -%### Options {#luaoptions} +%### Options {#lua-options} % % The Lua interface recognizes the following options. When unspecified, the % value of a key is taken from the \luamdef{defaultOptions} table. @@ -2081,7 +2082,7 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. } { \msg_error:nnnV - { @@ } + { markdown } { failed-typecheck-for-boolean-option } { #1 } \l_tmpa_tl @@ -2090,7 +2091,7 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. } } \msg_new:nnn - { @@ } + { markdown } { failed-typecheck-for-boolean-option } { Option~#1~has~value~#2,~ @@ -2139,7 +2140,7 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. \l_tmpa_bool { \msg_error:nnn - { @@ } + { markdown } { undefined-option } { #1 } } @@ -2148,7 +2149,7 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. \l_tmpa_tl { \msg_error:nnnV - { @@ } + { markdown } { unknown-option-type } { #1 } \l_tmpa_tl @@ -2158,13 +2159,13 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. \l_tmpa_tl } \msg_new:nnn - { @@ } + { markdown } { unknown-option-type } { Option~#1~has~unknown~type~#2. } \msg_new:nnn - { @@ } + { markdown } { undefined-option } { Option~#1~is~undefined. @@ -2191,7 +2192,7 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. \l_tmpa_bool { \msg_error:nnn - { @@ } + { markdown } { undefined-option } { #1 } } @@ -2247,7 +2248,17 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. \tl_tail:n { #1 } } } -\seq_new:N \g_@@_cases_seq +% \end{macrocode} +% \par +% \begin{markdown} +% +% To make it easier to support different coding styles in the interface, +% engines, we define the \mdef{\@\@_with_various_cases:nn} function +% that allows us to generate different variants of a string using +% different cases. +% +% \end{markdown} +% \begin{macrocode} \cs_new:Nn \@@_with_various_cases:nn { \seq_clear:N @@ -2268,6 +2279,29 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. \l_tmpa_seq { #2 } } +% \end{macrocode} +% \par +% \begin{markdown} +% +% To interrupt the \mref{\@\@_with_various_cases:nn} function +% prematurely, use the \mdef{\@\@_with_various_cases_break:} function. +% +% \end{markdown} +% \begin{macrocode} +\cs_new:Nn \@@_with_various_cases_break: + { + \seq_map_break: + } +% \end{macrocode} +% \begin{markdown} +% +% By default, camelCase and snake\\\_case are supported. +% Additional cases can be added by adding functions to the +% \mdef{g_\@\@_cases_seq} sequence. +% +% \end{markdown} +% \begin{macrocode} +\seq_new:N \g_@@_cases_seq \cs_new:Nn \@@_camel_case:N { \regex_replace_all:nnN @@ -2641,13 +2675,13 @@ defaultOptions.contentBlocksLanguageMap = "markdown-languages.json" extensible subset of the \acro{peg} grammar of markdown % (see the \luamref{walkable_syntax} hash table) after built-in syntax extensions -% (see Section <#sec:luabuiltinextensions>) +% (see Section <#sec:lua-built-in-extensions>) % \iffalse (see options \Opt{citations}, \Opt{contentBlocks}, \Opt{definitionLists}, etc.) % \fi and user-defined syntax extensions -% (see Section <#sec:luauserextensions>) +% (see Section <#sec:lua-user-extensions>) % \iffalse (see option \Opt{extensions}) % \fi @@ -2881,7 +2915,7 @@ Hi *world*! ``````` Last, invoke pdfTeX without shell access from the terminal: ``` sh -texexec --passon=--no-shell-escape frozen-document.tex +context frozen-document.tex `````` A PDF document named `frozen-document.pdf` should be produced and contain the text “Hello *world*!” Since we used the contents of the frozen cache using @@ -4622,13 +4656,13 @@ defaultOptions.contentBlocks = false extensible subset of the \acro{peg} grammar of markdown % (see the \luamref{walkable_syntax} hash table) after built-in syntax extensions -% (see Section <#sec:luabuiltinextensions>) +% (see Section <#sec:lua-built-in-extensions>) % \iffalse (see options \Opt{citations}, \Opt{contentBlocks}, \Opt{definitionLists}, etc.) % \fi and user-defined syntax extensions -% (see Section <#sec:luauserextensions>) +% (see Section <#sec:lua-user-extensions>) % \iffalse (see option \Opt{extensions}) % \fi @@ -5194,7 +5228,7 @@ metadata.grammar_version = 2 % markdown using the interface of a Lua \luamref{reader} object, such as % the \luamref{reader->insert_pattern} and % \luamref{reader->add_special_character} methods, -% see Section <#luauserextensions>. +% see Section <#lua-user-extensions>. % % \end{markdown} % \iffalse @@ -5857,7 +5891,7 @@ Hi *world*! ``````` Last, invoke pdfTeX without shell access from the terminal: ``` sh -texexec --passon=--no-shell-escape document.tex +context document.tex `````` A new PDF document named `document.pdf` should be produced and contain the same text “Hello *world*!” Since we used the contents of the frozen cache using @@ -10323,7 +10357,7 @@ for i = 1, #arg do % Unless the `-`{}`-` argument has been specified before, an argument % containing the equals sign (`=`) is assumed to be an option specification in % a \meta{key}`=`\meta{value} format. The available options are listed in -% Section <#sec:luaoptions>. +% Section <#sec:lua-options>. % \end{markdown} % \begin{macrocode} elseif arg[i]:match("=") then @@ -10491,7 +10525,7 @@ pdftex --shell-escape document.tex % % The plain \TeX{} interface provides macros for the typesetting of markdown % input from within plain \TeX{}, for setting the Lua interface options (see -% Section <#sec:luaoptions>) used during the conversion from markdown to +% Section <#sec:lua-options>) used during the conversion from markdown to % plain \TeX{} and for changing the way markdown the tokens are rendered. % % \end{markdown} @@ -10510,7 +10544,7 @@ pdftex --shell-escape document.tex % \noindent It is expected that the special plain \TeX{} characters have the % expected category codes, when `\input`ting the file. % -%### Typesetting Markdown {#textypesetting} +%### Typesetting Markdown {#tex-typesetting} % % The interface exposes the \mdef{markdownBegin}, \mdef{markdownEnd}, % \mdef{markdownInput}, and \mdef{markdownEscape} macros. @@ -10607,11 +10641,11 @@ pdftex --shell-escape document.tex % \par % \begin{markdown} % -%### Options {#texoptions} +%### Options {#tex-options} % % The plain \TeX{} options are represented by \TeX{} commands. Some of them map % directly to the options recognized by the Lua interface (see -% Section <#sec:luaoptions>), while some of them are specific to the plain +% Section <#sec:lua-options>), while some of them are specific to the plain % \TeX{} interface. % % To enable the enumeration of plain \TeX{} options, we will maintain the @@ -10880,7 +10914,7 @@ For more information, see the examples for the \Opt{finalizeCache} option. % % Furthemore, we also define macros that map directly to the options recognized % by the Lua interface, such as \mdef{markdownOptionHybrid} for the -% \Opt{hybrid} Lua option (see Section <#sec:luaoptions>), which are not +% \Opt{hybrid} Lua option (see Section <#sec:lua-options>), which are not % processed by the plain \TeX{} implementation, only passed along to Lua. % % For the macros that correspond to the non-boolean options recognized by the @@ -11125,7 +11159,7 @@ In this section, I will describe the individual token renderers. % % The following \TeX{} macros may occur inside the output of the % converter functions exposed by the Lua interface (see Section -% <#sec:luaconversion>) and represent the parsed markdown tokens. These +% <#sec:lua-conversion>) and represent the parsed markdown tokens. These % macros are intended to be redefined by the user who is typesetting a % document. By default, they point to the corresponding prototypes (see Section % <#sec:texrendererprototypes>). @@ -12637,8 +12671,8 @@ list is not tight). The macro receives no arguments. % \begin{markdown} The \mdef{markdownRendererDlBeginTight} macro represents the beginning of a -definition list that contains an item with several paragraphs of text (the -list is not tight). This macro will only be produced, when the +definition list that contains no item with several paragraphs of text (the +list is tight). This macro will only be produced, when the \Opt{tightLists} option is disabled. The macro receives no arguments. % \end{markdown} @@ -18540,7 +18574,7 @@ following text: % \begin{markdown} % The macro is exposed in the interface, so that the user can create their own % markdown environments. Due to the way the arguments are passed to Lua (see -% Section <#sec:directlua>), the first argument may not contain the +% Section <#sec:direct-lua>), the first argument may not contain the % string `]]` (regardless of the category code of the bracket symbol (`]`)). % % The \mdef{markdownMode} macro specifies how the plain \TeX{} implementation @@ -18677,7 +18711,7 @@ pdflatex --shell-escape document.tex % Section <#sec:texinterface>). % % The \LaTeX{} implementation redefines the plain \TeX{} logging macros (see -% Section <#sec:texinterfacelogging>) to use the \LaTeX{} `\PackageInfo`, +% Section <#sec:tex-interface-logging>) to use the \LaTeX{} `\PackageInfo`, % `\PackageWarning`, and `\PackageError` macros. % % \end{markdown} @@ -18697,10 +18731,10 @@ pdflatex --shell-escape document.tex % \end{Verbatim} % \begin{markdown} % where \meta{options} are the \LaTeX{} interface options (see Section -% <#sec:latexoptions>). Note that \meta{options} inside the `\usepackage` +% <#sec:latex-options>). Note that \meta{options} inside the `\usepackage` % macro may not set the `markdownRenderers` (see Section -% <#sec:latexrenderers>) and `markdownRendererPrototypes` (see Section -% <#sec:latexrendererprototypes>) keys. Furthermore, although the +% <#sec:latex-renderers>) and `markdownRendererPrototypes` (see Section +% <#sec:latex-renderer-prototypes>) 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 @@ -18718,7 +18752,7 @@ pdflatex --shell-escape document.tex % The \envmref{markdown} and \envmref{markdown*} \LaTeX{} environments are used to % typeset markdown document fragments. The starred version of the % \envmref{markdown} environment accepts \LaTeX{} interface options (see -% Section <#sec:latexoptions>) as its only argument. These options will +% Section <#sec:latex-options>) as its only argument. These options will % only influence this markdown document fragment. % % \end{markdown} @@ -18755,7 +18789,7 @@ pdflatex --shell-escape document.tex % the filename of a markdown document and expands to the result of the % conversion of the input markdown document to plain \TeX{}. Unlike the % \mref{markdownInput} macro provided by the plain \TeX{} interface, this macro -% also accepts \LaTeX{} interface options (see Section <#sec:latexoptions>) +% also accepts \LaTeX{} interface options (see Section <#sec:latex-options>) % as its optional argument. These options will only influnce this markdown % document. % @@ -18771,7 +18805,7 @@ pdflatex --shell-escape document.tex % \end{document} % ``````` % -%### Options {#latexoptions} +%### Options {#latex-options} % % The \LaTeX{} options are represented by a comma-delimited list of % \meta{key}`=`\meta{value} pairs. For boolean options, the `=`\meta{value} @@ -18780,9 +18814,9 @@ 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{} snippets described in Section <#sec:latexsetupsnippets>, +% \LaTeX{} snippets described in Section <#sec:latex-setup-snippets>, % \LaTeX{} options map directly to the options recognized by the plain -% \TeX{} interface (see Section <#sec:texoptions>) and to the markdown token +% \TeX{} interface (see Section <#sec:tex-options>) and to the markdown token % renderers and their prototypes recognized by the plain \TeX{} interface (see % Sections <#sec:texrenderersuser> and <#sec:texrendererprototypes>). % @@ -18807,7 +18841,7 @@ pdflatex --shell-escape document.tex % \end{macrocode} % \begin{markdown} % -%#### \LaTeX{} snippets {#latexsetupsnippets} +%#### \LaTeX{} snippets {#latex-setup-snippets} % % We may also set up \LaTeX{} options as *snippets* using the % \mdef{markdownSetupSnippet} macro and invoke them later. The @@ -18939,9 +18973,9 @@ other packages used in a document. Additionally, if we redefine token renderers and renderer prototypes ourselves, the default definitions will bring no benefit to us. Using the `plain` package option, we can keep the default definitions from the plain \TeX{} implementation -% (see Section <#sec:textokenrendererprototypes>) +% (see Section <#sec:tex-token-renderer-prototypes>) and prevent the soft \LaTeX{} prerequisites -% in Section <#sec:latexprerequisites> +% in Section <#sec:latex-prerequisites> from being loaded: The plain option must be set before or when loading the package. Setting the option after loading the package will have no effect. @@ -19112,7 +19146,7 @@ would use the following code in the preamble of your document: % \begin{markdown} % % The \LaTeX{} themes have a useful synergy with snippets (see Section -% <#sec:latexsetupsnippets>): To make it less likely that different themes +% <#sec:latex-setup-snippets>): 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 @@ -19406,7 +19440,7 @@ following text, where the middot (`·`) denotes a non-breaking space: % \par % \begin{markdown} % -% Please, see Section <#sec:latexthemesimplementation> for implementation +% Please, see Section <#sec:latex-themes-implementation> for implementation % details of the example themes. #### \LaTeX{} snippets {#latexsnippets} @@ -19483,7 +19517,8 @@ The following ordered list will be preceded by roman numerals: ``````` If the `romanNumerals` snippet were defined in the `jdoe/lists` theme, -we can import the theme and use the qualified name of the snippet: +we could import the `jdoe/lists` theme and use the qualified name +`jdoe/lists/romanNumerals` to invoke the snippet: ``` tex \markdownSetup{import=jdoe/lists} @@ -19499,7 +19534,7 @@ The following ordered list will be preceded by roman numerals: 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: +current namespace for easier access: ``` tex \markdownSetup{ @@ -19518,8 +19553,9 @@ The following ordered list will be preceded by roman numerals: ``````` 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: +namespace, which can be different from the name of the snippet in the +`jdoe/lists` theme. For example, we can make the snippet +`jdoe/lists/romanNumerals` available under the name `roman`. ``` tex \markdownSetup{ @@ -19538,7 +19574,23 @@ The following ordered list will be preceded by roman numerals: ``````` Several themes and/or snippets can be loaded at once using the extended -variant of the `import` \LaTeX{} option. +variant of the `import` \LaTeX{} option: + +``` tex +\markdownSetup{ + import = { + jdoe/longpackagename/lists = { + arabic as arabic1, + roman, + alphabetic, + }, + jdoe/anotherlongpackagename/lists = { + arabic as arabic2, + }, + jdoe/yetanotherlongpackagename, + }, +} +``````` % \markdownEnd % \iffalse @@ -19752,7 +19804,7 @@ variant of the `import` \LaTeX{} option. { s } { \msg_error:nnn - { @@ } + { markdown } { malformed-name-for-clist-option } { #3 } } @@ -19798,7 +19850,7 @@ variant of the `import` \LaTeX{} option. { en } { F } \msg_new:nnn - { @@ } + { markdown } { malformed-name-for-clist-option } { Clist~option~name~#1~does~not~end~with~-s. @@ -19851,12 +19903,13 @@ variant of the `import` \LaTeX{} option. % } % ``````` % -%#### Plain \TeX{} Markdown Token Renderers {#latexrenderers} +%#### Plain \TeX{} Markdown Token Renderers {#latex-renderers} % % The \LaTeX{} interface recognizes an option with the `renderers` key, -% whose value must be a list of options that map directly to the markdown token -% renderer macros exposed by the plain \TeX{} interface (see Section -% <#sec:texrenderersuser>). +% whose value must be a list of key-values, where the keys correspond +% to the markdown token renderer macros exposed by the plain \TeX{} +% interface (see Section <#sec:texrenderersuser>) and the values are +% new definitions of these token renderers. % % \end{markdown} % \begin{macrocode} @@ -19932,12 +19985,119 @@ variant of the `import` \LaTeX{} option. % } % ``````` % -%#### Plain \TeX{} Markdown Token Renderer Prototypes {#latexrendererprototypes} +% In addition to exact token renderer names, we also support wildcards +% that match multiple token renderer names. +% +% \end{markdown} +% \begin{macrocode} +\ExplSyntaxOn +\tl_new:N + \l_@@_renderer_definition_tl +\keys_define:nn + { markdown/latex-options/renderers } + { + unknown .code:n = { + \regex_match:nVTF + { \* } + \l_keys_key_str + { + \tl_set:Nn + \l_@@_renderer_definition_tl + { #1 } + \tl_set:NV + \l_tmpa_tl + \l_keys_key_str + \regex_replace_all:nnN + { \* } + { .* } + \l_tmpa_tl + \regex_set:NV + \l_tmpa_regex + \l_tmpa_tl + \int_zero:N + \l_tmpa_int + \seq_map_inline:Nn + \g_@@_renderers_seq + { + \@@_with_various_cases:nn + { ##1 } + { + \regex_match:NnT + \l_tmpa_regex + { ####1 } + { + \@@_renderer_tl_to_csname:nN + { ##1 } + \l_tmpa_tl + \prop_get:NnN + \g_@@_renderer_arities_prop + { ##1 } + \l_tmpb_tl + \cs_generate_from_arg_count:cNVV + { \l_tmpa_tl } + \cs_set:Npn + \l_tmpb_tl + \l_@@_renderer_definition_tl + \int_incr:N + \l_tmpa_int + \@@_with_various_cases_break: + } + } + } + \int_compare:nNnT + { \l_tmpa_int } = { 0 } + { + \msg_error:nnV + { markdown } + { nonmatched-renderer-wildcard } + \l_keys_key_str + } + } + { + \msg_error:nnV + { markdown } + { undefined-renderer } + \l_keys_key_str + } + }, + } +\msg_new:nnn + { markdown } + { undefined-renderer } + { + Renderer~#1~is~undefined. + } +\msg_new:nnn + { markdown } + { nonmatched-renderer-wildcard } + { + Wildcard~#1~matches~no~renderers. + } +\cs_generate_variant:Nn + \regex_set:Nn + { NV } +\cs_generate_variant:Nn + \cs_generate_from_arg_count:NNnn + { cNVV } +\cs_generate_variant:Nn + \msg_error:nnn + { nnV } +\prg_generate_conditional_variant:Nnn + \regex_match:nn + { nV } + { TF } +\ExplSyntaxOff +% \end{macrocode} +% \begin{markdown} +% +%#### Plain \TeX{} Markdown Token Renderer Prototypes {#latex-renderer-prototypes} % -% The \LaTeX{} interface recognizes an option with the `rendererPrototypes` -% key, whose value must be a list of options that map directly to the markdown -% token renderer prototype macros exposed by the plain \TeX{} interface (see -% Section <#sec:texrendererprototypes>). +% The \LaTeX{} interface recognizes an option with the +% `rendererPrototypes` key, whose value must be a list of key-values, +% where the keys correspond to the markdown token renderer prototype +% macros exposed by the plain \TeX{} interface (see Section +% <#sec:texrendererprototypes>) and the values are new definitions of +% these token renderer prototypes. % % \end{markdown} % \begin{macrocode} @@ -20000,6 +20160,111 @@ variant of the `import` \LaTeX{} option. % } % ``````` % +% In addition to exact token renderer prototype names, we also support +% wildcards that match multiple token renderer prototype names. +% +% \end{markdown} +% \begin{macrocode} +\ExplSyntaxOn +\tl_new:N + \l_@@_renderer_prototype_definition_tl +\keys_define:nn + { markdown/latex-options/renderer-prototypes } + { + unknown .code:n = { + \regex_match:nVTF + { \* } + \l_keys_key_str + { + \tl_set:Nn + \l_@@_renderer_prototype_definition_tl + { #1 } + \tl_set:NV + \l_tmpa_tl + \l_keys_key_str + \regex_replace_all:nnN + { \* } + { .* } + \l_tmpa_tl + \regex_set:NV + \l_tmpa_regex + \l_tmpa_tl + \int_zero:N + \l_tmpa_int + \seq_map_inline:Nn + \g_@@_renderers_seq + { + \@@_with_various_cases:nn + { ##1 } + { + \regex_match:NnT + \l_tmpa_regex + { ####1 } + { + \@@_renderer_prototype_tl_to_csname:nN + { ##1 } + \l_tmpa_tl + \prop_get:NnN + \g_@@_renderer_arities_prop + { ##1 } + \l_tmpb_tl + \cs_generate_from_arg_count:cNVV + { \l_tmpa_tl } + \cs_set:Npn + \l_tmpb_tl + \l_@@_renderer_prototype_definition_tl + \int_incr:N + \l_tmpa_int + \@@_with_various_cases_break: + } + } + } + \int_compare:nNnT + { \l_tmpa_int } = { 0 } + { + \msg_error:nnV + { markdown } + { nonmatched-renderer-prototype-wildcard } + \l_keys_key_str + } + } + { + \msg_error:nnV + { markdown } + { undefined-renderer-prototype } + \l_keys_key_str + } + }, + } +\msg_new:nnn + { markdown } + { undefined-renderer-prototype } + { + Renderer~prototype~#1~is~undefined. + } +\msg_new:nnn + { markdown } + { nonmatched-renderer-prototype-wildcard } + { + Wildcard~#1~matches~no~renderer~prototypes. + } +\cs_generate_variant:Nn + \regex_set:Nn + { NV } +\cs_generate_variant:Nn + \cs_generate_from_arg_count:NNnn + { cNVV } +\cs_generate_variant:Nn + \msg_error:nnn + { nnV } +\prg_generate_conditional_variant:Nnn + \regex_match:nn + { nV } + { TF } +\ExplSyntaxOff +% \end{macrocode} +% \begin{markdown} +% % \iffalse %</latex> %<*context> @@ -20052,11 +20317,6 @@ following text: > *equals* > <math><mi>i</mi></math>. -Invoking pdfTeX should have the same effect: -``` sh -texexec --passon=--shell-escape document.tex -`````` - %</manual-interfaces> %<*context> % \fi @@ -20077,7 +20337,7 @@ texexec --passon=--shell-escape document.tex % \begin{markdown} % % The \Hologo{ConTeXt} implementation redefines the plain \TeX{} logging macros -% (see Section <#sec:texinterfacelogging>) to use the \Hologo{ConTeXt} +% (see Section <#sec:tex-interface-logging>) to use the \Hologo{ConTeXt} % `\writestatus` macro. % % \end{markdown} @@ -20137,7 +20397,7 @@ texexec --passon=--shell-escape document.tex % the conversion of the input markdown document to plain \TeX{}. Unlike the % \mref{markdownInput} macro provided by the plain \TeX{} interface, this macro % also accepts \Hologo{ConTeXt} interface options (see Section -% <#sec:contextoptions>) as its optional argument. These options will only +% <#sec:context-options>) as its optional argument. These options will only % influnce this markdown document. % % The following example \LaTeX{} code showcases the usage of the @@ -20151,7 +20411,7 @@ texexec --passon=--shell-escape document.tex % \stoptext % ``````` % -%### Options {#contextoptions} +%### Options {#context-options} % % The \Hologo{ConTeXt} options are represented by a comma-delimited list of % \meta{key}`=`\meta{value} pairs. For boolean options, the `=`\meta{value} @@ -20160,7 +20420,7 @@ texexec --passon=--shell-escape document.tex % omitted. % % \Hologo{ConTeXt} options map directly to the options recognized by the plain -% \TeX{} interface (see Section <#sec:texoptions>). +% \TeX{} interface (see Section <#sec:tex-options>). % % The \Hologo{ConTeXt} options may be specified when using the % \mref{inputmarkdown} macro (see Section <#sec:contextinterface>), or via the @@ -22764,7 +23024,7 @@ end % \par % \begin{markdown} % -%### Plain \TeX{} Writer {#texwriter} +%### Plain \TeX{} Writer {#tex-writer} % % This section documents the \luamref{writer} object, which implements the % routines for producing the \TeX{} output. The object is an amalgamate of the @@ -22787,7 +23047,7 @@ M.writer = {} % % The \luamdef{writer.new} method creates and returns a new \TeX{} writer % object associated with the Lua interface options (see Section -% <#sec:luaoptions>) `options`. When `options` are unspecified, it is +% <#sec:lua-options>) `options`. When `options` are unspecified, it is % assumed that an empty table was passed to the method. % % The objects produced by the \luamref{writer.new} method expose instance methods @@ -23085,7 +23345,7 @@ function M.writer.new(options) {"\\markdownRendererCodeSpan{", self.escape(s), "}"}) if attributes ~= nil then table.insert(buf, - "\n\\markdownRendererCodeSpanAttributeContextEnd ") + "\\markdownRendererCodeSpanAttributeContextEnd{}") end return buf end @@ -23113,7 +23373,7 @@ function M.writer.new(options) "{",self.string(tit or ""),"}"}) if attributes ~= nil then table.insert(buf, - "\n\\markdownRendererLinkAttributeContextEnd ") + "\\markdownRendererLinkAttributeContextEnd{}") end return buf end @@ -23141,7 +23401,7 @@ function M.writer.new(options) "{",self.string(tit or ""),"}"}) if attributes ~= nil then table.insert(buf, - "\n\\markdownRendererImageAttributeContextEnd ") + "\\markdownRendererImageAttributeContextEnd{}") end return buf end @@ -23385,30 +23645,53 @@ function M.writer.new(options) % \begin{markdown} % % Define \luamdef{writer->attributes} as a function that will transform -% input attributes `attr` to the output format. +% input attributes `attrs` to the output format. % % \end{markdown} % \begin{macrocode} - function self.attributes(attr) - local buf = {} + function self.attributes(attributes) + local expanded_attributes = {} + local key_value_regex = "([^= ]+)%s*=%s*(.*)" + local key, value + for _, attribute in ipairs(attributes) do + if attribute:sub(1, 1) == "#" or attribute:sub(1, 1) == "." then + table.insert(expanded_attributes, attribute) + else + key, value = attribute:match(key_value_regex) + if key:lower() == "id" then + table.insert(expanded_attributes, "#" .. value) + elseif key:lower() == "class" then + local classes = {} + for class in value:gmatch("%S+") do + table.insert(classes, class) + end + table.sort(classes) + for _, class in ipairs(classes) do + table.insert(expanded_attributes, "." .. class) + end + else + table.insert(expanded_attributes, attribute) + end + end + end + table.sort(expanded_attributes) - table.sort(attr) + local buf = {} local seen = {} - local key, value - for i = 1, #attr do - if seen[attr[i]] ~= nil then + for _, attribute in ipairs(expanded_attributes) do + if seen[attribute] ~= nil then goto continue -- prevent duplicate attributes else - seen[attr[i]] = true + seen[attribute] = true end - if attr[i]:sub(1, 1) == "#" then + if attribute:sub(1, 1) == "#" then table.insert(buf, {"\\markdownRendererAttributeIdentifier{", - attr[i]:sub(2), "}"}) - elseif attr[i]:sub(1, 1) == "." then + attribute:sub(2), "}"}) + elseif attribute:sub(1, 1) == "." then table.insert(buf, {"\\markdownRendererAttributeClassName{", - attr[i]:sub(2), "}"}) + attribute:sub(2), "}"}) else - key, value = attr[i]:match("([^= ]+)%s*=%s*(.*)") + key, value = attribute:match(key_value_regex) table.insert(buf, {"\\markdownRendererAttributeKeyValue{", key, "}{", value, "}"}) end @@ -23866,13 +24149,16 @@ parsers.commented_line = Cg(Cc(""), "backslashes") parsers.chunk = parsers.line * (parsers.optionallyindentedline - parsers.blankline)^0 -parsers.attribute_key_char = parsers.alphanumeric + S("_-") +parsers.attribute_key_char = parsers.alphanumeric + S("-_:.") parsers.attribute_key = (parsers.attribute_key_char - parsers.dash - parsers.digit) * parsers.attribute_key_char^0 parsers.attribute_value = ( (parsers.dquote / "") * (parsers.anyescaped - parsers.dquote)^0 * (parsers.dquote / "")) + + ( (parsers.squote / "") + * (parsers.anyescaped - parsers.squote)^0 + * (parsers.squote / "")) + ( parsers.anyescaped - parsers.dquote - parsers.rbrace - parsers.space)^0 @@ -24247,7 +24533,7 @@ end % \par % \begin{markdown} % -%### Markdown Reader {#markdownreader} +%### Markdown Reader {#markdown-reader} % % This section documents the \luamref{reader} object, which implements the % routines for parsing the markdown input. The object corresponds to the @@ -24256,7 +24542,7 @@ end % % The \luamdef{reader.new} method creates and returns a new \TeX{} reader % object associated with the Lua interface options (see Section -% <#sec:luaoptions>) `options` and with a writer object `writer`. When +% <#sec:lua-options>) `options` and with a writer object `writer`. When % `options` are unspecified, it is assumed that an empty table was passed to % the method. % @@ -25321,7 +25607,7 @@ end % \begin{markdown} % % Although the interface of the \luamref{reader->insert_pattern} method does -% document this (see Section <#sec:luauserextensions>), we allow the +% document this (see Section <#sec:lua-user-extensions>), we allow the % \luamref{reader->insert_pattern} and \luamref{reader->update_rule} % methods to insert not just \acro{peg} patterns, but also rule names that % reference the \acro{peg} grammar of Markdown. @@ -25438,7 +25724,7 @@ end % \begin{markdown} % When determining the name of the cache file, create salt for the hashing % function out of the package version and the passed options recognized by the -% Lua interface (see Section <#sec:luaoptions>). The \Opt{cacheDir} option +% Lua interface (see Section <#sec:lua-options>). The \Opt{cacheDir} option % is disregarded. % \end{markdown} % \begin{macrocode} @@ -25509,7 +25795,7 @@ end % \end{macrocode} % \begin{markdown} % -%### Built-In Syntax Extensions {#luabuiltinextensions} +%### Built-In Syntax Extensions {#lua-built-in-extensions} % % Create \luamref{extensions} hash table that contains built-in syntax % extensions. Syntax extensions are functions that produce objects with two @@ -27611,6 +27897,7 @@ M.extensions.jekyll_data = function(expect_jekyll_data) , function(s, i, text) -- luacheck: ignore s i local data local ran_ok, _ = pcall(function() + -- TODO: Replace with `require("tinyyaml")` in TeX Live 2023 local tinyyaml = require("markdown-tinyyaml") data = tinyyaml.parse(text, {timestamps=false}) end) @@ -27654,7 +27941,7 @@ end % % The \luamref{new} function returns a conversion function that takes a % markdown string and turns it into a plain \TeX{} output. See Section -% <#sec:luaconversion>. +% <#sec:lua-conversion>. % % \end{markdown} % \begin{macrocode} @@ -27883,7 +28170,7 @@ function M.new(options) % % Finally, cast the user-defined syntax extension to the internal format % of user extensions used by the Markdown package (see Section -% <#sec:luabuiltinextensions>.) +% <#sec:lua-built-in-extensions>.) % % \end{markdown} % \begin{macrocode} @@ -28004,7 +28291,7 @@ end % used to implement the macros for the conversion from markdown to plain \TeX{} % exposed by the plain \TeX{} interface (see Section <#sec:texinterface>). % -%### Logging Facilities {#texinterfacelogging} +%### Logging Facilities {#tex-interface-logging} % % \end{markdown} % \begin{macrocode} @@ -28025,7 +28312,7 @@ end % \par % \begin{markdown} % -%### Token Renderer Prototypes {#textokenrendererprototypes} +%### Token Renderer Prototypes {#tex-token-renderer-prototypes} % % The following definitions should be considered placeholder. % @@ -28205,7 +28492,7 @@ end % \par % \begin{markdown} % -%#### YAML Metadata Renderer Prototypes {#expl3yamlmetadataimplementation} +%#### YAML Metadata Renderer Prototypes {#expl3-yaml-metadata-implementation} % % To keep track of the current type of structure we inhabit when we are % traversing a \acro{yaml} document, we will maintain the @@ -28445,8 +28732,8 @@ end %### Lua Snippets % After the \mdef{markdownPrepareLuaOptions} macro has been fully expanded, % the \mdef{markdownLuaOptions} macro will expands to a Lua table that -% contains the plain \TeX{} options (see Section <#sec:texoptions>) in a -% format recognized by Lua (see Section <#sec:luaoptions>). +% contains the plain \TeX{} options (see Section <#sec:tex-options>) in a +% format recognized by Lua (see Section <#sec:lua-options>). % % \end{markdown} % \begin{macrocode} @@ -28573,8 +28860,9 @@ end % \end{markdown} % \begin{macrocode} \ExplSyntaxOn -\cs_new:Nn - \@@_if_option:nTF +\prg_new_conditional:Nnn + \@@_if_option:n + { TF, T, F } { \@@_get_option_type:nN { #1 } @@ -28584,7 +28872,7 @@ end \c_@@_option_type_boolean_tl { \msg_error:nnxx - { @@ } + { markdown } { expected-boolean-option } { #1 } { \l_tmpa_tl } @@ -28595,11 +28883,11 @@ end \str_if_eq:NNTF \l_tmpa_tl \c_@@_option_value_true_tl - { #2 } - { #3 } + { \prg_return_true: } + { \prg_return_false: } } \msg_new:nnn - { @@ } + { markdown } { expected-boolean-option } { Option~#1~has~type~#2,~ @@ -28812,14 +29100,14 @@ end % \end{macrocode} % \begin{markdown} % -%### Lua Shell Escape Bridge {#luabridge} +%### Lua Shell Escape Bridge {#lua-bridge} % % The following \TeX{} code is intended for \TeX{} engines that do not provide % direct access to Lua, but expose the shell of the operating system. This % corresponds to the \mref{markdownMode} values of `0` and `1`. % % The \mref{markdownLuaExecute} macro defined here and in Section -% <#sec:directlua> are meant to be indistinguishable to the remaining code. +% <#sec:direct-lua> are meant to be indistinguishable to the remaining code. % % The package assumes that although the user is not using the Lua\TeX{} engine, % their \TeX{} distribution contains it, and uses shell access to produce and @@ -29001,11 +29289,11 @@ end % \par % \begin{markdown} % -%### Direct Lua Access {#directlua} +%### Direct Lua Access {#direct-lua} % % The following \TeX{} code is intended for \TeX{} engines that provide % direct access to Lua (Lua\TeX{}). The macro \mref{markdownLuaExecute} defined -% here and in Section <#sec:luabridge> are meant to be indistinguishable to +% here and in Section <#sec:lua-bridge> are meant to be indistinguishable to % the remaining code. This corresponds to the \mref{markdownMode} value of `2`. % % \end{markdown} @@ -29021,7 +29309,7 @@ end % The direct Lua access version of the \mref{markdownLuaExecute} macro is defined % in terms of the `\directlua` primitive. The `print` function is set as % an alias to the `tex.print` method in order to mimic the behaviour of the -% \mref{markdownLuaExecute} definition from Section <#sec:luabridge>, +% \mref{markdownLuaExecute} definition from Section <#sec:lua-bridge>, % % \end{markdown} % \begin{macrocode} @@ -29199,7 +29487,7 @@ end % %### Logging Facilities % The \LaTeX{} implementation redefines the plain \TeX{} logging macros (see -% Section <#sec:texinterfacelogging>) to use the \LaTeX{} `\PackageInfo`, +% Section <#sec:tex-interface-logging>) to use the \LaTeX{} `\PackageInfo`, % `\PackageWarning`, and `\PackageError` macros. % % \end{markdown} @@ -29212,7 +29500,7 @@ end % The \mdef{markdownInputPlainTeX} macro is used to store the original plain % \TeX{} implementation of the \mref{markdownInput} macro. The \mref{markdownInput} % is then redefined to accept an optional argument with options recognized by -% the \LaTeX{} interface (see Section <#sec:latexoptions>). +% the \LaTeX{} interface (see Section <#sec:latex-options>). % % \end{markdown} % \begin{macrocode} @@ -29258,7 +29546,7 @@ end % \par % \begin{markdown} % -%#### \LaTeX{} Themes {#latexthemesimplementation} +%#### \LaTeX{} Themes {#latex-themes-implementation} % % This section implements the theme-loading mechanism and the example themes % provided with the Markdown package. @@ -29320,7 +29608,7 @@ end % \begin{markdown} % % We load the \pkg{ifthen} and \pkg{grffile} packages, see also -% Section <#sec:latexprerequisites>: +% Section <#sec:latex-prerequisites>: % % \end{markdown} % \begin{macrocode} @@ -29394,7 +29682,7 @@ end % \begin{markdown} % % We load the \pkg{catchfile} and \pkg{grffile} packages, see also -% Section <#sec:latexprerequisites>: +% Section <#sec:latex-prerequisites>: % % \end{markdown} % \begin{macrocode} @@ -29655,7 +29943,7 @@ end % \par % \begin{markdown} % -%### Token Renderer Prototypes {#latexdefaultrendererprototypes} +%### Token Renderer Prototypes {#latex-default-renderer-prototypes} % % The following configuration should be considered placeholder. If the `plain` % package option has been enabled (see Section <#sec:latexplain>), none of @@ -29742,8 +30030,25 @@ end { #2 } } \markdownSetup{rendererPrototypes={ - ulBeginTight = {\begin{compactitem}}, - ulEndTight = {\end{compactitem}}, +% \end{macrocode} +% \par +% \begin{markdown} +% +% Make tight bullet lists a little less compact by adding extra vertical space +% above and below them. +% +% \end{markdown} +% \begin{macrocode} + ulBeginTight = {% + \group_begin: + \pltopsep=\topsep + \plpartopsep=\partopsep + \begin{compactitem} + }, + ulEndTight = { + \end{compactitem} + \group_end: + }, fancyOlBegin = { \group_begin: \tl_set:Nn @@ -29767,8 +30072,25 @@ end \end{enumerate} \group_end: }, - olBeginTight = {\begin{compactenum}}, - olEndTight = {\end{compactenum}}, +% \end{macrocode} +% \par +% \begin{markdown} +% +% Make tight ordered lists a little less compact by adding extra vertical +% space above and below them. +% +% \end{markdown} +% \begin{macrocode} + olBeginTight = {% + \group_begin: + \plpartopsep=\partopsep + \pltopsep=\topsep + \begin{compactenum} + }, + olEndTight = { + \end{compactenum} + \group_end: + }, fancyOlBeginTight = { \group_begin: \tl_set:Nn @@ -29779,7 +30101,11 @@ end { #2 } \tl_set:Nn \l_tmpa_tl - { \begin{compactenum}[ } + { + \plpartopsep=\partopsep + \pltopsep=\topsep + \begin{compactenum}[ + } \tl_put_right:Nx \l_tmpa_tl { \@@_latex_paralist_style:nn { #1 } { #2 } } @@ -29801,8 +30127,25 @@ end { #1 } ] }, - dlBeginTight = {\begin{compactdesc}}, - dlEndTight = {\end{compactdesc}}}} +% \end{macrocode} +% \par +% \begin{markdown} +% +% Make tight definition lists a little less compact by adding extra +% vertical space above and below them. +% +% \end{markdown} +% \begin{macrocode} + dlBeginTight = { + \group_begin: + \plpartopsep=\partopsep + \pltopsep=\topsep + \begin{compactdesc} + }, + dlEndTight = { + \end{compactdesc} + \group_end: + }}} \cs_generate_variant:Nn \@@_latex_fancy_list_item_label:nnn { VVn } @@ -30595,7 +30938,7 @@ end % \par % \begin{markdown} % -%#### YAML Metadata {#latexyamlmetadata} +%#### YAML Metadata {#latex-yaml-metadata} % % The default setup of \acro{yaml} metadata will invoke the `\title`, % `\author`, and `\date` macros when scalar values for keys that @@ -30701,7 +31044,7 @@ end % \end{markdown} % \begin{macrocode} \ExplSyntaxOn -\@@_if_option:nTF +\@@_if_option:nT { linkAttributes } { \RequirePackage{graphicx} @@ -30725,7 +31068,6 @@ end }, } } - { } \ExplSyntaxOff % \end{macrocode} % \par @@ -30846,7 +31188,7 @@ end %### Typesetting Markdown % The \mref{inputmarkdown} is defined to accept an optional argument with % options recognized by the \Hologo{ConTeXt} interface (see Section -% <#sec:contextoptions>). +% <#sec:context-options>). % % \end{markdown} % \begin{macrocode} |