diff options
Diffstat (limited to 'Master/texmf-dist/source/generic')
17 files changed, 3813 insertions, 1788 deletions
diff --git a/Master/texmf-dist/source/generic/babel-french/frenchb.dtx b/Master/texmf-dist/source/generic/babel-french/frenchb.dtx index 331a0195e04..b52e5c67e76 100644 --- a/Master/texmf-dist/source/generic/babel-french/frenchb.dtx +++ b/Master/texmf-dist/source/generic/babel-french/frenchb.dtx @@ -75,7 +75,7 @@ Please report errors to: <daniel (dot) flipo (at) free (dot) fr> %<frenchb>\ProvidesLanguage{frenchb} %<lua>--[[ %<lua> File `frenchb.lua’ generated from frenchb.dtx - [2024-05-24 v3.6a French support from the babel system] + [2024-07-25 v3.6c French support from the babel system] %<lua> Copyright © 2014-2024 Daniel Flipo %<lua> <daniel (dot) flipo (at) free (dot) fr> %<lua> License LPPL: see french.ldf. @@ -854,7 +854,7 @@ Please report errors to: <daniel (dot) flipo (at) free (dot) fr> % \subsubsection*{What’s new in version 3.6?} % % Version 3.6a no longer loads the \pkg{keyval} package, replaced by -% core LaTeX commands (\pkg{ltkeys}). The thin space added before +% core LaTeX commands (\pkg{l3keys}). The thin space added before % footnote’s calls is now customisable (suggested by Thomas Savary), % the command’s name is |\FBfnmarkspace|. % @@ -1150,11 +1150,6 @@ Please report errors to: <daniel (dot) flipo (at) free (dot) fr> % \end{macrocode} % \end{macro} % -% Check LaTeX2e version (support for \pkg{ltkeys} required). -% \begin{macrocode} -\ifLaTeXe \NeedsTeXFormat{LaTeX2e}[2022/06/01] \fi -% \end{macrocode} -% %\begin{macro}{\ifFBunicode} % \begin{macro}{\ifFBLuaTeX} % \begin{macro}{\ifFBXeTeX} @@ -2779,16 +2774,22 @@ return french_punctuation % active punctuation characters (if any). % It is engine independent (works for TeX, LuaTeX and % XeTeX based engines) and is meant to be used inside a group. +% The faked definition of |\texorpdfstring| will be overwritten +% by \file{hyperref.sty}. % % \changes{v3.2b}{2016/04/18}{\cs{NoAutoSpacing} made robust.} % % \changes{v3.2c}{2016/05/14}{New definition based on % \cs{FB@spacing@off} common to all engines.} % +% \changes{v3.6b}{2024/06/26}{\cs{NoAutoSpacing} must be inhibited +% in bookmarks.} +% % \begin{macrocode} +\providecommand\texorpdfstring[2]{#1} \DeclareRobustCommand*{\NoAutoSpacing}{% - \FB@spacing@off - \ifFB@active@punct\shorthandoff{;:!?}\fi + \texorpdfstring{\FB@spacing@off + \ifFB@active@punct\shorthandoff{;:!?}\fi}{}% } % \end{macrocode} % \end{macro} @@ -2860,7 +2861,6 @@ return french_punctuation % % |\FB@og| and |\FB@fg| are now designed to work in bookmarks. % \begin{macrocode} -\providecommand\texorpdfstring[2]{#1} \newcommand*{\FB@og}{\texorpdfstring{\@FB@og}{\guillemotleft\space}} \newcommand*{\FB@fg}{\texorpdfstring{\@FB@fg}{\space\guillemotright}} % \end{macrocode} @@ -4264,7 +4264,7 @@ return french_punctuation } % \end{macrocode} % -% \subsection{Setup options: key/value stuff (ltkeys)} +% \subsection{Setup options: key/value stuff (l3keys)} % \label{ssec-keyval} % % \changes{v2.0}{2006/11/06}{New command \cs{frenchbsetup} added @@ -4274,11 +4274,15 @@ return french_punctuation % reorganised, now \cs{babel@save} and\cs{babel@savevariable} are % usable for French.} % -% \changes{v3.6a}{2024/05/16}{Internal `ltkeys’ replaces package +% \changes{v3.6a}{2024/05/16}{Internal `l3keys’ replaces package % `keyval’ for options’ management.} % +% Check LaTeX2e version (support for \pkg{l3keys} required). +% \begin{macrocode} +\NeedsTeXFormat{LaTeX2e}[2022-06-01] +% \end{macrocode} % All setup options are handled by command \fbsetup{} based on -% the \file{ltkeys}’ |\SetKeys{}| command. A list of flags is +% the \file{l3keys}’ |\SetKeys{}| command. A list of flags is % defined beforehand and set to default values which will possibly % be changed `AtEndOfPackage’ in case French is the main language. % After this, \fbsetup{} eventually modifies the preset values of @@ -4578,6 +4582,10 @@ return french_punctuation \@onlypreamble\frenchbsetup % \end{macrocode} % +% \changes{v3.6c}{2024/07/25}{Removed spurious @ in +% \cs{FBCompactItemize@setup} and \cs{FBListOldLayout@setup} +% commands’ names.} +% % The following commands, defined with property |.code| in % |DeclareKeys{}|, execute some post-treatment required to % immediately take the flags value into account. @@ -4619,14 +4627,14 @@ return french_punctuation Reported}% \fi } -\newcommand*{\FB@ListOldLayout@setup}[1]% +\newcommand*{\FBListOldLayout@setup}[1]% {\csname FBListOldLayout#1\endcsname \ifFBListOldLayout \FBStandardEnumerateEnvtrue \renewcommand*{\FrenchLabelItem}{\textendash}% \fi } -\newcommand*{\FB@CompactItemize@setup}[1]% +\newcommand*{\FBCompactItemize@setup}[1]% {\csname FBCompactItemize#1\endcsname \ifFBCompactItemize \FBStandardItemizeEnvfalse diff --git a/Master/texmf-dist/source/generic/lt3luabridge/lt3luabridge.dtx b/Master/texmf-dist/source/generic/lt3luabridge/lt3luabridge.dtx index 67cc73c7387..d8bb7a3beec 100644 --- a/Master/texmf-dist/source/generic/lt3luabridge/lt3luabridge.dtx +++ b/Master/texmf-dist/source/generic/lt3luabridge/lt3luabridge.dtx @@ -47,7 +47,7 @@ % }^^A % } % -% \date{Released 2024-02-14} +% \date{Released 2024-07-03} % % \maketitle % @@ -151,7 +151,7 @@ % \texttt{-output-directory} parameter of the \TeX{} engine. % \end{variable} % -% \begin{variable}[added = 2022-06-26]{\c_luabridge_default_output_dirname_str} +% \begin{variable}[added = 2022-06-26, updated = 2024-07-03]{\c_luabridge_default_output_dirname_str} % This constant is the default value of \cs{g_luabridge_output_dirname_str}. % \end{variable} % @@ -261,9 +261,42 @@ = { \c_luabridge_method_shell_int } { - \str_const:Nn - \c_luabridge_default_output_dirname_str - { . } +% \end{macrocode} +% +% Instead of assuming the current working directory as the output directory, +% try to determine the output directory from the environmental variable +% \texttt{TEXMF_OUTPUT_DIRECTORY}, which is automatically defined by \TeX{} +% engines and accessible from child processes. +% +% \begin{macrocode} + \sys_if_platform_unix:TF + { + \str_const:Nn + \c_luabridge_default_output_dirname_str + { $TEXMF_OUTPUT_DIRECTORY } + } + { + \sys_if_platform_windows:TF + { + \str_set:Nn + \l_tmpa_str + { TEXMF_OUTPUT_DIRECTORY } + \str_put_left:NV + \l_tmpa_str + \c_percent_str + \str_put_right:NV + \l_tmpa_str + \c_percent_str + \str_const:NV + \c_luabridge_default_output_dirname_str + \l_tmpa_str + } + { + \str_const:Nn + \c_luabridge_default_output_dirname_str + { . } + } + } \str_const:Nx \c_luabridge_default_helper_script_filename_str { \jobname.luabridge.lua } @@ -358,9 +391,43 @@ \g_luabridge_helper_script_filename_str \sys_get_shell:xnNTF { - texlua~ - \g_luabridge_output_dirname_str / - \g_luabridge_helper_script_filename_str +% \end{macrocode} +% +% If the environmental variable \texttt{TEXMF_OUTPUT_DIRECTORY} is undefined, +% use the current working directory (\texttt{.}) instead. +% +% \begin{macrocode} + \str_if_eq:NNTF + \g_luabridge_output_dirname_str + \c_luabridge_default_output_dirname_str + { + \sys_if_platform_windows:TF + { + if~not~defined~TEXMF_OUTPUT_DIRECTORY~( + texlua~ + \g_luabridge_helper_script_filename_str + )~else~( + texlua~ + \g_luabridge_output_dirname_str / + \g_luabridge_helper_script_filename_str + ) + } + { + \sys_if_platform_unix:T + { + TEXMF_OUTPUT_DIRECTORY = + ${TEXMF_OUTPUT_DIRECTORY:-.} \iow_newline: + } + texlua~ + \g_luabridge_output_dirname_str / + \g_luabridge_helper_script_filename_str + } + } + { + texlua~ + \g_luabridge_output_dirname_str / + \g_luabridge_helper_script_filename_str + } } { } #1 @@ -492,8 +559,8 @@ \RequirePackage{expl3} \ProvidesExplPackage {lt3luabridge}% - {2024-02-14}% - {2.1.0}% + {2024-07-03}% + {2.2.0}% {An expl3 package that allows you to execute Lua code in LuaTeX or any other TeX engine that exposes the shell} \input lt3luabridge\relax diff --git a/Master/texmf-dist/source/generic/markdown/docstrip.cfg b/Master/texmf-dist/source/generic/markdown/docstrip.cfg index 9dc5f652309..44429e7b974 100644 --- a/Master/texmf-dist/source/generic/markdown/docstrip.cfg +++ b/Master/texmf-dist/source/generic/markdown/docstrip.cfg @@ -11,18 +11,18 @@ -- permit persons to whom the Software is furnished to do so, subject to^^J% -- the following conditions:^^J% --^^J% --- The above copyright notice and this permission notice shall be included^^J% --- in all copies or substantial portions of the Software.^^J% +-- The above copyright notice and this permission notice shall be^^J% +-- included in all copies or substantial portions of the Software.^^J% --^^J% -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,^^J% -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF^^J% --- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.^^J% +-- MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND NONINFRINGEMENT.^^J% -- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY^^J% -- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,^^J% -- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE^^J% -- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.^^J% --^^J% --- Copyright (C) 2016-2024 Vít Starý Novotný^^J% +-- Copyright (C) 2016-2024 Vít Starý Novotný, Andrej Genčur^^J% --^^J% -- This work may be distributed and/or modified under the^^J% -- conditions of the LaTeX Project Public License, either version 1.3^^J% @@ -62,7 +62,7 @@ \let\luapostamble\empty \declarepreamble\texpreamble -Copyright (C) 2016-2024 Vít Starý Novotný +Copyright (C) 2016-2024 Vít Starý Novotný, Andrej Genčur This work may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c diff --git a/Master/texmf-dist/source/generic/markdown/markdown.dtx b/Master/texmf-dist/source/generic/markdown/markdown.dtx index 6ad42a46b26..2ad94e6e9c9 100644 --- a/Master/texmf-dist/source/generic/markdown/markdown.dtx +++ b/Master/texmf-dist/source/generic/markdown/markdown.dtx @@ -122,7 +122,7 @@ --- title: A Markdown Interpreter for \TeX url: https://github.com/witiko/markdown -authors: [Vít Starý Novotný] +authors: [Vít Starý Novotný, Andrej Genčur] email: witiko@mail.muni.cz revision: \markdownVersion date: \markdownLastModified @@ -796,6 +796,7 @@ abbr { %<*themes-witiko-markdown-techdoc> \ProvidesPackage{markdownthemewitiko_markdown_techdoc}[2022/12/13] \RequirePackage{etoolbox} +\gdef\ltd@title@author{\@gobble}% \markdownSetup{ renderers = { head*Four = {\paragraph{#1}\leavevmode}, @@ -804,6 +805,7 @@ abbr { codeSpan = {\inline{#1}}, jekyllData(End) = {% \AfterEndPreamble{% + \hypersetup{pdfauthor=\ltd@title@author}% \printtitlepage \tableofcontents {\def\addcontentsline##1##2##3{}\listoffigures}% @@ -812,8 +814,9 @@ abbr { }, jekyllDataRenderers = { /authors/* = {% - \gdef\ltd@title@author{#1}% - \hypersetup{pdfauthor={#1}}% + \expandafter\gdef + \expandafter\ltd@title@author + \expandafter{\ltd@title@author, #1}% }, title = {% \gdef\ltd@title@title{#1}% @@ -875,7 +878,7 @@ abbr { --- title: Markdown Package User Manual -author: Vít Starý Novotný +author: Vít Starý Novotný, Andrej Genčur date: \markdownVersion{} \markdownLastModified{} --- @@ -890,7 +893,7 @@ Introduction The [Markdown package][pkg] converts [CommonMark][] markup to \TeX{} commands. The functionality is provided both as a Lua module and as plain \TeX{}, \LaTeX{}, and \Hologo{ConTeXt} macro packages that can be used to directly typeset \TeX{} documents -containing markdown markup. Unlike other convertors, the Markdown package +containing markdown markup. Unlike other converters, the Markdown package does not require any external programs, and makes it easy to redefine how each and every markdown element is rendered. Creative abuse of the markdown syntax is encouraged. 😉 @@ -922,21 +925,23 @@ documentation][techdoc]. (A Markdown Interpreter for TeX) %</manual> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} local metadata = { version = "(((VERSION)))", - comment = "A module for the conversion from markdown to plain TeX", - author = "John MacFarlane, Hans Hagen, Vít Starý Novotný", + comment = "A module for the conversion from markdown " + .. "to plain TeX", + author = "John MacFarlane, Hans Hagen, Vít Starý Novotný, " + .. "Andrej Genčur", copyright = {"2009-2016 John MacFarlane, Hans Hagen", - "2016-2023 Vít Starý Novotný"}, + "2016-2024 Vít Starý Novotný, Andrej Genčur"}, license = "LPPL 1.3c" } % \end{macrocode} % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*lua> % \fi % \begin{macrocode} @@ -965,22 +970,30 @@ requirements. Installation ------------ -If Markdown is not included in your \TeX{} distribution, you will need to -install it. +If the Markdown package is not included in your \TeX{} distribution, you will +need to install it. -First, download the package from the repository using Git: +From [Releases][], download [an archive `markdown.zip` for this version of the +Markdown package (\markdownShortVersion{})][this-release] or a different version +that you wish to install. Then, unzip the archive. If you downloaded an archive +for a different version of the Markdown package, you should now locate a file +named `markdown.html` with the user manual for that version, open it, and +follow the installation steps in it rather than the steps from this manual. + + [releases]: https://github.com/witiko/markdown/releases (Releases - witiko/markdown) + [this-release]: https://github.com/witiko/markdown/releases/download/\markdownShortVersion{}/markdown.zip (Release \markdownShortVersion{} - witiko/markdown) + +Alternatively, download the package from the repository using Git, enter the +directory named `markdown` and run the `make base` command using GNU Make: ``` sh git clone https://github.com/witiko/markdown -`````` -Next, enter the directory named `markdown` and run the `make base` command using -GNU Make: -``` sh cd markdown make base `````` -This should produce the following files: -* `markdown.lua`: The Lua module +Either of the two abovelisted approaches should produce the following files: + +* `markdown.lua` and `markdown-parser.lua`: The Lua module * `libraries/markdown-tinyyaml.lua`: An external library for reading \acro{yaml} * `markdown-cli.lua`: The Lua command-line interface * `markdown.tex`: The plain \TeX{} macro package @@ -1001,6 +1014,7 @@ directory structure. This is generally where the individual files should be placed: * `⟨TEXMF⟩/tex/luatex/markdown/markdown.lua` +* `⟨TEXMF⟩/tex/luatex/markdown/markdown-parser.lua` * `⟨TEXMF⟩/tex/luatex/markdown/markdown-tinyyaml.lua` * `⟨TEXMF⟩/scripts/markdown/markdown-cli.lua` * `⟨TEXMF⟩/tex/generic/markdown/markdown.tex` @@ -1027,6 +1041,7 @@ portably typeset on legacy \TeX{} distributions. This is where the individual files should be placed: * `./markdown.lua` +* `./markdown-parser.lua` * `./markdown-tinyyaml.lua` * `./markdown-cli.lua` * `./markdown/markdown.tex` @@ -1039,6 +1054,8 @@ This is where the individual files should be placed: * `./markdownthemewitiko_markdown_defaults.sty` * `./t-markdownthemewitiko_markdown_defaults.tex` +The file `markdown.tex` *must* be placed in a directory named `markdown`. + %</manual> %<*lua> % \fi @@ -1093,9 +1110,17 @@ local unicode = require("unicode") % Live${}\geq{}2008$). % % \end{markdown} +% \iffalse +%</lua> +%<*lua,lua-loader> +% \fi % \begin{macrocode} local md5 = require("md5"); % \end{macrocode} +% \iffalse +%</lua,lua-loader> +%<*lua> +% \fi % \begin{markdown} % % \pkg{Kpathsea} @@ -1138,6 +1163,17 @@ end)() %: A package that implements Unicode case-folding in \TeX{} Live${}\geq{}2020$. % % \end{markdown} +% \iffalse +%</lua> +%<*depends> +% \fi +% \begin{macrocode} +hard lua-uni-algos +% \end{macrocode} +% \iffalse +%</depends> +%<*lua> +% \fi % \begin{macrocode} local uni_algos = require("lua-uni-algos") % \end{macrocode} @@ -1156,6 +1192,13 @@ local uni_algos = require("lua-uni-algos") % \end{markdown} % \iffalse %</lua> +%<*depends> +% \fi +% \begin{macrocode} +# hard lua-tinyyaml # TODO: Uncomment after TeX Live 2022 deprecation. +% \end{macrocode} +% \iffalse +%</depends> %<*tex> % \fi % \par @@ -1175,18 +1218,33 @@ local uni_algos = require("lua-uni-algos") % such as options, renderers, and renderer prototypes. % % \end{markdown} -% \begin{macrocode} +% \iffalse %</tex> +%<*depends> +% \fi +% \begin{macrocode} +hard l3kernel +% \end{macrocode} +% \iffalse +%</depends> %<*context> +% \fi +% \begin{macrocode} \unprotect +% \end{macrocode} +% \iffalse %</context> %<*context,tex> +% \fi +% \begin{macrocode} \ifx\ExplSyntaxOn\undefined \input expl3-generic \fi +% \end{macrocode} +% \iffalse %</context,tex> %<*tex> -% \end{macrocode} +% \fi % \begin{markdown} % % \pkg{lt3luabridge} @@ -1195,6 +1253,20 @@ local uni_algos = require("lua-uni-algos") % with other TeX engines that provide the *shell escape* capability, % which allows them to execute code with the system's shell. % +% \end{markdown} +% \iffalse +%</tex> +%<*depends> +% \fi +% \begin{macrocode} +hard lt3luabridge +% \end{macrocode} +% \iffalse +%</depends> +%<*tex> +% \fi +% \begin{markdown} +% % The plain \TeX{} part of the package also requires the following Lua module: % % \pkg{Lua File System} @@ -1239,10 +1311,13 @@ local uni_algos = require("lua-uni-algos") %<*themes-witiko-dot,latex-themes-witiko-graphicx-http> % \fi % \begin{macrocode} -\NeedsTeXFormat{LaTeX2e}% +\NeedsTeXFormat{LaTeX2e} +\RequirePackage{expl3} % \end{macrocode} % \iffalse %</themes-witiko-dot,latex-themes-witiko-graphicx-http> +%</latex> +%<*depends> % \fi % \begin{markdown} % a \TeX{} engine that extends \Hologo{eTeX}, and all the plain \TeX{} @@ -1259,10 +1334,23 @@ local uni_algos = require("lua-uni-algos") % %: A package that provides the `\url` macro for the typesetting of links. % +% \end{markdown} +% \begin{macrocode} +soft url +% \end{macrocode} +% \begin{markdown} +% % \pkg{graphicx} % %: A package that provides the `\includegraphics` macro for the typesetting -% of images. +% of images.Furthermore, it also provides a key-value interface that is +% used in the default renderer prototypes for image attribute contexts. +% +% \end{markdown} +% \begin{macrocode} +soft graphics +% \end{macrocode} +% \begin{markdown} % % \pkg{paralist} % @@ -1271,45 +1359,85 @@ local uni_algos = require("lua-uni-algos") % ordered lists, and definition lists as well as the rendering of % fancy lists. % +% \end{markdown} +% \begin{macrocode} +soft paralist +% \end{macrocode} +% \begin{markdown} +% % \pkg{ifthen} % %: A package that provides a concise syntax for the inspection of macro % values. It is used in the `witiko/dot` \LaTeX{} theme (see Section % <#sec:latexthemes>). % +% \end{markdown} +% \begin{macrocode} +soft latex +soft epstopdf-pkg # required by `latex` +% \end{macrocode} +% \begin{markdown} +% % \pkg{fancyvrb} % %: A package that provides the `\VerbatimInput` macros for the verbatim % inclusion of files containing code. % +% \end{markdown} +% \begin{macrocode} +soft fancyvrb +% \end{macrocode} +% \begin{markdown} +% % \pkg{csvsimple} % %: A package that provides the `\csvautotabular` macro for typesetting % \acro{csv} files in the default renderer prototypes for iA\\,Writer % content blocks. % +% \end{markdown} +% \begin{macrocode} +soft csvsimple +soft pgf # required by `csvsimple`, which loads `pgfkeys.sty` +soft tools # required by `csvsimple`, which loads `shellesc.sty` +% \end{macrocode} +% \begin{markdown} +% % \pkg{gobble} % %: A package that provides the `\@gobblethree` \TeX{} command that % is used in the default renderer prototype for citations. The package % is included in \TeX Live${}\geq{}2016$. % +% \end{markdown} +% \begin{macrocode} +soft gobble +% \end{macrocode} +% \begin{markdown} +% % \pkg{amsmath} and \pkg{amssymb} % %: Packages that provide symbols used for drawing ticked and unticked % boxes. % +% \end{markdown} +% \begin{macrocode} +soft amsmath +soft amsfonts +% \end{macrocode} +% \begin{markdown} +% % \pkg{catchfile} % %: A package that catches the contents of a file and puts it in a macro. It % is used in the `witiko/graphicx/http` \LaTeX{} theme, see Section % <#sec:latexthemes>. % -% \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. +% \end{markdown} +% \begin{macrocode} +soft catchfile +% \end{macrocode} +% \begin{markdown} % % \pkg{grffile} % @@ -1320,6 +1448,12 @@ local uni_algos = require("lua-uni-algos") % the `witiko/dot` and `witiko/graphicx/http` \LaTeX{} themes, see Section % <#sec:latexthemes>. % +% \end{markdown} +% \begin{macrocode} +soft grffile +% \end{macrocode} +% \begin{markdown} +% % \pkg{etoolbox} % %: A package that is used to polyfill the general hook management system in @@ -1327,10 +1461,23 @@ local uni_algos = require("lua-uni-algos") % <#sec:latex-yaml-metadata>, and also in the default renderer prototype % for identifier attributes. % +% \end{markdown} +% \begin{macrocode} +soft etoolbox +% \end{macrocode} +% \begin{markdown} +% % \pkg{soulutf8} % %: A package that is used in the default renderer prototype for % strike-throughs and marked text. +% <!-- TODO: 1,$s/soulutf8/soul/g in TeX Live 2023. --> +% +% \end{markdown} +% \begin{macrocode} +soft soul +% \end{macrocode} +% \begin{markdown} % % \pkg{ltxcmds} % @@ -1338,6 +1485,12 @@ local uni_algos = require("lua-uni-algos") % \pkg{listings} packages are loaded in the default renderer prototype % for fenced code blocks. % +% \end{markdown} +% \begin{macrocode} +soft ltxcmds +% \end{macrocode} +% \begin{markdown} +% % \pkg{verse} % %: A package that is used in the default renderer prototypes for @@ -1345,10 +1498,13 @@ local uni_algos = require("lua-uni-algos") % % \end{markdown} % \begin{macrocode} -\RequirePackage{expl3} +soft verse % \end{macrocode} +% \begin{markdown} +% +% \end{markdown} % \iffalse -%</latex> +%</depends> %<*context> % \fi % \par @@ -1691,9 +1847,6 @@ In this section, I will describe the individual parts of the Markdown package. Each part will be shown by example, leaving the implementation details to the [technical documentation][techdoc]. - [techdoc]: https://mirrors.ctan.org/macros/generic/markdown/markdown.pdf - (A Markdown Interpreter for \TeX{}) - /markdown-interfaces.md /markdown-options.md /markdown-tokens.md @@ -1732,7 +1885,7 @@ module and a command-line interface (CLI). (Lua library for conversion between markup formats) %</manual-interfaces> -%<*lua> +%<*lua,lua-loader> % \fi % \begin{markdown} % @@ -1747,6 +1900,10 @@ module and a command-line interface (CLI). % \begin{macrocode} local M = {metadata = metadata} % \end{macrocode} +% \iffalse +% \fi +%</lua,lua-loader> +%<*lua> % \par % \begin{markdown} % @@ -2023,7 +2180,7 @@ In this section, I will describe all the options recognized by the Markdown package. %</manual-options> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} local defaultOptions = {} @@ -2032,7 +2189,7 @@ local defaultOptions = {} % \markdownSetup{snippet=lua-options} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> ### Lua @@ -2066,7 +2223,9 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. \prop_new:N \g_@@_default_lua_options_prop \seq_new:N \g_@@_option_layers_seq \tl_const:Nn \c_@@_option_layer_lua_tl { lua } -\seq_gput_right:NV \g_@@_option_layers_seq \c_@@_option_layer_lua_tl +\seq_gput_right:NV + \g_@@_option_layers_seq + \c_@@_option_layer_lua_tl \cs_new:Nn \@@_add_lua_option:nnn { @@ -2143,21 +2302,50 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. \cs_generate_variant:Nn \msg_error:nnnn { nnnV } -\seq_new:N \g_@@_option_types_seq -\tl_const:Nn \c_@@_option_type_clist_tl { clist } -\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_clist_tl -\tl_const:Nn \c_@@_option_type_counter_tl { counter } -\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_counter_tl -\tl_const:Nn \c_@@_option_type_boolean_tl { boolean } -\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_boolean_tl -\tl_const:Nn \c_@@_option_type_number_tl { number } -\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_number_tl -\tl_const:Nn \c_@@_option_type_path_tl { path } -\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_path_tl -\tl_const:Nn \c_@@_option_type_slice_tl { slice } -\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_slice_tl -\tl_const:Nn \c_@@_option_type_string_tl { string } -\seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_string_tl +\seq_new:N + \g_@@_option_types_seq +\tl_const:Nn + \c_@@_option_type_clist_tl + { clist } +\seq_gput_right:NV + \g_@@_option_types_seq + \c_@@_option_type_clist_tl +\tl_const:Nn + \c_@@_option_type_counter_tl + { counter } +\seq_gput_right:NV + \g_@@_option_types_seq + \c_@@_option_type_counter_tl +\tl_const:Nn + \c_@@_option_type_boolean_tl + { boolean } +\seq_gput_right:NV + \g_@@_option_types_seq + \c_@@_option_type_boolean_tl +\tl_const:Nn + \c_@@_option_type_number_tl + { number } +\seq_gput_right:NV + \g_@@_option_types_seq + \c_@@_option_type_number_tl +\tl_const:Nn + \c_@@_option_type_path_tl + { path } +\seq_gput_right:NV + \g_@@_option_types_seq + \c_@@_option_type_path_tl +\tl_const:Nn + \c_@@_option_type_slice_tl + { slice } +\seq_gput_right:NV + \g_@@_option_types_seq + \c_@@_option_type_slice_tl +\tl_const:Nn + \c_@@_option_type_string_tl + { string } +\seq_gput_right:NV + \g_@@_option_types_seq + \c_@@_option_type_string_tl \cs_new:Nn \@@_get_option_type:nN { @@ -2379,20 +2567,23 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. #### Option `eagerCache` -`eagerCache` (default value: `false`) +`eagerCache` (default value: `true`) % \fi % \begin{markdown} % -% \Optitem[false]{eagerCache}{\opt{true}, \opt{false}} +% \Optitem[true]{eagerCache}{\opt{true}, \opt{false}} % : true : Converted markdown documents will be cached in \Opt{cacheDir}. This can be useful for post-processing the converted documents and for recovering - historical versions of the documents from the cache. However, it also - produces a large number of auxiliary files on the disk and obscures the - output of the Lua command-line interface when it is used for plumbing. + historical versions of the documents from the cache. Furthermore, it can + also significantly improve the processing speed for documents that require + multiple compilation runs, since each markdown document is only converted once. + However, it also produces a large number of auxiliary files on the disk + and obscures the output of the Lua command-line interface when it is + used for plumbing. This behavior will always be used if the \Opt{finalizeCache} option is enabled. @@ -2401,7 +2592,11 @@ interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. : Converted markdown documents will not be cached. This decreases the number of auxiliary files that we produce and makes it easier to use the Lua - command-line interface for plumbing. + command-line interface for plumbing. However, it makes it impossible to + post-process the converted documents and recover historical versions of + the documents from the cache. Furthermore, it can significantly reduce + the processing speed for documents that require multiple compilation + runs, since each markdown document is converted multiple times needlessly. This behavior will only be used when the \Opt{finalizeCache} option is disabled. @@ -2463,18 +2658,18 @@ Hello \markdownRendererEmphasis{world}!\relax \@@_add_lua_option:nnn { eagerCache } { boolean } - { false } + { true } % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} -defaultOptions.eagerCache = false +defaultOptions.eagerCache = true % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `singletonCache` @@ -2502,11 +2697,11 @@ defaultOptions.eagerCache = false : Every call to the function \luamref{new}`(options)` will produce a new conversion function that will not be cached. This is slower than caching conversion functions and may expose bugs related to memory - leaks in the creation of conversion functions, see also issue [#226][1]. + leaks in the creation of conversion functions, see also [#226 (comment)][226-comment]. This was the default behavior until version 3.0.0 of the Markdown package. - [1]: https://github.com/witiko/markdown/pull/226#issuecomment-1599641634 + [226-comment]: https://github.com/witiko/markdown/pull/226#issuecomment-1599641634 % \end{markdown} % \iffalse @@ -2555,13 +2750,13 @@ conversion function. % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.singletonCache = true % \end{macrocode} % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*lua> % \fi % \begin{macrocode} @@ -2610,14 +2805,14 @@ local singletonCache = { % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.unicodeNormalization = true % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `unicodeNormalizationForm` @@ -2666,14 +2861,14 @@ defaultOptions.unicodeNormalization = true % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.unicodeNormalizationForm = "nfc" % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> % \fi % \begin{markdown} @@ -2842,14 +3037,14 @@ option. % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.cacheDir = "." % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `contentBlocksLanguageMap` @@ -3006,14 +3201,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.contentBlocksLanguageMap = "markdown-languages.json" % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `debugExtensionsFileName` @@ -3055,14 +3250,14 @@ defaultOptions.contentBlocksLanguageMap = "markdown-languages.json" % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.debugExtensionsFileName = "debug-extensions.json" % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `frozenCacheFileName` @@ -3297,14 +3492,14 @@ the markdown document from “Hello *world*!” to “Hi *world*!” was not ref % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.frozenCacheFileName = "frozenCache.tex" % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> % \fi % \begin{markdown} @@ -3354,14 +3549,14 @@ See also the option \Opt{gfmAutoIdentifiers}. % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.autoIdentifiers = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `blankBeforeBlockquote` @@ -3578,14 +3773,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeBlockquote = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `blankBeforeCodeFence` @@ -3835,14 +4030,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeCodeFence = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `blankBeforeDivFence` @@ -3918,14 +4113,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeDivFence = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `blankBeforeHeading` @@ -4158,14 +4353,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeHeading = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `blankBeforeList` @@ -4384,14 +4579,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeList = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `bracketedSpans` @@ -4480,14 +4675,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.bracketedSpans = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `breakableBlockquotes` @@ -4714,14 +4909,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.breakableBlockquotes = true % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `citationNbsps` @@ -4808,14 +5003,14 @@ following text, where the middot (`·`) denotes a non-breaking space: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.citationNbsps = true % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `citations` @@ -4911,14 +5106,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.citations = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `codeSpans` @@ -5137,14 +5332,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.codeSpans = true % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `contentBlocks` @@ -5311,14 +5506,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.contentBlocks = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `contentLevel` @@ -5448,14 +5643,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.contentLevel = "block" % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `debugExtensions` @@ -5603,14 +5798,14 @@ inserted to the grammar of markdown. % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.debugExtensions = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `definitionLists` @@ -5742,14 +5937,60 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.definitionLists = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> +%<*manual-options> + +#### Option `ensureJekyllData` + +`ensureJekyllData` (default value: `false`) + +% \fi +% \begin{markdown} +% +% \Optitem[false]{ensureJekyllData}{\opt{true}, \opt{false}} +% +: false + + : When the \Opt{jekyllData} and \Opt{expectJekyllData} options are + enabled, then a markdown document may begin directly with \acro{yaml} + metadata and may contain nothing but \acro{yaml} metadata. Otherwise, + the markdown document is processed as markdown text. + +: true + + : When the \Opt{jekyllData} and \Opt{expectJekyllData} options are + enabled, then a markdown document must begin directly with \acro{yaml} + metadata and must contain nothing but \acro{yaml} metadata. Otherwise, + an error is produced. + +% \end{markdown} +% \iffalse +%</manual-options> +%<*tex> +% \fi +% \begin{macrocode} +\@@_add_lua_option:nnn + { ensureJekyllData } + { boolean } + { false } +% \end{macrocode} +% \iffalse +%</tex> +%<*lua,lua-cli,lua-loader> +% \fi +% \begin{macrocode} +defaultOptions.ensureJekyllData = false +% \end{macrocode} +% \par +% \iffalse +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `expectJekyllData` @@ -5866,14 +6107,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.expectJekyllData = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `extensions` @@ -6017,14 +6258,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.extensions = {} % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `fancyLists` @@ -6119,14 +6360,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.fancyLists = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `fencedCode` @@ -6286,14 +6527,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.fencedCode = true % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `fencedCodeAttributes` @@ -6386,14 +6627,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.fencedCodeAttributes = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `fencedDivs` {#fenced-divs} @@ -6465,14 +6706,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.fencedDivs = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `finalizeCache` @@ -6629,14 +6870,14 @@ the markdown document from “Hello *world*!” to “Hi *world*!” was not ref % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.finalizeCache = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `frozenCacheCounter` @@ -6698,14 +6939,14 @@ requested using the `frozenCacheCounter` option. % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.frozenCacheCounter = 0 % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `gfmAutoIdentifiers` @@ -6747,14 +6988,14 @@ See also the option \Opt{autoIdentifiers}. % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.gfmAutoIdentifiers = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `hashEnumerators` @@ -6878,14 +7119,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.hashEnumerators = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `headerAttributes` {#header-attributes} @@ -6927,14 +7168,14 @@ defaultOptions.hashEnumerators = false % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.headerAttributes = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `html` @@ -7199,14 +7440,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.html = true % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `hybrid` @@ -7229,7 +7470,7 @@ defaultOptions.html = true : false : Enable the escaping of special plain \TeX{} characters outside verbatim - environments, so that they are not interpretted by \TeX{}. This is + environments, so that they are not interpreted by \TeX{}. This is encouraged when typesetting automatically generated content or markdown documents that were not prepared with this package in mind. @@ -7425,14 +7666,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.hybrid = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `inlineCodeAttributes` @@ -7521,14 +7762,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.inlineCodeAttributes = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `inlineNotes` @@ -7622,14 +7863,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.inlineNotes = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `jekyllData` @@ -7789,14 +8030,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.jekyllData = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `linkAttributes` @@ -7886,14 +8127,14 @@ image (from [Martin Scharrer's mwe package][mwe]) displayed at size 5cm × 4cm. % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.linkAttributes = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `lineBlocks` @@ -8021,14 +8262,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.lineBlocks = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `mark` @@ -8092,14 +8333,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.mark = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `notes` @@ -8182,10 +8423,6 @@ following text: > Here is a note reference,[^1] and another.[^longnote] > -> [^1]: Here is the note. -> -> [^longnote]: Here's one with multiple blocks. -> > Subsequent paragraphs are indented to show that they > belong to the previous note. > @@ -8236,10 +8473,6 @@ following text: > Here is a note reference,[^1] and another.[^longnote] > -> [^1]: Here is the note. -> -> [^longnote]: Here's one with multiple blocks. -> > Subsequent paragraphs are indented to show that they > belong to the previous note. > @@ -8263,14 +8496,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.notes = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `pipeTables` {#pipe-tables} @@ -8372,14 +8605,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.pipeTables = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `preserveTabs` @@ -8412,14 +8645,14 @@ defaultOptions.pipeTables = false % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.preserveTabs = true % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `rawAttribute` @@ -8507,14 +8740,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.rawAttribute = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `relativeReferences` @@ -8528,7 +8761,7 @@ defaultOptions.rawAttribute = false % : true - : Enable [relative references][1] in autolinks: + : Enable [relative references][rfc3986] in autolinks: ``` md I conclude in Section <#conclusion>. @@ -8544,7 +8777,7 @@ defaultOptions.rawAttribute = false : Disable relative references in autolinks. - [1]: https://datatracker.ietf.org/doc/html/rfc3986#section-4.2 + [rfc3986]: https://datatracker.ietf.org/doc/html/rfc3986#section-4.2 % \end{markdown} % \iffalse @@ -8596,14 +8829,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.relativeReferences = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `shiftHeadings` @@ -8736,14 +8969,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.shiftHeadings = 0 % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `slice` @@ -8954,14 +9187,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.slice = "^ $" % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `smartEllipses` @@ -9169,14 +9402,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.smartEllipses = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `startNumber` @@ -9305,14 +9538,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.startNumber = true % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `strikeThrough` @@ -9427,14 +9660,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.strikeThrough = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `stripIndent` @@ -9540,14 +9773,14 @@ text “Hello *world*!” % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.stripIndent = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `subscripts` @@ -9632,14 +9865,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.subscripts = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `superscripts` @@ -9724,14 +9957,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.superscripts = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `tableAttributes` @@ -9849,14 +10082,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.tableAttributes = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `tableCaptions` {#table-captions} @@ -9979,14 +10212,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.tableCaptions = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `taskLists` @@ -10092,14 +10325,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.taskLists = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `texComments` @@ -10208,14 +10441,14 @@ text “Hello *world*!” % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.texComments = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `texMathDollars` @@ -10419,14 +10652,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.texMathDollars = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `texMathDoubleBackslash` @@ -10486,9 +10719,9 @@ luatex document.tex A PDF document named `document.pdf` should be produced and contain the following text: -> \\(E=mc^2\\) +> \(E=mc^2\) > -> \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\] +> \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### Lua CLI Example {.unnumbered} @@ -10528,13 +10761,13 @@ 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\\] +> +> \(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} @@ -10559,9 +10792,9 @@ luatex document.tex A PDF document named `document.pdf` should be produced and contain the following text: -> \\(E=mc^2\\) +> \(E=mc^2\) > -> \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\] +> \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### \LaTeX{} Example {.unnumbered} @@ -10587,9 +10820,9 @@ lualatex document.tex A PDF document named `document.pdf` should be produced and contain the following text: -> \\(E=mc^2\\) +> \(E=mc^2\) > -> \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\] +> \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### \Hologo{ConTeXt} Example {.unnumbered} @@ -10615,9 +10848,9 @@ context --luatex document.tex A PDF document named `document.pdf` should be produced and contain the following text: -> \\(E=mc^2\\) +> \(E=mc^2\) > -> \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\] +> \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] %</manual-options> %<*tex> @@ -10630,14 +10863,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.texMathDoubleBackslash = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `texMathSingleBackslash` @@ -10841,14 +11074,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.texMathSingleBackslash = false % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `tightLists` @@ -10962,14 +11195,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.tightLists = true % \end{macrocode} % \par % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*manual-options> #### Option `underscores` @@ -11105,14 +11338,14 @@ following text: % \end{macrocode} % \iffalse %</tex> -%<*lua,lua-cli> +%<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.underscores = true % \end{macrocode} % \endgroup % \iffalse -%</lua,lua-cli> +%</lua,lua-cli,lua-loader> %<*lua-cli> % \fi % \par @@ -11198,7 +11431,8 @@ Copyright (C) ]] .. table.concat(metadata.copyright, License: ]] .. metadata.license local function warn(s) - io.stderr:write("Warning: " .. s .. "\n") end + io.stderr:write("Warning: " .. s .. "\n") +end local function error(s) io.stderr:write("Error: " .. s .. "\n") @@ -11289,8 +11523,8 @@ for i = 1, #arg do if default_type == "nil" then warn('Option "' .. key .. '" not recognized.') else - warn('Option "' .. key .. '" type not recognized, please file ' .. - 'a report to the package maintainer.') + warn('Option "' .. key .. '" type not recognized, ' .. + 'please file a report to the package maintainer.') end warn('Parsing the ' .. 'value "' .. value ..'" of option "' .. key .. '" as a string.') @@ -11322,7 +11556,7 @@ for i = 1, #arg do end % \end{macrocode} % \begin{markdown} -% The first argument that matches none of the above patters is assumed to be +% The first argument that matches none of the above patterns is assumed to be % the input filename. The input filename should correspond to the Markdown % document that is going to be converted to a \TeX{} document. % \end{markdown} @@ -11331,7 +11565,7 @@ for i = 1, #arg do input_filename = arg[i] % \end{macrocode} % \begin{markdown} -% The first argument that matches none of the above patters is assumed to be +% The first argument that matches none of the above patterns is assumed to be % the output filename. The output filename should correspond to the \TeX{} % document that will result from the conversion. % \end{markdown} @@ -11625,7 +11859,9 @@ pdftex --shell-escape document.tex % \begin{macrocode} \prop_new:N \g_@@_plain_tex_option_types_prop \prop_new:N \g_@@_default_plain_tex_options_prop -\seq_gput_right:NV \g_@@_option_layers_seq \c_@@_option_layer_plain_tex_tl +\seq_gput_right:NV + \g_@@_option_layers_seq + \c_@@_option_layer_plain_tex_tl \cs_new:Nn \@@_add_plain_tex_option:nnn { @@ -11856,47 +12092,10 @@ For more information, see the examples for the \Opt{finalizeCache} option. % % \end{markdown} % \begin{macrocode} -\cs_generate_variant:Nn - \@@_add_plain_tex_option:nnn - { nnV } -% \end{macrocode} -% \begin{markdown} -% -% Use the \pkg{lt3luabridge} library to determine the default value of the -% \mref{markdownOptionOutputDir} macro by using the environmental variable -% `TEXMF_OUTPUT_DIRECTORY` that is available since TeX~Live 2024. -% -% \end{markdown} -% \begin{macrocode} -\ExplSyntaxOff -\input lt3luabridge.tex -\ExplSyntaxOn -\bool_if:nTF - { - \cs_if_exist_p:N - \luabridge_tl_set:Nn && - ( - \int_compare_p:nNn - { \g_luabridge_method_int } - = - { \c_luabridge_method_directlua_int } || - \sys_if_shell_unrestricted_p: - ) - } - { - \luabridge_tl_set:Nn - \l_tmpa_tl - { print(os.getenv("TEXMF_OUTPUT_DIRECTORY") or ".") } - } - { - \tl_set:Nn - \l_tmpa_tl - { . } - } -\@@_add_plain_tex_option:nnV +\@@_add_plain_tex_option:nnn { outputDir } { path } - \l_tmpa_tl + { . } % \end{macrocode} % \iffalse %</tex> @@ -12172,22 +12371,73 @@ A PDF document named `document.pdf` should be produced and contain the text % \end{macrocode} % \begin{markdown} % -% Do not override options defined before loading the package. +% Use the \pkg{lt3luabridge} library to determine the default value of the +% \mref{markdownOptionOutputDir} macro by using the environmental variable +% `TEXMF_OUTPUT_DIRECTORY` that is available since TeX~Live 2024. % % \end{markdown} % \begin{macrocode} - \@@_option_tl_to_csname:nN + \str_if_eq:nnTF { #1 } - \l_tmpa_tl - \cs_if_exist:cF - { \l_tmpa_tl } + { outputDir } + { \@@_define_option_command_output_dir: } { - \@@_get_default_option_value:nN - { #1 } - \l_tmpa_tl - \@@_set_option_value:nV +% \end{macrocode} +% \begin{markdown} +% +% Do not override options defined before loading the package. +% +% \end{markdown} +% \begin{macrocode} + \@@_option_tl_to_csname:nN { #1 } \l_tmpa_tl + \cs_if_exist:cF + { \l_tmpa_tl } + { + \@@_get_default_option_value:nN + { #1 } + \l_tmpa_tl + \@@_set_option_value:nV + { #1 } + \l_tmpa_tl + } + } + } +\ExplSyntaxOff +\input lt3luabridge.tex +\ExplSyntaxOn +\cs_new:Nn + \@@_define_option_command_output_dir: + { + \cs_if_free:NT + \markdownOptionOutputDir + { + \bool_if:nTF + { + \cs_if_exist_p:N + \luabridge_tl_set:Nn && + ( + \int_compare_p:nNn + { \g_luabridge_method_int } + = + { \c_luabridge_method_directlua_int } || + \sys_if_shell_unrestricted_p: + ) + } + { + \luabridge_tl_set:Nn + \l_tmpa_tl + { print(os.getenv("TEXMF_OUTPUT_DIRECTORY") or ".") } + \tl_gset:NV + \markdownOptionOutputDir + \l_tmpa_tl + } + { + \tl_gset:Nn + \markdownOptionOutputDir + { . } + } } } \cs_new:Nn @@ -12682,10 +12932,14 @@ options locally. { redefined-snippet } \l_tmpa_tl } - \prop_gput:NVn + \keys_precompile:nnN + { markdown/options } + { #2 } + \l_tmpb_tl + \prop_gput:NVV \g_@@_snippets_prop \l_tmpa_tl - { #2 } + \l_tmpb_tl } \cs_gset_eq:NN \markdownSetupSnippet @@ -12751,7 +13005,7 @@ options locally. \g_@@_snippets_prop \l_tmpa_tl \l_tmpb_tl - \@@_setup:V + \tl_use:N \l_tmpb_tl } { @@ -12766,9 +13020,6 @@ options locally. { markdown } { undefined-snippet } { Can't~invoke~undefined~snippet~#1 } -\cs_generate_variant:Nn - \@@_setup:n - { V } \ExplSyntaxOff % \end{macrocode} % \iffalse @@ -14039,7 +14290,7 @@ following text: #### Code Block Renderers The \mdef{markdownRendererInputVerbatim} macro represents a code block. The macro receives a single argument that corresponds to the -filename of a file contaning the code block contents. +filename of a file containing the code block contents. % \end{markdown} % @@ -14073,7 +14324,7 @@ filename of a file contaning the code block contents. The \mdef{markdownRendererInputFencedCode} macro represents a fenced code block. This macro will only be produced, when the \Opt{fencedCode} option is enabled. The macro receives three arguments that correspond to the filename of -a file contaning the code block contents, the fully escaped code fence infostring +a file containing the code block contents, the fully escaped code fence infostring that can be directly typeset, and the raw code fence infostring that can be used outside typesetting. @@ -15289,7 +15540,7 @@ following text: % \begin{markdown} #### Ellipsis Renderer -The \mdef{markdownRendererEllipsis} macro replaces any occurance of ASCII +The \mdef{markdownRendererEllipsis} macro replaces any occurrence of ASCII ellipses in the input text. This macro will only be produced, when the \Opt{smartEllipses} option is enabled. The macro receives no arguments. @@ -15553,8 +15804,8 @@ following text: % \begin{markdown} #### Fenced Code Attribute Context Renderers -The following macros are only produced, when the \Opt{fencedCode} option is -enabled. +The following macros are only produced, when the \Opt{fencedCode} and +\Opt{fencedCodeAttributes} options are enabled. The \mdef{markdownRendererFencedCodeAttributeContextBegin} and \mdef{markdownRendererFencedCodeAttributeContextEnd} macros represent the @@ -18435,7 +18686,7 @@ following text: #### Raw Content Renderers The \mdef{markdownRendererInputRawInline} macro represents an inline raw span. -The macro receives two arguments: the filename of a file contaning the inline +The macro receives two arguments: the filename of a file containing the inline raw span contents and the raw attribute that designates the format of the inline raw span. This macro will only be produced, when the \Opt{rawAttribute} option is enabled. @@ -18470,7 +18721,7 @@ option is enabled. % \begin{markdown} The \mdef{markdownRendererInputRawBlock} macro represents a raw block. The -macro receives two arguments: the filename of a file contaning the raw block +macro receives two arguments: the filename of a file containing the raw block and the raw attribute that designates the format of the raw block. This macro will only be produced, when the \Opt{rawAttribute} and \Opt{fencedCode} options are enabled. @@ -19368,7 +19619,7 @@ following content: \markdownSetup{ renderers = { table = {% - This is a table with caption \emph{#1} that is #3 colums wide + This is a table with caption \emph{#1} that is #3 columns wide and #2 rows long. \rowCounter=0% \def\rowTotal{#2}% @@ -19397,7 +19648,7 @@ A PDF document named `document.pdf` should be produced and contain the following text: > This is a table with caption *Demonstration of pipe table syntax* that is 4 -> colums wide and 4 rows long. As for the alignment, column number 1 is +> columns wide and 4 rows long. As for the alignment, column number 1 is > right-aligned, column number 2 is left-aligned, column number 3 has default > alignment, and column number 4 is centered. In row 1, column number 1 says > *Right*, column number 2 says *Left*, column number 3 says *Default*, and @@ -19454,7 +19705,7 @@ following content: \input markdown \def\markdownOptionTexMathDollars{true} \def\markdownRendererInlineMath#1{$#1\dots$} -\def\markdownRendererDisplayMath#1{$$#1\eqno(1)$$} +\def\markdownRendererDisplayMath#1{$$#1\nonumber$$} \markdownBegin $E=mc^2$ @@ -19471,7 +19722,7 @@ following text: > $E=mc^2\dots$ > -> $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\eqno(1)$$ +> $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\nonumber$$ ##### \LaTeX{} Example {.unnumbered} @@ -19810,6 +20061,50 @@ following text: % % \begin{markdown} +#### Warning and Error Renderers + +The \mdef{markdownRendererWarning} and \mdef{markdownRendererError} macros +represent warnings and errors produced by the markdown parser. Both macros +receive a single parameter with the text of the warning or error. + +% \end{markdown} +% +% \iffalse +%</manual-tokens> +%<*tex> +% \fi +% +% \begin{macrocode} +\def\markdownRendererWarning{% + \markdownRendererWarningPrototype}% +\def\markdownRendererError{% + \markdownRendererErrorPrototype}% +\ExplSyntaxOn +\seq_gput_right:Nn + \g_@@_renderers_seq + { warning } +\prop_gput:Nnn + \g_@@_renderer_arities_prop + { warning } + { 1 } +\seq_gput_right:Nn + \g_@@_renderers_seq + { error } +\prop_gput:Nnn + \g_@@_renderer_arities_prop + { error } + { 1 } +\ExplSyntaxOff +% \end{macrocode} +% \par +% +% \iffalse +%</tex> +%<*manual-tokens> +% \fi +% +% \begin{markdown} + #### YAML Metadata Renderers {#yamlmetadatarenderers} The \mdef{markdownRendererJekyllDataBegin} macro represents the beginning of a @@ -20084,12 +20379,24 @@ following \acro{yaml} serialization rules. % % \begin{markdown} -The \mdef{markdownRendererJekyllDataString} macro represents a string scalar -value in a \acro{yaml} document. This macro will only be produced when the -\Opt{jekyllData} option is enabled. The macro receives two arguments: the +The \mdef{markdownRendererJekyllDataTypographicString} and +\mdef{markdownRendererJekyllDataProgrammaticString} macros represent string +scalar values in a \acro{yaml} document. This macro will only be produced when +the \Opt{jekyllData} option is enabled. The macro receives two arguments: the scalar key in the parent structure, cast to a string following \acro{yaml} serialization rules, and the scalar value. +For each string scalar value, both macros are produced. Whereas +\mref{markdownRendererJekyllDataTypographicString} receives the scalar value +after all markdown markup and special \TeX{} characters in the string have been +replaced by \TeX{} macros, \mref{markdownRendererJekyllDataProgrammaticString} +receives the raw scalar value. Therefore, whereas the +\mref{markdownRendererJekyllDataTypographicString} macro is more appropriate +for texts that are supposed to be typeset with \TeX{}, such as document titles, +author names, or exam questions, the +\mref{markdownRendererJekyllDataProgrammaticString} macro is more appropriate +for identifiers and other programmatic text that won't be typeset by \TeX{}. + % \end{markdown} % % \iffalse @@ -20098,11 +20405,83 @@ serialization rules, and the scalar value. % \fi % % \begin{macrocode} -\def\markdownRendererJekyllDataString{% - \markdownRendererJekyllDataStringPrototype}% +\def\markdownRendererJekyllDataTypographicString{% + \markdownRendererJekyllDataTypographicStringPrototype}% +\def\markdownRendererJekyllDataProgrammaticString{% + \markdownRendererJekyllDataProgrammaticStringPrototype}% \ExplSyntaxOn \seq_gput_right:Nn \g_@@_renderers_seq + { jekyllDataTypographicString } +\prop_gput:Nnn + \g_@@_renderer_arities_prop + { jekyllDataTypographicString } + { 2 } +\seq_gput_right:Nn + \g_@@_renderers_seq + { jekyllDataProgrammaticString } +\prop_gput:Nnn + \g_@@_renderer_arities_prop + { jekyllDataProgrammaticString } + { 2 } +\ExplSyntaxOff +% \end{macrocode} +% \par +% +% \iffalse +%</tex> +%<*manual-tokens> +% \fi +% +% \begin{markdown} + +Before Markdown 3.7.0, the \mref{markdownRendererJekyllDataTypographicString} +macro was named \mref{markdownRendererJekyllDataString} and the +\mref{markdownRendererJekyllDataProgrammaticString} macro was not produced. +The \mref{markdownRendererJekyllDataString} has been deprecated and will be +removed in Markdown 4.0.0. + +% \end{markdown} +% +% \iffalse +%</manual-tokens> +%<*tex> +% \fi +% +% \begin{macrocode} +\ExplSyntaxOn +\cs_gset:Npn + \markdownRendererJekyllDataTypographicString + { + \cs_if_exist:NTF + \markdownRendererJekyllDataString + { + \markdownWarning + { + The~jekyllDataString~renderer~has~been~deprecated,~ + to~be~removed~in~Markdown~4.0.0 + } + \markdownRendererJekyllDataString + } + { + \cs_if_exist:NTF + \markdownRendererJekyllDataStringPrototype + { + \markdownWarning + { + The~jekyllDataString~renderer~prototype~ + has~been~deprecated,~ + to~be~removed~in~Markdown~4.0.0 + } + \markdownRendererJekyllDataStringPrototype + } + { + \markdownRendererJekyllDataTypographicStringPrototype + } + } + } +\seq_gput_right:Nn + \g_@@_renderers_seq { jekyllDataString } \prop_gput:Nnn \g_@@_renderer_arities_prop @@ -20162,7 +20541,7 @@ following content: ``` tex \input markdown \def\markdownOptionJekyllData{true} -\def\markdownRendererJekyllDataString#1#2{\gdef\name{#2}} +\def\markdownRendererJekyllDataTypographicString#1#2{\gdef\name{#2}} \def\markdownRendererJekyllDataNumber#1#2{\gdef\age{#2}} \def\markdownRendererJekyllDataEnd{% \name{} is \age{} years old.} @@ -20192,7 +20571,7 @@ following content: \usepackage[jekyllData]{markdown} \markdownSetup{ renderers = { - jekyllDataString = {\gdef\name{#2}}, + jekyllDataTypographicString = {\gdef\name{#2}}, jekyllDataNumber = {\gdef\age{#2}}, jekyllDataEnd = {\name{} is \age{} years old.}, } @@ -20224,7 +20603,7 @@ following content: ``` tex \usemodule[t][markdown] \setupmarkdown[jekyllData = yes] -\def\markdownRendererJekyllDataString#1#2{\gdef\name{#2}} +\def\markdownRendererJekyllDataTypographicString#1#2{\gdef\name{#2}} \def\markdownRendererJekyllDataNumber#1#2{\gdef\age{#2}} \def\markdownRendererJekyllDataEnd{% \name{} is \age{} years old.} @@ -20256,7 +20635,7 @@ following text: %#### Generating Plain \TeX{} Token Renderer Macros and Key-Values {#plain-tex-renderers} % % We define the command \mdef{@@_define_renderers:} that defines plain \TeX{} -% macros for token renderers. Futhermore, the `\markdownSetup` macro also accepts +% macros for token renderers. Furthermore, the `\markdownSetup` macro also accepts % the `renderers` key, whose value must be a list of key-values, where the keys % correspond to the markdown token renderer macros and the values are new % definitions of these token renderers. @@ -20266,9 +20645,26 @@ following text: \ExplSyntaxOn \cs_new:Nn \@@_define_renderers: { - \seq_map_function:NN + \seq_map_inline:Nn \g_@@_renderers_seq - \@@_define_renderer:n + { +% \end{macrocode} +% \par +% \begin{markdown} +% +% The \mref{markdownRendererJekyllDataString} has been deprecated and will be +% removed in Markdown 4.0.0. +% +% \end{markdown} +% \begin{macrocode} + \str_if_eq:nnF + { ##1 } + { jekyllDataString } + { + \@@_define_renderer:n + { ##1 } + } + } } \cs_new:Nn \@@_define_renderer:n { @@ -20974,7 +21370,7 @@ following text: %#### Generating Plain \TeX{} Token Renderer Prototype Macros and Key-Values {#plain-tex-renderer-prototypes} % % We define the command \mdef{@@_define_renderer_prototypes:} that defines plain \TeX{} -% macros for token renderer prototypes. Futhermore, the `\markdownSetup` macro also accepts +% macros for token renderer prototypes. Furthermore, the `\markdownSetup` macro also accepts % the `rendererPrototype` key, whose value must be a list of key-values, where the keys % correspond to the markdown token renderer prototype macros and the values are new % definitions of these token renderer prototypes. @@ -20984,9 +21380,26 @@ following text: \ExplSyntaxOn \cs_new:Nn \@@_define_renderer_prototypes: { - \seq_map_function:NN + \seq_map_inline:Nn \g_@@_renderers_seq - \@@_define_renderer_prototype:n + { +% \end{macrocode} +% \par +% \begin{markdown} +% +% The \mref{markdownRendererJekyllDataString} has been deprecated and will be +% removed in Markdown 4.0.0. +% +% \end{markdown} +% \begin{macrocode} + \str_if_eq:nnF + { ##1 } + { jekyllDataString } + { + \@@_define_renderer_prototype:n + { ##1 } + } + } } \cs_new:Nn \@@_define_renderer_prototype:n { @@ -21466,9 +21879,10 @@ pdflatex --shell-escape document.tex % \LaTeX{} environments, and redefines the \mref{markinline} and % \mref{markdownInput} commands. % +%#### The `markdown` and `markdown*` \LaTeX{} environments % The \envmref{markdown} and \envmref{markdown*} \LaTeX{} environments are used % to typeset markdown document fragments. Both \LaTeX{} environments accept -% \LaTeX{} interface options (see ection <#sec:latex-options>) as the only +% \LaTeX{} interface options (see Section <#sec:latex-options>) as the only % argument. This argument is optional for the \envmref{markdown} environment % and mandatory for the \envmref{markdown*} environment. % @@ -21505,6 +21919,52 @@ pdflatex --shell-escape document.tex % \end{document} \end{document} % ``````` % +% You can't directly extend the \envmref{markdown} \LaTeX{} environment by +% using it in other environments as follows: +% +% ``` tex +% \newenvironment{foo}\% +% {code before \begin{markdown}[some, options]}\% +% {\end{markdown} code after} +% ``` +% +% This is because the implementation looks for the literal string +% `\end{markdown}` to stop scanning the markdown text. However, you can work +% around this limitation by using the \mref{markdown} and \mref{markdownEnd} +% macros directly in the definition as follows: +% +% \markdownEnd +% \begin{markdown} +% +% ``` tex +% \newenvironment{foo}\% +% {code before \markdown[some, options]}\% +% {\markdownEnd code after} +% ``` +% +% Specifically, the \mref{markdown} macro must appear at the end of the +% replacement text and must be followed by text that has not yet been ingested +% by \TeX's input processor. Furthermore, using the \mref{markdownEnd} macro is +% optional and only makes a difference if you redefined it to produce special +% effects before and after the \envmref{markdown} \LaTeX{} environment. Lastly, +% you can't nest the other environments. For example, the following definition +% is incorrect: +% +% ``` tex +% \newenvironment{bar}{\begin{foo}}{\end{foo}} +% ``` +% +% In this example, you should use the \mref{markdown} macro directly in the +% definition of the environment `bar`: +% +% ``` tex +% \newenvironment{bar}{\markdown[some, options]}{\markdownEnd} +% ``` +% +% \end{markdown} +% \markdownBegin +% +%#### The `\markinline` and `\markdownInput` macros % The \mref{markinline} macro accepts a single mandatory parameter containing % inline markdown content and expands to the result of the conversion of the % input markdown document to plain \TeX{}. Unlike the \mref{markinline} macro @@ -21600,7 +22060,7 @@ following code in our \LaTeX{} document: We can also set all plain \TeX{} options directly from \LaTeX{}. For example, to set the `\markdownOptionInputTempFileName` plain \TeX{} option to -`helper-script.lua`, we would inclde the following code in our \LaTeX{} +`helper-script.lua`, we would include the following code in our \LaTeX{} document: ``` tex @@ -22249,14 +22709,14 @@ Built-in \Hologo{ConTeXt} themes provided with the Markdown package include: % \end{markdown} % \iffalse %</manual-options> -%<*themes-witiko-markdown-defaults-context> +%<*themes-witiko-markdown-defaults-ctx> % \fi % \begin{macrocode} \startmodule[markdownthemewitiko_markdown_defaults] \unprotect % \end{macrocode} % \iffalse -%</themes-witiko-markdown-defaults-context> +%</themes-witiko-markdown-defaults-ctx> %<*manual-options> % \fi % \begin{markdown} @@ -22317,9 +22777,17 @@ local P, R, S, V, C, Cg, Cb, Cmt, Cc, Ct, B, Cs, Cp, any = % `lunamark/util.lua` file in the Lunamark Lua module. % % \end{markdown} +% \iffalse +%</lua> +%<*lua,lua-loader> +% \fi % \begin{macrocode} local util = {} % \end{macrocode} +% \iffalse +%</lua,lua-loader> +%<*lua> +% \fi % \par % \begin{markdown} % @@ -22334,13 +22802,17 @@ function util.err(msg, exit_code) os.exit(exit_code or 1) end % \end{macrocode} +% \iffalse +%</lua> +%<*lua,lua-loader> +% \fi % \par % \begin{markdown} % -% The \luamdef{util.cache} method computes the digest of `string` and -% `salt`, adds the `suffix` and looks into the directory `dir`, whether a -% file with such a name exists. If it does not, it gets created with -% `transform(string)` as its content. The filename is then returned. +% The \luamdef{util.cache} method used `dir`, `string`, `salt`, and `suffix` +% to determine a pathname. If a file with such a pathname does not exists, +% it gets created with `transform(string)` as its content. Regardless, the +% pathname is then returned. % % \end{markdown} % \begin{macrocode} @@ -22348,7 +22820,7 @@ function util.cache(dir, string, salt, transform, suffix) local digest = md5.sumhexa(string .. (salt or "")) local name = util.pathname(dir, digest .. suffix) local file = io.open(name, "r") - if file == nil then -- If no cache entry exists, then create a new one. + if file == nil then -- If no cache entry exists, create a new one. file = assert(io.open(name, "w"), [[Could not open file "]] .. name .. [[" for writing]]) local result = string @@ -22361,6 +22833,10 @@ function util.cache(dir, string, salt, transform, suffix) return name end % \end{macrocode} +% \iffalse +%</lua,lua-loader> +%<*lua> +% \fi % \par % \begin{markdown} % @@ -22559,7 +23035,7 @@ end % Given a table `char_escapes` mapping escapable characters to escaped % strings and optionally a table `string_escapes` mapping escapable strings % to escaped strings, the \luamdef{util.escaper} method returns an escaper -% function that escapes all occurances of escapable strings and characters (in +% function that escapes all occurrences of escapable strings and characters (in % this order). % % The method uses \pkg{LPeg}, which is faster than the Lua `string.gsub` @@ -22588,7 +23064,7 @@ function util.escaper(char_escapes, string_escapes) % \begin{markdown} % If `string_escapes` is provided, turn `escapable` into the % $$\sum^^B{(`k`, `v`)\in`string_escapes`}`P(k) / v` + `escapable`$$ -% capture that replaces any occurance of the string `k` with the string +% capture that replaces any occurrence of the string `k` with the string % `v` for each $(`k`, `v`)\in`string_escapes`$. Note that the pattern % summation is not commutative and its operands are inspected in the % summation order during the matching. As a corrolary, the strings always @@ -22619,6 +23095,10 @@ function util.escaper(char_escapes, string_escapes) end end % \end{macrocode} +% \iffalse +%</lua> +%<*lua,lua-loader> +% \fi % \par % \begin{markdown} % @@ -22638,6 +23118,43 @@ end % \par % \begin{markdown} % +% The \luamdef{util.salt} method produces cryptographic salt out of a table of +% options `options`. +% +% \end{markdown} +% \begin{macrocode} +function util.salt(options) + local opt_string = {} + for k, _ in pairs(defaultOptions) do + local v = options[k] + if type(v) == "table" then + for _, i in ipairs(v) do + opt_string[#opt_string+1] = k .. "=" .. tostring(i) + end +% \end{macrocode} +% \begin{markdown} +% +% The \Opt{cacheDir} option is disregarded. +% +% \end{markdown} +% \begin{macrocode} + elseif k ~= "cacheDir" then + opt_string[#opt_string+1] = k .. "=" .. tostring(v) + end + end + table.sort(opt_string) + local salt = table.concat(opt_string, ",") + .. "," .. metadata.version + return salt +end +% \end{macrocode} +% \iffalse +%</lua,lua-loader> +%<*lua> +% \fi +% \par +% \begin{markdown} +% %### HTML Entities % This section documents the \acro{HTML} entities recognized by the % markdown reader. These functions are encapsulated in the `entities` @@ -24954,15 +25471,6 @@ function M.writer.new(options) % \par % \begin{markdown} % -% Define \luamdef{writer->suffix} as the suffix of the produced cache files. -% -% \end{markdown} -% \begin{macrocode} - self.suffix = ".tex" -% \end{macrocode} -% \par -% \begin{markdown} -% % Define \luamdef{writer->space} as the output format of a space character. % % \end{markdown} @@ -25007,19 +25515,6 @@ function M.writer.new(options) % \par % \begin{markdown} % -% Define \luamdef{writer->pack} as a function that will take the filename -% `name` of the output file prepared by the reader and transform it to the -% output format. -% -% \end{markdown} -% \begin{macrocode} - function self.pack(name) - return [[\input{]] .. name .. [[}\relax]] - end -% \end{macrocode} -% \par -% \begin{markdown} -% % Define \luamdef{writer->interblocksep} as the output format of a block % element separator. % @@ -25123,13 +25618,17 @@ function M.writer.new(options) ["{"] = "\\markdownRendererLeftBrace{}", ["}"] = "\\markdownRendererRightBrace{}", ["\\"] = "\\markdownRendererBackslash{}", + ["\r"] = " ", + ["\n"] = " ", } self.escaped_minimal_strings = { - ["^^"] = "\\markdownRendererCircumflex\\markdownRendererCircumflex ", + ["^^"] = "\\markdownRendererCircumflex" + .. "\\markdownRendererCircumflex ", ["☒"] = "\\markdownRendererTickedBox{}", ["⌛"] = "\\markdownRendererHalfTickedBox{}", ["☐"] = "\\markdownRendererUntickedBox{}", - [entities.hex_entity('FFFD')] = "\\markdownRendererReplacementCharacter{}", + [entities.hex_entity('FFFD')] + = "\\markdownRendererReplacementCharacter{}", } % \end{macrocode} % \par @@ -25164,7 +25663,8 @@ function M.writer.new(options) ["^"] = "\\markdownRendererCircumflex{}", ["~"] = "\\markdownRendererTilde{}", ["|"] = "\\markdownRendererPipe{}", - [entities.hex_entity('0000')] = "\\markdownRendererReplacementCharacter{}", + [entities.hex_entity('0000')] + = "\\markdownRendererReplacementCharacter{}", } % \end{macrocode} % \par @@ -25172,9 +25672,9 @@ function M.writer.new(options) % % Use the \luamref{writer->escaped_chars}, \luamref{writer->escaped_uri_chars}, % and \luamref{writer->escaped_minimal_strings} tables to create the -% \luamdef{writer->escape_typographic_text}, -% \luamdef{writer->escape_programmatic_text}, and -% \luamdef{writer->escape_minimal} escaper functions. +% \luamdef{escape_typographic_text}, +% \luamdef{escape_programmatic_text}, and +% \luamdef{escape_minimal} local escaper functions. % % \end{markdown} % \begin{macrocode} @@ -25226,6 +25726,30 @@ function M.writer.new(options) % \par % \begin{markdown} % +% Define \luamdef{writer->warning} as a function that will transform an input +% warning `t` to the output format. +% +% \end{markdown} +% \begin{macrocode} + function self.warning(t) + return {"\\markdownRendererWarning{", self.identifier(t), "}"} + end +% \end{macrocode} +% \par +% \begin{markdown} +% +% Define \luamdef{writer->error} as a function that will transform an input +% error `t` to the output format. +% +% \end{markdown} +% \begin{macrocode} + function self.error(t) + return {"\\markdownRendererError{", self.identifier(t), "}"} + end +% \end{macrocode} +% \par +% \begin{markdown} +% % Define \luamdef{writer->code} as a function that will transform an input % inline code span `s` with optional attributes `attributes` to the output % format. @@ -25425,7 +25949,8 @@ function M.writer.new(options) % \begin{macrocode} function self.inline_html_tag(contents) if self.flatten_inlines then return contents end - return {"\\markdownRendererInlineHtmlTag{",self.string(contents),"}"} + return {"\\markdownRendererInlineHtmlTag{", + self.string(contents),"}"} end % \end{macrocode} % \par @@ -25716,8 +26241,10 @@ function M.writer.new(options) % \begin{macrocode} function self.push_attributes(attribute_type, attributes, start_output, end_output) - local attribute_type_level = self.attribute_type_levels[attribute_type] - self.attribute_type_levels[attribute_type] = attribute_type_level + 1 + local attribute_type_level + = self.attribute_type_levels[attribute_type] + self.attribute_type_levels[attribute_type] + = attribute_type_level + 1 -- index attributes in a hash table for easy lookup attributes = attributes or {} @@ -25772,8 +26299,10 @@ function M.writer.new(options) local attributes, _, end_output current_attribute_type, attributes, _, end_output = table.unpack( self.active_attributes[#self.active_attributes]) - local attribute_type_level = self.attribute_type_levels[current_attribute_type] - self.attribute_type_levels[current_attribute_type] = attribute_type_level - 1 + local attribute_type_level + = self.attribute_type_levels[current_attribute_type] + self.attribute_type_levels[current_attribute_type] + = attribute_type_level - 1 if self.is_writing and end_output ~= nil then table.insert(buf, end_output) end @@ -25807,7 +26336,8 @@ function M.writer.new(options) local prev_space = false local letter_found = false local normalized_s = s - if not options.unicodeNormalization or options.unicodeNormalizationForm ~= "nfc" then + if not options.unicodeNormalization + or options.unicodeNormalizationForm ~= "nfc" then normalized_s = uni_algos.normalize.NFC(normalized_s) end @@ -25824,7 +26354,8 @@ function M.writer.new(options) end end - -- Remove all non-alphanumeric characters, except underscores, hyphens, and periods. + -- Remove all non-alphanumeric characters, except underscores, + -- hyphens, and periods. if not unicode.utf8.match(char, "[%w_%-%.%s]") then goto continue end @@ -25852,7 +26383,8 @@ function M.writer.new(options) table.remove(buffer) end - local identifier = #buffer == 0 and "section" or table.concat(buffer, "") + local identifier = #buffer == 0 and "section" + or table.concat(buffer, "") return identifier end % \end{macrocode} @@ -25867,7 +26399,8 @@ function M.writer.new(options) local prev_space = false local letter_found = false local normalized_s = s - if not options.unicodeNormalization or options.unicodeNormalizationForm ~= "nfc" then + if not options.unicodeNormalization + or options.unicodeNormalizationForm ~= "nfc" then normalized_s = uni_algos.normalize.NFC(normalized_s) end @@ -25884,7 +26417,8 @@ function M.writer.new(options) end end - -- Remove all non-alphanumeric characters, except underscores and hyphens. + -- Remove all non-alphanumeric characters, except underscores + -- and hyphens. if not unicode.utf8.match(char, "[%w_%-%s]") then prev_space = false goto continue @@ -25913,7 +26447,8 @@ function M.writer.new(options) table.remove(buffer) end - local identifier = #buffer == 0 and "section" or table.concat(buffer, "") + local identifier = #buffer == 0 and "section" + or table.concat(buffer, "") return identifier end % \end{macrocode} @@ -25952,9 +26487,11 @@ function M.writer.new(options) table.insert(auto_identifiers, create_auto_identifier(flat_text)) end if self.options.gfmAutoIdentifiers then - table.insert(auto_identifiers, create_gfm_auto_identifier(flat_text)) + table.insert(auto_identifiers, + create_gfm_auto_identifier(flat_text)) end - local normalized_attributes = normalize_attributes(attributes, auto_identifiers) + local normalized_attributes = normalize_attributes(attributes, + auto_identifiers) -- push attributes for the new section local start_output = {} @@ -25970,7 +26507,8 @@ function M.writer.new(options) -- render the heading and its attributes if self.is_writing and #normalized_attributes > 0 then - table.insert(buf, "\\markdownRendererHeaderAttributeContextBegin\n") + table.insert(buf, + "\\markdownRendererHeaderAttributeContextBegin\n") table.insert(buf, self.attributes(normalized_attributes, false)) end @@ -26143,34 +26681,91 @@ parsers.ascii_punctuation = S("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~") % % \end{markdown} % \begin{macrocode} -parsers.punctuation = {} -(function() - local pathname = kpse.lookup("UnicodeData.txt") +;(function() + local pathname = assert(kpse.find_file("UnicodeData.txt"), + [[Could not locate file "UnicodeData.txt"]]) local file = assert(io.open(pathname, "r"), [[Could not open file "UnicodeData.txt"]]) +% \end{macrocode} +% \par +% \begin{markdown} +% +% In order to minimize the size and speed of the parser, we will first +% construct a prefix tree of UTF-8 encodings for all codepoints of a +% given code length. +% +% \end{markdown} +% \begin{macrocode} + local prefix_trees = {} for line in file:lines() do local codepoint, major_category = line:match("^(%x+);[^;]*;(%a)") if major_category == "P" or major_category == "S" then local code = unicode.utf8.char(tonumber(codepoint, 16)) - if parsers.punctuation[#code] == nil then - parsers.punctuation[#code] = parsers.fail + if prefix_trees[#code] == nil then + prefix_trees[#code] = {} end - local code_parser = parsers.succeed + local node = prefix_trees[#code] for i = 1, #code do local byte = code:sub(i, i) - local byte_parser = S(byte) - code_parser = code_parser - * byte_parser + if i < #code then + if node[byte] == nil then + node[byte] = {} + end + node = node[byte] + else + table.insert(node, byte) + end end - parsers.punctuation[#code] = parsers.punctuation[#code] - + code_parser end end assert(file:close()) +% \end{macrocode} +% \par +% \begin{markdown} +% +% Next, we will construct a parser out of the prefix tree. +% +% \end{markdown} +% \begin{macrocode} + local function depth_first_search(node, path, visit, leave) + visit(node, path) + for label, child in pairs(node) do + if type(child) == "table" then + depth_first_search(child, path .. label, visit, leave) + else + visit(child, path) + end + end + leave(node, path) + end + + parsers.punctuation = {} + for length, prefix_tree in pairs(prefix_trees) do + local subparsers = {} + depth_first_search(prefix_tree, "", function(node, path) + if type(node) == "table" then + subparsers[path] = parsers.fail + else + assert(type(node) == "string") + subparsers[path] = subparsers[path] + S(node) + end + end, function(_, path) + if #path > 0 then + local byte = path:sub(#path, #path) + local parent_path = path:sub(1, #path-1) + subparsers[parent_path] = subparsers[parent_path] + + S(byte) * subparsers[path] + else + parsers.punctuation[length] = subparsers[path] + end + end) + assert(parsers.punctuation[length] ~= nil) + end end)() parsers.escapable = parsers.ascii_punctuation -parsers.anyescaped = parsers.backslash / "" * parsers.escapable +parsers.anyescaped = parsers.backslash / "" + * parsers.escapable + parsers.any parsers.spacechar = S("\t ") @@ -26189,14 +26784,18 @@ parsers.linechar = P(1 - parsers.newline) parsers.blankline = parsers.optionalspace * parsers.newline / "\n" parsers.blanklines = parsers.blankline^0 -parsers.skipblanklines = (parsers.optionalspace * parsers.newline)^0 +parsers.skipblanklines = ( parsers.optionalspace + * parsers.newline)^0 parsers.indentedline = parsers.indent /"" - * C(parsers.linechar^1 * parsers.newline^-1) + * C( parsers.linechar^1 + * parsers.newline^-1) parsers.optionallyindentedline = parsers.indent^-1 /"" - * C(parsers.linechar^1 * parsers.newline^-1) + * C( parsers.linechar^1 + * parsers.newline^-1) parsers.sp = parsers.spacing^0 parsers.spnl = parsers.optionalspace - * (parsers.newline * parsers.optionalspace)^-1 + * ( parsers.newline + * parsers.optionalspace)^-1 parsers.line = parsers.linechar^0 * parsers.newline parsers.nonemptyline = parsers.line - parsers.blankline % \end{macrocode} @@ -26279,7 +26878,8 @@ local function update_indent_table(indent_table, new_indent, add) if add then indent_table.indents[#indent_table.indents + 1] = new_indent else - if indent_table.indents[#indent_table.indents].name == new_indent.name then + if indent_table.indents[#indent_table.indents].name + == new_indent.name then indent_table.indents[#indent_table.indents] = nil end end @@ -26295,10 +26895,12 @@ end % \end{markdown} % \begin{macrocode} local function remove_indent(name) - local function remove_indent_level(s, i, indent_table) -- luacheck: ignore s i - indent_table = update_indent_table(indent_table, {name=name}, false) - return true, indent_table - end + local remove_indent_level = + function(s, i, indent_table) -- luacheck: ignore s i + indent_table = update_indent_table(indent_table, {name=name}, + false) + return true, indent_table + end return Cg(Cmt(Cb("indent_info"), remove_indent_level), "indent_info") end @@ -26314,7 +26916,8 @@ end % % \end{markdown} % \begin{macrocode} -local function process_starter_spacing(indent, spacing, minimum, left_strip_length) +local function process_starter_spacing(indent, spacing, + minimum, left_strip_length) left_strip_length = left_strip_length or 0 local count = 0 @@ -26351,14 +26954,16 @@ local function process_starter_spacing(indent, spacing, minimum, left_strip_leng minimum_remainder = minimum_remainder .. character elseif (count >= minimum) then minimum_found = true - minimum_remainder = minimum_remainder .. string.rep(" ", count - minimum) + minimum_remainder = minimum_remainder + .. string.rep(" ", count - minimum) end if (code_started) then code_start = code_start .. character elseif (count >= minimum + 4) then code_started = true - code_start = code_start .. string.rep(" ", count - (minimum + 4)) + code_start = code_start + .. string.rep(" ", count - (minimum + 4)) end end end @@ -26425,7 +27030,8 @@ end % % \end{markdown} % \begin{macrocode} -local function process_starter_indent(_, _, indent_table, starter, is_blank, indent_type, breakable) +local function process_starter_indent(_, _, indent_table, starter, + is_blank, indent_type, breakable) local last_trail = starter[1] local delimiter = starter[2] local raw_new_trail = starter[3] @@ -26453,11 +27059,13 @@ local function process_starter_indent(_, _, indent_table, starter, is_blank, ind local last_trail_length = #last_trail local delimiter_length = total_delimiter_length(delimiter) - local total_indent_level = preceding_indentation + last_trail_length + delimiter_length + local total_indent_level = preceding_indentation + last_trail_length + + delimiter_length local sp = {} if not is_blank then - sp = process_starter_spacing(total_indent_level, raw_new_trail, 0, 1) + sp = process_starter_spacing(total_indent_level, raw_new_trail, + 0, 1) end local del_trail_length = sp.left_total_stripped @@ -26467,12 +27075,17 @@ local function process_starter_indent(_, _, indent_table, starter, is_blank, ind del_trail_length = del_trail_length + #sp.remainder end - local indent_length = last_trail_length + delimiter_length + del_trail_length + local indent_length = last_trail_length + delimiter_length + + del_trail_length local new_indent_info = {name=indent_type, length=indent_length} - indent_table = update_indent_table(indent_table, new_indent_info, true) - indent_table = add_trail(indent_table, {is_code=sp.is_code, remainder=sp.remainder, total_length=sp.total_length, - full_remainder=sp.full_remainder}) + indent_table = update_indent_table(indent_table, new_indent_info, + true) + indent_table = add_trail(indent_table, + {is_code=sp.is_code, + remainder=sp.remainder, + total_length=sp.total_length, + full_remainder=sp.full_remainder}) return true, indent_table end @@ -26490,7 +27103,8 @@ local function decode_pattern(name) delimeter = parsers.more end - return C(parsers.optionalspace) * C(delimeter) * C(parsers.optionalspace) * Cp() + return C(parsers.optionalspace) * C(delimeter) + * C(parsers.optionalspace) * Cp() end % \end{macrocode} @@ -26531,7 +27145,8 @@ end % % \end{markdown} % \begin{macrocode} -local function traverse_indent(s, i, indent_table, is_optional, is_blank, current_line_indents) +local function traverse_indent(s, i, indent_table, is_optional, + is_blank, current_line_indents) local new_index = i local preceding_indentation = 0 @@ -26550,12 +27165,17 @@ local function traverse_indent(s, i, indent_table, is_optional, is_blank, curren -- match decoded pattern local new_indent_info = lpeg.match(Ct(pattern), s, new_index) if new_indent_info == nil then - local blankline_end = lpeg.match(Ct(parsers.blankline * Cg(Cp(), "pos")), s, new_index) - if is_optional or not indent_table.ignore_blockquote_blank or not blankline_end then - return is_optional, new_index, current_trail, current_line_indents + local blankline_end = lpeg.match( + Ct(parsers.blankline * Cg(Cp(), "pos")), s, new_index) + if is_optional or not indent_table.ignore_blockquote_blank + or not blankline_end then + return is_optional, new_index, current_trail, + current_line_indents end - return traverse_indent(s, tonumber(blankline_end.pos), indent_table, is_optional, is_blank, current_line_indents) + return traverse_indent(s, tonumber(blankline_end.pos), + indent_table, is_optional, is_blank, + current_line_indents) end local raw_last_trail = new_indent_info[1] @@ -26568,13 +27188,15 @@ local function traverse_indent(s, i, indent_table, is_optional, is_blank, curren -- check previous trail if not space_only and next(current_trail) == nil then local sp = process_starter_spacing(0, raw_last_trail, 0, 0) - current_trail = {is_code=sp.is_code, remainder=sp.remainder, total_length=sp.total_length, + current_trail = {is_code=sp.is_code, remainder=sp.remainder, + total_length=sp.total_length, full_remainder=sp.full_remainder} end if next(current_trail) ~= nil then if not space_only and current_trail.is_code then - return is_optional, new_index, current_trail, current_line_indents + return is_optional, new_index, current_trail, + current_line_indents end if current_trail.internal_remainder ~= nil then raw_last_trail = current_trail.internal_remainder @@ -26589,7 +27211,8 @@ local function traverse_indent(s, i, indent_table, is_optional, is_blank, curren raw_last_trail_length = #raw_last_trail end - local total_indent_level = preceding_indentation + raw_last_trail_length + delimiter_length + local total_indent_level = preceding_indentation + + raw_last_trail_length + delimiter_length local spacing_to_process local minimum = 0 @@ -26603,13 +27226,17 @@ local function traverse_indent(s, i, indent_table, is_optional, is_blank, curren minimum = value.length end - local sp = process_starter_spacing(total_indent_level, spacing_to_process, minimum, left_strip_length) + local sp = process_starter_spacing(total_indent_level, + spacing_to_process, minimum, + left_strip_length) if space_only and not sp.is_minimum then - return is_optional or (is_blank and blank_starter <= index), new_index, current_trail, current_line_indents + return is_optional or (is_blank and blank_starter <= index), + new_index, current_trail, current_line_indents end - local indent_length = raw_last_trail_length + delimiter_length + sp.left_total_stripped + local indent_length = raw_last_trail_length + delimiter_length + + sp.left_total_stripped -- update info for the next pattern if not space_only then @@ -26618,8 +27245,10 @@ local function traverse_indent(s, i, indent_table, is_optional, is_blank, curren preceding_indentation = preceding_indentation + value.length end - current_trail = {is_code=sp.is_code, remainder=sp.remainder, internal_remainder=sp.minimum_remainder, - total_length=sp.total_length, full_remainder=sp.full_remainder} + current_trail = {is_code=sp.is_code, remainder=sp.remainder, + internal_remainder=sp.minimum_remainder, + total_length=sp.total_length, + full_remainder=sp.full_remainder} current_line_indents[#current_line_indents + 1] = new_indent_info new_index = next_index @@ -26647,34 +27276,36 @@ end % % \end{markdown} % \begin{macrocode} -local function check_trail_joined(s, i, indent_table, spacing, expect_code, omit_remainder) -- luacheck: ignore s i - local is_code - local remainder +local check_trail_joined = + function(s, i, indent_table, -- luacheck: ignore s i + spacing, expect_code, omit_remainder) + local is_code + local remainder - if has_trail(indent_table) then - local trail = indent_table.trail - is_code = trail.is_code - if is_code then - remainder = trail.remainder - else - remainder = trail.full_remainder - end - else - local sp = process_starter_spacing(0, spacing, 0, 0) - is_code = sp.is_code - if is_code then - remainder = sp.remainder + if has_trail(indent_table) then + local trail = indent_table.trail + is_code = trail.is_code + if is_code then + remainder = trail.remainder + else + remainder = trail.full_remainder + end else - remainder = sp.full_remainder + local sp = process_starter_spacing(0, spacing, 0, 0) + is_code = sp.is_code + if is_code then + remainder = sp.remainder + else + remainder = sp.full_remainder + end end - end - local result = check_trail(expect_code, is_code) - if omit_remainder then - return result + local result = check_trail(expect_code, is_code) + if omit_remainder then + return result + end + return result, remainder end - return result, remainder -end % \end{macrocode} % \begin{markdown} @@ -26683,22 +27314,24 @@ end % % \end{markdown} % \begin{macrocode} -local function check_trail_length(s, i, indent_table, spacing, min, max) -- luacheck: ignore s i - local trail +local check_trail_length = + function(s, i, indent_table, -- luacheck: ignore s i + spacing, min, max) + local trail - if has_trail(indent_table) then - trail = indent_table.trail - else - trail = process_starter_spacing(0, spacing, 0, 0) - end + if has_trail(indent_table) then + trail = indent_table.trail + else + trail = process_starter_spacing(0, spacing, 0, 0) + end - local total_length = trail.total_length - if total_length == nil then - return false - end + local total_length = trail.total_length + if total_length == nil then + return false + end - return min <= total_length and total_length <= max -end + return min <= total_length and total_length <= max + end % \end{macrocode} % \begin{markdown} @@ -26708,7 +27341,8 @@ end % % \end{markdown} % \begin{macrocode} -local function check_continuation_indentation(s, i, indent_table, is_optional, is_blank) +local function check_continuation_indentation(s, i, indent_table, + is_optional, is_blank) if not has_indents(indent_table) then return true end @@ -26761,27 +27395,29 @@ end % % \end{markdown} % \begin{macrocode} -local function check_trail_type(s, i, trail, spacing, trail_type) -- luacheck: ignore s i - if trail == nil then - trail = process_starter_spacing(0, spacing, 0, 0) - end +local check_trail_type = + function(s, i, -- luacheck: ignore s i + trail, spacing, trail_type) + if trail == nil then + trail = process_starter_spacing(0, spacing, 0, 0) + end - if trail_type == "non-code" then - return check_trail(false, trail.is_code) - end - if trail_type == "code" then - return check_trail(true, trail.is_code) - end - if trail_type == "full-code" then - if (trail.is_code) then - return i, trail.remainder + if trail_type == "non-code" then + return check_trail(false, trail.is_code) + end + if trail_type == "code" then + return check_trail(true, trail.is_code) + end + if trail_type == "full-code" then + if (trail.is_code) then + return i, trail.remainder + end + return i, "" + end + if trail_type == "full-any" then + return i, trail.internal_remainder end - return i, "" - end - if trail_type == "full-any" then - return i, trail.internal_remainder end -end % \end{macrocode} % \begin{markdown} @@ -26790,20 +27426,22 @@ end % % \end{markdown} % \begin{macrocode} -local function trail_freezing(s, i, indent_table, is_freezing) -- luacheck: ignore s i - if is_freezing then - if indent_table.is_trail_frozen then - indent_table.trail = indent_table.frozen_trail +local trail_freezing = + function(s, i, -- luacheck: ignore s i + indent_table, is_freezing) + if is_freezing then + if indent_table.is_trail_frozen then + indent_table.trail = indent_table.frozen_trail + else + indent_table.frozen_trail = indent_table.trail + indent_table.is_trail_frozen = true + end else - indent_table.frozen_trail = indent_table.trail - indent_table.is_trail_frozen = true + indent_table.frozen_trail = nil + indent_table.is_trail_frozen = false end - else - indent_table.frozen_trail = nil - indent_table.is_trail_frozen = false + return true, indent_table end - return true, indent_table -end % \end{macrocode} % \begin{markdown} @@ -26814,53 +27452,59 @@ end % % \end{markdown} % \begin{macrocode} -local function check_continuation_indentation_and_trail(s, i, indent_table, is_optional, is_blank, trail_type, - reset_rem, omit_remainder) - if not has_indents(indent_table) then - local spacing, new_index = lpeg.match(C(parsers.spacechar^0) * Cp(), s, i) - local result, remainder = check_trail_type(s, i, indent_table.trail, spacing, trail_type) - if remainder == nil then +local check_continuation_indentation_and_trail = + function (s, i, indent_table, is_optional, is_blank, trail_type, + reset_rem, omit_remainder) + if not has_indents(indent_table) then + local spacing, new_index = lpeg.match( C(parsers.spacechar^0) + * Cp(), s, i) + local result, remainder = check_trail_type(s, i, + indent_table.trail, spacing, trail_type) + if remainder == nil then + if result then + return new_index + end + return false + end if result then - return new_index + return new_index, remainder end return false end - if result then - return new_index, remainder - end - return false - end - local passes, new_index, current_trail = traverse_indent(s, i, indent_table, is_optional, is_blank) + local passes, new_index, current_trail = traverse_indent(s, i, + indent_table, is_optional, is_blank) + + if passes then + local spacing + if current_trail == nil then + local newer_spacing, newer_index = lpeg.match( + C(parsers.spacechar^0) * Cp(), s, i) + current_trail = process_starter_spacing(0, newer_spacing, 0, 0) + new_index = newer_index + spacing = newer_spacing + else + spacing = current_trail.remainder + end + local result, remainder = check_trail_type(s, new_index, + current_trail, spacing, trail_type) + if remainder == nil or omit_remainder then + if result then + return new_index + end + return false + end - if passes then - local spacing - if current_trail == nil then - local newer_spacing, newer_index = lpeg.match(C(parsers.spacechar^0) * Cp(), s, i) - current_trail = process_starter_spacing(0, newer_spacing, 0, 0) - new_index = newer_index - spacing = newer_spacing - else - spacing = current_trail.remainder - end - local result, remainder = check_trail_type(s, new_index, current_trail, spacing, trail_type) - if remainder == nil or omit_remainder then + if is_blank and reset_rem then + remainder = remove_remainder_if_blank(indent_table, remainder) + end if result then - return new_index + return new_index, remainder end return false end - - if is_blank and reset_rem then - remainder = remove_remainder_if_blank(indent_table, remainder) - end - if result then - return new_index, remainder - end return false end - return false -end % \end{macrocode} % \begin{markdown} @@ -26869,14 +27513,20 @@ end % % \end{markdown} % \begin{macrocode} -parsers.check_trail = Cmt(Cb("indent_info") * C(parsers.spacechar^0) * Cc(false), check_trail_joined) +parsers.check_trail = Cmt( Cb("indent_info") * C(parsers.spacechar^0) + * Cc(false), check_trail_joined) -parsers.check_trail_no_rem = Cmt(Cb("indent_info") * C(parsers.spacechar^0) * Cc(false) * Cc(true), check_trail_joined) +parsers.check_trail_no_rem = Cmt( Cb("indent_info") + * C(parsers.spacechar^0) * Cc(false) + * Cc(true), check_trail_joined) -parsers.check_code_trail = Cmt(Cb("indent_info") * C(parsers.spacechar^0) * Cc(true), check_trail_joined) +parsers.check_code_trail = Cmt( Cb("indent_info") + * C(parsers.spacechar^0) + * Cc(true), check_trail_joined) parsers.check_trail_length_range = function(min, max) - return Cmt(Cb("indent_info") * C(parsers.spacechar^0) * Cc(min) * Cc(max), check_trail_length) + return Cmt( Cb("indent_info") * C(parsers.spacechar^0) * Cc(min) + * Cc(max), check_trail_length) end parsers.check_trail_length = function(n) @@ -26891,9 +27541,11 @@ end % % \end{markdown} % \begin{macrocode} -parsers.freeze_trail = Cg(Cmt(Cb("indent_info") * Cc(true), trail_freezing), "indent_info") +parsers.freeze_trail = Cg( Cmt(Cb("indent_info") + * Cc(true), trail_freezing), "indent_info") -parsers.unfreeze_trail = Cg(Cmt(Cb("indent_info") * Cc(false), trail_freezing), "indent_info") +parsers.unfreeze_trail = Cg(Cmt(Cb("indent_info") * Cc(false), + trail_freezing), "indent_info") % \end{macrocode} % \begin{markdown} @@ -26902,11 +27554,16 @@ parsers.unfreeze_trail = Cg(Cmt(Cb("indent_info") * Cc(false), trail_freezing), % % \end{markdown} % \begin{macrocode} -parsers.check_minimal_indent = Cmt(Cb("indent_info") * Cc(false), check_continuation_indentation) +parsers.check_minimal_indent = Cmt(Cb("indent_info") * Cc(false), + check_continuation_indentation) -parsers.check_optional_indent = Cmt(Cb("indent_info") * Cc(true), check_continuation_indentation) +parsers.check_optional_indent = Cmt(Cb("indent_info") * Cc(true), + check_continuation_indentation) -parsers.check_minimal_blank_indent = Cmt(Cb("indent_info") * Cc(false) * Cc(true), check_continuation_indentation) +parsers.check_minimal_blank_indent + = Cmt( Cb("indent_info") * Cc(false) + * Cc(true) + , check_continuation_indentation) % \end{macrocode} % \begin{markdown} @@ -26917,37 +27574,45 @@ parsers.check_minimal_blank_indent = Cmt(Cb("indent_info") * Cc(false) * Cc(true % \end{markdown} % \begin{macrocode} -parsers.check_minimal_indent_and_trail = Cmt( Cb("indent_info") - * Cc(false) * Cc(false) * Cc("non-code") * Cc(true), - check_continuation_indentation_and_trail) +parsers.check_minimal_indent_and_trail = + Cmt( Cb("indent_info") + * Cc(false) * Cc(false) * Cc("non-code") * Cc(true) + , check_continuation_indentation_and_trail) -parsers.check_minimal_indent_and_code_trail = Cmt( Cb("indent_info") - * Cc(false) * Cc(false) * Cc("code") * Cc(false), - check_continuation_indentation_and_trail) +parsers.check_minimal_indent_and_code_trail = + Cmt( Cb("indent_info") + * Cc(false) * Cc(false) * Cc("code") * Cc(false) + , check_continuation_indentation_and_trail) -parsers.check_minimal_blank_indent_and_full_code_trail = Cmt( Cb("indent_info") - * Cc(false) * Cc(true) * Cc("full-code") * Cc(true), - check_continuation_indentation_and_trail) +parsers.check_minimal_blank_indent_and_full_code_trail = + Cmt( Cb("indent_info") + * Cc(false) * Cc(true) * Cc("full-code") * Cc(true) + , check_continuation_indentation_and_trail) -parsers.check_minimal_indent_and_any_trail = Cmt( Cb("indent_info") - * Cc(false) * Cc(false) * Cc("full-any") * Cc(true) * Cc(false), - check_continuation_indentation_and_trail) +parsers.check_minimal_indent_and_any_trail = + Cmt( Cb("indent_info") + * Cc(false) * Cc(false) * Cc("full-any") * Cc(true) * Cc(false) + , check_continuation_indentation_and_trail) -parsers.check_minimal_blank_indent_and_any_trail = Cmt( Cb("indent_info") - * Cc(false) * Cc(true) * Cc("full-any") * Cc(true) * Cc(false), - check_continuation_indentation_and_trail) +parsers.check_minimal_blank_indent_and_any_trail = + Cmt( Cb("indent_info") + * Cc(false) * Cc(true) * Cc("full-any") * Cc(true) * Cc(false) + , check_continuation_indentation_and_trail) -parsers.check_minimal_blank_indent_and_any_trail_no_rem = Cmt( Cb("indent_info") - * Cc(false) * Cc(true) * Cc("full-any") * Cc(true) * Cc(true), - check_continuation_indentation_and_trail) +parsers.check_minimal_blank_indent_and_any_trail_no_rem = + Cmt( Cb("indent_info") + * Cc(false) * Cc(true) * Cc("full-any") * Cc(true) * Cc(true) + , check_continuation_indentation_and_trail) -parsers.check_optional_indent_and_any_trail = Cmt( Cb("indent_info") - * Cc(true) * Cc(false) * Cc("full-any") * Cc(true) * Cc(false), - check_continuation_indentation_and_trail) +parsers.check_optional_indent_and_any_trail = + Cmt( Cb("indent_info") + * Cc(true) * Cc(false) * Cc("full-any") * Cc(true) * Cc(false) + , check_continuation_indentation_and_trail) -parsers.check_optional_blank_indent_and_any_trail = Cmt( Cb("indent_info") - * Cc(true) * Cc(true) * Cc("full-any") * Cc(true) * Cc(false), - check_continuation_indentation_and_trail) +parsers.check_optional_blank_indent_and_any_trail = + Cmt( Cb("indent_info") + * Cc(true) * Cc(true) * Cc("full-any") * Cc(true) * Cc(false) + , check_continuation_indentation_and_trail) % \end{macrocode} % \begin{markdown} @@ -26958,7 +27623,8 @@ parsers.check_optional_blank_indent_and_any_trail = Cmt( Cb("indent_info") % \begin{macrocode} parsers.spnlc_noexc = parsers.optionalspace - * (parsers.newline * parsers.check_minimal_indent_and_any_trail)^-1 + * ( parsers.newline + * parsers.check_minimal_indent_and_any_trail)^-1 parsers.spnlc = parsers.optionalspace * (V("EndlineNoSub"))^-1 @@ -26966,7 +27632,8 @@ parsers.spnlc = parsers.optionalspace parsers.spnlc_sep = parsers.optionalspace * V("EndlineNoSub") + parsers.spacechar^1 -parsers.only_blank = parsers.spacechar^0 * (parsers.newline + parsers.eof) +parsers.only_blank = parsers.spacechar^0 + * (parsers.newline + parsers.eof) % \end{macrocode} % \begin{figure} @@ -27013,64 +27680,66 @@ parsers.commented_line_letter = parsers.linechar + parsers.newline - parsers.backslash - parsers.percent -parsers.commented_line = Cg(Cc(""), "backslashes") - * ((#(parsers.commented_line_letter - - parsers.newline) - * Cb("backslashes") - * Cs(parsers.commented_line_letter - - parsers.newline)^1 -- initial - * Cg(Cc(""), "backslashes")) - + #(parsers.backslash * parsers.backslash) - * Cg((parsers.backslash -- even backslash - * parsers.backslash)^1, "backslashes") - + (parsers.backslash - * (#parsers.percent - * Cb("backslashes") - / function(backslashes) - return string.rep("\\", #backslashes / 2) - end - * C(parsers.percent) - + #parsers.commented_line_letter - * Cb("backslashes") - * Cc("\\") - * C(parsers.commented_line_letter)) - * Cg(Cc(""), "backslashes")))^0 - * (#parsers.percent - * Cb("backslashes") - / function(backslashes) - return string.rep("\\", #backslashes / 2) - end - * ((parsers.percent -- comment - * parsers.line - * #parsers.blankline) -- blank line - / "\n" - + parsers.percent -- comment - * parsers.line - * parsers.optionalspace) -- leading tabs and spaces - + #(parsers.newline) - * Cb("backslashes") - * C(parsers.newline)) - -parsers.chunk = parsers.line * (parsers.optionallyindentedline - - parsers.blankline)^0 - -parsers.attribute_key_char = parsers.alphanumeric + S("-_:.") -parsers.attribute_raw_char = parsers.alphanumeric + S("-_") -parsers.attribute_key = (parsers.attribute_key_char - - parsers.dash - parsers.digit) - * parsers.attribute_key_char^0 -parsers.attribute_value = ( (parsers.dquote / "") - * (parsers.anyescaped - parsers.dquote)^0 - * (parsers.dquote / "")) - + ( (parsers.squote / "") - * (parsers.anyescaped - parsers.squote)^0 - * (parsers.squote / "")) - + ( parsers.anyescaped - parsers.dquote - parsers.rbrace - - parsers.space)^0 -parsers.attribute_identifier = parsers.attribute_key_char^1 -parsers.attribute_classname = parsers.letter - * parsers.attribute_key_char^0 -parsers.attribute_raw = parsers.attribute_raw_char^1 +parsers.commented_line = Cg(Cc(""), "backslashes") + * ((#(parsers.commented_line_letter + - parsers.newline) + * Cb("backslashes") + * Cs(parsers.commented_line_letter + - parsers.newline)^1 -- initial + * Cg(Cc(""), "backslashes")) + + #(parsers.backslash * parsers.backslash) + * Cg((parsers.backslash -- even backslash + * parsers.backslash)^1, "backslashes") + + (parsers.backslash + * (#parsers.percent + * Cb("backslashes") + / function(backslashes) + return string.rep("\\", #backslashes / 2) + end + * C(parsers.percent) + + #parsers.commented_line_letter + * Cb("backslashes") + * Cc("\\") + * C(parsers.commented_line_letter)) + * Cg(Cc(""), "backslashes")))^0 + * (#parsers.percent + * Cb("backslashes") + / function(backslashes) + return string.rep("\\", #backslashes / 2) + end + * ((parsers.percent -- comment + * parsers.line + * #parsers.blankline) -- blank line + / "\n" + + parsers.percent -- comment + * parsers.line + * parsers.optionalspace) -- leading spaces + + #(parsers.newline) + * Cb("backslashes") + * C(parsers.newline)) + +parsers.chunk = parsers.line * (parsers.optionallyindentedline + - parsers.blankline)^0 + +parsers.attribute_key_char = parsers.alphanumeric + S("-_:.") +parsers.attribute_raw_char = parsers.alphanumeric + S("-_") +parsers.attribute_key = (parsers.attribute_key_char + - parsers.dash - parsers.digit) + * parsers.attribute_key_char^0 +parsers.attribute_value = ( (parsers.dquote / "") + * (parsers.anyescaped - parsers.dquote)^0 + * (parsers.dquote / "")) + + ( (parsers.squote / "") + * (parsers.anyescaped - parsers.squote)^0 + * (parsers.squote / "")) + + ( parsers.anyescaped + - parsers.dquote + - parsers.rbrace + - parsers.space)^0 +parsers.attribute_identifier = parsers.attribute_key_char^1 +parsers.attribute_classname = parsers.letter + * parsers.attribute_key_char^0 +parsers.attribute_raw = parsers.attribute_raw_char^1 parsers.attribute = (parsers.dash * Cc(".unnumbered")) + C( parsers.hash @@ -27078,7 +27747,9 @@ parsers.attribute = (parsers.dash * Cc(".unnumbered")) + C( parsers.period * parsers.attribute_classname) + Cs( parsers.attribute_key - * parsers.optionalspace * parsers.equal * parsers.optionalspace + * parsers.optionalspace + * parsers.equal + * parsers.optionalspace * parsers.attribute_value) parsers.attributes = parsers.lbrace * parsers.optionalspace @@ -27088,7 +27759,6 @@ parsers.attributes = parsers.lbrace * parsers.optionalspace * parsers.rbrace - parsers.raw_attribute = parsers.lbrace * parsers.optionalspace * parsers.equal @@ -27100,7 +27770,10 @@ parsers.raw_attribute = parsers.lbrace -- indented blocks with first line indented. parsers.indented_blocks = function(bl) return Cs( bl - * (parsers.blankline^1 * parsers.indent * -parsers.blankline * bl)^0 + * ( parsers.blankline^1 + * parsers.indent + * -parsers.blankline + * bl)^0 * (parsers.blankline^1 + parsers.eof) ) end % \end{macrocode} @@ -27116,15 +27789,18 @@ local function repeat_between(pattern, min, max) end parsers.hexentity = parsers.ampersand * parsers.hash * C(S("Xx")) - * C(repeat_between(parsers.hexdigit, 1, 6)) * parsers.semicolon + * C(repeat_between(parsers.hexdigit, 1, 6)) + * parsers.semicolon parsers.decentity = parsers.ampersand * parsers.hash - * C(repeat_between(parsers.digit, 1, 7)) * parsers.semicolon + * C(repeat_between(parsers.digit, 1, 7)) + * parsers.semicolon parsers.tagentity = parsers.ampersand * C(parsers.alphanumeric^1) * parsers.semicolon -parsers.html_entities = parsers.hexentity / entities.hex_entity_with_x_char - + parsers.decentity / entities.dec_entity - + parsers.tagentity / entities.char_entity +parsers.html_entities + = parsers.hexentity / entities.hex_entity_with_x_char + + parsers.decentity / entities.dec_entity + + parsers.tagentity / entities.char_entity % \end{macrocode} % \par % \begin{markdown} @@ -27138,7 +27814,8 @@ parsers.bullet = function(bullet_char, interrupting) if interrupting then allowed_end = C(parsers.spacechar^1) * #parsers.linechar else - allowed_end = C(parsers.spacechar^1) + #(parsers.newline + parsers.eof) + allowed_end = C(parsers.spacechar^1) + + #(parsers.newline + parsers.eof) end return parsers.check_trail * Ct(C(bullet_char) * Cc("")) @@ -27196,7 +27873,8 @@ parsers.inticks = parsers.openticks % % \end{markdown} % \begin{macrocode} --- case-insensitive match (we assume s is lowercase). must be single byte encoding +-- case-insensitive match (we assume s is lowercase) +-- must be single byte encoding parsers.keyword_exact = function(s) local parser = P(0) for i=1,#s do @@ -27278,13 +27956,14 @@ parsers.block_keyword = parsers.keyword_exact("ul") -- end conditions -parsers.html_blankline_end_condition = parsers.linechar^0 - * ( parsers.newline - * (parsers.check_minimal_blank_indent_and_any_trail - * #parsers.blankline - + parsers.check_minimal_indent_and_any_trail) - * parsers.linechar^1)^0 - * (parsers.newline^-1 / "") +parsers.html_blankline_end_condition + = parsers.linechar^0 + * ( parsers.newline + * (parsers.check_minimal_blank_indent_and_any_trail + * #parsers.blankline + + parsers.check_minimal_indent_and_any_trail) + * parsers.linechar^1)^0 + * (parsers.newline^-1 / "") local function remove_trailing_blank_lines(s) return s:gsub("[\n\r]+%s*$", "") @@ -27306,9 +27985,14 @@ parsers.html_attribute_spacing = parsers.optionalspace * parsers.optionalspace + parsers.spacechar^1 -parsers.html_attribute_name = (parsers.letter + parsers.colon + parsers.underscore) - * (parsers.alphanumeric + parsers.colon + parsers.underscore - + parsers.period + parsers.dash)^0 +parsers.html_attribute_name = ( parsers.letter + + parsers.colon + + parsers.underscore) + * ( parsers.alphanumeric + + parsers.colon + + parsers.underscore + + parsers.period + + parsers.dash)^0 parsers.html_attribute_value = parsers.squote * (parsers.linechar - parsers.squote)^0 @@ -27316,9 +28000,15 @@ parsers.html_attribute_value = parsers.squote + parsers.dquote * (parsers.linechar - parsers.dquote)^0 * parsers.dquote - + ( parsers.any - parsers.spacechar - parsers.newline - - parsers.dquote - parsers.squote - parsers.backtick - - parsers.equal - parsers.less - parsers.more)^1 + + ( parsers.any + - parsers.spacechar + - parsers.newline + - parsers.dquote + - parsers.squote + - parsers.backtick + - parsers.equal + - parsers.less + - parsers.more)^1 parsers.html_inline_attribute_value = parsers.squote * (V("NoSoftLineBreakEndline") @@ -27332,30 +28022,41 @@ parsers.html_inline_attribute_value = parsers.squote - parsers.blankline^2 - parsers.dquote)^0 * parsers.dquote - + (parsers.any - parsers.spacechar - parsers.newline - - parsers.dquote - parsers.squote - parsers.backtick - - parsers.equal - parsers.less - parsers.more)^1 - -parsers.html_attribute_value_specification = parsers.optionalspace - * parsers.equal - * parsers.optionalspace - * parsers.html_attribute_value + + (parsers.any + - parsers.spacechar + - parsers.newline + - parsers.dquote + - parsers.squote + - parsers.backtick + - parsers.equal + - parsers.less + - parsers.more)^1 + +parsers.html_attribute_value_specification + = parsers.optionalspace + * parsers.equal + * parsers.optionalspace + * parsers.html_attribute_value parsers.html_spnl = parsers.optionalspace - * (V("NoSoftLineBreakEndline") * parsers.optionalspace)^-1 + * (V("NoSoftLineBreakEndline") + * parsers.optionalspace)^-1 -parsers.html_inline_attribute_value_specification = parsers.html_spnl - * parsers.equal - * parsers.html_spnl - * parsers.html_inline_attribute_value +parsers.html_inline_attribute_value_specification + = parsers.html_spnl + * parsers.equal + * parsers.html_spnl + * parsers.html_inline_attribute_value -parsers.html_attribute = parsers.html_attribute_spacing - * parsers.html_attribute_name - * parsers.html_inline_attribute_value_specification^-1 +parsers.html_attribute + = parsers.html_attribute_spacing + * parsers.html_attribute_name + * parsers.html_inline_attribute_value_specification^-1 -parsers.html_non_newline_attribute = parsers.spacechar^1 - * parsers.html_attribute_name - * parsers.html_attribute_value_specification^-1 +parsers.html_non_newline_attribute + = parsers.spacechar^1 + * parsers.html_attribute_name + * parsers.html_attribute_value_specification^-1 parsers.nested_breaking_blank = parsers.newline * parsers.check_minimal_blank_indent @@ -27365,49 +28066,59 @@ parsers.html_comment_start = P("<!--") parsers.html_comment_end = P("-->") -parsers.html_comment = Cs( parsers.html_comment_start - * parsers.html_until_end(parsers.html_comment_end)) +parsers.html_comment + = Cs( parsers.html_comment_start + * parsers.html_until_end(parsers.html_comment_end)) parsers.html_inline_comment = (parsers.html_comment_start / "") * -P(">") * -P("->") - * Cs((V("NoSoftLineBreakEndline") + parsers.any - - parsers.nested_breaking_blank - parsers.html_comment_end)^0) + * Cs(( V("NoSoftLineBreakEndline") + + parsers.any + - parsers.nested_breaking_blank + - parsers.html_comment_end)^0) * (parsers.html_comment_end / "") parsers.html_cdatasection_start = P("<![CDATA[") parsers.html_cdatasection_end = P("]]>") -parsers.html_cdatasection = Cs( parsers.html_cdatasection_start - * parsers.html_until_end(parsers.html_cdatasection_end)) +parsers.html_cdatasection + = Cs( parsers.html_cdatasection_start + * parsers.html_until_end(parsers.html_cdatasection_end)) -parsers.html_inline_cdatasection = parsers.html_cdatasection_start - * Cs(V("NoSoftLineBreakEndline") + parsers.any - - parsers.nested_breaking_blank - parsers.html_cdatasection_end)^0 - * parsers.html_cdatasection_end +parsers.html_inline_cdatasection + = parsers.html_cdatasection_start + * Cs(V("NoSoftLineBreakEndline") + parsers.any + - parsers.nested_breaking_blank - parsers.html_cdatasection_end)^0 + * parsers.html_cdatasection_end parsers.html_declaration_start = P("<!") * parsers.letter parsers.html_declaration_end = P(">") -parsers.html_declaration = Cs( parsers.html_declaration_start - * parsers.html_until_end(parsers.html_declaration_end)) +parsers.html_declaration + = Cs( parsers.html_declaration_start + * parsers.html_until_end(parsers.html_declaration_end)) -parsers.html_inline_declaration = parsers.html_declaration_start - * Cs(V("NoSoftLineBreakEndline") + parsers.any - - parsers.nested_breaking_blank - parsers.html_declaration_end)^0 - * parsers.html_declaration_end +parsers.html_inline_declaration + = parsers.html_declaration_start + * Cs(V("NoSoftLineBreakEndline") + parsers.any + - parsers.nested_breaking_blank - parsers.html_declaration_end)^0 + * parsers.html_declaration_end parsers.html_instruction_start = P("<?") parsers.html_instruction_end = P("?>") -parsers.html_instruction = Cs( parsers.html_instruction_start - * parsers.html_until_end(parsers.html_instruction_end)) +parsers.html_instruction + = Cs( parsers.html_instruction_start + * parsers.html_until_end(parsers.html_instruction_end)) parsers.html_inline_instruction = parsers.html_instruction_start - * Cs(V("NoSoftLineBreakEndline") + parsers.any - - parsers.nested_breaking_blank - parsers.html_instruction_end)^0 + * Cs( V("NoSoftLineBreakEndline") + + parsers.any + - parsers.nested_breaking_blank + - parsers.html_instruction_end)^0 * parsers.html_instruction_end parsers.html_blankline = parsers.newline @@ -27453,25 +28164,28 @@ parsers.incomplete_tag_following = parsers.spacechar + parsers.slash * parsers.more + #(parsers.newline + parsers.eof) -parsers.incomplete_special_tag_following = parsers.spacechar - + parsers.more - + #(parsers.newline + parsers.eof) +parsers.incomplete_special_tag_following = parsers.spacechar + + parsers.more + + #( parsers.newline + + parsers.eof) parsers.html_incomplete_open_tag = parsers.html_tag_start * parsers.block_keyword * parsers.incomplete_tag_following -parsers.html_incomplete_open_special_tag = parsers.html_tag_start - * parsers.special_block_keyword - * parsers.incomplete_special_tag_following +parsers.html_incomplete_open_special_tag + = parsers.html_tag_start + * parsers.special_block_keyword + * parsers.incomplete_special_tag_following parsers.html_incomplete_close_tag = parsers.html_tag_closing_start * parsers.block_keyword * parsers.incomplete_tag_following -parsers.html_incomplete_close_special_tag = parsers.html_tag_closing_start - * parsers.special_block_keyword - * parsers.incomplete_tag_following +parsers.html_incomplete_close_special_tag + = parsers.html_tag_closing_start + * parsers.special_block_keyword + * parsers.incomplete_tag_following -- closing tags parsers.html_close_tag = parsers.html_tag_closing_start @@ -27509,27 +28223,33 @@ parsers.html_empty_special_tag = parsers.html_tag_start * parsers.html_attribute^0 * parsers.html_empty_tag_end -parsers.html_incomplete_blocks = parsers.html_incomplete_open_tag - + parsers.html_incomplete_open_special_tag - + parsers.html_incomplete_close_tag +parsers.html_incomplete_blocks + = parsers.html_incomplete_open_tag + + parsers.html_incomplete_open_special_tag + + parsers.html_incomplete_close_tag -- parse special html blocks -parsers.html_blankline_ending_special_block_opening = (parsers.html_close_special_tag - + parsers.html_empty_special_tag) - * #(parsers.optionalspace - * (parsers.newline + parsers.eof)) +parsers.html_blankline_ending_special_block_opening + = ( parsers.html_close_special_tag + + parsers.html_empty_special_tag) + * #( parsers.optionalspace + * (parsers.newline + parsers.eof)) -parsers.html_blankline_ending_special_block = parsers.html_blankline_ending_special_block_opening - * parsers.html_blankline_end_condition +parsers.html_blankline_ending_special_block + = parsers.html_blankline_ending_special_block_opening + * parsers.html_blankline_end_condition -parsers.html_special_block_opening = parsers.html_incomplete_open_special_tag - - parsers.html_empty_special_tag +parsers.html_special_block_opening + = parsers.html_incomplete_open_special_tag + - parsers.html_empty_special_tag -parsers.html_closing_special_block = parsers.html_special_block_opening - * parsers.html_until_end(parsers.html_close_special_tag) +parsers.html_closing_special_block + = parsers.html_special_block_opening + * parsers.html_until_end(parsers.html_close_special_tag) -parsers.html_special_block = parsers.html_blankline_ending_special_block - + parsers.html_closing_special_block +parsers.html_special_block + = parsers.html_blankline_ending_special_block + + parsers.html_closing_special_block -- parse html blocks parsers.html_block_opening = parsers.html_incomplete_open_tag @@ -27539,18 +28259,21 @@ parsers.html_block = parsers.html_block_opening * parsers.html_blankline_end_condition -- parse any html blocks -parsers.html_any_block_opening = (parsers.html_any_open_tag - + parsers.html_any_close_tag - + parsers.html_any_empty_tag) - * #(parsers.optionalspace * (parsers.newline + parsers.eof)) +parsers.html_any_block_opening + = ( parsers.html_any_open_tag + + parsers.html_any_close_tag + + parsers.html_any_empty_tag) + * #(parsers.optionalspace * (parsers.newline + parsers.eof)) parsers.html_any_block = parsers.html_any_block_opening * parsers.html_blankline_end_condition parsers.html_inline_comment_full = parsers.html_comment_start * -P(">") * -P("->") - * Cs((V("NoSoftLineBreakEndline") + parsers.any - P("--") - - parsers.nested_breaking_blank - parsers.html_comment_end)^0) + * Cs(( V("NoSoftLineBreakEndline") + + parsers.any - P("--") + - parsers.nested_breaking_blank + - parsers.html_comment_end)^0) * parsers.html_comment_end parsers.html_inline_tags = parsers.html_inline_comment_full @@ -27583,21 +28306,25 @@ parsers.auto_link_scheme = parsers.letter * parsers.auto_link_scheme_part^-30 parsers.absolute_uri = parsers.auto_link_scheme * parsers.colon - * (parsers.any - parsers.spacing - parsers.less - parsers.more)^0 + * ( parsers.any - parsers.spacing + - parsers.less - parsers.more)^0 parsers.printable_characters = S(".!#$%&'*+/=?^_`{|}~-") parsers.email_address_local_part_char = parsers.alphanumeric + parsers.printable_characters -parsers.email_address_local_part = parsers.email_address_local_part_char^1 +parsers.email_address_local_part + = parsers.email_address_local_part_char^1 parsers.email_address_dns_label = parsers.alphanumeric - * (parsers.alphanumeric + parsers.dash)^-62 + * ( parsers.alphanumeric + + parsers.dash)^-62 * B(parsers.alphanumeric) parsers.email_address_domain = parsers.email_address_dns_label - * (parsers.period * parsers.email_address_dns_label)^0 + * ( parsers.period + * parsers.email_address_dns_label)^0 parsers.email_address = parsers.email_address_local_part * parsers.at @@ -27653,26 +28380,40 @@ parsers.link_text = parsers.lbracket + parsers.autolink + V("InlineHtml") + ( parsers.backslash * parsers.backslash) - + ( parsers.backslash * (parsers.lbracket + parsers.rbracket) + + ( parsers.backslash + * ( parsers.lbracket + + parsers.rbracket) + V("NoSoftLineBreakSpace") + V("NoSoftLineBreakEndline") + (parsers.any - - (parsers.newline + parsers.lbracket + parsers.rbracket + parsers.blankline^2))))^0) + - ( parsers.newline + + parsers.lbracket + + parsers.rbracket + + parsers.blankline^2))))^0) * parsers.rbracket +parsers.link_label_body = -#(parsers.sp * parsers.rbracket) + * #( ( parsers.any + - parsers.rbracket)^-999 + * parsers.rbracket) + * Cs((parsers.alphanumeric^1 + + parsers.inticks + + parsers.autolink + + V("InlineHtml") + + ( parsers.backslash * parsers.backslash) + + ( parsers.backslash + * ( parsers.lbracket + + parsers.rbracket) + + V("NoSoftLineBreakSpace") + + V("NoSoftLineBreakEndline") + + (parsers.any + - ( parsers.newline + + parsers.lbracket + + parsers.rbracket + + parsers.blankline^2))))^1) + parsers.link_label = parsers.lbracket - * -#(parsers.sp * parsers.rbracket) - * #((parsers.any - parsers.rbracket)^-999 * parsers.rbracket) - * Cs((parsers.alphanumeric^1 - + parsers.inticks - + parsers.autolink - + V("InlineHtml") - + ( parsers.backslash * parsers.backslash) - + ( parsers.backslash * (parsers.lbracket + parsers.rbracket) - + V("NoSoftLineBreakSpace") - + V("NoSoftLineBreakEndline") - + (parsers.any - - (parsers.newline + parsers.lbracket + parsers.rbracket + parsers.blankline^2))))^1) + * parsers.link_label_body * parsers.rbracket parsers.inparens_url = P{ parsers.lparent @@ -27699,29 +28440,38 @@ parsers.title_s = parsers.squote * Cs((parsers.html_entities + V("NoSoftLineBreakSpace") + V("NoSoftLineBreakEndline") - + (parsers.anyescaped - parsers.newline - parsers.squote - parsers.blankline^2))^0) + + ( parsers.anyescaped + - parsers.newline + - parsers.squote + - parsers.blankline^2))^0) * parsers.squote parsers.title_d = parsers.dquote * Cs((parsers.html_entities + V("NoSoftLineBreakSpace") + V("NoSoftLineBreakEndline") - + (parsers.anyescaped - parsers.newline - parsers.dquote - parsers.blankline^2))^0) + + ( parsers.anyescaped + - parsers.newline + - parsers.dquote + - parsers.blankline^2))^0) * parsers.dquote parsers.title_p = parsers.lparent * Cs((parsers.html_entities + V("NoSoftLineBreakSpace") + V("NoSoftLineBreakEndline") - + (parsers.anyescaped - parsers.newline - parsers.lparent - parsers.rparent + + ( parsers.anyescaped + - parsers.newline + - parsers.lparent + - parsers.rparent - parsers.blankline^2))^0) * parsers.rparent -parsers.title = parsers.title_d + parsers.title_s + parsers.title_p +parsers.title + = parsers.title_d + parsers.title_s + parsers.title_p parsers.optionaltitle - = parsers.spnlc * parsers.title * parsers.spacechar^0 - + Cc("") + = parsers.spnlc * parsers.title * parsers.spacechar^0 + Cc("") % \end{macrocode} % \par @@ -27732,9 +28482,11 @@ parsers.optionaltitle % \end{markdown} % \begin{macrocode} -- parse a reference definition: [foo]: /bar "title" -parsers.define_reference_parser = (parsers.check_trail / "") * parsers.link_label * parsers.colon +parsers.define_reference_parser = (parsers.check_trail / "") + * parsers.link_label * parsers.colon * parsers.spnlc * parsers.url - * ( parsers.spnlc_sep * parsers.title * parsers.only_blank + * ( parsers.spnlc_sep * parsers.title + * parsers.only_blank + Cc("") * parsers.only_blank) % \end{macrocode} % \par @@ -27749,7 +28501,10 @@ parsers.Inline = V("Inline") -- parse many p between starter and ender parsers.between = function(p, starter, ender) local ender2 = B(parsers.nonspacechar) * ender - return (starter * #parsers.nonspacechar * Ct(p * (p - ender2)^0) * ender2) + return ( starter + * #parsers.nonspacechar + * Ct(p * (p - ender2)^0) + * ender2) end % \end{macrocode} @@ -27761,7 +28516,8 @@ end % \end{markdown} % \begin{macrocode} parsers.lineof = function(c) - return (parsers.check_trail_no_rem * (P(c) * parsers.optionalspace)^3 + return ( parsers.check_trail_no_rem + * (P(c) * parsers.optionalspace)^3 * (parsers.newline + parsers.eof)) end @@ -27781,8 +28537,11 @@ parsers.heading_start = #parsers.hash * C(parsers.hash^-6) * -parsers.hash / length -- parse setext header ending and return level -parsers.heading_level = parsers.nonindentspace * parsers.equal^1 * parsers.optionalspace * #parsers.newline * Cc(1) - + parsers.nonindentspace * parsers.dash^1 * parsers.optionalspace * #parsers.newline * Cc(2) +parsers.heading_level + = parsers.nonindentspace * parsers.equal^1 + * parsers.optionalspace * #parsers.newline * Cc(1) + + parsers.nonindentspace * parsers.dash^1 + * parsers.optionalspace * #parsers.newline * Cc(2) local function strip_atx_end(s) return s:gsub("%s+#*%s*\n$","") @@ -27954,9 +28713,11 @@ function M.reader.new(writer, options) local prefix = lpeg.match(C(parsers.optionalspace), line) local prefix_length = #prefix local is_shorter = min_prefix_length == nil - is_shorter = is_shorter or prefix_length < min_prefix_length + if not is_shorter then + is_shorter = prefix_length < min_prefix_length + end if is_shorter then - min_prefix_length, min_prefix = prefix_length, prefix + min_prefix_length, min_prefix = prefix_length, prefix end return line end) @@ -27978,7 +28739,8 @@ function M.reader.new(writer, options) end local res = lpeg.match(grammar(), str) if res == nil then - error(format("%s failed on:\n%s", name, str:sub(1,20))) + return writer.error(format("%s failed on:\n%s", + name, str:sub(1,20))) else return res end @@ -28028,35 +28790,47 @@ function M.reader.new(writer, options) % % \end{markdown} % \begin{macrocode} - parsers.minimally_indented_blankline = parsers.check_minimal_indent * (parsers.blankline / "") + parsers.minimally_indented_blankline + = parsers.check_minimal_indent * (parsers.blankline / "") - parsers.minimally_indented_block = parsers.check_minimal_indent * V("Block") + parsers.minimally_indented_block + = parsers.check_minimal_indent * V("Block") - parsers.minimally_indented_block_or_paragraph = parsers.check_minimal_indent * V("BlockOrParagraph") + parsers.minimally_indented_block_or_paragraph + = parsers.check_minimal_indent * V("BlockOrParagraph") - parsers.minimally_indented_paragraph = parsers.check_minimal_indent * V("Paragraph") + parsers.minimally_indented_paragraph + = parsers.check_minimal_indent * V("Paragraph") - parsers.minimally_indented_plain = parsers.check_minimal_indent * V("Plain") + parsers.minimally_indented_plain + = parsers.check_minimal_indent * V("Plain") - parsers.minimally_indented_par_or_plain = parsers.minimally_indented_paragraph - + parsers.minimally_indented_plain + parsers.minimally_indented_par_or_plain + = parsers.minimally_indented_paragraph + + parsers.minimally_indented_plain - parsers.minimally_indented_par_or_plain_no_blank = parsers.minimally_indented_par_or_plain - - parsers.minimally_indented_blankline + parsers.minimally_indented_par_or_plain_no_blank + = parsers.minimally_indented_par_or_plain + - parsers.minimally_indented_blankline - parsers.minimally_indented_ref = parsers.check_minimal_indent * V("Reference") + parsers.minimally_indented_ref + = parsers.check_minimal_indent * V("Reference") - parsers.minimally_indented_blank = parsers.check_minimal_indent * V("Blank") + parsers.minimally_indented_blank + = parsers.check_minimal_indent * V("Blank") - parsers.conditionally_indented_blankline = parsers.check_minimal_blank_indent * (parsers.blankline / "") + parsers.conditionally_indented_blankline + = parsers.check_minimal_blank_indent * (parsers.blankline / "") - parsers.minimally_indented_ref_or_block = parsers.minimally_indented_ref - + parsers.minimally_indented_block - - parsers.minimally_indented_blankline + parsers.minimally_indented_ref_or_block + = parsers.minimally_indented_ref + + parsers.minimally_indented_block + - parsers.minimally_indented_blankline - parsers.minimally_indented_ref_or_block_or_par = parsers.minimally_indented_ref - + parsers.minimally_indented_block_or_paragraph - - parsers.minimally_indented_blankline + parsers.minimally_indented_ref_or_block_or_par + = parsers.minimally_indented_ref + + parsers.minimally_indented_block_or_paragraph + - parsers.minimally_indented_blankline % \end{macrocode} % \begin{markdown} @@ -28066,7 +28840,8 @@ function M.reader.new(writer, options) % \end{markdown} % \begin{macrocode} - parsers.separator_loop = function(separated_block, paragraph, block_separator, paragraph_separator) + function parsers.separator_loop(separated_block, paragraph, + block_separator, paragraph_separator) return separated_block + block_separator * paragraph @@ -28075,10 +28850,14 @@ function M.reader.new(writer, options) * paragraph end - parsers.create_loop_body_pair = function(separated_block, paragraph, block_separator, paragraph_separator) + function parsers.create_loop_body_pair(separated_block, paragraph, + block_separator, + paragraph_separator) return { - block = parsers.separator_loop(separated_block, paragraph, block_separator, block_separator), - par = parsers.separator_loop(separated_block, paragraph, block_separator, paragraph_separator) + block = parsers.separator_loop(separated_block, paragraph, + block_separator, block_separator), + par = parsers.separator_loop(separated_block, paragraph, + block_separator, paragraph_separator) } end @@ -28101,18 +28880,20 @@ function M.reader.new(writer, options) parsers.content_blank = parsers.minimally_indented_blankline - parsers.ref_or_block_separated = parsers.sep_group_no_output(parsers.content_blank) - * ( parsers.minimally_indented_ref - - parsers.content_blank) - + parsers.block_sep_group(parsers.content_blank) - * ( parsers.minimally_indented_block - - parsers.content_blank) + parsers.ref_or_block_separated + = parsers.sep_group_no_output(parsers.content_blank) + * ( parsers.minimally_indented_ref + - parsers.content_blank) + + parsers.block_sep_group(parsers.content_blank) + * ( parsers.minimally_indented_block + - parsers.content_blank) parsers.loop_body_pair = - parsers.create_loop_body_pair(parsers.ref_or_block_separated, - parsers.minimally_indented_par_or_plain_no_blank, - parsers.block_sep_group(parsers.content_blank), - parsers.par_sep_group(parsers.content_blank)) + parsers.create_loop_body_pair( + parsers.ref_or_block_separated, + parsers.minimally_indented_par_or_plain_no_blank, + parsers.block_sep_group(parsers.content_blank), + parsers.par_sep_group(parsers.content_blank)) parsers.content_loop = ( V("Block") * parsers.loop_body_pair.block^0 @@ -28136,7 +28917,8 @@ function M.reader.new(writer, options) parsers.add_indent = function(pattern, name, breakable) return Cg(Cmt( Cb("indent_info") * Ct(pattern) - * (#parsers.linechar * Cc(false) + Cc(true)) -- check if starter is blank + * ( #parsers.linechar -- check if starter is blank + * Cc(false) + Cc(true)) * Cc(name) * Cc(breakable), process_starter_indent), "indent_info") @@ -28164,7 +28946,8 @@ function M.reader.new(writer, options) allowed_end = C(parsers.spacechar^1) * #parsers.linechar else delimiter_range = parsers.dig * parsers.dig^-8 - allowed_end = C(parsers.spacechar^1) + #(parsers.newline + parsers.eof) + allowed_end = C(parsers.spacechar^1) + + #(parsers.newline + parsers.eof) end return parsers.check_trail @@ -28186,16 +28969,21 @@ function M.reader.new(writer, options) % % \end{markdown} % \begin{macrocode} - parsers.blockquote_start = parsers.check_trail * C(parsers.more) * C(parsers.spacechar^0) + parsers.blockquote_start + = parsers.check_trail + * C(parsers.more) + * C(parsers.spacechar^0) - parsers.blockquote_body = parsers.add_indent(parsers.blockquote_start, "bq", true) - * parsers.indented_content() - * remove_indent("bq") + parsers.blockquote_body + = parsers.add_indent(parsers.blockquote_start, "bq", true) + * parsers.indented_content() + * remove_indent("bq") if not options.breakableBlockquotes then - parsers.blockquote_body = parsers.add_indent(parsers.blockquote_start, "bq", false) - * parsers.indented_content() - * remove_indent("bq") + parsers.blockquote_body + = parsers.add_indent(parsers.blockquote_start, "bq", false) + * parsers.indented_content() + * remove_indent("bq") end % \end{macrocode} % \par @@ -28209,7 +28997,8 @@ function M.reader.new(writer, options) % \begin{macrocode} local function parse_content_part(content_part) local rope = util.rope_to_string(content_part) - local parsed = self.parser_functions.parse_inlines_no_link_or_emphasis(rope) + local parsed + = self.parser_functions.parse_inlines_no_link_or_emphasis(rope) parsed.indent_info = nil return parsed end @@ -28221,37 +29010,40 @@ function M.reader.new(writer, options) % % \end{markdown} % \begin{macrocode} - local function collect_emphasis_content(t, opening_index, closing_index) - local content = {} + local collect_emphasis_content = + function(t, opening_index, closing_index) + local content = {} - local content_part = {} - for i = opening_index, closing_index do - local value = t[i] + local content_part = {} + for i = opening_index, closing_index do + local value = t[i] - if value.rendered ~= nil then - content[#content + 1] = parse_content_part(content_part) - content_part = {} - content[#content + 1] = value.rendered - value.rendered = nil - else - if value.type == "delimiter" and value.element == "emphasis" then - if value.is_active then - content_part[#content_part + 1] = string.rep(value.character, value.current_count) - end + if value.rendered ~= nil then + content[#content + 1] = parse_content_part(content_part) + content_part = {} + content[#content + 1] = value.rendered + value.rendered = nil else - content_part[#content_part + 1] = value.content + if value.type == "delimiter" + and value.element == "emphasis" then + if value.is_active then + content_part[#content_part + 1] + = string.rep(value.character, value.current_count) + end + else + content_part[#content_part + 1] = value.content + end + value.content = '' + value.is_active = false end - value.content = '' - value.is_active = false end - end - if next(content_part) ~= nil then - content[#content + 1] = parse_content_part(content_part) - end + if next(content_part) ~= nil then + content[#content + 1] = parse_content_part(content_part) + end - return content - end + return content + end % \end{macrocode} % \begin{markdown} @@ -28262,7 +29054,9 @@ function M.reader.new(writer, options) % \end{markdown} % \begin{macrocode} local function fill_emph(t, opening_index, closing_index) - local content = collect_emphasis_content(t, opening_index + 1, closing_index - 1) + local content + = collect_emphasis_content(t, opening_index + 1, + closing_index - 1) t[opening_index + 1].is_active = true t[opening_index + 1].rendered = writer.emphasis(content) end @@ -28276,7 +29070,9 @@ function M.reader.new(writer, options) % \end{markdown} % \begin{macrocode} local function fill_strong(t, opening_index, closing_index) - local content = collect_emphasis_content(t, opening_index + 1, closing_index - 1) + local content + = collect_emphasis_content(t, opening_index + 1, + closing_index - 1) t[opening_index + 1].is_active = true t[opening_index + 1].rendered = writer.strong(content) end @@ -28290,9 +29086,12 @@ function M.reader.new(writer, options) % \end{markdown} % \begin{macrocode} local function breaks_three_rule(opening_delimiter, closing_delimiter) - return (opening_delimiter.is_closing or closing_delimiter.is_opening) and - ((opening_delimiter.original_count + closing_delimiter.original_count) % 3 == 0) and - (opening_delimiter.original_count % 3 ~= 0 or closing_delimiter.original_count % 3 ~= 0) + return ( opening_delimiter.is_closing + or closing_delimiter.is_opening) + and (( opening_delimiter.original_count + + closing_delimiter.original_count) % 3 == 0) + and ( opening_delimiter.original_count % 3 ~= 0 + or closing_delimiter.original_count % 3 ~= 0) end % \end{macrocode} @@ -28304,7 +29103,8 @@ function M.reader.new(writer, options) % % \end{markdown} % \begin{macrocode} - local function find_emphasis_opener(t, bottom_index, latest_index, character, closing_delimiter) + local find_emphasis_opener = function(t, bottom_index, latest_index, + character, closing_delimiter) for i = latest_index, bottom_index, -1 do local value = t[i] if value.is_active and @@ -28368,12 +29168,18 @@ function M.reader.new(writer, options) local is_opening = value.is_opening local closing_length_modulo_three = value.original_count % 3 - local current_openers_bottom = openers_bottom[character][is_opening][closing_length_modulo_three + 1] + local current_openers_bottom + = openers_bottom[character][is_opening] + [closing_length_modulo_three + 1] - local opener_position = find_emphasis_opener(t, current_openers_bottom, current_position - 1, character, value) + local opener_position + = find_emphasis_opener(t, current_openers_bottom, + current_position - 1, character, value) if (opener_position == nil) then - openers_bottom[character][is_opening][closing_length_modulo_three + 1] = current_position + openers_bottom[character][is_opening] + [closing_length_modulo_three + 1] + = current_position current_position = current_position + 1 goto continue end @@ -28383,7 +29189,8 @@ function M.reader.new(writer, options) local current_opening_count = opening_delimiter.current_count local current_closing_count = t[current_position].current_count - if (current_opening_count >= 2) and (current_closing_count >= 2) then + if (current_opening_count >= 2) + and (current_closing_count >= 2) then opening_delimiter.current_count = current_opening_count - 2 t[current_position].current_count = current_closing_count - 2 fill_strong(t, opener_position, current_position) @@ -28467,15 +29274,19 @@ function M.reader.new(writer, options) return check_unicode_type(s, i, 0, 3, "%s") end - parsers.unicode_preceding_punctuation = B(parsers.escapable) - + Cmt(parsers.succeed, check_preceding_unicode_punctuation) + parsers.unicode_preceding_punctuation + = B(parsers.escapable) + + Cmt(parsers.succeed, check_preceding_unicode_punctuation) - parsers.unicode_preceding_whitespace = Cmt(parsers.succeed, check_preceding_unicode_whitespace) + parsers.unicode_preceding_whitespace + = Cmt(parsers.succeed, check_preceding_unicode_whitespace) - parsers.unicode_following_punctuation = #parsers.escapable - + Cmt(parsers.succeed, check_following_unicode_punctuation) + parsers.unicode_following_punctuation + = #parsers.escapable + + Cmt(parsers.succeed, check_following_unicode_punctuation) - parsers.unicode_following_whitespace = Cmt(parsers.succeed, check_following_unicode_whitespace) + parsers.unicode_following_whitespace + = Cmt(parsers.succeed, check_following_unicode_whitespace) parsers.delimiter_run = function(character) return (B(parsers.backslash * character) + -B(character)) @@ -28485,49 +29296,58 @@ function M.reader.new(writer, options) parsers.left_flanking_delimiter_run = function(character) return (B( parsers.any) - * (parsers.unicode_preceding_punctuation + parsers.unicode_preceding_whitespace) + * ( parsers.unicode_preceding_punctuation + + parsers.unicode_preceding_whitespace) + -B(parsers.any)) * parsers.delimiter_run(character) * parsers.unicode_following_punctuation + parsers.delimiter_run(character) - * -#(parsers.unicode_following_punctuation + parsers.unicode_following_whitespace + * -#( parsers.unicode_following_punctuation + + parsers.unicode_following_whitespace + parsers.eof) end parsers.right_flanking_delimiter_run = function(character) return parsers.unicode_preceding_punctuation * parsers.delimiter_run(character) - * (parsers.unicode_following_punctuation + parsers.unicode_following_whitespace + * ( parsers.unicode_following_punctuation + + parsers.unicode_following_whitespace + parsers.eof) + (B(parsers.any) - * -(parsers.unicode_preceding_punctuation + parsers.unicode_preceding_whitespace)) + * -( parsers.unicode_preceding_punctuation + + parsers.unicode_preceding_whitespace)) * parsers.delimiter_run(character) end if options.underscores then - parsers.emph_start = parsers.left_flanking_delimiter_run(parsers.asterisk) - + (-#parsers.right_flanking_delimiter_run(parsers.underscore) - + (parsers.unicode_preceding_punctuation - * #parsers.right_flanking_delimiter_run(parsers.underscore))) - * parsers.left_flanking_delimiter_run(parsers.underscore) - - parsers.emph_end = parsers.right_flanking_delimiter_run(parsers.asterisk) - + (-#parsers.left_flanking_delimiter_run(parsers.underscore) - + #(parsers.left_flanking_delimiter_run(parsers.underscore) - * parsers.unicode_following_punctuation)) - * parsers.right_flanking_delimiter_run(parsers.underscore) + parsers.emph_start + = parsers.left_flanking_delimiter_run(parsers.asterisk) + + ( -#parsers.right_flanking_delimiter_run(parsers.underscore) + + ( parsers.unicode_preceding_punctuation + * #parsers.right_flanking_delimiter_run(parsers.underscore))) + * parsers.left_flanking_delimiter_run(parsers.underscore) + + parsers.emph_end + = parsers.right_flanking_delimiter_run(parsers.asterisk) + + ( -#parsers.left_flanking_delimiter_run(parsers.underscore) + + #( parsers.left_flanking_delimiter_run(parsers.underscore) + * parsers.unicode_following_punctuation)) + * parsers.right_flanking_delimiter_run(parsers.underscore) else - parsers.emph_start = parsers.left_flanking_delimiter_run(parsers.asterisk) + parsers.emph_start + = parsers.left_flanking_delimiter_run(parsers.asterisk) - parsers.emph_end = parsers.right_flanking_delimiter_run(parsers.asterisk) + parsers.emph_end + = parsers.right_flanking_delimiter_run(parsers.asterisk) end - parsers.emph_capturing_open_and_close = #parsers.emph_start * #parsers.emph_end - * Ct( Cg(Cc("delimiter"), "type") - * Cg(Cc("emphasis"), "element") - * Cg(C(parsers.emph_start), "content") - * Cg(Cc(true), "is_opening") - * Cg(Cc(true), "is_closing")) + parsers.emph_capturing_open_and_close + = #parsers.emph_start * #parsers.emph_end + * Ct( Cg(Cc("delimiter"), "type") + * Cg(Cc("emphasis"), "element") + * Cg(C(parsers.emph_start), "content") + * Cg(Cc(true), "is_opening") + * Cg(Cc(true), "is_closing")) parsers.emph_capturing_open = Ct( Cg(Cc("delimiter"), "type") * Cg(Cc("emphasis"), "element") @@ -28562,6 +29382,9 @@ function M.reader.new(writer, options) -- List of references defined in the document local references + -- List of note references defined in the document + parsers.rawnotes = {} + % \end{macrocode} % \par % \begin{markdown} @@ -28599,19 +29422,39 @@ function M.reader.new(writer, options) return references[self.normalize_tag(tag)] end +% \end{macrocode} +% \par +% \begin{markdown} +% +% The \luamdef{reader->lookup_note_reference} method looks up a +% note reference with label `tag`. +% +% \end{markdown} +% \begin{macrocode} + function self.lookup_note_reference(tag) + return parsers.rawnotes[self.normalize_tag(tag)] + end + parsers.title_s_direct_ref = parsers.squote * Cs((parsers.html_entities - + (parsers.anyescaped - parsers.squote - parsers.blankline^2))^0) + + ( parsers.anyescaped + - parsers.squote + - parsers.blankline^2))^0) * parsers.squote parsers.title_d_direct_ref = parsers.dquote * Cs((parsers.html_entities - + (parsers.anyescaped - parsers.dquote - parsers.blankline^2))^0) + + ( parsers.anyescaped + - parsers.dquote + - parsers.blankline^2))^0) * parsers.dquote parsers.title_p_direct_ref = parsers.lparent * Cs((parsers.html_entities - + (parsers.anyescaped - parsers.lparent - parsers.rparent - parsers.blankline^2))^0) + + ( parsers.anyescaped + - parsers.lparent + - parsers.rparent + - parsers.blankline^2))^0) * parsers.rparent parsers.title_direct_ref = parsers.title_s_direct_ref @@ -28621,7 +29464,8 @@ function M.reader.new(writer, options) parsers.inline_direct_ref_inside = parsers.lparent * parsers.spnl * Cg(parsers.url + Cc(""), "url") * parsers.spnl - * Cg(parsers.title_direct_ref + Cc(""), "title") + * Cg( parsers.title_direct_ref + + Cc(""), "title") * parsers.spnl * parsers.rparent parsers.inline_direct_ref = parsers.lparent * parsers.spnlc @@ -28649,7 +29493,8 @@ function M.reader.new(writer, options) * Cg(Cc("inline"), "link_type") + #(parsers.exclamation * parsers.full_link) * Cg(Cc("full"), "link_type") - + #(parsers.exclamation * parsers.collapsed_link) + + #( parsers.exclamation + * parsers.collapsed_link) * Cg(Cc("collapsed"), "link_type") + #(parsers.exclamation * parsers.shortcut_link) * Cg(Cc("shortcut"), "link_type") @@ -28669,22 +29514,61 @@ function M.reader.new(writer, options) + #parsers.link_text * Cg(Cc("link_text"), "link_type") + parsers.note_opening = #(parsers.circumflex * parsers.link_text) + * Cg(Cc("note_inline"), "link_type") + + parsers.raw_note_opening = #( parsers.lbracket + * parsers.circumflex + * parsers.link_label_body + * parsers.rbracket) + * Cg(Cc("raw_note"), "link_type") + + local inline_note_element = Cg(Cc("note"), "element") + * parsers.note_opening + * Cg( parsers.circumflex + * parsers.lbracket, "content") + + local image_element = Cg(Cc("image"), "element") + * parsers.image_opening + * Cg( parsers.exclamation + * parsers.lbracket, "content") + + local note_element = Cg(Cc("note"), "element") + * parsers.raw_note_opening + * Cg( parsers.lbracket + * parsers.circumflex, "content") + + local link_element = Cg(Cc("link"), "element") + * parsers.link_opening + * Cg(parsers.lbracket, "content") + + local opening_elements = parsers.fail + + if options.inlineNotes then + opening_elements = opening_elements + inline_note_element + end + + opening_elements = opening_elements + image_element + + if options.notes then + opening_elements = opening_elements + note_element + end + + opening_elements = opening_elements + link_element + parsers.link_image_opening = Ct( Cg(Cc("delimiter"), "type") * Cg(Cc(true), "is_opening") * Cg(Cc(false), "is_closing") - * ( Cg(Cc("image"), "element") - * parsers.image_opening - * Cg(parsers.exclamation * parsers.lbracket, "content") - + Cg(Cc("link"), "element") - * parsers.link_opening - * Cg(parsers.lbracket, "content"))) + * opening_elements) parsers.link_image_closing = Ct( Cg(Cc("delimiter"), "type") * Cg(Cc("link"), "element") * Cg(Cc(false), "is_opening") * Cg(Cc(true), "is_closing") * ( Cg(Cc(true), "is_direct") - * Cg(parsers.rbracket * #parsers.inline_direct_ref, "content") + * Cg( parsers.rbracket + * #parsers.inline_direct_ref, + "content") + Cg(Cc(false), "is_direct") * Cg(parsers.rbracket, "content"))) @@ -28708,19 +29592,21 @@ function M.reader.new(writer, options) * -parsers.starter) / "") * parsers.spacechar^0 / "\n" - parsers.link_and_emph_content = Ct( Cg(Cc("content"), "type") - * Cg(Cs(( parsers.link_emph_precedence - + parsers.backslash * parsers.any - + parsers.link_and_emph_endline - + (parsers.linechar - - parsers.blankline^2 - - parsers.link_image_open_or_close - - parsers.emph_open_or_close))^0), "content")) + parsers.link_and_emph_content + = Ct( Cg(Cc("content"), "type") + * Cg(Cs(( parsers.link_emph_precedence + + parsers.backslash * parsers.any + + parsers.link_and_emph_endline + + (parsers.linechar + - parsers.blankline^2 + - parsers.link_image_open_or_close + - parsers.emph_open_or_close))^0), "content")) - parsers.link_and_emph_table = (parsers.link_image_opening + parsers.emph_open) - * parsers.link_and_emph_content - * ((parsers.link_image_open_or_close + parsers.emph_open_or_close) - * parsers.link_and_emph_content)^1 + parsers.link_and_emph_table + = (parsers.link_image_opening + parsers.emph_open) + * parsers.link_and_emph_content + * ((parsers.link_image_open_or_close + parsers.emph_open_or_close) + * parsers.link_and_emph_content)^1 % \end{macrocode} % \begin{markdown} @@ -28750,7 +29636,9 @@ function M.reader.new(writer, options) local value = t[i] if value.type == "delimiter" and value.is_opening and - (value.element == "link" or value.element == "image") + ( value.element == "link" + or value.element == "image" + or value.element == "note") and not value.removed then if value.is_active then return i @@ -28831,11 +29719,12 @@ function M.reader.new(writer, options) % % \end{markdown} % \begin{macrocode} - local function delete_parsed_content_in_range(t, opening_index, closing_index) - for i = opening_index, closing_index do - t[i].rendered = nil + local delete_parsed_content_in_range = + function(t, opening_index, closing_index) + for i = opening_index, closing_index do + t[i].rendered = nil + end end - end % \end{macrocode} % \begin{markdown} @@ -28880,25 +29769,40 @@ function M.reader.new(writer, options) % % \end{markdown} % \begin{macrocode} - local function render_link_or_image(t, opening_index, closing_index, content_end_index, reference) - process_emphasis(t, opening_index, content_end_index) - local mapped = collect_emphasis_content(t, opening_index + 1, content_end_index - 1) + local render_link_or_image = + function(t, opening_index, closing_index, content_end_index, + reference) + process_emphasis(t, opening_index, content_end_index) + local mapped = collect_emphasis_content(t, opening_index + 1, + content_end_index - 1) - local rendered = {} - if (t[opening_index].element == "link") then - rendered = writer.link(mapped, reference.url, reference.title, reference.attributes) - end + local rendered = {} + if (t[opening_index].element == "link") then + rendered = writer.link(mapped, reference.url, + reference.title, reference.attributes) + end - if (t[opening_index].element == "image") then - rendered = writer.image(mapped, reference.url, reference.title, reference.attributes) - end + if (t[opening_index].element == "image") then + rendered = writer.image(mapped, reference.url, reference.title, + reference.attributes) + end - t[opening_index].rendered = rendered - delete_parsed_content_in_range(t, opening_index + 1, closing_index) - empty_content_in_range(t, opening_index, closing_index) - disable_previous_link_openers(t, opening_index) - disable_range(t, opening_index, closing_index) - end + if (t[opening_index].element == "note") then + if (t[opening_index].link_type == "note_inline") then + rendered = writer.note(mapped) + end + if (t[opening_index].link_type == "raw_note") then + rendered = writer.note(reference) + end + end + + t[opening_index].rendered = rendered + delete_parsed_content_in_range(t, opening_index + 1, + closing_index) + empty_content_in_range(t, opening_index, closing_index) + disable_previous_link_openers(t, opening_index) + disable_range(t, opening_index, closing_index) + end % \end{macrocode} % \begin{markdown} @@ -28909,123 +29813,185 @@ function M.reader.new(writer, options) % % \end{markdown} % \begin{macrocode} - local function resolve_inline_following_content(t, closing_index, match_reference, match_link_attributes) - local content = "" - for i = closing_index + 1, #t do - content = content .. t[i].content - end + local resolve_inline_following_content = + function(t, closing_index, match_reference, match_link_attributes) + local content = "" + for i = closing_index + 1, #t do + content = content .. t[i].content + end - local matching_content = parsers.succeed + local matching_content = parsers.succeed - if match_reference then - matching_content = matching_content * parsers.inline_direct_ref_inside - end + if match_reference then + matching_content = matching_content + * parsers.inline_direct_ref_inside + end - if match_link_attributes then - matching_content = matching_content * Cg(Ct(parsers.attributes^-1), "attributes") - end + if match_link_attributes then + matching_content = matching_content + * Cg(Ct(parsers.attributes^-1), "attributes") + end - local matched = lpeg.match(Ct(matching_content * Cg(Cp(), "end_position")), content) + local matched = lpeg.match(Ct( matching_content + * Cg(Cp(), "end_position")), content) - local matched_count = matched.end_position - 1 - for i = closing_index + 1, #t do - local value = t[i] + local matched_count = matched.end_position - 1 + for i = closing_index + 1, #t do + local value = t[i] - local chars_left = matched_count - matched_count = matched_count - #value.content + local chars_left = matched_count + matched_count = matched_count - #value.content - if matched_count <= 0 then - value.content = value.content:sub(chars_left + 1) - break + if matched_count <= 0 then + value.content = value.content:sub(chars_left + 1) + break + end + + value.content = '' + value.is_active = false end - value.content = '' - value.is_active = false - end + local attributes = matched.attributes + if attributes == nil or next(attributes) == nil then + attributes = nil + end - local attributes = matched.attributes - if attributes == nil or next(attributes) == nil then - attributes = nil + return { + url = matched.url or "", + title = matched.title or "", + attributes = attributes + } end - return { - url = matched.url or "", - title = matched.title or "", - attributes = attributes - } - end - % \end{macrocode} % \begin{markdown} % -% Resolve an inline link [a](b "c") from the delimiters at `opening_index` and `closing_index` +% Resolve an inline link `[a](b "c")` from the delimiters at `opening_index` and `closing_index` % within a delimiter table `t`. Here, compared to other types of links, no reference definition is needed. % % \end{markdown} % \begin{macrocode} local function resolve_inline_link(t, opening_index, closing_index) - local inline_content = resolve_inline_following_content(t, closing_index, true, t.match_link_attributes) - render_link_or_image(t, opening_index, closing_index, closing_index, inline_content) + local inline_content + = resolve_inline_following_content(t, closing_index, true, + t.match_link_attributes) + render_link_or_image(t, opening_index, closing_index, + closing_index, inline_content) end % \end{macrocode} % \begin{markdown} % -% Resolve a shortcut link [a] from the delimiters at `opening_index` and `closing_index` within a delimiter table `t`. +% Resolve an inline note `^[a]` from the delimiters at `opening_index` and `closing_index` +% within a delimiter table `t`. +% +% \end{markdown} +% \begin{macrocode} + local resolve_note_inline_link = + function(t, opening_index, closing_index) + local inline_content + = resolve_inline_following_content(t, closing_index, + false, false) + render_link_or_image(t, opening_index, closing_index, + closing_index, inline_content) + end + +% \end{macrocode} +% \begin{markdown} +% +% Resolve a shortcut link `[a]` from the delimiters at `opening_index` and `closing_index` within a delimiter table `t`. % Continue if a tag `a` is not found in the references. % % \end{markdown} % \begin{macrocode} local function resolve_shortcut_link(t, opening_index, closing_index) - local content = collect_link_content(t, opening_index + 1, closing_index - 1) + local content + = collect_link_content(t, opening_index + 1, closing_index - 1) local r = self.lookup_reference(content) if r then - local inline_content = resolve_inline_following_content(t, closing_index, false, t.match_link_attributes) - r.attributes = join_attributes(r.attributes, inline_content.attributes) - render_link_or_image(t, opening_index, closing_index, closing_index, r) + local inline_content + = resolve_inline_following_content(t, closing_index, false, + t.match_link_attributes) + r.attributes + = join_attributes(r.attributes, inline_content.attributes) + render_link_or_image(t, opening_index, closing_index, + closing_index, r) end end % \end{macrocode} % \begin{markdown} % -% Resolve a full link [a][b] from the delimiters at `opening_index` and `closing_index` within a delimiter table `t`. +% Resolve a note `[^a]` from the delimiters at `opening_index` and `closing_index` within a delimiter table `t`. +% Continue if a tag `a` is not found in the rawnotes. +% +% \end{markdown} +% \begin{macrocode} + local function resolve_raw_note_link(t, opening_index, closing_index) + local content + = collect_link_content(t, opening_index + 1, closing_index - 1) + local r = self.lookup_note_reference(content) + + if r then + local parsed_ref = self.parser_functions.parse_blocks_nested(r) + render_link_or_image(t, opening_index, closing_index, + closing_index, parsed_ref) + end + end + +% \end{macrocode} +% \begin{markdown} +% +% Resolve a full link `[a][b]` from the delimiters at `opening_index` and `closing_index` within a delimiter table `t`. % Continue if a tag `b` is not found in the references. % % \end{markdown} % \begin{macrocode} local function resolve_full_link(t, opening_index, closing_index) - local next_link_closing_index = find_next_link_closing_index(t, closing_index + 4) - local next_link_content = collect_link_content(t, closing_index + 3, next_link_closing_index - 1) + local next_link_closing_index + = find_next_link_closing_index(t, closing_index + 4) + local next_link_content + = collect_link_content(t, closing_index + 3, + next_link_closing_index - 1) local r = self.lookup_reference(next_link_content) if r then - local inline_content = resolve_inline_following_content(t, next_link_closing_index, false, - t.match_link_attributes) - r.attributes = join_attributes(r.attributes, inline_content.attributes) - render_link_or_image(t, opening_index, next_link_closing_index, closing_index, r) + local inline_content + = resolve_inline_following_content(t, next_link_closing_index, + false, + t.match_link_attributes) + r.attributes + = join_attributes(r.attributes, inline_content.attributes) + render_link_or_image(t, opening_index, next_link_closing_index, + closing_index, r) end end % \end{macrocode} % \begin{markdown} % -% Resolve a collapsed link [a][] from the delimiters at `opening_index` and `closing_index` +% Resolve a collapsed link `[a][]` from the delimiters at `opening_index` and `closing_index` % within a delimiter table `t`. % Continue if a tag `a` is not found in the references. % % \end{markdown} % \begin{macrocode} local function resolve_collapsed_link(t, opening_index, closing_index) - local next_link_closing_index = find_next_link_closing_index(t, closing_index + 4) - local content = collect_link_content(t, opening_index + 1, closing_index - 1) + local next_link_closing_index + = find_next_link_closing_index(t, closing_index + 4) + local content + = collect_link_content(t, opening_index + 1, closing_index - 1) local r = self.lookup_reference(content) if r then - local inline_content = resolve_inline_following_content(t, closing_index, false, t.match_link_attributes) - r.attributes = join_attributes(r.attributes, inline_content.attributes) - render_link_or_image(t, opening_index, next_link_closing_index, closing_index, r) + local inline_content + = resolve_inline_following_content(t, closing_index, false, + t.match_link_attributes) + r.attributes + = join_attributes(r.attributes, inline_content.attributes) + render_link_or_image(t, opening_index, next_link_closing_index, + closing_index, r) end end @@ -29045,9 +30011,12 @@ function M.reader.new(writer, options) end for i,value in ipairs(t) do - if not value.is_closing or - value.type ~= "delimiter" or - not (value.element == "link" or value.element == "image") then + if not value.is_closing + or value.type ~= "delimiter" + or not ( value.element == "link" + or value.element == "image" + or value.element == "note") + or value.removed then goto continue end @@ -29073,6 +30042,12 @@ function M.reader.new(writer, options) if (link_type == "collapsed") then resolve_collapsed_link(t, opener_position, i) end + if (link_type == "note_inline") then + resolve_note_inline_link(t, opener_position, i) + end + if (link_type == "raw_note") then + resolve_raw_note_link(t, opener_position, i) + end ::continue:: end @@ -29098,7 +30073,8 @@ function M.reader.new(writer, options) % % \end{markdown} % \begin{macrocode} - parsers.Str = (parsers.normalchar * (parsers.normalchar + parsers.at)^0) + parsers.Str = ( parsers.normalchar + * (parsers.normalchar + parsers.at)^0) / writer.string parsers.Symbol = (parsers.backtick^1 + V("SpecialChar")) @@ -29126,25 +30102,28 @@ function M.reader.new(writer, options) parsers.interrupting_bullets = parsers.fail parsers.interrupting_enumerators = parsers.fail else - parsers.interrupting_bullets = parsers.bullet(parsers.dash, true) - + parsers.bullet(parsers.asterisk, true) - + parsers.bullet(parsers.plus, true) - - parsers.interrupting_enumerators = parsers.enumerator(parsers.period, true) - + parsers.enumerator(parsers.rparent, true) + parsers.interrupting_bullets + = parsers.bullet(parsers.dash, true) + + parsers.bullet(parsers.asterisk, true) + + parsers.bullet(parsers.plus, true) + + parsers.interrupting_enumerators + = parsers.enumerator(parsers.period, true) + + parsers.enumerator(parsers.rparent, true) end if options.html then - parsers.html_interrupting = parsers.check_trail - * ( parsers.html_incomplete_open_tag - + parsers.html_incomplete_close_tag - + parsers.html_incomplete_open_special_tag - + parsers.html_comment_start - + parsers.html_cdatasection_start - + parsers.html_declaration_start - + parsers.html_instruction_start - - parsers.html_close_special_tag - - parsers.html_empty_special_tag) + parsers.html_interrupting + = parsers.check_trail + * ( parsers.html_incomplete_open_tag + + parsers.html_incomplete_close_tag + + parsers.html_incomplete_open_special_tag + + parsers.html_comment_start + + parsers.html_cdatasection_start + + parsers.html_declaration_start + + parsers.html_instruction_start + - parsers.html_close_special_tag + - parsers.html_empty_special_tag) else parsers.html_interrupting = parsers.fail end @@ -29166,7 +30145,7 @@ function M.reader.new(writer, options) * -V("EndlineExceptions") + parsers.check_optional_indent * -V("EndlineExceptions") - * -parsers.starter) + * -parsers.starter) / function(_) return end * parsers.spacechar^0 parsers.Endline = parsers.endline @@ -29192,30 +30171,37 @@ function M.reader.new(writer, options) parsers.Space = parsers.spacechar^2 * parsers.Endline / writer.hard_line_break - + parsers.spacechar^1 * parsers.Endline^-1 * parsers.eof / self.expandtabs + + parsers.spacechar^1 + * parsers.Endline^-1 + * parsers.eof / self.expandtabs + parsers.spacechar^1 * parsers.Endline / writer.soft_line_break - + parsers.spacechar^1 * -parsers.newline / self.expandtabs + + parsers.spacechar^1 + * -parsers.newline / self.expandtabs parsers.NoSoftLineBreakSpace = parsers.spacechar^2 * parsers.Endline / writer.hard_line_break - + parsers.spacechar^1 * parsers.Endline^-1 * parsers.eof / self.expandtabs + + parsers.spacechar^1 + * parsers.Endline^-1 + * parsers.eof / self.expandtabs + parsers.spacechar^1 * parsers.Endline / writer.soft_line_break - + parsers.spacechar^1 * -parsers.newline / self.expandtabs + + parsers.spacechar^1 + * -parsers.newline / self.expandtabs parsers.NonbreakingEndline = parsers.endline - / writer.soft_line_break + / writer.nbsp parsers.NonbreakingSpace - = parsers.spacechar^2 * parsers.Endline - / writer.hard_line_break - + parsers.spacechar^1 * parsers.Endline^-1 * parsers.eof / "" - + parsers.spacechar^1 * parsers.Endline + = parsers.spacechar^2 * parsers.endline + / writer.nbsp + + parsers.spacechar^1 + * parsers.endline^-1 * parsers.eof / "" + + parsers.spacechar^1 * parsers.endline * parsers.optionalspace - / writer.soft_line_break + / writer.nbsp + parsers.spacechar^1 * parsers.optionalspace / writer.nbsp @@ -29264,18 +30250,20 @@ end parsers.LinkAndEmph = Ct(parsers.link_and_emph_table) / self.defer_link_and_emphasis_processing - parsers.EscapedChar = parsers.backslash * C(parsers.escapable) / writer.string + parsers.EscapedChar = parsers.backslash + * C(parsers.escapable) / writer.string - parsers.InlineHtml = Cs(parsers.html_inline_comment) / writer.inline_html_comment - + Cs(parsers.html_any_empty_inline_tag - + parsers.html_inline_instruction - + parsers.html_inline_cdatasection - + parsers.html_inline_declaration - + parsers.html_any_open_inline_tag - + parsers.html_any_close_tag) - / writer.inline_html_tag + parsers.InlineHtml = Cs(parsers.html_inline_comment) + / writer.inline_html_comment + + Cs(parsers.html_any_empty_inline_tag + + parsers.html_inline_instruction + + parsers.html_inline_cdatasection + + parsers.html_inline_declaration + + parsers.html_any_open_inline_tag + + parsers.html_any_close_tag) + / writer.inline_html_tag - parsers.HtmlEntity = parsers.html_entities / writer.string + parsers.HtmlEntity = parsers.html_entities / writer.string % \end{macrocode} % \par % \begin{markdown} @@ -29294,15 +30282,18 @@ end + parsers.html_declaration)) / writer.block_html_element - parsers.indented_non_blank_line = parsers.indentedline - parsers.blankline + parsers.indented_non_blank_line = parsers.indentedline + - parsers.blankline - parsers.Verbatim = Cs( - parsers.check_code_trail - * (parsers.line - parsers.blankline) - * ((parsers.check_minimal_blank_indent_and_full_code_trail * parsers.blankline)^0 - * ((parsers.check_minimal_indent / "") * parsers.check_code_trail - * (parsers.line - parsers.blankline))^1)^0 - ) / self.expandtabs / writer.verbatim + parsers.Verbatim + = Cs( parsers.check_code_trail + * (parsers.line - parsers.blankline) + * (( parsers.check_minimal_blank_indent_and_full_code_trail + * parsers.blankline)^0 + * ( (parsers.check_minimal_indent / "") + * parsers.check_code_trail + * (parsers.line - parsers.blankline))^1)^0) + / self.expandtabs / writer.verbatim parsers.Blockquote = parsers.blockquote_body / writer.blockquote @@ -29341,73 +30332,79 @@ end parsers.list_blank = parsers.conditionally_indented_blankline - parsers.ref_or_block_list_separated = parsers.sep_group_no_output(parsers.list_blank) - * parsers.minimally_indented_ref - + parsers.block_sep_group(parsers.list_blank) - * parsers.minimally_indented_block - - parsers.ref_or_block_non_separated = parsers.minimally_indented_ref - + (parsers.succeed / writer.interblocksep) - * parsers.minimally_indented_block - - parsers.minimally_indented_blankline - - parsers.tight_list_loop_body_pair = - parsers.create_loop_body_pair(parsers.ref_or_block_non_separated, - parsers.minimally_indented_par_or_plain_no_blank, - (parsers.succeed / writer.interblocksep), - (parsers.succeed / writer.paragraphsep)) - - parsers.loose_list_loop_body_pair = - parsers.create_loop_body_pair(parsers.ref_or_block_list_separated, - parsers.minimally_indented_par_or_plain, - parsers.block_sep_group(parsers.list_blank), - parsers.par_sep_group(parsers.list_blank)) - - parsers.tight_list_content_loop = V("Block") - * parsers.tight_list_loop_body_pair.block^0 - + (V("Paragraph") + V("Plain")) - * parsers.ref_or_block_non_separated - * parsers.tight_list_loop_body_pair.block^0 - + (V("Paragraph") + V("Plain")) - * parsers.tight_list_loop_body_pair.par^0 - - parsers.loose_list_content_loop = V("Block") - * parsers.loose_list_loop_body_pair.block^0 - + (V("Paragraph") + V("Plain")) - * parsers.ref_or_block_list_separated - * parsers.loose_list_loop_body_pair.block^0 - + (V("Paragraph") + V("Plain")) - * parsers.loose_list_loop_body_pair.par^0 - - parsers.list_item_tightness_condition = -#( parsers.list_blank^0 - * parsers.minimally_indented_ref_or_block_or_par) - * remove_indent("li") - + remove_indent("li") - * parsers.fail - - parsers.indented_content_tight = Ct( (parsers.blankline / "") - * #parsers.list_blank - * remove_indent("li") - + ( (V("Reference") + (parsers.blankline / "")) - * parsers.check_minimal_indent - * parsers.tight_list_content_loop - + (V("Reference") + (parsers.blankline / "")) - + (parsers.tickbox^-1 / writer.escape) - * parsers.tight_list_content_loop - ) - * parsers.list_item_tightness_condition - ) - - parsers.indented_content_loose = Ct( (parsers.blankline / "") - * #parsers.list_blank - + ( (V("Reference") + (parsers.blankline / "")) - * parsers.check_minimal_indent - * parsers.loose_list_content_loop - + (V("Reference") + (parsers.blankline / "")) - + (parsers.tickbox^-1 / writer.escape) - * parsers.loose_list_content_loop - ) - ) + parsers.ref_or_block_list_separated + = parsers.sep_group_no_output(parsers.list_blank) + * parsers.minimally_indented_ref + + parsers.block_sep_group(parsers.list_blank) + * parsers.minimally_indented_block + + parsers.ref_or_block_non_separated + = parsers.minimally_indented_ref + + (parsers.succeed / writer.interblocksep) + * parsers.minimally_indented_block + - parsers.minimally_indented_blankline + + parsers.tight_list_loop_body_pair = + parsers.create_loop_body_pair( + parsers.ref_or_block_non_separated, + parsers.minimally_indented_par_or_plain_no_blank, + (parsers.succeed / writer.interblocksep), + (parsers.succeed / writer.paragraphsep)) + + parsers.loose_list_loop_body_pair = + parsers.create_loop_body_pair( + parsers.ref_or_block_list_separated, + parsers.minimally_indented_par_or_plain, + parsers.block_sep_group(parsers.list_blank), + parsers.par_sep_group(parsers.list_blank)) + + parsers.tight_list_content_loop + = V("Block") + * parsers.tight_list_loop_body_pair.block^0 + + (V("Paragraph") + V("Plain")) + * parsers.ref_or_block_non_separated + * parsers.tight_list_loop_body_pair.block^0 + + (V("Paragraph") + V("Plain")) + * parsers.tight_list_loop_body_pair.par^0 + + parsers.loose_list_content_loop + = V("Block") + * parsers.loose_list_loop_body_pair.block^0 + + (V("Paragraph") + V("Plain")) + * parsers.ref_or_block_list_separated + * parsers.loose_list_loop_body_pair.block^0 + + (V("Paragraph") + V("Plain")) + * parsers.loose_list_loop_body_pair.par^0 + + parsers.list_item_tightness_condition + = -#( parsers.list_blank^0 + * parsers.minimally_indented_ref_or_block_or_par) + * remove_indent("li") + + remove_indent("li") + * parsers.fail + + parsers.indented_content_tight + = Ct( (parsers.blankline / "") + * #parsers.list_blank + * remove_indent("li") + + ( (V("Reference") + (parsers.blankline / "")) + * parsers.check_minimal_indent + * parsers.tight_list_content_loop + + (V("Reference") + (parsers.blankline / "")) + + (parsers.tickbox^-1 / writer.escape) + * parsers.tight_list_content_loop + ) + * parsers.list_item_tightness_condition) + + parsers.indented_content_loose + = Ct( (parsers.blankline / "") + * #parsers.list_blank + + ( (V("Reference") + (parsers.blankline / "")) + * parsers.check_minimal_indent + * parsers.loose_list_content_loop + + (V("Reference") + (parsers.blankline / "")) + + (parsers.tickbox^-1 / writer.escape) + * parsers.loose_list_content_loop)) parsers.TightListItem = function(starter) return -parsers.ThematicBreak @@ -29465,13 +30462,15 @@ end local enumerator = parsers.enumerator(delimiter_type) return Cg(enumerator, "listtype") * (Ct( parsers.TightListItem(Cb("listtype")) - * ((parsers.check_minimal_indent / "") * parsers.TightListItem(enumerator))^0) + * ( (parsers.check_minimal_indent / "") + * parsers.TightListItem(enumerator))^0) * Cc(true) * -#((parsers.list_blank^0 / "") * parsers.check_minimal_indent * enumerator) + Ct( parsers.LooseListItem(Cb("listtype")) * ((parsers.list_blank^0 / "") - * (parsers.check_minimal_indent / "") * parsers.LooseListItem(enumerator))^0) + * (parsers.check_minimal_indent / "") + * parsers.LooseListItem(enumerator))^0) * Cc(false) ) * Ct(Cb("listtype")) / ordered_list end @@ -29524,15 +30523,21 @@ end - parsers.thematic_break_lines parsers.heading_text = parsers.heading_line - * ((V("Endline") / "\n") * (parsers.heading_line - parsers.heading_level))^0 + * ( (V("Endline") / "\n") + * ( parsers.heading_line + - parsers.heading_level))^0 * parsers.newline^-1 - parsers.SetextHeading = parsers.freeze_trail * parsers.check_trail_no_rem - * #(parsers.heading_text - * parsers.check_minimal_indent * parsers.check_trail * parsers.heading_level) + parsers.SetextHeading = parsers.freeze_trail + * parsers.check_trail_no_rem + * #( parsers.heading_text + * parsers.check_minimal_indent + * parsers.check_trail + * parsers.heading_level) * Cs(parsers.heading_text) / parsers.parse_heading_text - * parsers.check_minimal_indent_and_trail * parsers.heading_level + * parsers.check_minimal_indent_and_trail + * parsers.heading_level * parsers.newline * parsers.unfreeze_trail / writer.heading @@ -29584,14 +30589,18 @@ end local current_extension_name = nil self.insert_pattern = function(selector, pattern, pattern_name) assert(pattern_name == nil or type(pattern_name) == "string") - local _, _, lhs, pos, rhs = selector:find("^(%a+)%s+([%a%s]+%a+)%s+(%a+)$") + local _, _, lhs, pos, rhs + = selector:find("^(%a+)%s+([%a%s]+%a+)%s+(%a+)$") assert(lhs ~= nil, - [[Expected selector in form "LHS (before|after|instead of) RHS", not "]] + [[Expected selector in form ]] + .. [["LHS (before|after|instead of) RHS", not "]] .. selector .. [["]]) assert(walkable_syntax[lhs] ~= nil, - [[Rule ]] .. lhs .. [[ -> ... does not exist in markdown grammar]]) + [[Rule ]] .. lhs + .. [[ -> ... does not exist in markdown grammar]]) assert(pos == "before" or pos == "after" or pos == "instead of", - [[Expected positional specifier "before", "after", or "instead of", not "]] + [[Expected positional specifier "before", "after", ]] + .. [[or "instead of", not "]] .. pos .. [["]]) local rule = walkable_syntax[lhs] local index = nil @@ -29609,10 +30618,12 @@ end .. [[ does not exist in markdown grammar]]) local accountable_pattern if current_extension_name then - accountable_pattern = { pattern, current_extension_name, pattern_name } + accountable_pattern + = {pattern, current_extension_name, pattern_name} else assert(type(pattern) == "string", - [[reader->insert_pattern() was called outside an extension with ]] + [[reader->insert_pattern() was called outside ]] + .. [[an extension with ]] .. [[a PEG pattern instead of a rule name]]) accountable_pattern = pattern end @@ -29635,11 +30646,9 @@ end local syntax = { "Blocks", - Blocks = V("InitializeState") - * ( V("ExpectedJekyllData") - * (V("Blank")^0 / writer.interblocksep) - )^-1 - * V("Blank")^0 + Blocks = V("InitializeState") + * V("ExpectedJekyllData") + * V("Blank")^0 % \end{macrocode} % \par % \begin{markdown} @@ -29650,71 +30659,72 @@ end % % \end{markdown} % \begin{macrocode} - * ( V("Block") - * ( V("Blank")^0 * parsers.eof - + ( V("Blank")^2 / writer.paragraphsep - + V("Blank")^0 / writer.interblocksep - ) - ) - + ( V("Paragraph") + V("Plain") ) - * ( V("Blank")^0 * parsers.eof - + ( V("Blank")^2 / writer.paragraphsep - + V("Blank")^0 / writer.interblocksep - ) - ) - * V("Block") - * ( V("Blank")^0 * parsers.eof - + ( V("Blank")^2 / writer.paragraphsep - + V("Blank")^0 / writer.interblocksep - ) - ) - + ( V("Paragraph") + V("Plain") ) - * ( V("Blank")^0 * parsers.eof - + V("Blank")^0 / writer.paragraphsep - ) - )^0, - - ExpectedJekyllData = parsers.fail, - - Blank = parsers.Blank, - Reference = parsers.Reference, - - Blockquote = parsers.Blockquote, - Verbatim = parsers.Verbatim, - ThematicBreak = parsers.ThematicBreak, - BulletList = parsers.BulletList, - OrderedList = parsers.OrderedList, - DisplayHtml = parsers.DisplayHtml, - Heading = parsers.Heading, - Paragraph = parsers.Paragraph, - Plain = parsers.Plain, - - EndlineExceptions = parsers.EndlineExceptions, + * ( V("Block") + * ( V("Blank")^0 * parsers.eof + + ( V("Blank")^2 / writer.paragraphsep + + V("Blank")^0 / writer.interblocksep + ) + ) + + ( V("Paragraph") + V("Plain") ) + * ( V("Blank")^0 * parsers.eof + + ( V("Blank")^2 / writer.paragraphsep + + V("Blank")^0 / writer.interblocksep + ) + ) + * V("Block") + * ( V("Blank")^0 * parsers.eof + + ( V("Blank")^2 / writer.paragraphsep + + V("Blank")^0 / writer.interblocksep + ) + ) + + ( V("Paragraph") + V("Plain") ) + * ( V("Blank")^0 * parsers.eof + + V("Blank")^0 / writer.paragraphsep + ) + )^0, + + ExpectedJekyllData = parsers.succeed, + + Blank = parsers.Blank, + Reference = parsers.Reference, + + Blockquote = parsers.Blockquote, + Verbatim = parsers.Verbatim, + ThematicBreak = parsers.ThematicBreak, + BulletList = parsers.BulletList, + OrderedList = parsers.OrderedList, + DisplayHtml = parsers.DisplayHtml, + Heading = parsers.Heading, + Paragraph = parsers.Paragraph, + Plain = parsers.Plain, + + EndlineExceptions = parsers.EndlineExceptions, NoSoftLineBreakEndlineExceptions - = parsers.NoSoftLineBreakEndlineExceptions, - - Str = parsers.Str, - Space = parsers.Space, - NoSoftLineBreakSpace = parsers.NoSoftLineBreakSpace, - OptionalIndent = parsers.OptionalIndent, - Endline = parsers.Endline, - EndlineNoSub = parsers.EndlineNoSub, + = parsers.NoSoftLineBreakEndlineExceptions, + + Str = parsers.Str, + Space = parsers.Space, + NoSoftLineBreakSpace + = parsers.NoSoftLineBreakSpace, + OptionalIndent = parsers.OptionalIndent, + Endline = parsers.Endline, + EndlineNoSub = parsers.EndlineNoSub, NoSoftLineBreakEndline - = parsers.NoSoftLineBreakEndline, - EndlineBreak = parsers.EndlineBreak, - LinkAndEmph = parsers.LinkAndEmph, - Code = parsers.Code, - AutoLinkUrl = parsers.AutoLinkUrl, - AutoLinkEmail = parsers.AutoLinkEmail, + = parsers.NoSoftLineBreakEndline, + EndlineBreak = parsers.EndlineBreak, + LinkAndEmph = parsers.LinkAndEmph, + Code = parsers.Code, + AutoLinkUrl = parsers.AutoLinkUrl, + AutoLinkEmail = parsers.AutoLinkEmail, AutoLinkRelativeReference - = parsers.AutoLinkRelativeReference, - InlineHtml = parsers.InlineHtml, - HtmlEntity = parsers.HtmlEntity, - EscapedChar = parsers.EscapedChar, - Smart = parsers.Smart, - Symbol = parsers.Symbol, - SpecialChar = parsers.fail, - InitializeState = parsers.succeed, + = parsers.AutoLinkRelativeReference, + InlineHtml = parsers.InlineHtml, + HtmlEntity = parsers.HtmlEntity, + EscapedChar = parsers.EscapedChar, + Smart = parsers.Smart, + Symbol = parsers.Symbol, + SpecialChar = parsers.fail, + InitializeState = parsers.succeed, } % \end{macrocode} % \par @@ -29732,13 +30742,17 @@ end self.update_rule = function(rule_name, get_pattern) assert(current_extension_name ~= nil) assert(syntax[rule_name] ~= nil, - [[Rule ]] .. rule_name .. [[ -> ... does not exist in markdown grammar]]) + [[Rule ]] .. rule_name + .. [[ -> ... does not exist in markdown grammar]]) local previous_pattern local extension_name if walkable_syntax[rule_name] then - local previous_accountable_pattern = walkable_syntax[rule_name][1] + local previous_accountable_pattern + = walkable_syntax[rule_name][1] previous_pattern = previous_accountable_pattern[1] - extension_name = previous_accountable_pattern[2] .. ", " .. current_extension_name + extension_name + = previous_accountable_pattern[2] + .. ", " .. current_extension_name else previous_pattern = nil extension_name = current_extension_name @@ -29868,9 +30882,11 @@ end pattern_name = "Anonymous Pattern" end local extension_name = rhs[2] - human_readable_rhs = pattern_name .. [[ (]] .. extension_name .. [[)]] + human_readable_rhs = pattern_name .. [[ (]] + .. extension_name .. [[)]] end - local encoded_rhs = util.encode_json_string(human_readable_rhs) + local encoded_rhs + = util.encode_json_string(human_readable_rhs) local output_line = [[ ]] .. encoded_rhs if rhs_index < #rule then output_line = output_line .. "," @@ -29888,7 +30904,8 @@ end local output = table.concat(output_lines, "\n") local output_filename = options.debugExtensionsFileName local output_file = assert(io.open(output_filename, "w"), - [[Could not open file "]] .. output_filename .. [[" for writing]]) + [[Could not open file "]] .. output_filename + .. [[" for writing]]) assert(output_file:write(output)) assert(output_file:close()) end @@ -29981,7 +30998,7 @@ end end local blocks_nested_t = util.table_copy(syntax) - blocks_nested_t.ExpectedJekyllData = parsers.fail + blocks_nested_t.ExpectedJekyllData = parsers.succeed parsers.blocks_nested = Ct(blocks_nested_t) parsers.blocks = Ct(syntax) @@ -30011,8 +31028,10 @@ end local inlines_no_link_or_emphasis_t = util.table_copy(inlines_t) inlines_no_link_or_emphasis_t.LinkAndEmph = parsers.fail - inlines_no_link_or_emphasis_t.EndlineExceptions = parsers.EndlineExceptions - parsers.eof - parsers.inlines_no_link_or_emphasis = Ct(inlines_no_link_or_emphasis_t) + inlines_no_link_or_emphasis_t.EndlineExceptions + = parsers.EndlineExceptions - parsers.eof + parsers.inlines_no_link_or_emphasis + = Ct(inlines_no_link_or_emphasis_t) % \end{macrocode} % \par % \begin{markdown} @@ -30039,7 +31058,8 @@ end elseif form == "nfkd" then input = uni_algos.normalize.NFKD(input) else - error(format("Unknown normalization form %s", form)) + return writer.error( + format("Unknown normalization form %s", form)) end end % \end{macrocode} @@ -30055,30 +31075,12 @@ end end % \end{macrocode} % \begin{markdown} -% When determining the name of the cache file, create salt for the hashing -% function out of the package version and the passed options recognized by the -% Lua interface (see Section <#sec:lua-options>). The \Opt{cacheDir} option -% is disregarded. +% Clear the table of references. % \end{markdown} % \begin{macrocode} references = {} - local opt_string = {} - for k, _ in pairs(defaultOptions) do - local v = options[k] - if type(v) == "table" then - for _, i in ipairs(v) do - opt_string[#opt_string+1] = k .. "=" .. tostring(i) - end - elseif k ~= "cacheDir" then - opt_string[#opt_string+1] = k .. "=" .. tostring(v) - end - end - table.sort(opt_string) - local salt = table.concat(opt_string, ",") .. "," .. metadata.version - local output - local function convert(input) - local document = self.parser_functions.parse_blocks(input) - local output = util.rope_to_string(writer.document(document)) + local document = self.parser_functions.parse_blocks(input) + local output = util.rope_to_string(writer.document(document)) % \end{macrocode} % \begin{markdown} % Remove block element / paragraph separators immediately followed by the @@ -30086,82 +31088,49 @@ end % Then, remove any leftover output of \luamref{writer->undosep}. % \end{markdown} % \begin{macrocode} - local undosep_start, undosep_end - local potential_secend_start, secend_start - local potential_sep_start, sep_start + local undosep_start, undosep_end + local potential_secend_start, secend_start + local potential_sep_start, sep_start + while true do + -- find a `writer->undosep` + undosep_start, undosep_end + = output:find(writer.undosep_text, 1, true) + if undosep_start == nil then break end + -- skip any preceding section ends + secend_start = undosep_start while true do - -- find a `writer->undosep` - undosep_start, undosep_end = output:find(writer.undosep_text, 1, true) - if undosep_start == nil then break end - -- skip any preceding section ends - secend_start = undosep_start - while true do - potential_secend_start = secend_start - #writer.secend_text - if potential_secend_start < 1 - or output:sub(potential_secend_start, secend_start - 1) ~= writer.secend_text then - break - end - secend_start = potential_secend_start + potential_secend_start = secend_start - #writer.secend_text + if potential_secend_start < 1 + or output:sub(potential_secend_start, + secend_start - 1) ~= writer.secend_text + then + break end - -- find an immediately preceding block element / paragraph separator - sep_start = secend_start - potential_sep_start = sep_start - #writer.interblocksep_text + secend_start = potential_secend_start + end + -- find an immediately preceding + -- block element / paragraph separator + sep_start = secend_start + potential_sep_start = sep_start - #writer.interblocksep_text + if potential_sep_start >= 1 + and output:sub(potential_sep_start, + sep_start - 1) == writer.interblocksep_text + then + sep_start = potential_sep_start + else + potential_sep_start = sep_start - #writer.paragraphsep_text if potential_sep_start >= 1 - and output:sub(potential_sep_start, sep_start - 1) == writer.interblocksep_text then + and output:sub(potential_sep_start, + sep_start - 1) == writer.paragraphsep_text + then sep_start = potential_sep_start - else - potential_sep_start = sep_start - #writer.paragraphsep_text - if potential_sep_start >= 1 - and output:sub(potential_sep_start, sep_start - 1) == writer.paragraphsep_text then - sep_start = potential_sep_start - end end - -- remove `writer->undosep` and immediately preceding block element / paragraph separator - output = output:sub(1, sep_start - 1) - .. output:sub(secend_start, undosep_start - 1) - .. output:sub(undosep_end + 1) - end - return output - end -% \end{macrocode} -% \begin{markdown} -% If we cache markdown documents, produce the cache file and transform its -% filename to plain \TeX{} output via the \luamref{writer->pack} method. -% \end{markdown} -% \begin{macrocode} - if options.eagerCache or options.finalizeCache then - local name = util.cache(options.cacheDir, input, salt, convert, - ".md" .. writer.suffix) - output = writer.pack(name) -% \end{macrocode} -% \begin{markdown} -% Otherwise, return the result of the conversion directly. -% \end{markdown} -% \begin{macrocode} - else - output = convert(input) - end -% \end{macrocode} -% \begin{markdown} -% If the \Opt{finalizeCache} option is enabled, populate the frozen cache in -% the file \Opt{frozenCacheFileName} with an entry for markdown document -% number \Opt{frozenCacheCounter}. -% \end{markdown} -% \begin{macrocode} - if options.finalizeCache then - local file, mode - if options.frozenCacheCounter > 0 then - mode = "a" - else - mode = "w" end - file = assert(io.open(options.frozenCacheFileName, mode), - [[Could not open file "]] .. options.frozenCacheFileName - .. [[" for writing]]) - assert(file:write([[\expandafter\global\expandafter\def\csname ]] - .. [[markdownFrozenCache]] .. options.frozenCacheCounter - .. [[\endcsname{]] .. output .. [[}]] .. "\n")) - assert(file:close()) + -- remove `writer->undosep` and immediately preceding + -- block element / paragraph separator + output = output:sub(1, sep_start - 1) + .. output:sub(secend_start, undosep_start - 1) + .. output:sub(undosep_end + 1) end return output end @@ -30223,10 +31192,13 @@ M.extensions.bracketed_spans = function() + parsers.autolink + V("InlineHtml") + ( parsers.backslash * parsers.backslash) - + ( parsers.backslash * (parsers.lbracket + parsers.rbracket) + + ( parsers.backslash + * (parsers.lbracket + parsers.rbracket) + V("Space") + V("Endline") + (parsers.any - - (parsers.newline + parsers.lbracket + parsers.rbracket + - ( parsers.newline + + parsers.lbracket + + parsers.rbracket + parsers.blankline^2))))^1) / self.parser_functions.parse_inlines) * parsers.rbracket @@ -30289,11 +31261,15 @@ M.extensions.citations = function(citation_nbsps) end end else - table.insert(buffer, {"\\markdownRenderer", text_cites and "TextCite" or "Cite", - "{", #cites, "}"}) + table.insert(buffer, + {"\\markdownRenderer", + text_cites and "TextCite" or "Cite", + "{", #cites, "}"}) for _,cite in ipairs(cites) do - table.insert(buffer, {cite.suppress_author and "-" or "+", "{", - cite.prenote or "", "}{", cite.postnote or "", "}{", cite.name, "}"}) + table.insert(buffer, + {cite.suppress_author and "-" or "+", "{", + cite.prenote or "", "}{", + cite.postnote or "", "}{", cite.name, "}"}) end end return buffer @@ -30309,12 +31285,16 @@ M.extensions.citations = function(citation_nbsps) local citation_name = Cs(parsers.dash^-1) * parsers.at * Cs(citation_chars - * (((citation_chars + parsers.internal_punctuation + * ((( citation_chars + + parsers.internal_punctuation - parsers.comma - parsers.semicolon) - * -#((parsers.internal_punctuation - parsers.comma + * -#(( parsers.internal_punctuation + - parsers.comma - parsers.semicolon)^0 - * -(citation_chars + parsers.internal_punctuation - - parsers.comma - parsers.semicolon)))^0 + * -( citation_chars + + parsers.internal_punctuation + - parsers.comma + - parsers.semicolon)))^0 * citation_chars)^-1) local citation_body_prenote @@ -30323,10 +31303,14 @@ M.extensions.citations = function(citation_nbsps) + parsers.inticks + parsers.autolink + V("InlineHtml") - + V("Space") + V("Endline") + + V("Space") + V("EndlineNoSub") + (parsers.anyescaped - - (parsers.newline + parsers.rbracket + parsers.blankline^2)) - - (parsers.spnl * parsers.dash^-1 * parsers.at))^1) + - ( parsers.newline + + parsers.rbracket + + parsers.blankline^2)) + - ( parsers.spnl + * parsers.dash^-1 + * parsers.at))^1) local citation_body_postnote = Cs((parsers.alphanumeric^1 @@ -30334,9 +31318,11 @@ M.extensions.citations = function(citation_nbsps) + parsers.inticks + parsers.autolink + V("InlineHtml") - + V("Space") + V("Endline") + + V("Space") + V("EndlineNoSub") + (parsers.anyescaped - - (parsers.newline + parsers.rbracket + parsers.semicolon + - ( parsers.newline + + parsers.rbracket + + parsers.semicolon + parsers.blankline^2)) - (parsers.spnl * parsers.rbracket))^1) @@ -30347,8 +31333,9 @@ M.extensions.citations = function(citation_nbsps) * parsers.spnlc ) * citation_name - * (parsers.internal_punctuation - parsers.semicolon)^-1 - * ( parsers.spnlc + * ( parsers.internal_punctuation + - parsers.semicolon)^-1 + * ( parsers.spnlc / function(_) return end * citation_body_postnote + Cc("") * parsers.spnlc @@ -30369,7 +31356,9 @@ M.extensions.citations = function(citation_nbsps) + V("InlineHtml") + V("Space") + V("Endline") + (parsers.anyescaped - - (parsers.newline + parsers.rbracket + parsers.at + - ( parsers.newline + + parsers.rbracket + + parsers.at + parsers.semicolon + parsers.blankline^2)) - (parsers.spnl * parsers.rbracket))^0) @@ -30463,7 +31452,8 @@ M.extensions.content_blocks = function(language_map) % \begin{macrocode} local languages_json = (function() local base, prev, curr - for _, pathname in ipairs{kpse.lookup(language_map, { all=true })} do + for _, pathname in ipairs{kpse.lookup(language_map, + {all=true})} do local file = io.open(pathname, "r") if not file then goto continue end local input = assert(file:read("*a")) @@ -30504,20 +31494,20 @@ M.extensions.content_blocks = function(language_map) suf = suf:lower() if type == "onlineimage" then return {"\\markdownRendererContentBlockOnlineImage{",suf,"}", - "{",self.string(src),"}", - "{",self.uri(src),"}", - "{",self.string(tit or ""),"}"} + "{",self.string(src),"}", + "{",self.uri(src),"}", + "{",self.string(tit or ""),"}"} elseif languages_json[suf] then return {"\\markdownRendererContentBlockCode{",suf,"}", - "{",self.string(languages_json[suf]),"}", - "{",self.string(src),"}", - "{",self.uri(src),"}", - "{",self.string(tit or ""),"}"} + "{",self.string(languages_json[suf]),"}", + "{",self.string(src),"}", + "{",self.uri(src),"}", + "{",self.string(tit or ""),"}"} else return {"\\markdownRendererContentBlock{",suf,"}", - "{",self.string(src),"}", - "{",self.uri(src),"}", - "{",self.string(tit or ""),"}"} + "{",self.string(src),"}", + "{",self.uri(src),"}", + "{",self.string(tit or ""),"}"} end end end, extend_reader = function(self) @@ -30552,8 +31542,8 @@ M.extensions.content_blocks = function(language_map) return parser end)("png", "jpg", "jpeg", "gif", "tif", "tiff") - -- online image url for iA Writer content blocks with mandatory suffix, - -- allowing nested brackets: + -- online image url for iA Writer content blocks with + -- mandatory suffix, allowing nested brackets: local onlineimageurl = (parsers.less * Cs((parsers.anyescaped @@ -30631,8 +31621,9 @@ M.extensions.definition_lists = function(tight_lists) local function dlitem(term, defs) local retVal = {"\\markdownRendererDlItem{",term,"}"} for _, def in ipairs(defs) do - retVal[#retVal+1] = {"\\markdownRendererDlDefinitionBegin ",def, - "\\markdownRendererDlDefinitionEnd "} + retVal[#retVal+1] + = {"\\markdownRendererDlDefinitionBegin ",def, + "\\markdownRendererDlDefinitionEnd "} end retVal[#retVal+1] = "\\markdownRendererDlItemEnd " return retVal @@ -30658,17 +31649,26 @@ M.extensions.definition_lists = function(tight_lists) local defstartchar = S("~:") - local defstart = parsers.check_trail_length(0) * defstartchar * #parsers.spacing - * (parsers.tab + parsers.space^-3) - + parsers.check_trail_length(1) * defstartchar * #parsers.spacing - * (parsers.tab + parsers.space^-2) - + parsers.check_trail_length(2) * defstartchar * #parsers.spacing - * (parsers.tab + parsers.space^-1) - + parsers.check_trail_length(3) * defstartchar * #parsers.spacing - - local indented_line = (parsers.check_minimal_indent / "") * parsers.check_code_trail * parsers.line - - local blank = parsers.check_minimal_blank_indent_and_any_trail * parsers.optionalspace * parsers.newline + local defstart + = parsers.check_trail_length(0) * defstartchar + * #parsers.spacing + * (parsers.tab + parsers.space^-3) + + parsers.check_trail_length(1) + * defstartchar * #parsers.spacing + * (parsers.tab + parsers.space^-2) + + parsers.check_trail_length(2) + * defstartchar * #parsers.spacing + * (parsers.tab + parsers.space^-1) + + parsers.check_trail_length(3) + * defstartchar * #parsers.spacing + + local indented_line + = (parsers.check_minimal_indent / "") + * parsers.check_code_trail * parsers.line + + local blank + = parsers.check_minimal_blank_indent_and_any_trail + * parsers.optionalspace * parsers.newline local dlchunk = Cs(parsers.line * (indented_line - blank)^0) @@ -30685,24 +31685,24 @@ M.extensions.definition_lists = function(tight_lists) end local DefinitionListItemLoose - = C(parsers.line) * blank^0 - * Ct((parsers.check_minimal_indent * (defstart - * indented_blocks(dlchunk) - / self.parser_functions.parse_blocks_nested))^1) - * Cc(false) / definition_list_item + = C(parsers.line) * blank^0 + * Ct((parsers.check_minimal_indent * (defstart + * indented_blocks(dlchunk) + / self.parser_functions.parse_blocks_nested))^1) + * Cc(false) / definition_list_item local DefinitionListItemTight - = C(parsers.line) - * Ct((parsers.check_minimal_indent * (defstart * dlchunk - / self.parser_functions.parse_blocks_nested))^1) - * Cc(true) / definition_list_item + = C(parsers.line) + * Ct((parsers.check_minimal_indent * (defstart * dlchunk + / self.parser_functions.parse_blocks_nested))^1) + * Cc(true) / definition_list_item local DefinitionList - = ( Ct(DefinitionListItemLoose^1) * Cc(false) - + Ct(DefinitionListItemTight^1) - * (blank^0 - * -DefinitionListItemLoose * Cc(true)) - ) / writer.definitionlist + = ( Ct(DefinitionListItemLoose^1) * Cc(false) + + Ct(DefinitionListItemTight^1) + * (blank^0 + * -DefinitionListItemLoose * Cc(true)) + ) / writer.definitionlist self.insert_pattern("Block after Heading", DefinitionList, "DefinitionList") @@ -30787,7 +31787,8 @@ M.extensions.fancy_lists = function() return {"\\markdownRendererFancyOlItemWithNumber{",num,"}",s, "\\markdownRendererFancyOlItemEnd "} else - return {"\\markdownRendererFancyOlItem ",s,"\\markdownRendererFancyOlItemEnd "} + return {"\\markdownRendererFancyOlItem ",s, + "\\markdownRendererFancyOlItemEnd "} end end end, extend_reader = function(self) @@ -30808,7 +31809,8 @@ M.extensions.fancy_lists = function() continuation_marker = marker end for _,delim in ipairs(delims) do - table.insert(markers_table, {start_marker, continuation_marker, delim}) + table.insert(markers_table, + {start_marker, continuation_marker, delim}) end end return markers_table @@ -30827,15 +31829,18 @@ M.extensions.fancy_lists = function() local roman_marker = function(chars) local m, d, c = P(chars[1]), P(chars[2]), P(chars[3]) - local l, x, v, i = P(chars[4]), P(chars[5]), P(chars[6]), P(chars[7]) + local l, x, v, i + = P(chars[4]), P(chars[5]), P(chars[6]), P(chars[7]) return m^-3 * (c*m + c*d + d^-1 * c^-3) * (x*c + x*l + l^-1 * x^-3) * (i*x + i*v + v^-1 * i^-3) end - local lowercase_roman_marker = roman_marker({"m", "d", "c", "l", "x", "v", "i"}) - local uppercase_roman_marker = roman_marker({"M", "D", "C", "L", "X", "V", "I"}) + local lowercase_roman_marker + = roman_marker({"m", "d", "c", "l", "x", "v", "i"}) + local uppercase_roman_marker + = roman_marker({"M", "D", "C", "L", "X", "V", "I"}) local lowercase_opening_roman_marker = P("i") local uppercase_opening_roman_marker = P("I") @@ -30859,7 +31864,8 @@ M.extensions.fancy_lists = function() local markers_table = combine_markers_and_delims(markers, delims) - local function enumerator(start_marker, _, delimiter_type, interrupting) + local function enumerator(start_marker, _, + delimiter_type, interrupting) local delimiter_range local allowed_end if interrupting then @@ -30867,7 +31873,8 @@ M.extensions.fancy_lists = function() allowed_end = C(parsers.spacechar^1) * #parsers.linechar else delimiter_range = start_marker - allowed_end = C(parsers.spacechar^1) + #(parsers.newline + parsers.eof) + allowed_end = C(parsers.spacechar^1) + + #(parsers.newline + parsers.eof) end return parsers.check_trail @@ -30889,13 +31896,15 @@ M.extensions.fancy_lists = function() end local function roman2number(roman) - local romans = { ["M"] = 1000, ["D"] = 500, ["C"] = 100, ["L"] = 50, ["X"] = 10, ["V"] = 5, ["I"] = 1 } + local romans = { ["M"] = 1000, ["D"] = 500, ["C"] = 100, + ["L"] = 50, ["X"] = 10, ["V"] = 5, ["I"] = 1 } local numeral = 0 local i = 1 local len = string.len(roman) while i < len do - local z1, z2 = romans[ string.sub(roman, i, i) ], romans[ string.sub(roman, i+1, i+1) ] + local z1, z2 = romans[ string.sub(roman, i, i) ], + romans[ string.sub(roman, i+1, i+1) ] if z1 < z2 then numeral = numeral + (z2 - z1) i = i + 2 @@ -30904,7 +31913,9 @@ M.extensions.fancy_lists = function() i = i + 1 end end - if i <= len then numeral = numeral + romans[ string.sub(roman,i,i) ] end + if i <= len then + numeral = numeral + romans[ string.sub(roman,i,i) ] + end return numeral end @@ -30929,11 +31940,13 @@ M.extensions.fancy_lists = function() end num = numstr:match("^([A-Z])$") if num then - return string.byte(num) - string.byte("A") + 1, "UpperAlpha", numdelim + return string.byte(num) - string.byte("A") + 1, + "UpperAlpha", numdelim end num = numstr:match("^([a-z])$") if num then - return string.byte(num) - string.byte("a") + 1, "LowerAlpha", numdelim + return string.byte(num) - string.byte("a") + 1, + "LowerAlpha", numdelim end num = numstr:match("^([IVXLCDM]+)") if num then @@ -30947,30 +31960,39 @@ M.extensions.fancy_lists = function() end local function fancylist(items,tight,start) - local startnum, numstyle, numdelim = sniffstyle(start[2][1], start[2][2]) + local startnum, numstyle, numdelim + = sniffstyle(start[2][1], start[2][2]) return writer.fancylist(items,tight, options.startNumber and startnum or 1, numstyle or "Decimal", numdelim or "Default") end - local FancyListOfType = function(start_marker, continuation_marker, delimiter_type) - local enumerator_start = enumerator(start_marker, continuation_marker, delimiter_type) - local enumerator_cont = enumerator(continuation_marker, continuation_marker, delimiter_type) - return Cg(enumerator_start, "listtype") - * (Ct( TightListItem(Cb("listtype")) - * ((parsers.check_minimal_indent / "") * TightListItem(enumerator_cont))^0) - * Cc(true) - * -#((parsers.conditionally_indented_blankline^0 / "") - * parsers.check_minimal_indent * enumerator_cont) - + Ct( LooseListItem(Cb("listtype")) - * ((parsers.conditionally_indented_blankline^0 / "") - * (parsers.check_minimal_indent / "") * LooseListItem(enumerator_cont))^0) - * Cc(false) - ) * Ct(Cb("listtype")) / fancylist - end + local FancyListOfType + = function(start_marker, continuation_marker, delimiter_type) + local enumerator_start + = enumerator(start_marker, continuation_marker, + delimiter_type) + local enumerator_cont + = enumerator(continuation_marker, continuation_marker, + delimiter_type) + return Cg(enumerator_start, "listtype") + * (Ct( TightListItem(Cb("listtype")) + * ((parsers.check_minimal_indent / "") + * TightListItem(enumerator_cont))^0) + * Cc(true) + * -#((parsers.conditionally_indented_blankline^0 / "") + * parsers.check_minimal_indent * enumerator_cont) + + Ct( LooseListItem(Cb("listtype")) + * ((parsers.conditionally_indented_blankline^0 / "") + * (parsers.check_minimal_indent / "") + * LooseListItem(enumerator_cont))^0) + * Cc(false) + ) * Ct(Cb("listtype")) / fancylist + end - local FancyList = join_table_with_func(FancyListOfType, markers_table) + local FancyList + = join_table_with_func(FancyListOfType, markers_table) local Endline = parsers.newline * (parsers.check_minimal_indent @@ -31026,14 +32048,17 @@ M.extensions.fenced_code = function(blank_before_code_fence, s = s:gsub("\n$", "") local buf = {} if attr ~= nil then - table.insert(buf, {"\\markdownRendererFencedCodeAttributeContextBegin", - self.attributes(attr)}) + table.insert(buf, + {"\\markdownRendererFencedCodeAttributeContextBegin", + self.attributes(attr)}) end local name = util.cache_verbatim(options.cacheDir, s) - table.insert(buf, {"\\markdownRendererInputFencedCode{", - name,"}{",self.string(i),"}{",self.infostring(i),"}"}) + table.insert(buf, + {"\\markdownRendererInputFencedCode{", + name,"}{",self.string(i),"}{",self.infostring(i),"}"}) if attr ~= nil then - table.insert(buf, "\\markdownRendererFencedCodeAttributeContextEnd{}") + table.insert(buf, + "\\markdownRendererFencedCodeAttributeContextEnd{}") end return buf end @@ -31073,11 +32098,13 @@ M.extensions.fenced_code = function(blank_before_code_fence, - parsers.newline)^0) / strip_enclosing_whitespaces) - local backtick_infostring = Cs(Cs((V("HtmlEntity") - + (-#(parsers.backslash * parsers.backtick) * parsers.anyescaped) - - parsers.newline - - parsers.backtick)^0) - / strip_enclosing_whitespaces) + local backtick_infostring + = Cs( Cs((V("HtmlEntity") + + ( -#(parsers.backslash * parsers.backtick) + * parsers.anyescaped) + - parsers.newline + - parsers.backtick)^0) + / strip_enclosing_whitespaces) local fenceindent @@ -31099,77 +32126,93 @@ M.extensions.fenced_code = function(blank_before_code_fence, end end - local function count_fenced_start_indent(_, _, indent_table, trail) - local last_indent_name = get_last_indent_name(indent_table) - fenceindent = 0 - if last_indent_name ~= "li" then - fenceindent = #trail + local count_fenced_start_indent = + function(_, _, indent_table, trail) + local last_indent_name = get_last_indent_name(indent_table) + fenceindent = 0 + if last_indent_name ~= "li" then + fenceindent = #trail + end + return true end - return true - end - local fencehead = function(char, infostring) - return Cmt(Cb("indent_info") * parsers.check_trail, count_fenced_start_indent) - * Cg(char^3, "fencelength") - * parsers.optionalspace - * infostring - * (parsers.newline + parsers.eof) + local fencehead = function(char, infostring) + return Cmt( Cb("indent_info") + * parsers.check_trail, count_fenced_start_indent) + * Cg(char^3, "fencelength") + * parsers.optionalspace + * infostring + * (parsers.newline + parsers.eof) end - local fencetail = function(char) - return parsers.check_trail_no_rem - * Cmt(C(char^3) * Cb("fencelength"), captures_geq_length) - * parsers.optionalspace * (parsers.newline + parsers.eof) - + parsers.eof + local fencetail = function(char) + return parsers.check_trail_no_rem + * Cmt(C(char^3) * Cb("fencelength"), captures_geq_length) + * parsers.optionalspace * (parsers.newline + parsers.eof) + + parsers.eof end - local function process_fenced_line(s, i, indent_table, line_content, is_blank) -- luacheck: ignore s i - local remainder = "" - if has_trail(indent_table) then - remainder = indent_table.trail.internal_remainder - end + local process_fenced_line = + function(s, i, -- luacheck: ignore s i + indent_table, line_content, is_blank) + local remainder = "" + if has_trail(indent_table) then + remainder = indent_table.trail.internal_remainder + end - if is_blank and get_last_indent_name(indent_table) == "li" then - remainder = "" - end + if is_blank + and get_last_indent_name(indent_table) == "li" then + remainder = "" + end - local str = remainder .. line_content - local index = 1 - local remaining = fenceindent + local str = remainder .. line_content + local index = 1 + local remaining = fenceindent - while true do - local c = str:sub(index, index) - if c == " " and remaining > 0 then - remaining = remaining - 1 - index = index + 1 - elseif c == "\t" and remaining > 3 then - remaining = remaining - 4 - index = index + 1 - else - break + while true do + local c = str:sub(index, index) + if c == " " and remaining > 0 then + remaining = remaining - 1 + index = index + 1 + elseif c == "\t" and remaining > 3 then + remaining = remaining - 4 + index = index + 1 + else + break + end end - end - return true, str:sub(index) - end + return true, str:sub(index) + end local fencedline = function(char) - return Cmt(Cb("indent_info") * C(parsers.line - fencetail(char)) * Cc(false), process_fenced_line) + return Cmt( Cb("indent_info") + * C(parsers.line - fencetail(char)) + * Cc(false), process_fenced_line) end - local blankfencedline = Cmt(Cb("indent_info") * C(parsers.blankline) * Cc(true), process_fenced_line) + local blankfencedline + = Cmt( Cb("indent_info") + * C(parsers.blankline) + * Cc(true), process_fenced_line) local TildeFencedCode - = fencehead(parsers.tilde, tilde_infostring) - * Cs(((parsers.check_minimal_blank_indent / "") * blankfencedline - + (parsers.check_minimal_indent / "") * fencedline(parsers.tilde))^0) - * ((parsers.check_minimal_indent / "") * fencetail(parsers.tilde) + parsers.succeed) + = fencehead(parsers.tilde, tilde_infostring) + * Cs(( (parsers.check_minimal_blank_indent / "") + * blankfencedline + + ( parsers.check_minimal_indent / "") + * fencedline(parsers.tilde))^0) + * ( (parsers.check_minimal_indent / "") + * fencetail(parsers.tilde) + parsers.succeed) local BacktickFencedCode = fencehead(parsers.backtick, backtick_infostring) - * Cs(((parsers.check_minimal_blank_indent / "") * blankfencedline - + (parsers.check_minimal_indent / "") * fencedline(parsers.backtick))^0) - * ((parsers.check_minimal_indent / "") * fencetail(parsers.backtick) + parsers.succeed) + * Cs(( (parsers.check_minimal_blank_indent / "") + * blankfencedline + + (parsers.check_minimal_indent / "") + * fencedline(parsers.backtick))^0) + * ( (parsers.check_minimal_indent / "") + * fencetail(parsers.backtick) + parsers.succeed) local infostring_with_attributes = Ct(C((parsers.linechar @@ -31179,28 +32222,28 @@ M.extensions.fenced_code = function(blank_before_code_fence, * Ct(parsers.attributes)) local FencedCode - = ((TildeFencedCode + BacktickFencedCode) - / function(infostring, code) - local expanded_code = self.expandtabs(code) - - if allow_raw_blocks then - local raw_attr = lpeg.match(parsers.raw_attribute, - infostring) - if raw_attr then - return writer.rawBlock(expanded_code, raw_attr) - end - end - - local attr = nil - if allow_attributes then - local match = lpeg.match(infostring_with_attributes, - infostring) - if match then - infostring, attr = table.unpack(match) - end - end - return writer.fencedCode(expanded_code, infostring, attr) - end) + = ((TildeFencedCode + BacktickFencedCode) + / function(infostring, code) + local expanded_code = self.expandtabs(code) + + if allow_raw_blocks then + local raw_attr = lpeg.match(parsers.raw_attribute, + infostring) + if raw_attr then + return writer.rawBlock(expanded_code, raw_attr) + end + end + + local attr = nil + if allow_attributes then + local match = lpeg.match(infostring_with_attributes, + infostring) + if match then + infostring, attr = table.unpack(match) + end + end + return writer.fencedCode(expanded_code, infostring, attr) + end) self.insert_pattern("Block after Verbatim", FencedCode, "FencedCode") @@ -31252,10 +32295,13 @@ M.extensions.fenced_divs = function(blank_before_div_fence) % \end{markdown} % \begin{macrocode} function self.div_begin(attributes) - local start_output = {"\\markdownRendererFencedDivAttributeContextBegin\n", - self.attributes(attributes)} - local end_output = {"\\markdownRendererFencedDivAttributeContextEnd{}"} - return self.push_attributes("div", attributes, start_output, end_output) + local start_output + = {"\\markdownRendererFencedDivAttributeContextBegin\n", + self.attributes(attributes)} + local end_output + = {"\\markdownRendererFencedDivAttributeContextEnd{}"} + return self.push_attributes( + "div", attributes, start_output, end_output) end % \end{macrocode} % \par @@ -31316,21 +32362,24 @@ M.extensions.fenced_divs = function(blank_before_div_fence) self.initialize_named_group("fenced_div_num_opening_indents") local function increment_div_level() - local function push_indent_table(s, i, indent_table, -- luacheck: ignore s i - fenced_div_num_opening_indents, fenced_div_level) - fenced_div_level = tonumber(fenced_div_level) + 1 - local num_opening_indents = 0 - if indent_table.indents ~= nil then - num_opening_indents = #indent_table.indents + local push_indent_table = + function(s, i, indent_table, -- luacheck: ignore s i + fenced_div_num_opening_indents, fenced_div_level) + fenced_div_level = tonumber(fenced_div_level) + 1 + local num_opening_indents = 0 + if indent_table.indents ~= nil then + num_opening_indents = #indent_table.indents + end + fenced_div_num_opening_indents[fenced_div_level] + = num_opening_indents + return true, fenced_div_num_opening_indents end - fenced_div_num_opening_indents[fenced_div_level] = num_opening_indents - return true, fenced_div_num_opening_indents - end - local function increment_level(s, i, fenced_div_level) -- luacheck: ignore s i - fenced_div_level = tonumber(fenced_div_level) + 1 - return true, tostring(fenced_div_level) - end + local increment_level = + function(s, i, fenced_div_level) -- luacheck: ignore s i + fenced_div_level = tonumber(fenced_div_level) + 1 + return true, tostring(fenced_div_level) + end return Cg( Cmt( Cb("indent_info") * Cb("fenced_div_num_opening_indents") @@ -31341,11 +32390,13 @@ M.extensions.fenced_divs = function(blank_before_div_fence) end local function decrement_div_level() - local function pop_indent_table(s, i, fenced_div_indent_table, fenced_div_level) -- luacheck: ignore s i - fenced_div_level = tonumber(fenced_div_level) - fenced_div_indent_table[fenced_div_level] = nil - return true, tostring(fenced_div_level - 1) - end + local pop_indent_table = + function(s, i, -- luacheck: ignore s i + fenced_div_indent_table, fenced_div_level) + fenced_div_level = tonumber(fenced_div_level) + fenced_div_indent_table[fenced_div_level] = nil + return true, tostring(fenced_div_level - 1) + end return Cg( Cmt( Cb("fenced_div_num_opening_indents") * Cb("fenced_div_level"), pop_indent_table) @@ -31353,21 +32404,24 @@ M.extensions.fenced_divs = function(blank_before_div_fence) end - local non_fenced_div_block = parsers.check_minimal_indent * V("Block") - - parsers.check_minimal_indent_and_trail * fenced_div_end + local non_fenced_div_block + = parsers.check_minimal_indent * V("Block") + - parsers.check_minimal_indent_and_trail * fenced_div_end - local non_fenced_div_paragraph = parsers.check_minimal_indent * V("Paragraph") - - parsers.check_minimal_indent_and_trail * fenced_div_end + local non_fenced_div_paragraph + = parsers.check_minimal_indent * V("Paragraph") + - parsers.check_minimal_indent_and_trail * fenced_div_end local blank = parsers.minimally_indented_blank - local block_separated = parsers.block_sep_group(blank) - * non_fenced_div_block + local block_separated = parsers.block_sep_group(blank) + * non_fenced_div_block - local loop_body_pair = parsers.create_loop_body_pair(block_separated, - non_fenced_div_paragraph, - parsers.block_sep_group(blank), - parsers.par_sep_group(blank)) + local loop_body_pair + = parsers.create_loop_body_pair(block_separated, + non_fenced_div_paragraph, + parsers.block_sep_group(blank), + parsers.par_sep_group(blank)) local content_loop = ( non_fenced_div_block * loop_body_pair.block^0 @@ -31380,7 +32434,9 @@ M.extensions.fenced_divs = function(blank_before_div_fence) local FencedDiv = fenced_div_begin / function (infostring) - local attr = lpeg.match(Ct(parsers.attributes), infostring) + local attr + = lpeg.match(Ct(parsers.attributes), + infostring) if attr == nil then attr = {"." .. infostring} end @@ -31391,7 +32447,8 @@ M.extensions.fenced_divs = function(blank_before_div_fence) * parsers.skipblanklines * Ct(content_loop) * parsers.minimally_indented_blank^0 - * parsers.check_minimal_indent_and_trail * fenced_div_end + * parsers.check_minimal_indent_and_trail + * fenced_div_end * decrement_div_level() * (Cc("") / writer.div_end) @@ -31412,23 +32469,27 @@ M.extensions.fenced_divs = function(blank_before_div_fence) % \end{markdown} % \begin{macrocode} local function is_inside_div() - local function check_div_level(s, i, fenced_div_level) -- luacheck: ignore s i - fenced_div_level = tonumber(fenced_div_level) - return fenced_div_level > 0 - end + local check_div_level = + function(s, i, fenced_div_level) -- luacheck: ignore s i + fenced_div_level = tonumber(fenced_div_level) + return fenced_div_level > 0 + end return Cmt(Cb("fenced_div_level"), check_div_level) end local function check_indent() - local function compare_indent(s, i, indent_table, -- luacheck: ignore s i - fenced_div_num_opening_indents, fenced_div_level) - fenced_div_level = tonumber(fenced_div_level) - local num_current_indents = (indent_table.current_line_indents ~= nil and - #indent_table.current_line_indents) or 0 - local num_opening_indents = fenced_div_num_opening_indents[fenced_div_level] - return num_current_indents == num_opening_indents - end + local compare_indent = + function(s, i, indent_table, -- luacheck: ignore s i + fenced_div_num_opening_indents, fenced_div_level) + fenced_div_level = tonumber(fenced_div_level) + local num_current_indents + = ( indent_table.current_line_indents ~= nil and + #indent_table.current_line_indents) or 0 + local num_opening_indents + = fenced_div_num_opening_indents[fenced_div_level] + return num_current_indents == num_opening_indents + end return Cmt( Cb("indent_info") * Cb("fenced_div_num_opening_indents") @@ -31500,26 +32561,31 @@ M.extensions.header_attributes = function() * parsers.newline))^1 - parsers.thematic_break_lines - local heading_text = heading_line - * ((V("Endline") / "\n") * (heading_line - parsers.heading_level))^0 - * parsers.newline^-1 - - local SetextHeading = parsers.freeze_trail * parsers.check_trail_no_rem - * #(heading_text - * (parsers.attributes - * parsers.optionalspace - * parsers.newline)^-1 - * parsers.check_minimal_indent * parsers.check_trail * parsers.heading_level) - * Cs(heading_text) / strip_trailing_spaces - / parsers.parse_heading_text - * Cg(Ct((parsers.attributes - * parsers.optionalspace - * parsers.newline)^-1), "attributes") - * parsers.check_minimal_indent_and_trail * parsers.heading_level - * Cb("attributes") - * parsers.newline - * parsers.unfreeze_trail - / writer.heading + local heading_text + = heading_line + * ( (V("Endline") / "\n") + * (heading_line - parsers.heading_level))^0 + * parsers.newline^-1 + + local SetextHeading + = parsers.freeze_trail * parsers.check_trail_no_rem + * #(heading_text + * (parsers.attributes + * parsers.optionalspace + * parsers.newline)^-1 + * parsers.check_minimal_indent + * parsers.check_trail + * parsers.heading_level) + * Cs(heading_text) / strip_trailing_spaces + / parsers.parse_heading_text + * Cg(Ct((parsers.attributes + * parsers.optionalspace + * parsers.newline)^-1), "attributes") + * parsers.check_minimal_indent_and_trail * parsers.heading_level + * Cb("attributes") + * parsers.newline + * parsers.unfreeze_trail + / writer.heading local Heading = AtxHeading + SetextHeading self.update_rule("Heading", Heading) @@ -31593,18 +32659,18 @@ M.extensions.line_blocks = function() local parsers = self.parsers local writer = self.writer - local LineBlock = Ct( - (Cs( - ( (parsers.pipe * parsers.space)/"" - * ((parsers.space)/entities.char_entity("nbsp"))^0 - * parsers.linechar^0 * (parsers.newline/"")) - * (-parsers.pipe - * (parsers.space^1/" ") - * parsers.linechar^1 - * (parsers.newline/"") - )^0 - * (parsers.blankline/"")^0 - ) / self.parser_functions.parse_inlines)^1) / writer.lineblock + local LineBlock + = Ct((Cs(( (parsers.pipe * parsers.space) / "" + * ((parsers.space)/entities.char_entity("nbsp"))^0 + * parsers.linechar^0 * (parsers.newline/"")) + * (-parsers.pipe + * (parsers.space^1/" ") + * parsers.linechar^1 + * (parsers.newline/"") + )^0 + * (parsers.blankline/"")^0) + / self.parser_functions.parse_inlines)^1) + / writer.lineblock self.insert_pattern("Block after Blockquote", LineBlock, "LineBlock") @@ -31644,8 +32710,9 @@ M.extensions.mark = function() local doubleequals = P("==") - local Mark = parsers.between(V("Inline"), doubleequals, doubleequals) - / function (inlines) return writer.mark(inlines) end + local Mark + = parsers.between(V("Inline"), doubleequals, doubleequals) + / function (inlines) return writer.mark(inlines) end self.add_special_character("=") self.insert_pattern("Inline before LinkAndEmph", @@ -31678,13 +32745,18 @@ M.extensions.link_attributes = function() % % \end{markdown} % \begin{macrocode} - local define_reference_parser = (parsers.check_trail / "") * parsers.link_label * parsers.colon - * parsers.spnlc * parsers.url - * ( parsers.spnlc_sep * parsers.title * (parsers.spnlc * Ct(parsers.attributes)) - * parsers.only_blank - + parsers.spnlc_sep * parsers.title * parsers.only_blank - + Cc("") * (parsers.spnlc * Ct(parsers.attributes)) * parsers.only_blank - + Cc("") * parsers.only_blank) + local define_reference_parser + = (parsers.check_trail / "") + * parsers.link_label + * parsers.colon + * parsers.spnlc * parsers.url + * ( parsers.spnlc_sep * parsers.title + * (parsers.spnlc * Ct(parsers.attributes)) + * parsers.only_blank + + parsers.spnlc_sep * parsers.title * parsers.only_blank + + Cc("") * (parsers.spnlc * Ct(parsers.attributes)) + * parsers.only_blank + + Cc("") * parsers.only_blank) local ReferenceWithAttributes = define_reference_parser / self.register_link @@ -31699,8 +32771,10 @@ M.extensions.link_attributes = function() % \end{markdown} % \begin{macrocode} - local LinkWithAttributesAndEmph = Ct(parsers.link_and_emph_table * Cg(Cc(true), "match_link_attributes")) - / self.defer_link_and_emphasis_processing + local LinkWithAttributesAndEmph + = Ct(parsers.link_and_emph_table * Cg(Cc(true), + "match_link_attributes")) + / self.defer_link_and_emphasis_processing self.update_rule("LinkAndEmph", LinkWithAttributesAndEmph) @@ -31781,11 +32855,14 @@ M.extensions.notes = function(notes, inline_notes) local parsers = self.parsers local writer = self.writer + local rawnotes = parsers.rawnotes + if inline_notes then local InlineNote - = parsers.circumflex - * (parsers.link_label / self.parser_functions.parse_inlines_no_inline_note) - / writer.note + = parsers.circumflex + * ( parsers.link_label + / self.parser_functions.parse_inlines_no_inline_note) + / writer.note self.insert_pattern("Inline after LinkAndEmph", InlineNote, "InlineNote") @@ -31799,8 +32876,6 @@ M.extensions.notes = function(notes, inline_notes) = #(parsers.lbracket * parsers.circumflex) * parsers.link_label / strip_first_char - local rawnotes = {} - -- like indirect_link local function lookup_note(ref) return writer.defer_call(function() @@ -31825,20 +32900,27 @@ M.extensions.notes = function(notes, inline_notes) local NoteRef = RawNoteRef / lookup_note - local optionally_indented_line = parsers.check_optional_indent_and_any_trail * parsers.line + local optionally_indented_line + = parsers.check_optional_indent_and_any_trail * parsers.line - local blank = parsers.check_optional_blank_indent_and_any_trail * parsers.optionalspace * parsers.newline + local blank + = parsers.check_optional_blank_indent_and_any_trail + * parsers.optionalspace * parsers.newline - local chunk = Cs(parsers.line * (optionally_indented_line - blank)^0) + local chunk + = Cs(parsers.line + * (optionally_indented_line - blank)^0) local indented_blocks = function(bl) return Cs( bl - * (blank^1 * (parsers.check_optional_indent / "") - * parsers.check_code_trail * -parsers.blankline * bl)^0) + * ( blank^1 * (parsers.check_optional_indent / "") + * parsers.check_code_trail + * -parsers.blankline * bl)^0) end local NoteBlock - = parsers.check_trail_no_rem * RawNoteRef * parsers.colon + = parsers.check_trail_no_rem + * RawNoteRef * parsers.colon * parsers.spnlc * indented_blocks(chunk) / register_note @@ -31996,24 +33078,26 @@ M.extensions.pipe_tables = function(table_captions, table_attributes) , table_hline_separator , table_hline_column) - local table_caption_beginning = (parsers.check_minimal_blank_indent_and_any_trail_no_rem - * parsers.optionalspace * parsers.newline)^0 - * parsers.check_minimal_indent_and_trail - * (P("Table")^-1 * parsers.colon) - * parsers.optionalspace + local table_caption_beginning + = ( parsers.check_minimal_blank_indent_and_any_trail_no_rem + * parsers.optionalspace * parsers.newline)^0 + * parsers.check_minimal_indent_and_trail + * (P("Table")^-1 * parsers.colon) + * parsers.optionalspace local function strip_trailing_spaces(s) return s:gsub("%s*$","") end - local table_row = pipe_table_row(true - , (C((parsers.linechar - parsers.pipe)^1) - / strip_trailing_spaces - / self.parser_functions.parse_inlines) - , parsers.pipe - , (C((parsers.linechar - parsers.pipe)^0) - / strip_trailing_spaces - / self.parser_functions.parse_inlines)) + local table_row + = pipe_table_row(true + , (C((parsers.linechar - parsers.pipe)^1) + / strip_trailing_spaces + / self.parser_functions.parse_inlines) + , parsers.pipe + , (C((parsers.linechar - parsers.pipe)^0) + / strip_trailing_spaces + / self.parser_functions.parse_inlines)) local table_caption if table_captions then @@ -32030,7 +33114,8 @@ M.extensions.pipe_tables = function(table_captions, table_attributes) + ( parsers.newline * #( parsers.optionalspace * parsers.linechar) - * C(parsers.optionalspace) / writer.space)) + * C(parsers.optionalspace) + / writer.space)) * (parsers.linechar - parsers.lbrace)^0)^1) / self.parser_functions.parse_inlines) @@ -32044,7 +33129,8 @@ M.extensions.pipe_tables = function(table_captions, table_attributes) + ( parsers.newline * #( parsers.optionalspace * parsers.linechar) - * C(parsers.optionalspace) / writer.space))^1) + * C(parsers.optionalspace) + / writer.space))^1) / self.parser_functions.parse_inlines * parsers.newline end @@ -32052,12 +33138,15 @@ M.extensions.pipe_tables = function(table_captions, table_attributes) table_caption = parsers.fail end - local PipeTable = Ct(table_row * parsers.newline * (parsers.check_minimal_indent_and_trail / {}) - * table_hline * parsers.newline - * ((parsers.check_minimal_indent / {}) * table_row * parsers.newline)^0) - / make_pipe_table_rectangular - * table_caption^-1 - / writer.table + local PipeTable + = Ct( table_row * parsers.newline + * (parsers.check_minimal_indent_and_trail / {}) + * table_hline * parsers.newline + * ( (parsers.check_minimal_indent / {}) + * table_row * parsers.newline)^0) + / make_pipe_table_rectangular + * table_caption^-1 + / writer.table self.insert_pattern("Block after Blockquote", PipeTable, "PipeTable") @@ -32225,7 +33314,8 @@ M.extensions.superscripts = function() local writer = self.writer local Superscript = ( - parsers.between(parsers.Str, parsers.circumflex, parsers.circumflex) + parsers.between(parsers.Str, parsers.circumflex, + parsers.circumflex) ) / writer.superscript self.insert_pattern("Inline after LinkAndEmph", @@ -32288,11 +33378,13 @@ M.extensions.tex_math = function(tex_math_dollars, return str:gsub("^%s*(.-)$", "%1") end - local allowed_before_closing = B( parsers.backslash * parsers.any - + parsers.any * (parsers.any - parsers.backslash)) + local allowed_before_closing + = B( parsers.backslash * parsers.any + + parsers.any * (parsers.any - parsers.backslash)) - local allowed_before_closing_no_space = B( parsers.backslash * parsers.any - + parsers.any * (parsers.nonspacechar - parsers.backslash)) + local allowed_before_closing_no_space + = B( parsers.backslash * parsers.any + + parsers.any * (parsers.nonspacechar - parsers.backslash)) % \end{macrocode} % \begin{markdown} @@ -32301,18 +33393,20 @@ M.extensions.tex_math = function(tex_math_dollars, % % \end{markdown} % \begin{macrocode} - local dollar_math_content = (parsers.newline * (parsers.check_optional_indent / "") - + parsers.backslash^-1 - * parsers.linechar) - - parsers.blankline^2 - - parsers.dollar + local dollar_math_content + = (parsers.newline * (parsers.check_optional_indent / "") + + parsers.backslash^-1 + * parsers.linechar) + - parsers.blankline^2 + - parsers.dollar local inline_math_opening_dollars = parsers.dollar * #(parsers.nonspacechar) - local inline_math_closing_dollars = allowed_before_closing_no_space - * parsers.dollar - * -#(parsers.digit) + local inline_math_closing_dollars + = allowed_before_closing_no_space + * parsers.dollar + * -#(parsers.digit) local inline_math_dollars = between(Cs( dollar_math_content), inline_math_opening_dollars, @@ -32335,9 +33429,10 @@ M.extensions.tex_math = function(tex_math_dollars, % % \end{markdown} % \begin{macrocode} - local backslash_math_content = (parsers.newline * (parsers.check_optional_indent / "") - + parsers.linechar) - - parsers.blankline^2 + local backslash_math_content + = (parsers.newline * (parsers.check_optional_indent / "") + + parsers.linechar) + - parsers.blankline^2 % \end{macrocode} % \begin{markdown} % @@ -32457,11 +33552,15 @@ end % \acro{yaml} metadata block syntax extension. When the % `expect_jekyll_data` parameter is `true`, then a markdown document % may begin directly with \acro{yaml} metadata and may contain nothing -% but \acro{yaml} metadata. +% but \acro{yaml} metadata. When both `expect_jekyll_data` and +% `ensure_jekyll_data` parameters are `true`, then a a markdown document must +% begin directly with \acro{yaml} metadata and must contain nothing but +% \acro{yaml} metadata. % % \end{markdown} % \begin{macrocode} -M.extensions.jekyll_data = function(expect_jekyll_data) +M.extensions.jekyll_data = function(expect_jekyll_data, + ensure_jekyll_data) return { name = "built-in jekyll_data syntax extension", extend_writer = function(self) @@ -32474,7 +33573,8 @@ M.extensions.jekyll_data = function(expect_jekyll_data) % the key `p` in the parent table; if `p` is nil, then the table has no parent. % All scalar keys and values encountered in the table will be cast to a string % following \acro{yaml} serialization rules. String values will also be -% transformed using the function `t`. +% transformed using the function `t` for the typographic output format used by +% the \mref{markdownRendererJekyllDataTypographicString} macro. % % \end{markdown} % \begin{macrocode} @@ -32519,17 +33619,18 @@ M.extensions.jekyll_data = function(expect_jekyll_data) ::not_a_sequence:: if is_sequence then - table.insert(buf, "\\markdownRendererJekyllDataSequenceBegin{") - table.insert(buf, self.identifier(p or "null")) - table.insert(buf, "}{") - table.insert(buf, #keys) - table.insert(buf, "}") + table.insert(buf, + "\\markdownRendererJekyllDataSequenceBegin{") + table.insert(buf, self.identifier(p or "null")) + table.insert(buf, "}{") + table.insert(buf, #keys) + table.insert(buf, "}") else - table.insert(buf, "\\markdownRendererJekyllDataMappingBegin{") - table.insert(buf, self.identifier(p or "null")) - table.insert(buf, "}{") - table.insert(buf, #keys) - table.insert(buf, "}") + table.insert(buf, "\\markdownRendererJekyllDataMappingBegin{") + table.insert(buf, self.identifier(p or "null")) + table.insert(buf, "}{") + table.insert(buf, #keys) + table.insert(buf, "}") end for _, k in ipairs(keys) do @@ -32557,7 +33658,14 @@ M.extensions.jekyll_data = function(expect_jekyll_data) table.insert(buf, v) table.insert(buf, "}") elseif typ == "string" then - table.insert(buf, "\\markdownRendererJekyllDataString{") + table.insert(buf, + "\\markdownRendererJekyllDataProgrammaticString{") + table.insert(buf, k) + table.insert(buf, "}{") + table.insert(buf, self.identifier(v)) + table.insert(buf, "}") + table.insert(buf, + "\\markdownRendererJekyllDataTypographicString{") table.insert(buf, k) table.insert(buf, "}{") table.insert(buf, t(v)) @@ -32567,8 +33675,10 @@ M.extensions.jekyll_data = function(expect_jekyll_data) table.insert(buf, k) table.insert(buf, "}") else - error(format("Unexpected type %s for value of " .. - "YAML key %s", typ, k)) + local error = self.error(format( + "Unexpected type %s for value of " + .. "YAML key %s", typ, k)) + table.insert(buf, error) end end end @@ -32590,38 +33700,49 @@ M.extensions.jekyll_data = function(expect_jekyll_data) local writer = self.writer local JekyllData - = Cmt( C((parsers.line - P("---") - P("..."))^0) - , function(s, i, text) -- luacheck: ignore s i - local data - local ran_ok, _ = pcall(function() - -- TODO: Replace with `require("tinyyaml")` in TeX Live 2023 - local tinyyaml = require("markdown-tinyyaml") - data = tinyyaml.parse(text, {timestamps=false}) - end) - if ran_ok and data ~= nil then - return true, writer.jekyllData(data, function(s) - return self.parser_functions.parse_blocks_nested(s) - end, nil) - else - return false - end - end - ) + = Cmt( C((parsers.line - P("---") - P("..."))^0) + , function(s, i, text) -- luacheck: ignore s i + local data + local ran_ok, _ = pcall(function() + -- TODO: Use `require("tinyyaml")` in TeX Live 2023 + local tinyyaml = require("markdown-tinyyaml") + data = tinyyaml.parse(text, {timestamps=false}) + end) + if ran_ok and data ~= nil then + return true, writer.jekyllData(data, function(s) + return self.parser_functions.parse_blocks_nested(s) + end, nil) + else + return false + end + end + ) local UnexpectedJekyllData - = P("---") - * parsers.blankline / 0 - * #(-parsers.blankline) -- if followed by blank, it's thematic break - * JekyllData - * (P("---") + P("...")) + = P("---") + * parsers.blankline / 0 + -- if followed by blank, it's thematic break + * #(-parsers.blankline) + * JekyllData + * (P("---") + P("...")) local ExpectedJekyllData - = ( P("---") - * parsers.blankline / 0 - * #(-parsers.blankline) -- if followed by blank, it's thematic break - )^-1 - * JekyllData - * (P("---") + P("..."))^-1 + = ( P("---") + * parsers.blankline / 0 + -- if followed by blank, it's thematic break + * #(-parsers.blankline) + )^-1 + * JekyllData + * (P("---") + P("..."))^-1 + + if ensure_jekyll_data then + ExpectedJekyllData = ExpectedJekyllData + * parsers.eof + else + ExpectedJekyllData = ( ExpectedJekyllData + * (V("Blank")^0 / writer.interblocksep) + )^-1 + end self.insert_pattern("Block before Blockquote", UnexpectedJekyllData, "UnexpectedJekyllData") @@ -32636,9 +33757,127 @@ end % %### Conversion from Markdown to Plain \TeX{} % -% The \luamref{new} function returns a conversion function that takes a -% markdown string and turns it into a plain \TeX{} output. See Section -% <#sec:lua-conversion>. +% The \luamref{new} function of file `markdown.lua` loads file +% `markdown-parser.lua` and calls its own function \luamref{new} unless option +% \Opt{eagerCache} or \Opt{finalizeCache} has been enabled and a cached +% conversion output exists, in which case it is returned without loading file +% `markdown-parser.lua`. +% +% \end{markdown} +% \iffalse +%</lua> +%<*lua-loader> +% \fi +% \begin{macrocode} +local function warn(s) + io.stderr:write("Warning: " .. s .. "\n") +end + +function M.new(options) +% \end{macrocode} +% \par +% \begin{markdown} +% +% Make the `options` table inherit from the \luamref{defaultOptions} table. +% +% \end{markdown} +% \begin{macrocode} + options = options or {} + setmetatable(options, { __index = function (_, key) + return defaultOptions[key] end }) +% \end{macrocode} +% \par +% \begin{markdown} +% +% Return a conversion function that tries to produce a cached conversion output +% exists. If no cached conversion output exists, we load the file +% `markdown-parser.lua` and use it to convert the input. +% +% \end{markdown} +% \begin{macrocode} + local parser_convert = nil + return function(input) + local function convert(input) + if parser_convert == nil then +% \end{macrocode} +% \par +% \begin{markdown} +% +% Lazy-load `markdown-parser.lua` and check that it originates from the same +% version of the Markdown package. +% +% \end{markdown} +% \begin{macrocode} + local parser = require("markdown-parser") + if metadata.version ~= parser.metadata.version then + warn("markdown.lua " .. metadata.version .. " used with " .. + "markdown-parser.lua " .. parser.metadata.version .. ".") + end + parser_convert = parser.new(options) + end + return parser_convert(input) + end +% \end{macrocode} +% \begin{markdown} +% If we cache markdown documents, produce the cache file and transform its +% filename to plain \TeX{} output. +% +% When determining the name of the cache file, create salt for the hashing +% function out of the package version and the passed options recognized by the +% Lua interface (see Section <#sec:lua-options>). +% \end{markdown} +% \begin{macrocode} + local output + if options.eagerCache or options.finalizeCache then + local salt = util.salt(options) + local name = util.cache(options.cacheDir, input, salt, convert, + ".md.tex") + output = [[\input{]] .. name .. [[}\relax]] +% \end{macrocode} +% \begin{markdown} +% Otherwise, return the result of the conversion directly. +% \end{markdown} +% \begin{macrocode} + else + output = convert(input) + end +% \end{macrocode} +% \begin{markdown} +% If the \Opt{finalizeCache} option is enabled, populate the frozen cache in +% the file \Opt{frozenCacheFileName} with an entry for markdown document +% number \Opt{frozenCacheCounter}. +% \end{markdown} +% \begin{macrocode} + if options.finalizeCache then + local file, mode + if options.frozenCacheCounter > 0 then + mode = "a" + else + mode = "w" + end + file = assert(io.open(options.frozenCacheFileName, mode), + [[Could not open file "]] .. options.frozenCacheFileName + .. [[" for writing]]) + assert(file:write( + [[\expandafter\global\expandafter\def\csname ]] + .. [[markdownFrozenCache]] .. options.frozenCacheCounter + .. [[\endcsname{]] .. output .. [[}]] .. "\n")) + assert(file:close()) + end + return output + end +end +% \end{macrocode} +% \iffalse +%</lua-loader> +%<*lua> +% \fi +% \par +% \begin{markdown} +% +% The \luamref{new} function from file `markdown-parser.lua` returns a +% conversion function that takes a markdown string and turns it into a plain +% \TeX{} output. See Section <#sec:lua-conversion>. % % \end{markdown} % \begin{macrocode} @@ -32671,7 +33910,15 @@ function M.new(options) goto miss end end - elseif singletonCache.options[k] ~= options[k] then +% \end{macrocode} +% \begin{markdown} +% +% The \Opt{cacheDir} option is disregarded. +% +% \end{markdown} +% \begin{macrocode} + elseif k ~= "cacheDir" + and singletonCache.options[k] ~= options[k] then goto miss end end @@ -32732,7 +33979,7 @@ function M.new(options) if options.jekyllData then local jekyll_data_extension = M.extensions.jekyll_data( - options.expectJekyllData) + options.expectJekyllData, options.ensureJekyllData) table.insert(extensions, jekyll_data_extension) end @@ -32795,7 +34042,8 @@ function M.new(options) end if options.citations then - local citations_extension = M.extensions.citations(options.citationNbsps) + local citations_extension + = M.extensions.citations(options.citationNbsps) table.insert(extensions, citations_extension) end @@ -32820,7 +34068,9 @@ function M.new(options) % % \end{markdown} % \begin{macrocode} - local pathname = kpse.lookup(filename) + local pathname = assert(kpse.find_file(filename), + [[Could not locate user-defined syntax extension "]] + .. filename) local input_file = assert(io.open(pathname, "r"), [[Could not open user-defined syntax extension "]] .. pathname .. [[" for reading]]) @@ -32850,7 +34100,8 @@ function M.new(options) .. type(user_extension.api_version) .. [[" but "number" was expected]]) assert(user_extension.api_version > 0 - and user_extension.api_version <= metadata.user_extension_api_version, + and user_extension.api_version + <= metadata.user_extension_api_version, [[User-defined syntax extension "]] .. pathname .. [[" uses syntax extension API version "]] .. user_extension.api_version .. [[ but markdown.lua ]] @@ -32868,7 +34119,8 @@ function M.new(options) .. [[" but "number" was expected]]) assert(user_extension.grammar_version == metadata.grammar_version, [[User-defined syntax extension "]] .. pathname - .. [[" uses grammar version "]] .. user_extension.grammar_version + .. [[" uses grammar version "]] + .. user_extension.grammar_version .. [[ but markdown.lua ]] .. metadata.version .. [[ uses grammar version ]] .. metadata.grammar_version .. [[, which is incompatible]]) @@ -32950,11 +34202,16 @@ function M.new(options) % \begin{macrocode} return convert end - -return M % \end{macrocode} % \iffalse %</lua> +%<*lua,lua-loader> +% \fi +% \begin{macrocode} +return M +% \end{macrocode} +% \iffalse +%</lua,lua-loader> %<*lua-cli> % \fi % \par @@ -33119,7 +34376,7 @@ end %### Themes {#themes-implementation} % % This section implements the theme-loading mechanism and the built-in themes -% provided with the Markdown package. Futhermore, this section also implements +% provided with the Markdown package. Furthermore, this section also implements % the built-in plain \TeX{} themes provided with the Markdown package. % % \end{markdown} @@ -33308,18 +34565,22 @@ end \def\markdownRendererUlEndTightPrototype{}% \def\markdownRendererOlBeginPrototype{}% \def\markdownRendererOlBeginTightPrototype{}% -\def\markdownRendererFancyOlBeginPrototype#1#2{\markdownRendererOlBegin}% -\def\markdownRendererFancyOlBeginTightPrototype#1#2{\markdownRendererOlBeginTight}% +\def\markdownRendererFancyOlBeginPrototype#1#2{% + \markdownRendererOlBegin}% +\def\markdownRendererFancyOlBeginTightPrototype#1#2{% + \markdownRendererOlBeginTight}% \def\markdownRendererOlItemPrototype{}% \def\markdownRendererOlItemWithNumberPrototype#1{}% \def\markdownRendererOlItemEndPrototype{}% \def\markdownRendererFancyOlItemPrototype{\markdownRendererOlItem}% -\def\markdownRendererFancyOlItemWithNumberPrototype{\markdownRendererOlItemWithNumber}% +\def\markdownRendererFancyOlItemWithNumberPrototype{% + \markdownRendererOlItemWithNumber}% \def\markdownRendererFancyOlItemEndPrototype{}% \def\markdownRendererOlEndPrototype{}% \def\markdownRendererOlEndTightPrototype{}% \def\markdownRendererFancyOlEndPrototype{\markdownRendererOlEnd}% -\def\markdownRendererFancyOlEndTightPrototype{\markdownRendererOlEndTight}% +\def\markdownRendererFancyOlEndTightPrototype{% + \markdownRendererOlEndTight}% \def\markdownRendererDlBeginPrototype{}% \def\markdownRendererDlBeginTightPrototype{}% \def\markdownRendererDlItemPrototype#1{#1}% @@ -33393,6 +34654,8 @@ end \ExplSyntaxOff \def\markdownRendererSectionBeginPrototype{}% \def\markdownRendererSectionEndPrototype{}% +\let\markdownRendererWarningPrototype\markdownWarning +\let\markdownRendererErrorPrototype\markdownError % \end{macrocode} % \par % \begin{markdown} @@ -33407,7 +34670,7 @@ end % \begin{macrocode} \ExplSyntaxOn \cs_new:Nn - \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn + \@@_plain_tex_default_input_raw_inline:nn { \str_case:nn { #2 } @@ -33417,7 +34680,7 @@ end } } \cs_new:Nn - \@@_plain_tex_default_input_raw_block_renderer_prototype:nn + \@@_plain_tex_default_input_raw_block:nn { \str_case:nn { #2 } @@ -33429,14 +34692,14 @@ end \cs_gset:Npn \markdownRendererInputRawInlinePrototype#1#2 { - \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn + \@@_plain_tex_default_input_raw_inline:nn { #1 } { #2 } } \cs_gset:Npn \markdownRendererInputRawBlockPrototype#1#2 { - \@@_plain_tex_default_input_raw_block_renderer_prototype:nn + \@@_plain_tex_default_input_raw_block:nn { #1 } { #2 } } @@ -33673,7 +34936,17 @@ end { #1 } { #2 } } -\def\markdownRendererJekyllDataStringPrototype#1#2{ +% \end{macrocode} +% \par +% \begin{markdown} +% +% We will process all string scalar values assuming that they may contain +% markdown markup and are intended for typesetting. +% +% \end{markdown} +% \begin{macrocode} +\def\markdownRendererJekyllDataProgrammaticStringPrototype#1#2{} +\def\markdownRendererJekyllDataTypographicStringPrototype#1#2{ \markdown_jekyll_data_set_keyvals:nn { #1 } { #2 } @@ -34063,6 +35336,9 @@ end } } } + \str_gset:NV + \g_luabridge_output_dirname_str + \markdownOptionOutputDir \luabridge_now:e { #1 } } @@ -34199,12 +35475,14 @@ end \msg_new:nnn { markdown } { buffering-markinline } - { Buffering~inline~markdown~input~into~the~temporary~input~file~"#1". } + { Buffering~inline~markdown~input~into~ + the~temporary~input~file~"#1". } \msg_new:nnnn { markdown } { markinline-peek-failure } { Use~of~\iow_char:N \\ markinline~doesn't~match~its~definition } - { The~macro~should~be~followed~by~inline~markdown~text~in~curly~braces } + { The~macro~should~be~followed~by~inline~ + markdown~text~in~curly~braces } \ExplSyntaxOff % \end{macrocode} % \begin{markdown} @@ -34223,6 +35501,13 @@ end \markdownInput #1 { + \@@_if_option:nTF + { frozenCache } + { + \markdownInputRaw + { #1 } + } + { % \end{macrocode} % \begin{markdown} % @@ -34232,19 +35517,23 @@ end % % \end{markdown} % \begin{macrocode} - \file_get_full_name:nNTF - { #1 } - \l_tmpa_tl - { - \exp_args:NV - \markdownInputRaw + \tl_set:Nx \l_tmpa_tl - } - { - \msg_error:nnnV - { markdown } - { markdown-file-does-not-exist } { #1 } + \file_get_full_name:VNTF + \l_tmpa_tl + \l_tmpb_tl + { + \exp_args:NV + \markdownInputRaw + \l_tmpb_tl + } + { + \msg_error:nnV + { markdown } + { markdown-file-does-not-exist } + \l_tmpa_tl + } } } \msg_new:nnn @@ -34298,7 +35587,8 @@ end |fi |markdownInfo{Including markdown document number "|the|markdownOptionFrozenCacheCounter" from frozen cache}% - |csname markdownFrozenCache|the|markdownOptionFrozenCacheCounter|endcsname + |csname markdownFrozenCache% + |the|markdownOptionFrozenCacheCounter|endcsname |global|advance|markdownOptionFrozenCacheCounter by 1|relax }{% |markdownInfo{Including markdown document "&1"}% @@ -34358,7 +35648,7 @@ end % \LaTeX{} Implementation {#lateximplementation} %------------------------- % -% The \LaTeX{} implemenation makes use of the fact that, apart from some subtle +% The \LaTeX{} implementation makes use of the fact that, apart from some subtle % differences, \LaTeX{} implements the majority of the plain \TeX{} % format~[@latex17, Section 9]. As a consequence, we can directly reuse the % existing plain \TeX{} implementation. @@ -34522,13 +35812,26 @@ end % we let the \mref{markdownReadAndConvert} macro process the rest of the % \LaTeX{} environment. % +% We also make provision for using the \mref{markdown} command as a part of a +% different \LaTeX{} environment as follows: +% +% ``` tex +% \newenvironment{foo}\% +% {code before \markdown[some, options]}\% +% {\markdownEnd code after} +% ``` +% % \end{markdown} % \begin{macrocode} - \c { markdownReadAndConvert@markdown } { } + \c { exp_args:NV } + \c { markdownReadAndConvert@ } + \c { @currenvir } } { \group_end: - \markdownReadAndConvert@markdown { } + \exp_args:NV + \markdownReadAndConvert@ + \@currenvir } } { \markdownEnd } @@ -34542,7 +35845,8 @@ end { #1 } \@@_setup:n { #1 } - \markdownReadAndConvert@markdown * + \markdownReadAndConvert@ + { markdown* } } { \markdownEnd } \msg_new:nnn @@ -34552,6 +35856,9 @@ end The~markdown*~LaTeX~environment~has~been~deprecated~and~will~ be~removed~in~the~next~major~version~of~the~Markdown~package. } +\cs_generate_variant:Nn + \@@_setup:n + { V } \ExplSyntaxOff \begingroup % \end{macrocode} @@ -34565,9 +35872,9 @@ end % \begin{macrocode} \catcode`\|=0\catcode`\<=1\catcode`\>=2% \catcode`\\=12|catcode`|{=12|catcode`|}=12% - |gdef|markdownReadAndConvert@markdown#1<% - |markdownReadAndConvert<\end{markdown#1}>% - <|end<markdown#1>>>% + |gdef|markdownReadAndConvert@#1<% + |markdownReadAndConvert<\end{#1}>% + <|end<#1>>>% |endgroup % \end{macrocode} % \par @@ -34587,7 +35894,7 @@ end %### Themes {#latex-themes-implementation} % % This section overrides the plain \TeX{} implementation of the theme-loading -% mechanism from Section <#sec:themes-implementation>. Futhermore, this section +% mechanism from Section <#sec:themes-implementation>. Furthermore, this section % also implements the built-in \LaTeX{} themes provided with the Markdown package. % % \end{markdown} @@ -34782,7 +36089,8 @@ end % \end{markdown} % \begin{macrocode} }{% - \markdown@witiko@dot@oldRendererInputFencedCodePrototype{#1}{#2}{#3}% + \markdown@witiko@dot@oldRendererInputFencedCodePrototype + {#1}{#2}{#3}% }% }% \next#2 \relax}% @@ -35112,21 +36420,15 @@ end \tl_set:Nn \l_@@_latex_fancy_list_item_label_delimiter_style_tl { #2 } - \tl_set:Nn - \l_tmpa_tl - { - \plpartopsep=\partopsep - \pltopsep=\topsep - } \@@_if_option:nTF { startNumber } { - \tl_put_right:Nn + \tl_set:Nn \l_tmpa_tl { \begin{compactenum} } } { - \tl_put_right:Nn + \tl_set:Nn \l_tmpa_tl { \begin{compactenum}[ } \tl_put_right:Nx @@ -35136,6 +36438,12 @@ end \l_tmpa_tl { ] } } + \tl_put_left:Nn + \l_tmpa_tl + { + \plpartopsep=\partopsep + \pltopsep=\topsep + } \tl_use:N \l_tmpa_tl }, @@ -35598,8 +36906,9 @@ end \advance\markdownLaTeXCitationsCounter by 1\relax \ifx\relax#4\relax \ifx\relax#5\relax - \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax - \cite{#1#2#6}% Without prenotes and postnotes, just accumulate cites + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal + \relax + \cite{#1#2#6}% No prenotes/postnotes, just accumulate cites \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter \@gobblethree @@ -35609,7 +36918,8 @@ end \cite{#1}% \fi \cite[#5]{#6}% - \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal + \relax \else \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter @@ -35636,7 +36946,8 @@ end \space % Insert a space before the prenote in later citations \fi #4~\expandafter\cite\ifx\relax#5\relax{#6}\else[#5]{#6}\fi - \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal + \relax \else \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter @@ -35656,8 +36967,9 @@ end \advance\markdownLaTeXCitationsCounter by 1\relax \ifx\relax#3\relax \ifx\relax#4\relax - \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax - \citep{#1,#5}% Without prenotes and postnotes, just accumulate cites + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal + \relax + \citep{#1,#5}% No prenotes/postnotes, just accumulate cites \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter \@gobbletwo @@ -35667,7 +36979,8 @@ end \citep{#1}% \fi \citep[][#4]{#5}% - \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal + \relax \else \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter @@ -35687,7 +37000,8 @@ end \citep{#1}% \fi \citep[#3][#4]{#5}% - \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal + \relax \else \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter @@ -35702,8 +37016,9 @@ end \advance\markdownLaTeXCitationsCounter by 1\relax \ifx\relax#3\relax \ifx\relax#4\relax - \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax - \citet{#1,#5}% Without prenotes and postnotes, just accumulate cites + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal + \relax + \citet{#1,#5}% No prenotes/postnotes, just accumulate cites \expandafter\expandafter\expandafter \expandafter\expandafter\expandafter\expandafter \@gobbletwo @@ -35713,10 +37028,13 @@ end \citet{#1}% \fi , \citet[#3][#4]{#5}% - \ifnum\markdownLaTeXCitationsCounter<\markdownLaTeXCitationsTotal\relax + \ifnum\markdownLaTeXCitationsCounter<\markdownLaTeXCitationsTotal + \relax , \else - \ifnum\markdownLaTeXCitationsCounter=\markdownLaTeXCitationsTotal\relax + \ifnum + \markdownLaTeXCitationsCounter=\markdownLaTeXCitationsTotal + \relax , \fi \fi @@ -35735,10 +37053,13 @@ end \citet{#1}% \fi , \citet[#3][#4]{#5}% - \ifnum\markdownLaTeXCitationsCounter<\markdownLaTeXCitationsTotal\relax + \ifnum\markdownLaTeXCitationsCounter<\markdownLaTeXCitationsTotal + \relax , \else - \ifnum\markdownLaTeXCitationsCounter=\markdownLaTeXCitationsTotal\relax + \ifnum + \markdownLaTeXCitationsCounter=\markdownLaTeXCitationsTotal + \relax , \fi \fi @@ -35753,13 +37074,15 @@ end % BibLaTeX implementation \def\markdownLaTeXBibLaTeXCitations#1#2#3#4#5{% \advance\markdownLaTeXCitationsCounter by 1\relax - \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal + \relax \autocites#1[#3][#4]{#5}% \expandafter\@gobbletwo \fi\markdownLaTeXBibLaTeXCitations{#1[#3][#4]{#5}}} \def\markdownLaTeXBibLaTeXTextCitations#1#2#3#4#5{% \advance\markdownLaTeXCitationsCounter by 1\relax - \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal + \relax \textcites#1[#3][#4]{#5}% \expandafter\@gobbletwo \fi\markdownLaTeXBibLaTeXTextCitations{#1[#3][#4]{#5}}} @@ -35852,7 +37175,8 @@ end { \markdownLaTeXRendererAutolink { #2 } { #3 } }{ - \markdownLaTeXRendererDirectOrIndirectLink { #1 } { #2 } { #3 } { #4 } + \markdownLaTeXRendererDirectOrIndirectLink + { #1 } { #2 } { #3 } { #4 } } } \def\markdownLaTeXRendererAutolink#1#2{% @@ -36151,13 +37475,13 @@ end { { latex } { - \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn + \@@_plain_tex_default_input_raw_inline:nn { #1 } { tex } } } { - \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn + \@@_plain_tex_default_input_raw_inline:nn { #1 } { #2 } } @@ -36170,13 +37494,13 @@ end { { latex } { - \@@_plain_tex_default_input_raw_block_renderer_prototype:nn + \@@_plain_tex_default_input_raw_block:nn { #1 } { tex } } } { - \@@_plain_tex_default_input_raw_block_renderer_prototype:nn + \@@_plain_tex_default_input_raw_block:nn { #1 } { #2 } } @@ -36314,7 +37638,7 @@ end %### Themes {#context-themes-implementation} % % This section overrides the plain \TeX{} implementation of the theme-loading -% mechanism from Section <#sec:themes-implementation>. Futhermore, this section +% mechanism from Section <#sec:themes-implementation>. Furthermore, this section % also implements the built-in \Hologo{ConTeXt} themes provided with the % Markdown package. % @@ -36359,7 +37683,7 @@ end % \end{macrocode} % \iffalse %</context> -%<*themes-witiko-markdown-defaults-context> +%<*themes-witiko-markdown-defaults-ctx> % \fi % \par % \begin{markdown} @@ -36541,7 +37865,8 @@ end \def\markdownRendererStrikeThroughPrototype#1{\overstrikes{#1}} \def\markdownRendererSuperscriptPrototype#1{\high{#1}} \def\markdownRendererSubscriptPrototype#1{\low{#1}} -\def\markdownRendererDisplayMathPrototype#1{\startformula#1\stopformula}% +\def\markdownRendererDisplayMathPrototype#1{% + \startformula#1\stopformula}% % \end{macrocode} % \par % \begin{markdown} @@ -36567,8 +37892,10 @@ end \placetable{#1}{\the\markdownConTeXtTable}}% \fi \begingroup - \setupTABLE[r][each][topframe=off, bottomframe=off, leftframe=off, rightframe=off] - \setupTABLE[c][each][topframe=off, bottomframe=off, leftframe=off, rightframe=off] + \setupTABLE[r][each][topframe=off, bottomframe=off, + leftframe=off, rightframe=off] + \setupTABLE[c][each][topframe=off, bottomframe=off, + leftframe=off, rightframe=off] \setupTABLE[r][1][topframe=on, bottomframe=on] \setupTABLE[r][#1][bottomframe=on] \markdownConTeXtRowCounter=0% @@ -36606,14 +37933,16 @@ end \fi\if#1r% \setupTABLE[c][\the\markdownConTeXtColumnCounter][align=left] \fi - \ifnum\markdownConTeXtColumnCounter<\markdownConTeXtColumnTotal\relax\else + \ifnum\markdownConTeXtColumnCounter<\markdownConTeXtColumnTotal\relax + \else \expandafter\gobbleoneargument \fi\markdownConTeXtReadAlignments} \def\markdownConTeXtRenderTableCell#1{% \advance\markdownConTeXtColumnCounter by 1\relax \markdownConTeXtTable=\expandafter{% \the\markdownConTeXtTable\bTD#1\eTD}% - \ifnum\markdownConTeXtColumnCounter<\markdownConTeXtColumnTotal\relax\else + \ifnum\markdownConTeXtColumnCounter<\markdownConTeXtColumnTotal\relax + \else \expandafter\gobbleoneargument \fi\markdownConTeXtRenderTableCell} % \end{macrocode} @@ -36636,13 +37965,13 @@ end { { latex } { - \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn + \@@_plain_tex_default_input_raw_inline:nn { #1 } { context } } } { - \@@_plain_tex_default_input_raw_inline_renderer_prototype:nn + \@@_plain_tex_default_input_raw_inline:nn { #1 } { #2 } } @@ -36655,13 +37984,13 @@ end { { context } { - \@@_plain_tex_default_input_raw_block_renderer_prototype:nn + \@@_plain_tex_default_input_raw_block:nn { #1 } { tex } } } { - \@@_plain_tex_default_input_raw_block_renderer_prototype:nn + \@@_plain_tex_default_input_raw_block:nn { #1 } { #2 } } @@ -36675,7 +38004,7 @@ end \protect % \end{macrocode} % \iffalse -%</themes-witiko-markdown-defaults-context> +%</themes-witiko-markdown-defaults-ctx> %<*context> % \fi % \par diff --git a/Master/texmf-dist/source/generic/markdown/markdown.ins b/Master/texmf-dist/source/generic/markdown/markdown.ins index 8e777f4217c..152fe4832b2 100644 --- a/Master/texmf-dist/source/generic/markdown/markdown.ins +++ b/Master/texmf-dist/source/generic/markdown/markdown.ins @@ -2,7 +2,8 @@ \generate{ \usepreamble\luapreamble \usepostamble\luapostamble - \file{markdown.lua}{\from{markdown.dtx}{lua}} + \file{markdown.lua}{\from{markdown.dtx}{lua-loader}} + \file{markdown-parser.lua}{\from{markdown.dtx}{lua}} \file{markdown-cli.lua}{\from{markdown.dtx}{lua-cli}} \usepreamble\texpreamble \usepostamble\texpostamble @@ -14,7 +15,7 @@ \file{markdownthemewitiko_tilde.tex}{\from{markdown.dtx}{themes-witiko-tilde}} \file{markdownthemewitiko_markdown_defaults.tex}{\from{markdown.dtx}{themes-witiko-markdown-defaults-tex}} \file{markdownthemewitiko_markdown_defaults.sty}{\from{markdown.dtx}{themes-witiko-markdown-defaults-latex}} - \file{t-markdownthemewitiko_markdown_defaults.tex}{\from{markdown.dtx}{themes-witiko-markdown-defaults-context}} + \file{t-markdownthemewitiko_markdown_defaults.tex}{\from{markdown.dtx}{themes-witiko-markdown-defaults-ctx}} \file{markdownthemewitiko_markdown_techdoc.sty}{\from{markdown.dtx}{themes-witiko-markdown-techdoc}} \usepreamble\empty \usepostamble\empty @@ -25,5 +26,6 @@ \file{markdown.css}{\from{markdown.dtx}{manual-css}} \file{markdown-figure-block-diagram.tex}{\from{markdown.dtx}{techdoc-block-diagram}} \file{markdown.bib}{\from{markdown.dtx}{techdoc-bibliography}} + \file{DEPENDS-raw.txt}{\from{markdown.dtx}{depends}} } \endbatchfile diff --git a/Master/texmf-dist/source/generic/pst-diffraction/Makefile b/Master/texmf-dist/source/generic/pst-diffraction/Makefile deleted file mode 100644 index 1d4650b7c1b..00000000000 --- a/Master/texmf-dist/source/generic/pst-diffraction/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# `Makefile' for `pst-diffraction.pdf', hv, 2007/03/17 - -.SUFFIXES : .tex .ltx .dvi .ps .pdf .eps - -PACKAGE = pst-diffraction - -LATEX = latex - -ARCHNAME = $(PACKAGE)-$(shell date +%y%m%d) -ARCHFILES = $(PACKAGE).sty *.tex $(PACKAGE).pro *.tex README Changes Makefile - -all : DE E FR clean - -DE : $(PACKAGE)-docDE.pdf -E : $(PACKAGE)-docE.pdf -FR : $(PACKAGE)-docFR.pdf - -doc : $(MAIN).pdf - -%.pdf : %.ps - GS_OPTIONS=-dAutoRotatePages=/None ps2pdf $< - -%.ps : %.dvi - dvips $< - -%.dvi : %.tex - $(LATEX) $< - $(LATEX) $< - if ! test -f $(basename $<).glo ; then touch $(basename $<).glo; fi - if ! test -f $(basename $<).idx ; then touch $(basename $<).idx; fi - makeindex -s gglo.ist -t $(basename $<).glg -o $(basename $<).gls \ - $(basename $<).glo - makeindex -t $(basename $<).ilg -o $(basename $<).ind \ - $(basename $<).idx - bibtex $(basename $<) - $(LATEX) $< - $(LATEX) $< - -clean : - $(RM) $(addprefix $(PACKAGE)-docDE, .log .aux .glg .glo .gls .ilg .idx .ind .tmp .toc .out .blg .Roessler .bbl ) - $(RM) $(addprefix $(PACKAGE)-docDE, .dvi .ps) - $(RM) $(addprefix $(PACKAGE)-docE, .log .aux .glg .glo .gls .ilg .idx .ind .tmp .toc .out .blg .Roessler .bbl ) - $(RM) $(addprefix $(PACKAGE)-docE, .dvi .ps) - $(RM) $(addprefix $(PACKAGE)-docFR, .log .aux .glg .glo .gls .ilg .idx .ind .tmp .toc .out .blg .Roessler .bbl ) - $(RM) $(addprefix $(PACKAGE)-docFR, .dvi .ps) - -veryclean : clean - $(RM) $(addprefix $(PACKAGE)-docDE, .pdf .bbl .blg) - $(RM) $(addprefix $(PACKAGE)-docE, .pdf .bbl .blg) - $(RM) $(addprefix $(PACKAGE)-docFR, .pdf .bbl .blg) - -arch : - zip $(ARCHNAME).zip $(ARCHFILES) - -# EOF diff --git a/Master/texmf-dist/source/generic/tex4ht/ChangeLog b/Master/texmf-dist/source/generic/tex4ht/ChangeLog index dd7c62fc27e..8b627b50551 100644 --- a/Master/texmf-dist/source/generic/tex4ht/ChangeLog +++ b/Master/texmf-dist/source/generic/tex4ht/ChangeLog @@ -1,8 +1,101 @@ +2024-08-27 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-mathml.tex (mathml.4ht): fixed support of upper case Greek + letters inside pictures. + https://tex.stackexchange.com/q/725157/2891 + +2024-08-19 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (moderncv.4ht), + * tex4ht-html4.tex (html4.4ht): added support for the Moderncv + package. + https://tex.stackexchange.com/q/721180/2891 + +2024-08-13 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (amsfonts.4ht): fixed support for \mathbb and + \mathfrak. + + * tex4ht-jats.tex (jats.4ht): added support for LaTeX + bibliographies. + +2024-08-11 Karl Berry <karl@freefriends.org> + + * tex4ht-mathml.tex (html-mml.4ht): copyright 2024. + +2024-08-02 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-mathml.tex (mathml.4ht): added "texsource" option. It will + keep the original LaTeX code as an annotation in MathML. + https://chat.stackexchange.com/rooms/154333/discussion-on-question-by-yannisl-alternatives-to-mathml-for-pdf-tagging + + * tex4ht-4ht.tex (esvect.4ht), + * tex4ht-mathml.tex (mathml.4ht): added support for the Esvect + package. + https://tex.stackexchange.com/a/723587/2891 + +2024-07-31 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-fonts-noncjk.tex ( + ./tex4ht.dir/texmf/tex4ht/ht-fonts/unicode/TeXvect10/vect10.htf + ): Added support for the vector font from the Esvect package. + https://tex.stackexchange.com/q/723560/2891 + +2024-07-28 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-mathjax.tex (mathjax-latex-4ht.4ht): don't add spaces after + LaTeX commands. + +2024-07-26 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (tagpdf-hooks.4ht, tagpdf-base-hooks.4ht): removed + \__tag_whatsits definitions, they fix is no longer necessary. + https://github.com/michal-h21/make4ht/issues/145#issuecomment-2085215582 + +2024-07-07 Karl Berry <karl@freefriends.org> + + * Makefile (tex4ht_env_derived), + * tex4ht-env.tex: no longer generate tex4ht.env, just + .env-unix and .env-win32, since those are the only ones we use. + +2024-07-06 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-html4.tex (html4.4ht): added itemize+ option. It will keep + original characters for itemize bullets. + https://tex.stackexchange.com/a/722062/2891 + +2024-07-03 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (fontawesome5.4ht): use icon name as the alt text. + +2024-06-21 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (arydshln.4ht): fixed clash between Colortbl and + Arydshln packages. + https://tex.stackexchange.com/a/721185/2891 + +2024-06-23 Karl Berry <karl@freefriends.org> + + * tex4ht-cpright.tex: https for urls. + +2024-06-21 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-html4.tex (html4.4ht): don't use picture name as alt in + \epsfbox, it can lead to spurious characters in the resulting HTML. + Thanks to Rolf Brigola + +2024-06-20 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (footmisc.4ht): fixed handling of footnote counter + reset. + https://tex.stackexchange.com/a/720989/2891 + + 2024-06-17 Michal Hoftich <michal.h21@gmail.com> * tex4ht-4ht.tex (tabularray.4ht): updated names of token lists that holds rowspan and colspan. - https://tex.stackexchange.com/a/720800/2891 + https://tex.stackexchange.com/a/720800/2891 2024-06-15 Michal Hoftich <michal.h21@gmail.com> diff --git a/Master/texmf-dist/source/generic/tex4ht/Makefile b/Master/texmf-dist/source/generic/tex4ht/Makefile index fd6995f4a59..5328185f784 100644 --- a/Master/texmf-dist/source/generic/tex4ht/Makefile +++ b/Master/texmf-dist/source/generic/tex4ht/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 1503 2024-04-18 22:51:03Z karl $ +# $Id: Makefile 1538 2024-07-07 15:55:16Z karl $ # This file is public domain. Originally written 2010, Karl Berry. # Assumes GNU make. @@ -138,7 +138,7 @@ tex4ht_docbook_xtpipes_derived = docbook.4xt $(wd)/src/DbUtilities.java endif derived += $(tex4ht_env_derived) -tex4ht_env_derived = tex4ht.env-unix tex4ht.env-win32 tex4ht.env +tex4ht_env_derived = tex4ht.env-unix tex4ht.env-win32 derived += $(tex4ht_fonts_cjk_derived) tex4ht_fonts_cjk_derived = \ diff --git a/Master/texmf-dist/source/generic/tex4ht/mktex4ht-cnf.tex b/Master/texmf-dist/source/generic/tex4ht/mktex4ht-cnf.tex index 7bc692fff6d..ee48ba93f7f 100644 --- a/Master/texmf-dist/source/generic/tex4ht/mktex4ht-cnf.tex +++ b/Master/texmf-dist/source/generic/tex4ht/mktex4ht-cnf.tex @@ -1,4 +1,4 @@ -% $Id: mktex4ht-cnf.tex 1523 2024-05-27 14:16:04Z michal_h21 $ +% $Id: mktex4ht-cnf.tex 1547 2024-08-19 14:07:03Z michal_h21 $ % Manually-maintained file, listing *.4ht files created by tex4ht-4ht.tex. % Read by tex4ht-cond4ht. % @@ -238,6 +238,7 @@ \AddFile{9}{europecv} \AddFile{9}{resume} \AddFile{9}{curve} +\AddFile{9}{moderncv} \AddFile{9}{vowel} \AddFile{9}{enumitem} \AddFile{9}{esperanto} @@ -415,4 +416,5 @@ \AddFile{9}{fontawesome5} \AddFile{9}{mhchem} \AddFile{9}{chemfig} +\AddFile{9}{esvect} % \AddFile{9}{mktex4ht} diff --git a/Master/texmf-dist/source/generic/tex4ht/tex4ht-4ht.tex b/Master/texmf-dist/source/generic/tex4ht/tex4ht-4ht.tex index 0fd6e45cbaa..9882b08f734 100644 --- a/Master/texmf-dist/source/generic/tex4ht/tex4ht-4ht.tex +++ b/Master/texmf-dist/source/generic/tex4ht/tex4ht-4ht.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-4ht.tex 1531 2024-06-17 19:40:15Z michal_h21 $ +% $Id: tex4ht-4ht.tex 1547 2024-08-19 14:07:03Z michal_h21 $ % tex tex4ht-4ht or ht tex tex4ht-4ht % % Copyright 2009-2024 TeX Users Group @@ -4265,18 +4265,19 @@ icons to pictures by TeX4ht conversion. \<fontawesome5.4ht\><<< % fontawesome5.4ht (|version), generated from |jobname.tex -% Copyright 2021 TeX Users Group +% Copyright 2021-2024 TeX Users Group |<TeX4ht license text|> \NewConfigure{fontawesome}{2} \ExplSyntaxOn \cs_new_protected:Nn\temp:nn{% +\def\:fontawesomeicon{#2}% to be used in the alt text \a:fontawesome% \o:fontawesome_use_icon:nn:{#1}{#2} \b:fontawesome} \HLet\fontawesome_use_icon:nn\temp:nn \ExplSyntaxOff -\Configure{fontawesome}{\Picture+{}}{\EndPicture} +\Configure{fontawesome}{\Picture+[icon: \:fontawesomeicon]{}}{\EndPicture} \Hinput{fontawesome5} \endinput >>> \AddFile{9}{fontawesome5} @@ -5099,13 +5100,14 @@ as it leads to a fatal error. \Configure{PackageHooks}{tagpdf.sty}{tagpdf-hooks.4ht} >>> +% This is no longer useful, it was fixed in tagpdf code +% \cs_set_protected:Npn \__tag_whatsits: {} + \<tagpdf-hooks.4ht\><<< % tagpdf-hooks.4ht (|version), generated from |jobname.tex % Copyright 2022-2024 TeX Users Group |<TeX4ht license text|> \ExplSyntaxOn -% ignore tagpdf's specials -\cs_set_protected:Npn \__tag_whatsits: {} \ExplSyntaxOff \:AtEndOfPackage{% \RenewDocumentCommand \tagpdfsetup { m }{} @@ -5117,16 +5119,17 @@ as it leads to a fatal error. \Configure{PackageHooks}{tagpdf-base.sty}{tagpdf-base-hooks.4ht} >>> -This file can be used explicitly, we need to provide the whatsits command -here as well. +This file can be used explicitly, we used to provide the whatsits command +here as well, but it is no longer neeeded. + +% ignore tagpdf's specials +% we use csname, because \ExplSyntaxOn .. Off caused catcode issues +% \expandafter\def\csname __tag_whatsits:\endcsname{} \<tagpdf-base-hooks.4ht\><<< % tagpd-base-hooks.4ht (|version), generated from |jobname.tex % Copyright 2024 TeX Users Group |<TeX4ht license text|> -% ignore tagpdf's specials -% we use csname, because \ExplSyntaxOn .. Off caused catcode issues -\expandafter\def\csname __tag_whatsits:\endcsname{} \endinput >>> \AddFile{9}{tagpdf-base-hooks} @@ -11225,12 +11228,13 @@ compilation errors \<arydshln.4ht\><<< %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % arydshln.4ht (|version), generated from |jobname.tex -% Copyright 2022 TeX Users Group +% Copyright 2022-2024 TeX Users Group |<TeX4ht license text|> % this is a copy of code that arydshln inserts to \@array \def\:new:array{\adl@everyvbox\everyvbox \everyvbox{\adl@arrayinit \the\adl@everyvbox \everyvbox\adl@everyvbox}% - \ifadl@inactive \adl@inactivate \else \adl@activate \fi + % this line may lead to errors if the document uses Colortbl: + % \ifadl@inactive \adl@inactivate \else \adl@activate \fi \let\adl@noalign\noalign} \ifcsname n:@array:\endcsname% if \@array was already patched by TeX4ht \let\orig:n@array\n:@array: @@ -22275,14 +22279,14 @@ $$ \<amsfonts sty\><<<< \NewConfigure{mathbb}{2} -\def\:temp#1{{\a:mathbb \o:@mathbb:{#1}\b:mathbb}} -\HLet\@mathbb\:temp +\def\:temp#1{{\a:mathbb \o:mathbb:{#1}\b:mathbb}} +\HLet\mathbb\:temp >>> \<amsfonts sty\><<<< \NewConfigure{mathfrak}{2} -\def\:temp#1{{\a:mathfrak \o:@mathfrak:{#1}\b:mathfrak}} -\HLet\@mathfrak\:temp +\def\:temp#1{{\a:mathfrak \o:mathfrak:{#1}\b:mathfrak}} +\HLet\mathfrak\:temp >>> Commands like \''\rm' need low level implemetation through @@ -30143,6 +30147,173 @@ A style file for resumes. >>> %%%%%%%%%%%%%%%%%%%%%%%%% +\Section{moderncv} +%%%%%%%%%%%%%%%%%%%%%%%%% + +\<moderncv.4ht\><<< +% moderncv.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> +|<moderncv configs|> +\Hinput{moderncv} +\endinput +>>>\AddFile{9}{moderncv} + +This is a bit messy. We had to redefine a bunch of commands from various +files that Moderncv uses, mostly to prevent compilation errors and to +insert some basic formatting. + +\<moderncv configs\><<< +\NewConfigure{section}{2} +\RenewDocumentCommand\section{sm}{\a:section #2\b:section} + +\NewConfigure{subsection}{2} +\RenewDocumentCommand\subsection{sm}{\a:subsection #2\b:subsection} + + +\NewConfigure{cvitem}{3} +\renewcommand*{\cvitem}[3][.25em]{ +\a:cvitem #2\b:cvitem #3\c:cvitem +} + +\NewConfigure{cvdoubleitem}{2} +\renewcommand*{\cvdoubleitem}[5][.25em]{% +\a:cvdoubleitem +\cvitem{#2}{#3} +\cvitem{#4}{#5} +\b:cvdoubleitem +} + +\NewConfigure{cvlistitem}{2} +\renewcommand*{\cvlistitem}[2][.25em]{% + \a:cvlistitem\cvitem[#1]{\listitemsymbol}{#2}\b:cvlistitem +} + +\NewConfigure{cvlistdoubleitem}{2} +\renewcommand*{\cvlistdoubleitem}[3][.25em]{% + \a:cvlistdoubleitem% + \cvitem[#1]{\listitemsymbol}{#2}% + \cvitem[#1]{\listitemsymbol}{#3}% + \b:cvlistdoubleitem% +} + +\NewConfigure{cvhead}{2} +\NewConfigure{cvphoto}{2} + + +\renewcommand*{\makecvhead}{% + \a:cvhead + % recompute lengths (in case we are switching from letter to resume, or vice versa) + \recomputecvlengths% + % optional detailed information (pre-rendering) + \@initializebox{\makecvheaddetailsbox}% + \if@details% + \def\phonesdetails{}% + \collectionloop{phones}{% the key holds the phone type (=symbol command prefix), the item holds the number + \protected@edef\phonesdetails{\phonesdetails\protect\makenewline\csname\collectionloopkey phonesymbol\endcsname\collectionloopitem}}% + \def\socialsdetails{}% + \collectionloop{socials}{% the key holds the social type (=symbol command prefix), the item holds the link + \protected@edef\socialsdetails{\socialsdetails\protect\makenewline\csname\collectionloopkey socialsymbol\endcsname\collectionloopitem}}% + \savebox{\makecvheaddetailsbox}{% + \addressfont\color{color2}% + \if@left\begin{tabular}[b]{@{}r@{}}\fi% + \if@right\begin{tabular}[b]{@{}l@{}}\fi% + \ifthenelse{\isundefined{\@addressstreet}}{}{\makenewline\addresssymbol\@addressstreet% + \ifthenelse{\equal{\@addresscity}{}}{}{\makenewline\@addresscity}% if \addresstreet is defined, \addresscity and addresscountry will always be defined but could be empty + \ifthenelse{\equal{\@addresscountry}{}}{}{\makenewline\@addresscountry}}% + \ifthenelse{\isundefined{\@born}}{}{\makenewline\bornsymbol\@born}% + \phonesdetails% needs to be pre-rendered as loops and tabulars seem to conflict + \ifthenelse{\isundefined{\@email}}{}{\makenewline\emailsymbol\emaillink{\@email}}% + \ifthenelse{\isundefined{\@homepage}}{}{\makenewline\homepagesymbol\httpslink{\@homepage}}% + \socialsdetails% needs to be pre-rendered as loops and tabulars seem to conflict + \ifthenelse{\isundefined{\@extrainfo}}{}{\makenewline\@extrainfo}% + \end{tabular} + }\fi% + % optional photo (pre-rendering) + \@initializebox{\makecvheadpicturebox}% + \savebox{\makecvheadpicturebox}{% + \ifthenelse{\isundefined{\@photo}}% + {}% + {% + \a:cvphoto\includegraphics[]{\@photo}\b:cvphoto}% + }% + % name and title (pre-rendering) + \@initializelength{\makecvheaddetailswidth}\settowidth{\makecvheaddetailswidth}{\usebox{\makecvheaddetailsbox}}% + \@initializelength{\makecvheadpicturewidth}\settowidth{\makecvheadpicturewidth}{\usebox{\makecvheadpicturebox}}% + \ifthenelse{\lengthtest{\makecvheadnamewidth=0pt}}% check for dummy value (equivalent to \ifdim\makecvheadnamewidth=0pt) + {\setlength{\makecvheadnamewidth}{\textwidth-\makecvheaddetailswidth-\makecvheadpicturewidth}}% + {}% + \@initializebox{\makecvheadnamebox}% + \savebox{\makecvheadnamebox}{% + \begin{minipage}[b]{\makecvheadnamewidth}% + \if@left\raggedright\fi% + \if@right\raggedleft\fi% + \namestyle{\@firstname\ \@lastname}% + \ifthenelse{\equal{\@title}{}}{}{\\[1.25em]\titlestyle{\@title}}% + \end{minipage}}% + % rendering + \if@left% + \usebox{\makecvheadnamebox}% + \hfill% + \llap{\usebox{\makecvheaddetailsbox}}% \llap is used to suppress the width of the box, allowing overlap if the value of makecvheadnamewidth is forced + \usebox{\makecvheadpicturebox}\fi% + \if@right% + \usebox{\makecvheadpicturebox}% + \rlap{\usebox{\makecvheaddetailsbox}}% \llap is used to suppress the width of the box, allowing overlap if the value of makecvheadnamewidth is forced + \hfill% + \usebox{\makecvheadnamebox}\fi% + \\[2.5em]% + % optional quote + \ifthenelse{\isundefined{\@quote}}% + {}% + {{\centering\begin{minipage}{\quotewidth}\centering\quotestyle{\@quote}\end{minipage}\\[2.5em]}}% + \b:cvhead\par}% to avoid weird spacing bug at the first section if no blank line is left after \makecvhead + + +\RenewDocumentCommand\cvskilllegend{s +O{.25em} +O{\skillLegend@defaultLevelOne} +O{\skillLegend@defaultLevelTwo} +O{\skillLegend@defaultLevelThree} +O{\skillLegend@defaultLevelFour} +O{\skillLegend@defaultLevelFive} +m}{% +\begin{tabular}{l l l l l l} + \raggedleft\hintstyle{#8} & \cvskill{1}\, & \,{\skillLegend@FontSize #3} & \cvskill{3}\, &\,{\skillLegend@FontSize #5 } \\% + % + & \cvskill{2}\, & \,\multirow{2}{\cvskilllegend@leftdescriptorwidth}{{\skillLegend@FontSize #4}} & \cvskill{4}\, &\,{\skillLegend@FontSize #6 } \\% + % + & & & \cvskill{5}\, &\,{\skillLegend@FontSize #7 }% + \end{tabular}% +}% + + +\NewConfigure{cvskill}{2} +\def\:tempa#1{\def\:cvskillamount{#1}\a:cvskill\o:cvskill:{#1}\b:cvskill} +\HLet\cvskill\:tempa + +\NewConfigure{cvskillhead}{2} +\NewConfigure{cvskillentry}{2} +\RenewDocumentCommand\cvskillhead{O{.25em} +O{\skillMatrix@HeaderDefaultOne} +O{\skillMatrix@HeaderDefaultTwo} +O{\skillMatrix@HeaderDefaultThree} +O{\skillMatrix@HeaderDefaultFour}}{% + \begingroup + \a:cvskillhead + \begin{tabular}{ p{6em} p{12em} p{4em} p{20em}}% + { #2} & { #3} & { #4} & { #5} + \end{tabular}% + \b:cvskillhead + \endgroup + \par\addvspace{#1} +} + +\RenewDocumentCommand\cvskillentry{s +O{.25em} +m +m +m +m +m}{% +\a:cvskillentry +\cvitem{#3}{ + \begin{tabular}{ p{6em} p{12em} p{4em} p{20em}} + \centering \cvskill{#4} &\centering {#5} & \centering {#6} &{\itshape#7}% + \end{tabular}}% + \b:cvskillentry + \par\addvspace{#2} +} + +>>> + +%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%%%%%%%%%%%%%%%%% \Chapter{Small Ones} %%%%%%%%%%%%%%%%%%%%%%%%% @@ -31406,6 +31577,20 @@ for output formats. \ExplSyntaxOff >>> +%%%%%%%%%%%%%%% +\Section{Esvect} +%%%%%%%%%%%%%%% + +\<esvect.4ht\><<< +% esvect.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> +|<esvect redefinitions|> + +\Hinput{esvect} +\endinput +>>> \AddFile{9}{esvect} + %%%%%%%%%%%%% \Section{Ushort} %%%%%%%%%%%%% @@ -37900,9 +38085,39 @@ Use \<footmisc.4ht\><<< % footmisc.4ht (|version), generated from |jobname.tex -% Copyright 2019 TeX Users Group +% Copyright 2019-2024 TeX Users Group |<TeX4ht license text|> +|<footmisc footnote counter|> +|<footmisc footnotetext|> +|<footmisc symbols|> + + +\Hinput{footmisc} +\endinput +>>> \AddFile{9}{footmisc} + +Footmisc can reset the normal footnote counter on every page. Footnote links are +then wrong, as they point to an earlier footnote. My solution is to use a global +counter that gives each footnote unique number and which doesn't rely on the footnote +symbol. +\<footmisc footnote counter\><<< +\newcounter{:footnotes} + +\def\FNnum{\the\:footnotes} + +\HRestore\footnote + +\def\:tempc{% + \HAssign\FNnum = \csname c@:footnotes\endcsname% + \stepcounter{:footnotes}% + \HAdvance\FNnum by 1% + \o:footnote:% +} +\HLet\footnote=\:tempc +>>> + +\<footmisc footnotetext\><<< \long\def\@footnotetext#1{\leavevmode \vbox{%\IgnorePar \leftskip0pt {\ht:everypar{}\parindent0pt\leavevmode}% @@ -37921,6 +38136,9 @@ Use \color@endgroup \ht:special{t4ht@[}}\ht:special{t4ht@]}} +>>> + +\<footmisc symbols\><<< % detect if the symbol or symbol* option were used % we can detect that by testing of \thefootnote macro @@ -37937,10 +38155,7 @@ Use \newcommand\p@footmisc@footnote[1]{\p@footnote{#1}} \fi \fi - -\Hinput{footmisc} -\endinput ->>> \AddFile{9}{footmisc} +>>> %%%%%%%%%%%%%%% \Section{tablefootnote} diff --git a/Master/texmf-dist/source/generic/tex4ht/tex4ht-cpright.tex b/Master/texmf-dist/source/generic/tex4ht/tex4ht-cpright.tex index 35276909217..c15155fcc57 100644 --- a/Master/texmf-dist/source/generic/tex4ht/tex4ht-cpright.tex +++ b/Master/texmf-dist/source/generic/tex4ht/tex4ht-cpright.tex @@ -4,14 +4,14 @@ % conditions of the LaTeX Project Public License, either % version 1.3c of this license or (at your option) any % later version. The latest version of this license is in -% http://www.latex-project.org/lppl.txt +% https://www.latex-project.org/lppl.txt % and version 1.3c or later is part of all distributions % of LaTeX version 2005/12/01 or later. % % This work has the LPPL maintenance status "maintained". % % The Current Maintainer of this work -% is the TeX4ht Project <http://tug.org/tex4ht>. +% is the TeX4ht Project <https://tug.org/tex4ht>. % % If you modify this program, changing the % version identification would be appreciated.>>> diff --git a/Master/texmf-dist/source/generic/tex4ht/tex4ht-env.tex b/Master/texmf-dist/source/generic/tex4ht/tex4ht-env.tex index 5d66aa43d02..3ac0f4443d4 100644 --- a/Master/texmf-dist/source/generic/tex4ht/tex4ht-env.tex +++ b/Master/texmf-dist/source/generic/tex4ht/tex4ht-env.tex @@ -1,8 +1,8 @@ -% $Id: tex4ht-env.tex 1419 2023-12-11 23:23:52Z karl $ +% $Id: tex4ht-env.tex 1538 2024-07-07 15:55:16Z karl $ % latex tex4ht-env % or htlatex tex4ht-env "xhtml,3" % -% Copyright 2009-2023 TeX Users Group +% Copyright 2009-2024 TeX Users Group % Copyright 1997-2009 Eitan M. Gurari % Released under LPPL 1.3c+. % See tex4ht-cpright.tex for license text. @@ -1650,27 +1650,30 @@ Note: the permission option `S' takes into account also trailing spaces. \<unix copyright\><<< % tex4ht.env-unix (@version), generated from @jobname.tex -% (can be used as ~/.tex4ht) -% Copyright 2009-2023 TeX Users Group +% Copyright 2009-2024 TeX Users Group % Copyright @CopyYear.1997. Eitan M. Gurari @<TeX4ht copyright@>>>> \<private copyright\><<< % tex4ht.env (private) (@version), generated from @jobname.tex % (can be used as ~/.tex4ht) -% Copyright 2009-2023 TeX Users Group +% Copyright 2009-2024 TeX Users Group % Copyright @CopyYear.1997. Eitan M. Gurari @<TeX4ht copyright@>>>> \<win32 copyright\><<< % tex4ht.env-win32 (@version), generated from @jobname.tex -% Copyright 2009-2023 TeX Users Group +% Copyright 2009-2024 TeX Users Group % Copyright @CopyYear.1997. Eitan M. Gurari @<TeX4ht copyright@>>>> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\OutputCode\<tex4ht\> +% Let's no longer create tex4ht.env; it's too easy to mistakenly update +% a system version with it. Post-Eitan, we haven't tried to keep it in +% sync with the others. +%\OutputCode\<tex4ht\> + \OutputCodE\<tex4ht.env-unix\> \OutputCodE\<tex4ht.env-win32\> diff --git a/Master/texmf-dist/source/generic/tex4ht/tex4ht-fonts-noncjk.tex b/Master/texmf-dist/source/generic/tex4ht/tex4ht-fonts-noncjk.tex index ae68aa34d59..0e22004638e 100644 --- a/Master/texmf-dist/source/generic/tex4ht/tex4ht-fonts-noncjk.tex +++ b/Master/texmf-dist/source/generic/tex4ht/tex4ht-fonts-noncjk.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-fonts-noncjk.tex 1517 2024-05-10 11:27:42Z michal_h21 $ +% $Id: tex4ht-fonts-noncjk.tex 1541 2024-07-31 10:01:14Z michal_h21 $ % tex tex4ht-fonts-noncjk % or ht tex tex4ht-fonts-noncjk % @@ -24483,6 +24483,69 @@ fplmbb 49 90 +\Section{Esvect} + +Font file for the Esvect package. + +% writing vect10.htf hash: d9018d0b41b7639bd8c3bf0419c3b8a5 +\<vect10\><<< +vect10 0 47 +'`' '' grave 0 % generated from vect10.tfm, 2024-07-31-11:51 +'´' '' acute 1 % Copyright 2024 TeX Users Group +'ˆ' '' circumflex 2 % +'˜' '' tilde 3 % This work may be distributed and/or modified under the +'¨' '' dieresis 4 % conditions of the LaTeX Project Public License, either +'˝' '' hungarumlaut 5 % version 1.3c of this license or (at your option) any +'˚' '' ring 6 % later version. The latest version of this license is in +'ˇ' '' caron 7 % http://www.latex-project.org/lppl.txt +'˘' '' breve 8 % and version 1.3c or later is part of all distributions +'' '' % of LaTeX version 2005/12/01 or later. +'' '' % +'' '' % This work has the LPPL maintenance status "maintained". +'' '' % +'' '' % The Current Maintainer of this work +'' '' % is the TeX4ht Project <http://tug.org/tex4ht>. +'' '' % +'“' '' quotedblleft 16 % If you modify this program, changing the +'”' '' quotedblright 17 % version identification would be appreciated. +'„' '' quotedblbase 18 +'«' '' guillemotleft 19 +'»' '' guillemotright 20 +'–' '' endash 21 +'—' '' emdash 22 +'‌' '' cwm 23 +'‰' '' perthousand 24 +'' '' +'' '' +'' '' +'' '' +'' '' +'' '' +'' '' +' ' '' space 32 +'!' '' exclam 33 +'"' '' quotedbl 34 +'#' '' numbersign 35 +'$' '' dollar 36 +'%' '' percent 37 +'&' '' ampersand 38 +'’' '' quoteright 39 +'(' '' parenleft 40 +')' '' parenright 41 +'*' '' asterisk 42 +'+' '' plus 43 +',' '' comma 44 +'-' '' hyphen 45 +'.' '' period 46 +'/' '' slash 47 +vect10 0 47 +htfcss: vect10 font-family: 'TeXvect10', serif; + +>>> +\AddFont{vect10}{unicode/TeXvect10/vect10}{} + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Master/texmf-dist/source/generic/tex4ht/tex4ht-html4.tex b/Master/texmf-dist/source/generic/tex4ht/tex4ht-html4.tex index a2f3a577811..3dfd40a6c65 100644 --- a/Master/texmf-dist/source/generic/tex4ht/tex4ht-html4.tex +++ b/Master/texmf-dist/source/generic/tex4ht/tex4ht-html4.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-html4.tex 1526 2024-05-28 19:03:35Z michal_h21 $ +% $Id: tex4ht-html4.tex 1547 2024-08-19 14:07:03Z michal_h21 $ % Compile 4 times: latex tex4ht-html4 % Copy html4.4ht into the work directory before all but the last compilation. % @@ -2950,6 +2950,22 @@ such a case, we don't have proper nestings of environments. \EndP\HCode{</li></ul>}\ShowPar} {\end:itm \global\def\end:itm{\EndP\Tg</li>}\DeleteMark} {\HCode{<li class="\getClass{li}itemize">}\afterGetClass{li}|<list par|>} + +\:CheckOption{itemize+}\if:Option +\ConfigureList{itemize}% + {\EndP\HCode{<ul \a:LRdir + class="\getClass{itemize}itemize\expandafter\the + \csname @itemdepth\endcsname">}% + \afterGetClass{itemize}% + |<save end:itm|>\global\let\end:itm=\empty} + {|<recall end:itm|>\ifvmode \IgnorePar\fi + \EndP\HCode{</li></ul>}\ShowPar} + {\end:itm \global\def\end:itm{\EndP\Tg</li>}\HCode{<li class="\getClass{li}itemize"><span class="itemizeHead" aria-hidden="true">}\afterGetClass{li}} + {\HCode{</span>}|<list par|>} +\Css{.itemizeHead{float: left; margin-left: -1em; width: 1em;}} +\Css{li.itemize{list-style: none;}} +\fi + \NewConfigure{itemizeClass}{2} \Configure{itemizeClass}{}{} \NewConfigure{liClass}{2} @@ -13824,7 +13840,7 @@ for margin pars. \<configure html4 epsf\><<< \Configure{epsfsetgraph} - {\Picture+[\PicName]{}} + {\Picture+[]{}} {\EndPicture} >>> @@ -17790,6 +17806,45 @@ Blue = 1-minimum(1,Yellow *(1-Black)+Black) >>> %%%%%%%%%%%%%%%%%% +\section{moderncv} +%%%%%%%%%%%%%%%%%% + +\<configure html4 moderncv\><<< +\Configure{cvhead}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvhead">}}{\ifvmode\IgnorePar\fi\EndP\HCode{</div>}} +\Configure{cvphoto}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvphoto">}}{\ifvmode\IgnorePar\fi\EndP\HCode{</div>}} + +\Configure{section}{\ifvmode\IgnorePar\fi\EndP\HCode{<h2>}}{\HCode{</h2>}} +\Configure{subsection}{\ifvmode\IgnorePar\fi\EndP\HCode{<h3>}}{\HCode{</h3>}} +\Configure{cvitem}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvitem"><span class="cvitemhead">}}{\HCode{</span><span class="cvitembody">}}{\HCode{</span></div>}} +\Configure{cvdoubleitem}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvdoubleitem">}}{\HCode{</div>}} +\Configure{cvlistitem}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvlistitem">}}{\HCode{</div>}} +\Configure{cvlistdoubleitem}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvlistdoubleitem">}}{\HCode{</div>}} + +\Configure{cvskillhead}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvskillhead">}}{\HCode{</div>}} +\Configure{cvskillentry}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvskillentry">}}{\HCode{</div>}} + +\Configure{cvskill}{\Picture*[skill level: \:cvskillamount]{}}{\EndPicture} + +\Css{.cvskillentry .tabular, .cvskillhead .tabular {margin:0pt;}} +\Css{.cvskillentry .tabular td:nth-child(1), .cvskillhead .tabular td:nth-child(1){width: 8ch}} +\Css{.cvskillentry .tabular td:nth-child(2), .cvskillhead .tabular td:nth-child(2){width: 12ch}} +\Css{.cvskillentry .tabular td:nth-child(3), .cvskillhead .tabular td:nth-child(3){width: 6ch}} +\Css{.cvskillentry .tabular td:nth-child(4), .cvskillhead .tabular td:nth-child(4){width: 54ch}} + +\Css{.cvitemhead{margin-right: 1em;}} + +\Css{ +@media (min-width:94ch) { +.cvitemhead{ + margin-left: -14ch; + width: 12ch; + float: left; + text-align: right; + } +}} +>>> + +%%%%%%%%%%%%%%%%%% \section{CSS} %%%%%%%%%%%%%%%%%% diff --git a/Master/texmf-dist/source/generic/tex4ht/tex4ht-jats.tex b/Master/texmf-dist/source/generic/tex4ht/tex4ht-jats.tex index e54de5ad206..16182ba8f5c 100644 --- a/Master/texmf-dist/source/generic/tex4ht/tex4ht-jats.tex +++ b/Master/texmf-dist/source/generic/tex4ht/tex4ht-jats.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-jats.tex 1473 2024-02-23 12:26:51Z michal_h21 $ +% $Id: tex4ht-jats.tex 1545 2024-08-13 19:02:54Z michal_h21 $ % compile 3 times: latex tex4ht-jats % or xhlatex tex4ht-jats "html,3,sections+" % @@ -201,6 +201,7 @@ Configurations that are shared only for article and report |<latex footnotes|> |<latex quotes|> |<latex lists|> +|<latex bibliography|> >>> \<shared article,report\><<< @@ -841,6 +842,29 @@ them separatelly. {\EndNoFonts\HCode{</term><def>}\HtmlParOn|<list par|>} >>> + +We cannot create a structured bibliographic record for plain LaTeX references, so we +at least mark individual entries. + +Entry id is set on the label element. The id comes from a child xref element that is removed +by make4ht. Ideally, it should be set on ref, but we need to use label here, to catch +potential entry number. + + +\<latex bibliography\><<< +\ConfigureList{thebibliography}% + {\ifvmode\IgnorePar\fi \EndP \HCode{<ref-list>}\let\en:bib=\empty} + {\en:bib \ifvmode\IgnorePar\fi \EndP \HCode{</ref-list>}} + {\en:bib\def\en:bib{\HCode{</mixed-citation></ref>}}% + \HCode{<ref><label>}% + \Configure{HtmlPar}% + {\EndP}% + {\EndP}% + {} {}% + } + {\HCode{</label><mixed-citation>}} +>>> + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Packages} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Master/texmf-dist/source/generic/tex4ht/tex4ht-mathjax.tex b/Master/texmf-dist/source/generic/tex4ht/tex4ht-mathjax.tex index 23ca24a586c..25f324ab7fa 100644 --- a/Master/texmf-dist/source/generic/tex4ht/tex4ht-mathjax.tex +++ b/Master/texmf-dist/source/generic/tex4ht/tex4ht-mathjax.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-mathjax.tex 1474 2024-02-25 16:27:19Z karl $ +% $Id: tex4ht-mathjax.tex 1540 2024-07-28 17:10:17Z michal_h21 $ % compile: latex tex4ht-mathjax % % Copyright 2018-2024 TeX Users Group @@ -37,12 +37,14 @@ in LaTeX kernel now. \<required packages\><<< >>> -The \verb|\alteqtoks| command saves the used command in HTML. It uses detokenize command -to insert arguments verbatim. The side effect of this is that detokeize inserts space +The \verb|\alteqtoks| command prints the used LaTeX math code to the output document in +verbatim. + +In the past, we used \verb|\detokenize|. The side effect of this is that detokeize inserts space after each control sequence. This is completely valid TeX code, but earlier versions of MathJax didn't like that, rendering resulted in error. -Fortunatelly, MathJax 3 supports these spaces, so we can remove regular expressions for space handling. +Fortunatelly, MathJax 3 supports these spaces, so we could remove regular expressions for space handling. The original code was this: % % convert \ { to \:{ @@ -52,14 +54,24 @@ The original code was this: % % replace \\:{ back to \\ { -- this can be introduced by the previous regex % \regex_replace_all:nnN { \x{5C} \x{5C} \x{3A} \x{7B} } { \x{5C} \x{5C} \x{20} \x{7B} } \l_tmpa_tl +Now (July 2024), when I researched another issue, I've found that it is actually possible to avoid these +extra spaces using LaTeX 3 commands. The inspiration comes from +\Link[https://tex.stackexchange.com/a/44444/2891]this Bruno Le Foch\EndLink. +One ongoing issue is that newlines are not presented. But they weren't preserved with \verb|\detokenize| +either, so it shouldn't be a problem. + -We still use regula expressions to escape invalid XML characters to entities, so it works only with LaTeX. +We still use regular expressions to escape invalid XML characters to entities, so it works only with LaTeX. \<defined commands\><<< \ExplSyntaxOn \cs_new_protected:Npn \alteqtoks #1 { - \tl_set:Ne \l_tmpa_tl {\detokenize{#1}} + % save tokens, but preserve spaces + % https://tex.stackexchange.com/a/44444/2891 + \tl_set:Nn \l_tmpa_tl {#1} + \regex_replace_all:nnN { . } { \c{string} \0 } \l_tmpa_tl + \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl } % % replace < > and & with xml entities \regex_replace_all:nnN { \x{26} } { & } \l_tmpa_tl \regex_replace_all:nnN { \x{3C} } { < } \l_tmpa_tl diff --git a/Master/texmf-dist/source/generic/tex4ht/tex4ht-mathml.tex b/Master/texmf-dist/source/generic/tex4ht/tex4ht-mathml.tex index e7f496d6bf0..707d65805f8 100644 --- a/Master/texmf-dist/source/generic/tex4ht/tex4ht-mathml.tex +++ b/Master/texmf-dist/source/generic/tex4ht/tex4ht-mathml.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-mathml.tex 1495 2024-03-21 16:39:31Z michal_h21 $$ +% $Id: tex4ht-mathml.tex 1548 2024-08-27 14:38:17Z michal_h21 $$ % compile 3 times: latex tex4ht-mathltx % or xhlatex tex4ht-mathltx "html,3,sections+" % @@ -584,7 +584,7 @@ in italic and without space that would separate it from the following element. \<html-mml\><<< % html-mml.4ht (|version), generated from |jobname.tex -% Copyright 2009-2022 TeX Users Group +% Copyright 2009-2024 TeX Users Group % Copyright |CopyYear.1999. Eitan M. Gurari |<TeX4ht copywrite|> >>> @@ -1939,6 +1939,189 @@ primes. \fi >>> + +We may want to include LaTeX source as an annotation in MathML. In particular LaTeX PDF tagging code can use +this feature. We will not use it by default, but only with texsource option, as it can potentially +break some functionality. + +The code is based on the LaTeX MathJax code, but heavily modified. + +\<configure html-mml latex\><<< +\:CheckOption{texsource}\if:Option + +\newtoks\mmleqtoks +\ExplSyntaxOn +\cs_new_protected:Npn \mmlalteqtoks #1 +{ + % save tokens, but preserve spaces + % https://tex.stackexchange.com/a/44444/2891 + \tl_set:Nn \l_tmpa_tl {#1} + \regex_replace_all:nnN { . } { \c{string} \0 } \l_tmpa_tl + \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl } + % % replace < > and & with xml entities + \regex_replace_all:nnN { \x{26} } { & } \l_tmpa_tl + \regex_replace_all:nnN { \x{3C} } { < } \l_tmpa_tl + \regex_replace_all:nnN { \x{3E} } { > } \l_tmpa_tl + % \regex_replace_all:nnN { \n } {\HCode{ \Hnewline }} \l_tmpa_tl + % replace \par command with blank lines + \regex_replace_all:nnN { \x{5C}par\b } {\x{A}\x{A}} \l_tmpa_tl + \tl_set:Nx \mmleqtoks{ \l_tmpa_tl } + + %\HCode{\l_tmpb_tl} +} +\ExplSyntaxOff + + +\def\AltMath#1${\mmlalteqtoks{#1}% + #1\HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation>}$} +\Configure{$}{\Configure{@math}{display="inline"}\DviMath\HCode{<\a:mathml semantics><\a:mathml mrow>}}{\HCode{</\a:mathml semantics>}\EndDviMath}{\expandafter\AltMath} + +\def\AltMathParen#1\){\mmlalteqtoks{#1}% + #1\HCode{</\a:mathml mrow><a\a:mathml nnotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation>}$} + +\def\AltMathParen#1\){\mmlalteqtoks{#1}#1\HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation>}\)} +%\Configure{()}{\Configure{@math}{display="inline"}\DviMath\HCode{<\a:mathml semantics><\a:mathml mrow>}\AltMathParen$}{\EndDviMath\HCode{</\a:mathml semantics>}} +\Configure{()} + {\Configure{@math}{%\a:mathml + display="inline" +}\csname a:mathml()\endcsname +\DviMath\HCode{<\a:mathml semantics><\a:mathml mrow>}$\expandafter\AltMathParen} +{$\HCode{</\a:mathml semantics>}\EndDviMath\csname b:mathml()\endcsname} + + +\long\def\AltDisplay#1\]{\mmlalteqtoks{#1}#1\HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation></\a:mathml semantics>}\]} +\Configure{[]}{\Configure{@math}{display="block"}\DviMath$$\DisplayMathtrue\HCode{<\a:mathml semantics><\a:mathml mrow>}\AltDisplay}{$$\EndDviMath} + + +% \long\def\MMLAltlDisplayDollars#1$${\mmlalteqtoks{\[#1\]}#1\HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation>}$$} + +% configuarartion of display math doesn't work yet. need to investigate it. +% \Configure{$$} +% {\Configure{@math}{%\a:mathml +% display="block" +% }\IgnorePar +% \ifvmode\else \HCode{<!--tex4ht:inline-->}\fi +% \EndP\DviMath\HCode{<\a:mathml semantics><\a:mathml mrow>}} +% {\HCode{</\a:mathml semantics>}\EndDviMath\ShowPar\par{\csname HCondtrue\endcsname\noindent}} +% {\DisplayMathtrue\expandafter\MMLAltlDisplayDollars} + + +% \renewcommand\eqannotate[1]{\mmlalteqtoks{#1}\HCode{<\a:mathml semantics><\a:mathml mrow>}#1\HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation></\a:mathml semantics>}} + + +% environment support +\newcommand\MMLVerbMathToks[2]{% + \mmlalteqtoks{\begin{#2} + #1 + \end{#2}}% + \begingroup% + \ifvmode\IgnorePar\fi\EndP\Configure{@math}{display="block"}\DviMath\DisplayMathtrue\HCode{<\a:mathml semantics><\a:mathml mrow>} + \Configure{$$}{}{}{} + \begin{old#2} + #1 + \end{old#2} + \HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">} + \HCode{\mmleqtoks} + \HCode{</\a:mathml annotation></\a:mathml semantics>} + \EndDviMath + \endgroup +} + +% we must handle equations separatelly. +% it is a bit messy +\newcommand\MMLVerbMathToksEquation[2]{% + \mmlalteqtoks{\begin{#2} + #1 + \end{#2}}% + \begingroup% + \def\@tempa{#2}% + \def\@equationname{equation}% + \def\mlabeledtr{mtr} + \ifx\@equationname\@tempa% + \def\mlabeledtr{mlabeledtr} % this element can be used to print the equation number, but it is supported only by MathJax + \fi + \ifvmode\IgnorePar\fi\EndP\Configure{@math}{display="block"}\DviMath\DisplayMathtrue\HCode{<\a:mathml semantics><\a:mathml mrow><\a:mathml mtable><\a:mathml \mlabeledtr><\a:mathml mtd>}% + \ifx\@equationname\@tempa% + \incr@eqnum% + \print@eqnum% + \HCode{</\a:mathml mtd><\a:mathml mtd>}% + \fi + #1% + \HCode{</\a:mathml mtd></\a:mathml \mlabeledtr></\a:mathml mtable></\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">}% + \HCode{\mmleqtoks}% + \HCode{</\a:mathml annotation></\a:mathml semantics>}% + \EndDviMath% + \endgroup% +} + +\ExplSyntaxOn +\newcommand\MMLVerbMath[1]{% + \cs_if_exist:cTF{#1}{ + \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname + \expandafter\let\csname endold#1\expandafter\endcsname\csname end#1\endcsname + \RenewDocumentEnvironment{#1}{+!b}{% + \NoFonts\expandafter\MMLVerbMathToks\expandafter{##1}{#1}\EndNoFonts% + }{} + }{}% +} + +\newcommand\MMLVerbEquation[1]{% + \cs_if_exist:cTF{#1}{ + \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname + \expandafter\let\csname endold#1\expandafter\endcsname\csname end#1\endcsname + \RenewDocumentEnvironment{#1}{+!b}{% + \NoFonts\expandafter\MMLVerbMathToksEquation\expandafter{##1}{#1}\EndNoFonts% + }{} + }{}% +} +\ExplSyntaxOff + +% \MMLVerbEquation{equation} +% \MMLVerbEquation{equation*} + +\fi +>>> + +\<configure html-mml amsmath\><<< +\:CheckOption{texsource}\if:Option +\MMLVerbMath{subarray} +\MMLVerbMath{smallmatrix} +\MMLVerbMath{matrix} +\MMLVerbMath{pmatrix} +\MMLVerbMath{bmatrix} +\MMLVerbMath{Bmatrix} +\MMLVerbMath{vmatrix} +\MMLVerbMath{Vmatrix} +\MMLVerbMath{cases} +\MMLVerbMath{subequations} +\MMLVerbMath{aligned} +\MMLVerbMath{alignedat} +\MMLVerbMath{gathered} +\MMLVerbMath{gather} +\MMLVerbMath{gather*} +\MMLVerbMath{alignat} +\MMLVerbMath{alignat*} +\MMLVerbMath{xalignat} +\MMLVerbMath{xalignat*} +\MMLVerbMath{xxalignat} +\MMLVerbMath{align} +\MMLVerbMath{align*} +\MMLVerbMath{flalign} +\MMLVerbMath{flalign*} +\MMLVerbMath{split} +\MMLVerbMath{multline} +\MMLVerbMath{multline*} +% equations fails with errors, even though it worked in a .cfg +% I will need to investigate it more +% \MMLVerbEquation{equation} +% \MMLVerbEquation{equation*} +\MMLVerbMath{math} +\MMLVerbMath{displaymath} +\MMLVerbMath{eqnarray} +\MMLVerbMath{eqnarray*} +\fi +>>> + %%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{plain.sty} %%%%%%%%%%%%%%%%%%%%%%%%%% @@ -3584,14 +3767,19 @@ charactes. Extra brackets are used in order to support subscripts and superscripts. \<configure mathml latex\><<< -\def\:temp#1#2{\def#1{\PauseMathClass{\HCode{<mi mathvariant="normal">}\ht:special{t4ht@+\string&{35}x#2{59}}\a:HChar\HCode{</mi>}}\EndPauseMathClass}} -\:temp\Psi{03A8} +\def\:temp#1#2{\def\:tempa{\PauseMathClass{\HCode{<mi mathvariant="normal">}\ht:special{t4ht@+\string&{35}x#2{59}}\a:HChar\HCode{</mi>}}\EndPauseMathClass}\HLet#1\:tempa} +\:temp\Gamma{0393} \:temp\Delta{0394} +\:temp\Theta{0398} +\:temp\Lambda{039B} \:temp\Xi{039E} \:temp\Pi{03A0} \:temp\Sigma{03A3} \:temp\Upsilon{03A5} +\:temp\Phi{03A6} +\:temp\Psi{03A8} \:temp\Omega{03A9} + >>> @@ -5703,6 +5891,25 @@ elements that are printed to support the munderover element easily. >>> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{esvec} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +We need to redefine these commands only for MathML. By default, Esvect produces images, which is OK. + +\<configure mathml esvect\><<< +\def\:tempa#1{% + \bgroup\HCode{<\a:mathml mover><\a:mathml mrow>}#1\HCode{</\a:mathml mrow><\a:mathml mo>→</\a:mathml mo></\a:mathml mover>}\egroup +} + +\HLet\ESV@vecteur\:tempa +\def\:tempa#1#2{% + \ESV@vecteur{{#1}\sb{#2}} +} +\HLet\vvstar\:tempa + +>>> + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Notes} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |