From b2f78dce83a87bc899dc0aeb2f178ca3ac558019 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Gen=C4=8Dur?= Date: Mon, 29 Jan 2024 19:25:01 +0100 Subject: [PATCH 1/6] add `contentType` option and `markinline` command --- markdown.dtx | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 267 insertions(+), 1 deletion(-) diff --git a/markdown.dtx b/markdown.dtx index 74d94e4b..1f9c420c 100644 --- a/markdown.dtx +++ b/markdown.dtx @@ -5209,6 +5209,142 @@ defaultOptions.contentBlocks = false % %<*manual-options> +#### Option `contentType` + +`contentType` (default value: `block`) + +% \fi +% \begin{markdown} +% +% \Optitem[block]{contentType}{\opt{inline}, \opt{block}} +% +: inline + + : Treat all content as inline elements. Blank lines are + replaced with spaces. + + ``` md + - this is a text + - not a list + `````` + +: block + + : Render block and inline elements normally, + no behaviour is changed. + +% \end{markdown} +% \iffalse + +##### Plain \TeX{} Example {.unnumbered} + +Using a text editor, create a text document named `document.tex` with the +following content: +``` tex +\input markdown +\def\markdownOptionContentType{inline} +\markdownBegin +- this is +- a text +\markdownEnd +\bye +``````` +Next, invoke LuaTeX from the terminal: +``` sh +luatex document.tex +`````` +A PDF document named `document.pdf` should be produced and contain the +following text: + +> \- this is - a text + +##### \LaTeX{} Example {.unnumbered} + +Using a text editor, create a text document named `document.tex` with the +following content: +``` tex +\documentclass{article} +\usepackage{markdown} +\begin{document} + +\begin{markdown} +- this is +- a list +\end{markdown} + +\begin{markdown}[contentType=inline] +- this is +- a text +\end{markdown} + +\end{document} +``````` +Next, invoke LuaTeX from the terminal: +``` sh +lualatex document.tex +`````` +A PDF document named `document.pdf` should be produced and contain the +following text: + +> - this is +> - a list +> +> \- this is - a text + +##### \Hologo{ConTeXt} Example {.unnumbered} + +Using a text editor, create a text document named `document.tex` with the +following content: +``` tex +\usemodule[t][markdown] +\starttext + +\startmarkdown +- this is +- a list +\stopmarkdown + +\setupmarkdown[contentType = inline] +\startmarkdown +- this is +- a text +\stopmarkdown + +\stoptext +```````` +Next, invoke LuaTeX from the terminal: +``` sh +context --luatex document.tex +````` +A PDF document named `document.pdf` should be produced and contain the +following text: + +> - this is +> - a list +> +> \- this is - a text + +% +%<*tex> +% \fi +% \begin{macrocode} +\@@_add_lua_option:nnn + { contentType } + { string } + { block } +% \end{macrocode} +% \iffalse +% +%<*lua,lua-cli> +% \fi +% \begin{macrocode} +defaultOptions.contentType = "block" +% \end{macrocode} +% \par +% \iffalse +% +%<*manual-options> + #### Option `debugExtensions` `debugExtensions` (default value: `false`) @@ -11202,7 +11338,7 @@ pdftex --shell-escape document.tex %### Typesetting Markdown {#tex-typesetting} % % The interface exposes the \mdef{markdownBegin}, \mdef{markdownEnd}, -% \mdef{markdownInput}, and \mdef{markdownEscape} macros. +% \mdef{markdownInput}, \mdef{markinline} and \mdef{markdownEscape} macros. % % The \mref{markdownBegin} macro marks the beginning of a markdown document % fragment and the \mref{markdownEnd} macro marks its end. @@ -11285,6 +11421,31 @@ pdftex --shell-escape document.tex % \bye % ``````` % +% You can use the \mref{markinline} macro to include +% just inline elements. +% The \mref{markinline} macro accepts a single parameter +% with the input markdown and expands to the result of the +% conversion of the input markdown to plain \TeX{}. +% +% \end{markdown} +% \begin{macrocode} +\let\markinline\relax +% \end{macrocode} +% \par +% \begin{markdown} +% +% This macro is not subject to the abovelisted limitations of the +% \mref{markdownBegin} and \mref{markdownEnd} macros. +% +% The following example plain \TeX{} code showcases the usage of the +% \mref{markinline} macro: +% +% ``` tex +% \input markdown +% Hello, \markinline{*world*} ! +% \bye +% ``````` +% % The \mref{markdownEscape} macro accepts a single parameter with the filename % of a \TeX{} document and executes the \TeX{} document in the middle of a % markdown document fragment. Unlike the `\input` built-in of \TeX, @@ -29299,6 +29460,15 @@ end syntax.AutoLinkRelativeReference = parsers.fail end + if options.contentType == "inline" then + syntax[1] = "Inlines" + syntax.Inlines = V("InitializeState") + * parsers.Inline^0 + * ( parsers.spacing^0 + * parsers.eof / "") + syntax.Space = parsers.Space + parsers.blankline / writer.space + end + local blocks_nested_t = util.table_copy(syntax) blocks_nested_t.ExpectedJekyllData = parsers.fail parsers.blocks_nested = Ct(blocks_nested_t) @@ -33265,6 +33435,84 @@ end }% |endgroup % \end{macrocode} +% \begin{markdown} +% The \mref{markinline} macro uses an implementation of the +% \mref{markdownLuaExecute} macro to convert inline markdown to plain +% \TeX{}. +% +% \end{markdown} +% \begin{macrocode} +\begingroup +% \end{macrocode} +% \begin{markdown} +% Swap the category code of the backslash symbol and the pipe symbol, so that +% we may use the backslash symbol freely inside the Lua code. Furthermore, +% use the ampersand symbol to specify parameters. +% \end{markdown} +% \begin{macrocode} + \catcode`|=0% + \catcode`\\=12% + \catcode`|&=6% + |gdef|markinline#1{% +% \end{macrocode} +% \begin{markdown} +% Change the category code of the percent sign (`\%`) to other, so that a user +% of the \Opt{hybrid} Lua option or a malevolent actor can't produce TeX +% comments in the plain TeX output of the Markdown package. +% \end{markdown} +% \begin{macrocode} + |begingroup + |catcode`|%=12 +% \end{macrocode} +% \begin{markdown} +% Furthermore, also change the category code of the hash sign (`#`) to other, +% so that it's safe to tokenize the plain TeX output without mistaking hash +% signs with TeX's parameter numbers. +% \end{markdown} +% \begin{macrocode} + |catcode`|#=12 +% \end{macrocode} +% \begin{markdown} +% Set the content type as inline. +% \end{markdown} +% \begin{macrocode} + |markdownSetup{contentType=inline} +% \end{macrocode} +% \begin{markdown} +% If we are reading from the frozen cache, input it, expand the corresponding +% `\markdownFrozenCache`\meta{number} macro, and increment +% \Opt{frozenCacheCounter}. +% \end{markdown} +% \begin{macrocode} + |markdownIfOption{frozenCache}{% + |ifnum|markdownOptionFrozenCacheCounter=0|relax + |markdownInfo{Reading frozen cache from + "|markdownOptionFrozenCacheFileName"}% + |input|markdownOptionFrozenCacheFileName|relax + |fi + |markdownInfo{Including markdown document number + "|the|markdownOptionFrozenCacheCounter" from frozen cache}% + |csname markdownFrozenCache|the|markdownOptionFrozenCacheCounter|endcsname + |global|advance|markdownOptionFrozenCacheCounter by 1|relax + }{% + |markdownPrepareLuaOptions + |markdownLuaExecute{% + |markdownPrepare + local input = "&1" + print(convert(input)) + |markdownCleanup}% +% \end{macrocode} +% \begin{markdown} +% If we are finalizing the frozen cache, increment \Opt{frozenCacheCounter}. +% \end{markdown} +% \begin{macrocode} + |markdownIfOption{finalizeCache}{% + |global|advance|markdownOptionFrozenCacheCounter by 1|relax}{}% + }% + |endgroup + }% +|endgroup +% \end{macrocode} % \par % \begin{markdown} % The \mref{markdownEscape} macro resets the category codes of the percent sign @@ -33334,6 +33582,24 @@ end % \par % \begin{markdown} % +% The \mdef{markinlinePlainTeX} macro is used to store the original plain +% \TeX{} implementation of the \mref{markinline} macro. The \mref{markinline} +% is then redefined to accept an optional argument with options recognized by +% the \LaTeX{} interface (see Section <#sec:latex-options>). +% +% \end{markdown} +% \begin{macrocode} +\let\markinlinePlainTeX\markinline +\renewcommand\markinline[2][]{% + \begingroup + \markdownSetup{#1}% + \markinlinePlainTeX{#2}% + \endgroup}% + +% \end{macrocode} +% \par +% \begin{markdown} +% % The \envmref{markdown}, and \envmref{markdown*} \LaTeX{} environments are % implemented using the \mref{markdownReadAndConvert} macro. % From a44b9c3a93698d1ef802d99835ffbcaaa34722bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Novotn=C3=BD?= Date: Thu, 23 Nov 2023 10:51:45 +0100 Subject: [PATCH 2/6] Add unit tests for the `contentType` Lua option --- .../lunamark-markdown/content-type-block.test | 86 +++++++++++++++++++ .../content-type-inline.test | 47 ++++++++++ 2 files changed, 133 insertions(+) create mode 100644 tests/testfiles/lunamark-markdown/content-type-block.test create mode 100644 tests/testfiles/lunamark-markdown/content-type-inline.test diff --git a/tests/testfiles/lunamark-markdown/content-type-block.test b/tests/testfiles/lunamark-markdown/content-type-block.test new file mode 100644 index 00000000..d5d92981 --- /dev/null +++ b/tests/testfiles/lunamark-markdown/content-type-block.test @@ -0,0 +1,86 @@ +\markdownSetup{contentType=block} +<<< +This test ensures that the Lua `contentType` option correctly propagates +through the plain TeX interface. Setting the `contentType` option to the +default value `block` should have no effect. + +Here are some inline elements: + +- *emphasis* and __strong emphasis__ +- [link](https://example/url "Example title") +- ![image](https://example/url "Example title") +- `code` + +Here are some block elements: + +- > blockquote +- code + + block +- + * bullet + * list +- + 1. ordered + 2. list +>>> +BEGIN document +codeSpan: contentType +someLineBreak +codeSpan: contentType +someLineBreak +codeSpan: block +paragraphSeparator +interblockSeparator +ulBeginTight +ulItem +emphasis: emphasis +strongEmphasis: strong emphasis +ulItemEnd +ulItem +BEGIN link +- label: link +- URI: https://example/url +- title: Example title +END link +ulItemEnd +ulItem +BEGIN image +- label: image +- URI: https://example/url +- title: Example title +END image +ulItemEnd +ulItem +codeSpan: code +ulItemEnd +ulEndTight +interblockSeparator +interblockSeparator +ulBegin +ulItem +blockQuoteBegin +blockQuoteEnd +ulItemEnd +ulItem +interblockSeparator +inputVerbatim: ./_markdown_test/14511f2f5564650d129ca7cabc333278.verbatim +ulItemEnd +ulItem +ulBeginTight +ulItem +ulItemEnd +ulItem +ulItemEnd +ulEndTight +ulItemEnd +ulItem +olBeginTight +olItemWithNumber: 1 +olItemEnd +olItemWithNumber: 2 +olItemEnd +olEndTight +ulItemEnd +ulEnd +END document diff --git a/tests/testfiles/lunamark-markdown/content-type-inline.test b/tests/testfiles/lunamark-markdown/content-type-inline.test new file mode 100644 index 00000000..ea47bf5e --- /dev/null +++ b/tests/testfiles/lunamark-markdown/content-type-inline.test @@ -0,0 +1,47 @@ +\markdownSetup{contentType=inline} +<<< +This test ensures that the Lua `contentType` option correctly propagates +through the plain TeX interface. Setting the `contentType` option to the +`inline` value should disable the part of the markdown grammar that deals +with block elements. Instead of separating blocks and paragraphs, blank +lines should translate to spaces, lists and blockquotes should just be +understood as plain text. + +Here are some inline elements: + +- *emphasis* and __strong emphasis__ +- [link](https://example/url "Example title") +- ![image](https://example/url "Example title") +- `code` + +Here are some block elements: + +- > blockquote +- code + + block +- + * bullet + * list +- + 1. ordered + 2. list +>>> +BEGIN document +codeSpan: contentType +codeSpan: contentType +codeSpan: inline +emphasis: emphasis +strongEmphasis: strong emphasis +BEGIN link +- label: link +- URI: https://example/url +- title: Example title +END link +BEGIN image +- label: image +- URI: https://example/url +- title: Example title +END image +codeSpan: code +END document From 662e3b943e537bf228e25aa97821cce085522443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Gen=C4=8Dur?= Date: Wed, 31 Jan 2024 09:56:41 +0100 Subject: [PATCH 3/6] replace line break placeholder --- tests/testfiles/lunamark-markdown/content-type-block.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testfiles/lunamark-markdown/content-type-block.test b/tests/testfiles/lunamark-markdown/content-type-block.test index d5d92981..3415176d 100644 --- a/tests/testfiles/lunamark-markdown/content-type-block.test +++ b/tests/testfiles/lunamark-markdown/content-type-block.test @@ -26,9 +26,9 @@ Here are some block elements: >>> BEGIN document codeSpan: contentType -someLineBreak +softLineBreak codeSpan: contentType -someLineBreak +softLineBreak codeSpan: block paragraphSeparator interblockSeparator From cd10c27e5469c289efb49f8a5fd150fc2df89a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Gen=C4=8Dur?= Date: Wed, 31 Jan 2024 10:05:05 +0100 Subject: [PATCH 4/6] change option description --- markdown.dtx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/markdown.dtx b/markdown.dtx index 1f9c420c..c257b7c2 100644 --- a/markdown.dtx +++ b/markdown.dtx @@ -5216,23 +5216,24 @@ defaultOptions.contentBlocks = false % \fi % \begin{markdown} % -% \Optitem[block]{contentType}{\opt{inline}, \opt{block}} +% \Optitem[block]{contentType}{\opt{block}, \opt{inline}} % -: inline - - : Treat all content as inline elements. Blank lines are - replaced with spaces. +: block + + : Treat content as a sequence of blocks. + ``` md + - this is a list + - it contains two items + `````` +: inline + + : Treat all content as inline content. ``` md - this is a text - not a list `````` -: block - - : Render block and inline elements normally, - no behaviour is changed. - % \end{markdown} % \iffalse From 38cdee2dfe4f74d950c050ba26a5d42d05f5f8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Gen=C4=8Dur?= Date: Wed, 31 Jan 2024 10:06:49 +0100 Subject: [PATCH 5/6] remove `markinline` TeX implementation --- markdown.dtx | 123 +-------------------------------------------------- 1 file changed, 1 insertion(+), 122 deletions(-) diff --git a/markdown.dtx b/markdown.dtx index c257b7c2..b479ff52 100644 --- a/markdown.dtx +++ b/markdown.dtx @@ -11339,7 +11339,7 @@ pdftex --shell-escape document.tex %### Typesetting Markdown {#tex-typesetting} % % The interface exposes the \mdef{markdownBegin}, \mdef{markdownEnd}, -% \mdef{markdownInput}, \mdef{markinline} and \mdef{markdownEscape} macros. +% \mdef{markdownInput}, and \mdef{markdownEscape} macros. % % The \mref{markdownBegin} macro marks the beginning of a markdown document % fragment and the \mref{markdownEnd} macro marks its end. @@ -11422,31 +11422,6 @@ pdftex --shell-escape document.tex % \bye % ``````` % -% You can use the \mref{markinline} macro to include -% just inline elements. -% The \mref{markinline} macro accepts a single parameter -% with the input markdown and expands to the result of the -% conversion of the input markdown to plain \TeX{}. -% -% \end{markdown} -% \begin{macrocode} -\let\markinline\relax -% \end{macrocode} -% \par -% \begin{markdown} -% -% This macro is not subject to the abovelisted limitations of the -% \mref{markdownBegin} and \mref{markdownEnd} macros. -% -% The following example plain \TeX{} code showcases the usage of the -% \mref{markinline} macro: -% -% ``` tex -% \input markdown -% Hello, \markinline{*world*} ! -% \bye -% ``````` -% % The \mref{markdownEscape} macro accepts a single parameter with the filename % of a \TeX{} document and executes the \TeX{} document in the middle of a % markdown document fragment. Unlike the `\input` built-in of \TeX, @@ -33436,84 +33411,6 @@ end }% |endgroup % \end{macrocode} -% \begin{markdown} -% The \mref{markinline} macro uses an implementation of the -% \mref{markdownLuaExecute} macro to convert inline markdown to plain -% \TeX{}. -% -% \end{markdown} -% \begin{macrocode} -\begingroup -% \end{macrocode} -% \begin{markdown} -% Swap the category code of the backslash symbol and the pipe symbol, so that -% we may use the backslash symbol freely inside the Lua code. Furthermore, -% use the ampersand symbol to specify parameters. -% \end{markdown} -% \begin{macrocode} - \catcode`|=0% - \catcode`\\=12% - \catcode`|&=6% - |gdef|markinline#1{% -% \end{macrocode} -% \begin{markdown} -% Change the category code of the percent sign (`\%`) to other, so that a user -% of the \Opt{hybrid} Lua option or a malevolent actor can't produce TeX -% comments in the plain TeX output of the Markdown package. -% \end{markdown} -% \begin{macrocode} - |begingroup - |catcode`|%=12 -% \end{macrocode} -% \begin{markdown} -% Furthermore, also change the category code of the hash sign (`#`) to other, -% so that it's safe to tokenize the plain TeX output without mistaking hash -% signs with TeX's parameter numbers. -% \end{markdown} -% \begin{macrocode} - |catcode`|#=12 -% \end{macrocode} -% \begin{markdown} -% Set the content type as inline. -% \end{markdown} -% \begin{macrocode} - |markdownSetup{contentType=inline} -% \end{macrocode} -% \begin{markdown} -% If we are reading from the frozen cache, input it, expand the corresponding -% `\markdownFrozenCache`\meta{number} macro, and increment -% \Opt{frozenCacheCounter}. -% \end{markdown} -% \begin{macrocode} - |markdownIfOption{frozenCache}{% - |ifnum|markdownOptionFrozenCacheCounter=0|relax - |markdownInfo{Reading frozen cache from - "|markdownOptionFrozenCacheFileName"}% - |input|markdownOptionFrozenCacheFileName|relax - |fi - |markdownInfo{Including markdown document number - "|the|markdownOptionFrozenCacheCounter" from frozen cache}% - |csname markdownFrozenCache|the|markdownOptionFrozenCacheCounter|endcsname - |global|advance|markdownOptionFrozenCacheCounter by 1|relax - }{% - |markdownPrepareLuaOptions - |markdownLuaExecute{% - |markdownPrepare - local input = "&1" - print(convert(input)) - |markdownCleanup}% -% \end{macrocode} -% \begin{markdown} -% If we are finalizing the frozen cache, increment \Opt{frozenCacheCounter}. -% \end{markdown} -% \begin{macrocode} - |markdownIfOption{finalizeCache}{% - |global|advance|markdownOptionFrozenCacheCounter by 1|relax}{}% - }% - |endgroup - }% -|endgroup -% \end{macrocode} % \par % \begin{markdown} % The \mref{markdownEscape} macro resets the category codes of the percent sign @@ -33583,24 +33480,6 @@ end % \par % \begin{markdown} % -% The \mdef{markinlinePlainTeX} macro is used to store the original plain -% \TeX{} implementation of the \mref{markinline} macro. The \mref{markinline} -% is then redefined to accept an optional argument with options recognized by -% the \LaTeX{} interface (see Section <#sec:latex-options>). -% -% \end{markdown} -% \begin{macrocode} -\let\markinlinePlainTeX\markinline -\renewcommand\markinline[2][]{% - \begingroup - \markdownSetup{#1}% - \markinlinePlainTeX{#2}% - \endgroup}% - -% \end{macrocode} -% \par -% \begin{markdown} -% % The \envmref{markdown}, and \envmref{markdown*} \LaTeX{} environments are % implemented using the \mref{markdownReadAndConvert} macro. % From 14a364e5997cfe144cfe3aa717b91e78174f63f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Star=C3=BD=20Novotn=C3=BD?= Date: Wed, 31 Jan 2024 11:33:00 +0100 Subject: [PATCH 6/6] Update `CHANGES.md` --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index facbb31d..405eac6c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,8 @@ Development: `witiko/markdown/defaults`. (#391, #392) - Add format-independent options `noDefaults` and `plain`, which control the loading of theme `witiko/markdown/defaults`. (#393, #394) +- Add `contentLevel` Lua option. + (#300, #375, #400, contributed by @lostenderman) Default Renderer Prototypes: