From 29f78b6e95b90c77d3c87a970902d08f82f1dab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Novotn=C3=BD?= Date: Sun, 13 Feb 2022 00:36:06 +0100 Subject: [PATCH 1/7] Add attribute context renderers --- markdown.dtx | 155 +++++++++++++++--- .../markdownthemewitiko_markdown_test.sty | 4 + tests/support/plain-setup.tex | 4 + 3 files changed, 138 insertions(+), 25 deletions(-) diff --git a/markdown.dtx b/markdown.dtx index e07358498..ff7b8ac44 100644 --- a/markdown.dtx +++ b/markdown.dtx @@ -7737,27 +7737,6 @@ into account. ##### \LaTeX{} Example {.unnumbered} -\def\markdownRendererDocumentEnd{% - \endgroup - This is the end of a document.\par -} -\def\markdownRendererDocumentBegin{% - This is the beginning of a document.\par - \begingroup - \def\markdownRendererDocumentBegin{% - This is the beginning of a nested document.\par - \begingroup - \def\markdownRendererDocumentBegin{% - This is the beginning of a nested document.\par - \begingroup - }% - \def\markdownRendererDocumentEnd{% - \endgroup - This is the end of a nested document.\par - }% - }% -} - Using a text editor, create a text document named `nested.md` with the following content: ``` md @@ -11982,6 +11961,96 @@ following body text: % % \begin{markdown} +#### Attribute Context Renderers +The following macros are only produced, when the \Opt{headerAttributes} option +is enabled. + +The \mdef{markdownRendererAttributeContextBegin} and +\mdef{markdownRendererAttributeContextEnd} macros represent the beginning and +the end of a context in which certain attributes apply. The macros receive no +arguments. + +% \end{markdown} +% +% \iffalse + +##### \LaTeX{} Example {.unnumbered} + +Using a text editor, create a text document named `document.tex` with the +following content: +``` tex +\documentclass{article} +\usepackage[headerAttributes]{markdown} +\markdownSetup{ + renderers = { + attributeContextBegin = {% + \par + \emph{(The beginning of an attribute context)} + \par + }, + attributeContextBegin = {% + \par + \emph{(The end of an attribute context)} + \par + }, + }, +} +\begin{document} +\begin{markdown} + +# First top-level heading + +## A subheading + +# Second top-level heading + +\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: + +> *(The beginning of an attribute context)* +> +> # First top-level heading +> +> *(The beginning of an attribute context)* +> +> ## A subheading +> +> *(The end of an attribute context)* +> +> *(The end of an attribute context)* +> +> *(The beginning of an attribute context)* +> +> # Second top-level heading +> +> *(The end of an attribute context)* + +% +%<*tex> +% \fi +% +% \begin{macrocode} +\def\markdownRendererAttributeContextBegin{% + \markdownRendererAttributeContextBeginPrototype}% +\def\markdownRendererAttributeContextEnd{% + \markdownRendererAttributeContextEndPrototype}% +% \end{macrocode} +% \par +% +% \iffalse +% +%<*manual-tokens> +% \fi +% +% \begin{markdown} + ### Token Renderer Prototypes % \label{sec:texrendererprototypes} @@ -12113,6 +12182,8 @@ following text: % % \end{markdown} % \begin{macrocode} +\def\markdownRendererAttributeContextBeginPrototype{}% +\def\markdownRendererAttributeContextEndPrototype{}% \def\markdownRendererDocumentBeginPrototype{}% \def\markdownRendererDocumentEndPrototype{}% \def\markdownRendererInterblockSeparatorPrototype{}% @@ -13171,6 +13242,10 @@ The following ordered list will be preceded by roman numerals: % % \end{markdown} % \begin{macrocode} +\define@key{markdownRenderers}{attributeContextBegin}{% + \renewcommand\markdownRendererAttributeContextBegin{#1}}% +\define@key{markdownRenderers}{attributeContextEnd}{% + \renewcommand\markdownRendererAttributeContextEnd{#1}}% \define@key{markdownRenderers}{documentBegin}{% \renewcommand\markdownRendererDocumentBegin{#1}}% \define@key{markdownRenderers}{documentEnd}{% @@ -13348,6 +13423,10 @@ The following ordered list will be preceded by roman numerals: % % \end{markdown} % \begin{macrocode} +\define@key{markdownRendererPrototypes}{attributeContextBegin}{% + \renewcommand\markdownRendererAttributeContextBeginPrototype{#1}}% +\define@key{markdownRendererPrototypes}{attributeContextEnd}{% + \renewcommand\markdownRendererAttributeContextEndPrototype{#1}}% \define@key{markdownRendererPrototypes}{documentBegin}{% \renewcommand\markdownRendererDocumentBeginPrototype{#1}}% \define@key{markdownRendererPrototypes}{documentEnd}{% @@ -16746,8 +16825,20 @@ function M.writer.new(options) % \end{markdown} % \begin{macrocode} function self.document(d) - return {"\\markdownRendererDocumentBegin\n", d, - "\\markdownRendererDocumentEnd"} + local active_headings = self.active_headings + local buf = {"\\markdownRendererDocumentBegin\n", d} + + if options.headerAttributes then + while #active_headings > 0 do + -- insert attribute context end for sections that ended + table.insert(buf, "\\markdownRendererAttributeContextEnd") + table.remove(active_headings, #active_headings) + end + end + + table.insert(buf, "\\markdownRendererDocumentEnd") + + return buf end % \end{macrocode} % \par @@ -16872,9 +16963,14 @@ function M.writer.new(options) local slice_end_type = self.slice_end:sub(1, 1) local slice_end_identifier = self.slice_end:sub(2) or "" - while #active_headings < level do + local buf = {} + + while #active_headings < level-1 do -- push empty identifiers for implied sections table.insert(active_headings, {}) + if options.headerAttributes then + table.insert(buf, "\\markdownRendererAttributeContextBegin") + end end while #active_headings >= level do @@ -16888,6 +16984,9 @@ function M.writer.new(options) and slice_end_type == "$" then self.is_writing = false end + if options.headerAttributes then + table.insert(buf, "\\markdownRendererAttributeContextEnd") + end table.remove(active_headings, #active_headings) end @@ -16908,6 +17007,10 @@ function M.writer.new(options) end table.insert(active_headings, identifiers) + if options.headerAttributes then + table.insert(buf, "\\markdownRendererAttributeContextBegin") + end + if not self.is_writing then return "" end local cmd @@ -16927,7 +17030,9 @@ function M.writer.new(options) else cmd = "" end - return {cmd,"{",s,"}"} + table.insert(buf, {cmd, "{", s, "}"}) + + return buf end % \end{macrocode} % \par diff --git a/tests/support/markdownthemewitiko_markdown_test.sty b/tests/support/markdownthemewitiko_markdown_test.sty index 8d5cd00e2..c6cecf0ec 100644 --- a/tests/support/markdownthemewitiko_markdown_test.sty +++ b/tests/support/markdownthemewitiko_markdown_test.sty @@ -1,5 +1,9 @@ \markdownSetupSnippet{snippet}{% renderers = {% + attributeContextBegin = {% + \TYPE{attributeContextBegin}}, + attributeContextEnd = {% + \TYPE{attributeContextEnd}}, documentBegin = {% \TYPE{documentBegin}}, documentEnd = {% diff --git a/tests/support/plain-setup.tex b/tests/support/plain-setup.tex index 6ff66d09a..c28c88601 100644 --- a/tests/support/plain-setup.tex +++ b/tests/support/plain-setup.tex @@ -1,3 +1,7 @@ +\def\markdownRendererAttributeContextBegin{% + \TYPE{attributeContextBegin}}% +\def\markdownRendererAttributeContextEnd{% + \TYPE{attributeContextEnd}}% \def\markdownRendererDocumentBegin{% \TYPE{documentBegin}}% \def\markdownRendererDocumentEnd{% From 52ed63df029c865dc059e83b0f897ca931145945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Novotn=C3=BD?= Date: Fri, 18 Feb 2022 21:08:59 +0100 Subject: [PATCH 2/7] Track active attributes, not just identifiers --- markdown.dtx | 44 +++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/markdown.dtx b/markdown.dtx index ff7b8ac44..f2566c72f 100644 --- a/markdown.dtx +++ b/markdown.dtx @@ -16825,14 +16825,14 @@ function M.writer.new(options) % \end{markdown} % \begin{macrocode} function self.document(d) - local active_headings = self.active_headings + local active_attributes = self.active_attributes local buf = {"\\markdownRendererDocumentBegin\n", d} if options.headerAttributes then - while #active_headings > 0 do + while #active_attributes > 0 do -- insert attribute context end for sections that ended table.insert(buf, "\\markdownRendererAttributeContextEnd") - table.remove(active_headings, #active_headings) + table.remove(active_attributes, #active_attributes) end end @@ -16939,13 +16939,13 @@ function M.writer.new(options) % \par % \begin{markdown} % -% Define \luamdef{writer->active\_headings} as a stack of identifiers +% Define \luamdef{writer->active\_attributes} as a stack of attributes % of the headings that are currently active. The % \luamref{writer->active\_headings} member variable is mutable. % % \end{markdown} % \begin{macrocode} - self.active_headings = {} + self.active_attributes = {} % \end{macrocode} % \par % \begin{markdown} @@ -16957,7 +16957,7 @@ function M.writer.new(options) % \end{markdown} % \begin{macrocode} function self.heading(s,level,attributes) - local active_headings = self.active_headings + local active_attributes = self.active_attributes local slice_begin_type = self.slice_begin:sub(1, 1) local slice_begin_identifier = self.slice_begin:sub(2) or "" local slice_end_type = self.slice_end:sub(1, 1) @@ -16965,47 +16965,33 @@ function M.writer.new(options) local buf = {} - while #active_headings < level-1 do + while #active_attributes < level-1 do -- push empty identifiers for implied sections - table.insert(active_headings, {}) + table.insert(active_attributes, {}) if options.headerAttributes then table.insert(buf, "\\markdownRendererAttributeContextBegin") end end - while #active_headings >= level do + while #active_attributes >= level do -- pop identifiers for sections that have ended - local active_identifiers = active_headings[#active_headings] - if active_identifiers[slice_begin_identifier] ~= nil + local active_identifiers = active_attributes[#active_attributes] + if active_identifiers["#" .. slice_begin_identifier] ~= nil and slice_begin_type == "$" then self.is_writing = true end - if active_identifiers[slice_end_identifier] ~= nil + if active_identifiers["#" .. slice_end_identifier] ~= nil and slice_end_type == "$" then self.is_writing = false end if options.headerAttributes then table.insert(buf, "\\markdownRendererAttributeContextEnd") end - table.remove(active_headings, #active_headings) + table.remove(active_attributes, #active_attributes) end -- push identifiers for the new section - attributes = attributes or {} - local identifiers = {} - for index = 1, #attributes do - attribute = attributes[index] - identifiers[attribute:sub(2)] = true - end - if identifiers[slice_begin_identifier] ~= nil - and slice_begin_type == "^" then - self.is_writing = true - end - if identifiers[slice_end_identifier] ~= nil - and slice_end_type == "^" then - self.is_writing = false - end - table.insert(active_headings, identifiers) + table.insert(active_attributes, attributes or {}) if options.headerAttributes then table.insert(buf, "\\markdownRendererAttributeContextBegin") @@ -17088,7 +17074,7 @@ function M.writer.new(options) function self.get_state() return { is_writing=self.is_writing, - active_headings={table.unpack(self.active_headings)}, + active_attributes={table.unpack(self.active_attributes)}, } end % \end{macrocode} From c0cc4e3e3dec4171a9cf5377331c34755d6aa0a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Novotn=C3=BD?= Date: Fri, 18 Feb 2022 18:28:40 +0100 Subject: [PATCH 3/7] Apply and tear down attribute contexts at slice boundaries --- markdown.dtx | 79 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/markdown.dtx b/markdown.dtx index f2566c72f..ff18e853b 100644 --- a/markdown.dtx +++ b/markdown.dtx @@ -16828,10 +16828,13 @@ function M.writer.new(options) local active_attributes = self.active_attributes local buf = {"\\markdownRendererDocumentBegin\n", d} - if options.headerAttributes then + -- pop attributes for sections that have ended + if options.headerAttributes and self.is_writing then while #active_attributes > 0 do - -- insert attribute context end for sections that ended - table.insert(buf, "\\markdownRendererAttributeContextEnd") + local attributes = active_attributes[#active_attributes] + if #attributes > 0 then + table.insert(buf, "\\markdownRendererAttributeContextEnd") + end table.remove(active_attributes, #active_attributes) end end @@ -16956,7 +16959,12 @@ function M.writer.new(options) % % \end{markdown} % \begin{macrocode} - function self.heading(s,level,attributes) + function self.heading(s, level, attributes) + attributes = attributes or {} + for i = 1, #attributes do + attributes[attributes[i]] = true + end + local active_attributes = self.active_attributes local slice_begin_type = self.slice_begin:sub(1, 1) local slice_begin_identifier = self.slice_begin:sub(2) or "" @@ -16965,39 +16973,67 @@ function M.writer.new(options) local buf = {} + -- push empty attributes for implied sections while #active_attributes < level-1 do - -- push empty identifiers for implied sections table.insert(active_attributes, {}) - if options.headerAttributes then - table.insert(buf, "\\markdownRendererAttributeContextBegin") - end end + -- pop attributes for sections that have ended while #active_attributes >= level do - -- pop identifiers for sections that have ended local active_identifiers = active_attributes[#active_attributes] - if active_identifiers["#" .. slice_begin_identifier] ~= nil - and slice_begin_type == "$" then - self.is_writing = true - end + -- tear down all active attributes at slice end if active_identifiers["#" .. slice_end_identifier] ~= nil and slice_end_type == "$" then + for header_level = #active_attributes, 1, -1 do + if options.headerAttributes and #active_attributes[header_level] > 0 then + table.insert(buf, "\\markdownRendererAttributeContextEnd") + end + end self.is_writing = false end - if options.headerAttributes then + table.remove(active_attributes, #active_attributes) + if self.is_writing and options.headerAttributes and #active_identifiers > 0 then table.insert(buf, "\\markdownRendererAttributeContextEnd") end - table.remove(active_attributes, #active_attributes) + -- apply all active attributes at slice beginning + if active_identifiers["#" .. slice_begin_identifier] ~= nil + and slice_begin_type == "$" then + for header_level = 1, #active_attributes do + if options.headerAttributes and #active_attributes[header_level] > 0 then + table.insert(buf, "\\markdownRendererAttributeContextBegin") + end + end + self.is_writing = true + end end - -- push identifiers for the new section - table.insert(active_attributes, attributes or {}) + -- tear down all active attributes at slice end + if attributes["#" .. slice_end_identifier] ~= nil + and slice_end_type == "^" then + for header_level = #active_attributes, 1, -1 do + if options.headerAttributes and #active_attributes[header_level] > 0 then + table.insert(buf, "\\markdownRendererAttributeContextEnd") + end + end + self.is_writing = false + end - if options.headerAttributes then + -- push attributes for the new section + table.insert(active_attributes, attributes) + if self.is_writing and options.headerAttributes and #attributes > 0 then table.insert(buf, "\\markdownRendererAttributeContextBegin") end - if not self.is_writing then return "" end + -- apply all active attributes at slice beginning + if attributes["#" .. slice_begin_identifier] ~= nil + and slice_begin_type == "^" then + for header_level = 1, #active_attributes do + if options.headerAttributes and #active_attributes[header_level] > 0 then + table.insert(buf, "\\markdownRendererAttributeContextBegin") + end + end + self.is_writing = true + end local cmd level = level + options.shiftHeadings @@ -17016,7 +17052,10 @@ function M.writer.new(options) else cmd = "" end - table.insert(buf, {cmd, "{", s, "}"}) + + if self.is_writing then + table.insert(buf, {cmd, "{", s, "}"}) + end return buf end From f12484b804b5d4ee8d09915a33a94fc05cfb68f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Novotn=C3=BD?= Date: Fri, 18 Feb 2022 22:12:07 +0100 Subject: [PATCH 4/7] Update unit tests for headerAttributes and slice --- .../testfiles/lunamark-markdown/header-attributes.test | 10 ++++++++++ tests/testfiles/lunamark-markdown/no-slice.test | 4 ++++ .../lunamark-markdown/slice-existing-section.test | 2 ++ .../lunamark-markdown/slice-two-sections.test | 4 ++++ .../lunamark-markdown/slice-with-deferred-content.test | 2 ++ 5 files changed, 22 insertions(+) diff --git a/tests/testfiles/lunamark-markdown/header-attributes.test b/tests/testfiles/lunamark-markdown/header-attributes.test index 1597b869b..b1db76ffc 100644 --- a/tests/testfiles/lunamark-markdown/header-attributes.test +++ b/tests/testfiles/lunamark-markdown/header-attributes.test @@ -21,19 +21,29 @@ A level two heading {#fourth4-id .2not-a-class} documentBegin codeSpan: headerAttributes interblockSeparator +attributeContextBegin headingOne: A level one heading interblockSeparator +attributeContextEnd +attributeContextBegin headingOne: A level one heading interblockSeparator +attributeContextBegin headingTwo: A level two heading interblockSeparator +attributeContextEnd headingTwo: A level two heading (leftBrace)(hash)fourth4-id .2not-a-class(rightBrace) interblockSeparator headingThree: A level three heading (hash)(hash) (leftBrace)(hash)5not-the-fifth-id(rightBrace) interblockSeparator headingFour: A level four heading (leftBrace)(hash)-6not-the-sixth-id(rightBrace) interblockSeparator +attributeContextBegin headingFive: A level five heading interblockSeparator +attributeContextBegin headingSix: A level six heading +attributeContextEnd +attributeContextEnd +attributeContextEnd documentEnd diff --git a/tests/testfiles/lunamark-markdown/no-slice.test b/tests/testfiles/lunamark-markdown/no-slice.test index 142fa937d..055f27075 100644 --- a/tests/testfiles/lunamark-markdown/no-slice.test +++ b/tests/testfiles/lunamark-markdown/no-slice.test @@ -136,6 +136,7 @@ codeSpan: slice interblockSeparator headingOne: This is an H1 interblockSeparator +attributeContextBegin headingTwo: This is an H2 interblockSeparator headingThree: This is an H3 @@ -168,6 +169,8 @@ interblockSeparator interblockSeparator codeSpan: latex (backslash)documentclass(leftBrace)article(rightBrace) (backslash)begin(leftBrace)document(rightBrace) Hello world! (backslash)end(leftBrace)document(rightBrace) interblockSeparator +attributeContextEnd +attributeContextBegin headingTwo: This is an H2 interblockSeparator interblockSeparator @@ -237,6 +240,7 @@ interblockSeparator interblockSeparator emphasis: Term 2 interblockSeparator +attributeContextEnd headingTwo: This is an H2 interblockSeparator interblockSeparator diff --git a/tests/testfiles/lunamark-markdown/slice-existing-section.test b/tests/testfiles/lunamark-markdown/slice-existing-section.test index 2c3f0e962..6b4d9cfcb 100644 --- a/tests/testfiles/lunamark-markdown/slice-existing-section.test +++ b/tests/testfiles/lunamark-markdown/slice-existing-section.test @@ -140,6 +140,7 @@ belong to the previous footnote. multi-paragraph list items. >>> documentBegin +attributeContextBegin headingTwo: This is an H2 interblockSeparator headingThree: This is an H3 @@ -181,4 +182,5 @@ BEGIN fencedCode - infostring: latex END fencedCode interblockSeparator +attributeContextEnd documentEnd diff --git a/tests/testfiles/lunamark-markdown/slice-two-sections.test b/tests/testfiles/lunamark-markdown/slice-two-sections.test index 86ad14a91..f4464735f 100644 --- a/tests/testfiles/lunamark-markdown/slice-two-sections.test +++ b/tests/testfiles/lunamark-markdown/slice-two-sections.test @@ -140,6 +140,7 @@ belong to the previous footnote. multi-paragraph list items. >>> documentBegin +attributeContextBegin headingTwo: This is an H2 interblockSeparator headingThree: This is an H3 @@ -181,6 +182,8 @@ BEGIN fencedCode - infostring: latex END fencedCode interblockSeparator +attributeContextEnd +attributeContextBegin headingTwo: This is an H2 interblockSeparator interblockSeparator @@ -277,4 +280,5 @@ dlDefinitionEnd dlItemEnd dlEndTight interblockSeparator +attributeContextEnd documentEnd diff --git a/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test b/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test index 1a5b68988..4a38c36e5 100644 --- a/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test +++ b/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test @@ -16,6 +16,7 @@ Here are the definitions: [image]: http://image (This is the title of the image.) >>> documentBegin +attributeContextBegin headingOne: This is another section interblockSeparator footnote: This is the text of the footnote. @@ -30,4 +31,5 @@ BEGIN image - title: This is the title of the image. END image interblockSeparator +attributeContextEnd documentEnd From b7e66b1797304120ca9af7caa463c06e37cd156a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Novotn=C3=BD?= Date: Mon, 21 Feb 2022 21:27:32 +0100 Subject: [PATCH 5/7] Rename attributeContext renderers to headerAttributeContext --- markdown.dtx | 76 +++++++++---------- .../markdownthemewitiko_markdown_test.sty | 8 +- tests/support/plain-setup.tex | 8 +- .../lunamark-markdown/header-attributes.test | 20 ++--- .../testfiles/lunamark-markdown/no-slice.test | 8 +- .../slice-existing-section.test | 4 +- .../lunamark-markdown/slice-two-sections.test | 8 +- .../slice-with-deferred-content.test | 4 +- 8 files changed, 66 insertions(+), 70 deletions(-) diff --git a/markdown.dtx b/markdown.dtx index ff18e853b..1cb411880 100644 --- a/markdown.dtx +++ b/markdown.dtx @@ -11961,14 +11961,14 @@ following body text: % % \begin{markdown} -#### Attribute Context Renderers +#### Header Attribute Context Renderers The following macros are only produced, when the \Opt{headerAttributes} option is enabled. -The \mdef{markdownRendererAttributeContextBegin} and -\mdef{markdownRendererAttributeContextEnd} macros represent the beginning and -the end of a context in which certain attributes apply. The macros receive no -arguments. +The \mdef{markdownRendererHeaderAttributeContextBegin} and +\mdef{markdownRendererHeaderAttributeContextEnd} macros represent the beginning +and the end of a section in which the attributes of a heading apply. The macros +receive no arguments. % \end{markdown} % @@ -11983,14 +11983,14 @@ following content: \usepackage[headerAttributes]{markdown} \markdownSetup{ renderers = { - attributeContextBegin = {% + headerAttributeContextBegin = {% \par - \emph{(The beginning of an attribute context)} + \emph{(The beginning of a header attribute context)} \par }, - attributeContextBegin = {% + headerAttributeContextBegin = {% \par - \emph{(The end of an attribute context)} + \emph{(The end of a header attribute context)} \par }, }, @@ -12000,9 +12000,9 @@ following content: # First top-level heading -## A subheading +## A subheading {#identifier} -# Second top-level heading +# Second top-level heading {.class_name} \end{markdown} \end{document} @@ -12014,33 +12014,29 @@ lualatex document.tex A PDF document named `document.pdf` should be produced and contain the following text: -> *(The beginning of an attribute context)* -> > # First top-level heading > -> *(The beginning of an attribute context)* +> *(The beginning of a header attribute context)* > > ## A subheading > -> *(The end of an attribute context)* -> -> *(The end of an attribute context)* +> *(The end of a header attribute context)* > -> *(The beginning of an attribute context)* +> *(The beginning of a header attribute context)* > > # Second top-level heading > -> *(The end of an attribute context)* +> *(The end of a header attribute context)* % %<*tex> % \fi % % \begin{macrocode} -\def\markdownRendererAttributeContextBegin{% - \markdownRendererAttributeContextBeginPrototype}% -\def\markdownRendererAttributeContextEnd{% - \markdownRendererAttributeContextEndPrototype}% +\def\markdownRendererHeaderAttributeContextBegin{% + \markdownRendererHeaderAttributeContextBeginPrototype}% +\def\markdownRendererHeaderAttributeContextEnd{% + \markdownRendererHeaderAttributeContextEndPrototype}% % \end{macrocode} % \par % @@ -12182,8 +12178,8 @@ following text: % % \end{markdown} % \begin{macrocode} -\def\markdownRendererAttributeContextBeginPrototype{}% -\def\markdownRendererAttributeContextEndPrototype{}% +\def\markdownRendererHeaderAttributeContextBeginPrototype{}% +\def\markdownRendererHeaderAttributeContextEndPrototype{}% \def\markdownRendererDocumentBeginPrototype{}% \def\markdownRendererDocumentEndPrototype{}% \def\markdownRendererInterblockSeparatorPrototype{}% @@ -13242,10 +13238,10 @@ The following ordered list will be preceded by roman numerals: % % \end{markdown} % \begin{macrocode} -\define@key{markdownRenderers}{attributeContextBegin}{% - \renewcommand\markdownRendererAttributeContextBegin{#1}}% -\define@key{markdownRenderers}{attributeContextEnd}{% - \renewcommand\markdownRendererAttributeContextEnd{#1}}% +\define@key{markdownRenderers}{headerAttributeContextBegin}{% + \renewcommand\markdownRendererHeaderAttributeContextBegin{#1}}% +\define@key{markdownRenderers}{headerAttributeContextEnd}{% + \renewcommand\markdownRendererHeaderAttributeContextEnd{#1}}% \define@key{markdownRenderers}{documentBegin}{% \renewcommand\markdownRendererDocumentBegin{#1}}% \define@key{markdownRenderers}{documentEnd}{% @@ -13423,10 +13419,10 @@ The following ordered list will be preceded by roman numerals: % % \end{markdown} % \begin{macrocode} -\define@key{markdownRendererPrototypes}{attributeContextBegin}{% - \renewcommand\markdownRendererAttributeContextBeginPrototype{#1}}% -\define@key{markdownRendererPrototypes}{attributeContextEnd}{% - \renewcommand\markdownRendererAttributeContextEndPrototype{#1}}% +\define@key{markdownRendererPrototypes}{headerAttributeContextBegin}{% + \renewcommand\markdownRendererHeaderAttributeContextBeginPrototype{#1}}% +\define@key{markdownRendererPrototypes}{headerAttributeContextEnd}{% + \renewcommand\markdownRendererHeaderAttributeContextEndPrototype{#1}}% \define@key{markdownRendererPrototypes}{documentBegin}{% \renewcommand\markdownRendererDocumentBeginPrototype{#1}}% \define@key{markdownRendererPrototypes}{documentEnd}{% @@ -16833,7 +16829,7 @@ function M.writer.new(options) while #active_attributes > 0 do local attributes = active_attributes[#active_attributes] if #attributes > 0 then - table.insert(buf, "\\markdownRendererAttributeContextEnd") + table.insert(buf, "\\markdownRendererHeaderAttributeContextEnd") end table.remove(active_attributes, #active_attributes) end @@ -16986,21 +16982,21 @@ function M.writer.new(options) and slice_end_type == "$" then for header_level = #active_attributes, 1, -1 do if options.headerAttributes and #active_attributes[header_level] > 0 then - table.insert(buf, "\\markdownRendererAttributeContextEnd") + table.insert(buf, "\\markdownRendererHeaderAttributeContextEnd") end end self.is_writing = false end table.remove(active_attributes, #active_attributes) if self.is_writing and options.headerAttributes and #active_identifiers > 0 then - table.insert(buf, "\\markdownRendererAttributeContextEnd") + table.insert(buf, "\\markdownRendererHeaderAttributeContextEnd") end -- apply all active attributes at slice beginning if active_identifiers["#" .. slice_begin_identifier] ~= nil and slice_begin_type == "$" then for header_level = 1, #active_attributes do if options.headerAttributes and #active_attributes[header_level] > 0 then - table.insert(buf, "\\markdownRendererAttributeContextBegin") + table.insert(buf, "\\markdownRendererHeaderAttributeContextBegin") end end self.is_writing = true @@ -17012,7 +17008,7 @@ function M.writer.new(options) and slice_end_type == "^" then for header_level = #active_attributes, 1, -1 do if options.headerAttributes and #active_attributes[header_level] > 0 then - table.insert(buf, "\\markdownRendererAttributeContextEnd") + table.insert(buf, "\\markdownRendererHeaderAttributeContextEnd") end end self.is_writing = false @@ -17021,7 +17017,7 @@ function M.writer.new(options) -- push attributes for the new section table.insert(active_attributes, attributes) if self.is_writing and options.headerAttributes and #attributes > 0 then - table.insert(buf, "\\markdownRendererAttributeContextBegin") + table.insert(buf, "\\markdownRendererHeaderAttributeContextBegin") end -- apply all active attributes at slice beginning @@ -17029,7 +17025,7 @@ function M.writer.new(options) and slice_begin_type == "^" then for header_level = 1, #active_attributes do if options.headerAttributes and #active_attributes[header_level] > 0 then - table.insert(buf, "\\markdownRendererAttributeContextBegin") + table.insert(buf, "\\markdownRendererHeaderAttributeContextBegin") end end self.is_writing = true diff --git a/tests/support/markdownthemewitiko_markdown_test.sty b/tests/support/markdownthemewitiko_markdown_test.sty index c6cecf0ec..092dcc961 100644 --- a/tests/support/markdownthemewitiko_markdown_test.sty +++ b/tests/support/markdownthemewitiko_markdown_test.sty @@ -1,9 +1,9 @@ \markdownSetupSnippet{snippet}{% renderers = {% - attributeContextBegin = {% - \TYPE{attributeContextBegin}}, - attributeContextEnd = {% - \TYPE{attributeContextEnd}}, + headerAttributeContextBegin = {% + \TYPE{headerAttributeContextBegin}}, + headerAttributeContextEnd = {% + \TYPE{headerAttributeContextEnd}}, documentBegin = {% \TYPE{documentBegin}}, documentEnd = {% diff --git a/tests/support/plain-setup.tex b/tests/support/plain-setup.tex index c28c88601..77cc42dbb 100644 --- a/tests/support/plain-setup.tex +++ b/tests/support/plain-setup.tex @@ -1,7 +1,7 @@ -\def\markdownRendererAttributeContextBegin{% - \TYPE{attributeContextBegin}}% -\def\markdownRendererAttributeContextEnd{% - \TYPE{attributeContextEnd}}% +\def\markdownRendererHeaderAttributeContextBegin{% + \TYPE{headerAttributeContextBegin}}% +\def\markdownRendererHeaderAttributeContextEnd{% + \TYPE{headerAttributeContextEnd}}% \def\markdownRendererDocumentBegin{% \TYPE{documentBegin}}% \def\markdownRendererDocumentEnd{% diff --git a/tests/testfiles/lunamark-markdown/header-attributes.test b/tests/testfiles/lunamark-markdown/header-attributes.test index b1db76ffc..caa2df393 100644 --- a/tests/testfiles/lunamark-markdown/header-attributes.test +++ b/tests/testfiles/lunamark-markdown/header-attributes.test @@ -21,29 +21,29 @@ A level two heading {#fourth4-id .2not-a-class} documentBegin codeSpan: headerAttributes interblockSeparator -attributeContextBegin +headerAttributeContextBegin headingOne: A level one heading interblockSeparator -attributeContextEnd -attributeContextBegin +headerAttributeContextEnd +headerAttributeContextBegin headingOne: A level one heading interblockSeparator -attributeContextBegin +headerAttributeContextBegin headingTwo: A level two heading interblockSeparator -attributeContextEnd +headerAttributeContextEnd headingTwo: A level two heading (leftBrace)(hash)fourth4-id .2not-a-class(rightBrace) interblockSeparator headingThree: A level three heading (hash)(hash) (leftBrace)(hash)5not-the-fifth-id(rightBrace) interblockSeparator headingFour: A level four heading (leftBrace)(hash)-6not-the-sixth-id(rightBrace) interblockSeparator -attributeContextBegin +headerAttributeContextBegin headingFive: A level five heading interblockSeparator -attributeContextBegin +headerAttributeContextBegin headingSix: A level six heading -attributeContextEnd -attributeContextEnd -attributeContextEnd +headerAttributeContextEnd +headerAttributeContextEnd +headerAttributeContextEnd documentEnd diff --git a/tests/testfiles/lunamark-markdown/no-slice.test b/tests/testfiles/lunamark-markdown/no-slice.test index 055f27075..80e3e3cbd 100644 --- a/tests/testfiles/lunamark-markdown/no-slice.test +++ b/tests/testfiles/lunamark-markdown/no-slice.test @@ -136,7 +136,7 @@ codeSpan: slice interblockSeparator headingOne: This is an H1 interblockSeparator -attributeContextBegin +headerAttributeContextBegin headingTwo: This is an H2 interblockSeparator headingThree: This is an H3 @@ -169,8 +169,8 @@ interblockSeparator interblockSeparator codeSpan: latex (backslash)documentclass(leftBrace)article(rightBrace) (backslash)begin(leftBrace)document(rightBrace) Hello world! (backslash)end(leftBrace)document(rightBrace) interblockSeparator -attributeContextEnd -attributeContextBegin +headerAttributeContextEnd +headerAttributeContextBegin headingTwo: This is an H2 interblockSeparator interblockSeparator @@ -240,7 +240,7 @@ interblockSeparator interblockSeparator emphasis: Term 2 interblockSeparator -attributeContextEnd +headerAttributeContextEnd headingTwo: This is an H2 interblockSeparator interblockSeparator diff --git a/tests/testfiles/lunamark-markdown/slice-existing-section.test b/tests/testfiles/lunamark-markdown/slice-existing-section.test index 6b4d9cfcb..b967aecf0 100644 --- a/tests/testfiles/lunamark-markdown/slice-existing-section.test +++ b/tests/testfiles/lunamark-markdown/slice-existing-section.test @@ -140,7 +140,7 @@ belong to the previous footnote. multi-paragraph list items. >>> documentBegin -attributeContextBegin +headerAttributeContextBegin headingTwo: This is an H2 interblockSeparator headingThree: This is an H3 @@ -182,5 +182,5 @@ BEGIN fencedCode - infostring: latex END fencedCode interblockSeparator -attributeContextEnd +headerAttributeContextEnd documentEnd diff --git a/tests/testfiles/lunamark-markdown/slice-two-sections.test b/tests/testfiles/lunamark-markdown/slice-two-sections.test index f4464735f..9379e963c 100644 --- a/tests/testfiles/lunamark-markdown/slice-two-sections.test +++ b/tests/testfiles/lunamark-markdown/slice-two-sections.test @@ -140,7 +140,7 @@ belong to the previous footnote. multi-paragraph list items. >>> documentBegin -attributeContextBegin +headerAttributeContextBegin headingTwo: This is an H2 interblockSeparator headingThree: This is an H3 @@ -182,8 +182,8 @@ BEGIN fencedCode - infostring: latex END fencedCode interblockSeparator -attributeContextEnd -attributeContextBegin +headerAttributeContextEnd +headerAttributeContextBegin headingTwo: This is an H2 interblockSeparator interblockSeparator @@ -280,5 +280,5 @@ dlDefinitionEnd dlItemEnd dlEndTight interblockSeparator -attributeContextEnd +headerAttributeContextEnd documentEnd diff --git a/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test b/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test index 4a38c36e5..14d6b0cc9 100644 --- a/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test +++ b/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test @@ -16,7 +16,7 @@ Here are the definitions: [image]: http://image (This is the title of the image.) >>> documentBegin -attributeContextBegin +headerAttributeContextBegin headingOne: This is another section interblockSeparator footnote: This is the text of the footnote. @@ -31,5 +31,5 @@ BEGIN image - title: This is the title of the image. END image interblockSeparator -attributeContextEnd +headerAttributeContextEnd documentEnd From 18c0470b4a77767eaf4548bb705c6300b7a04af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Novotn=C3=BD?= Date: Mon, 21 Feb 2022 23:11:51 +0100 Subject: [PATCH 6/7] Add attribute renderers --- markdown.dtx | 165 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 150 insertions(+), 15 deletions(-) diff --git a/markdown.dtx b/markdown.dtx index 1cb411880..5567f1a28 100644 --- a/markdown.dtx +++ b/markdown.dtx @@ -11961,6 +11961,108 @@ following body text: % % \begin{markdown} +#### Attribute Renderers +The following macros are only produced, when the \Opt{headerAttributes} option +is enabled. + +\mdef{markdownRendererAttributeIdentifier} represents the \meta{identifier} of +a markdown element (`id="`\meta{identifier}`"` in HTML and `#`\meta{identifier} +in Markdown's \Opt{headerAttributes} syntax extension). The macro receives a +single attribute that corresponds to the \meta{identifier}. + +\mdef{markdownRendererAttributeClassName} represents the \meta{class name} of a +markdown element (`class="`\meta{class name} ...`"` in HTML and +`.`\meta{class name} in Markdown's \Opt{headerAttributes} syntax extension). +The macro receives a single attribute that corresponds to the \meta{class +name}. + +\mdef{markdownRendererAttributeKeyValue} represents a HTML attribute in the form +\meta{key}`=`\meta{value} that is neither an identifier nor a class name. +The macro receives two attributes that correspond to the \meta{key} and the +\meta{value}, respectively. + +% \end{markdown} +% +% \iffalse + +##### \LaTeX{} Example {.unnumbered} + +Using a text editor, create a text document named `document.tex` with the +following content: +``` tex +\documentclass{article} +\usepackage[headerAttributes, underscores=false]{markdown} +\markdownSetup{ + renderers = { + attributeIdentifier = {% + \par + \emph{(Identifier: #1)} + \par + }, + attributeClassName = {% + \par + \emph{(Class name: #1)} + \par + }, + attributeKeyValue = {% + \par + \emph{(Key: #1, Value: #2)} + \par + }, + }, +} +\begin{document} +\begin{markdown} + +# First top-level heading {jane=doe} + +## A subheading {#identifier} + +# Second top-level heading {.class_name} + +\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: + +> # First top-level heading +> +> *(Key: Jane, Value: Doe)* +> +> ## A subheading +> +> *(Identifier: identifier)* +> +> # Second top-level heading +> +> *(Class name: class\_name)* + +% +%<*tex> +% \fi +% +% \begin{macrocode} +\def\markdownRendererAttributeIdentifier{% + \markdownRendererAttributeIdentifierPrototype}% +\def\markdownRendererAttributeClassName{% + \markdownRendererAttributeClassNamePrototype}% +\def\markdownRendererAttributeKeyValue{% + \markdownRendererAttributeKeyValuePrototype}% +% \end{macrocode} +% \par +% +% \iffalse +% +%<*manual-tokens> +% \fi +% +% \begin{markdown} + #### Header Attribute Context Renderers The following macros are only produced, when the \Opt{headerAttributes} option is enabled. @@ -12178,13 +12280,16 @@ following text: % % \end{markdown} % \begin{macrocode} -\def\markdownRendererHeaderAttributeContextBeginPrototype{}% -\def\markdownRendererHeaderAttributeContextEndPrototype{}% +\def\markdownRendererAttributeIdentifierPrototype{}% +\def\markdownRendererAttributeClassNamePrototype{}% +\def\markdownRendererAttributeKeyValuePrototype{}% \def\markdownRendererDocumentBeginPrototype{}% \def\markdownRendererDocumentEndPrototype{}% \def\markdownRendererInterblockSeparatorPrototype{}% \def\markdownRendererLineBreakPrototype{}% \def\markdownRendererEllipsisPrototype{}% +\def\markdownRendererHeaderAttributeContextBeginPrototype{}% +\def\markdownRendererHeaderAttributeContextEndPrototype{}% \def\markdownRendererNbspPrototype{}% \def\markdownRendererLeftBracePrototype{}% \def\markdownRendererRightBracePrototype{}% @@ -13238,10 +13343,12 @@ The following ordered list will be preceded by roman numerals: % % \end{markdown} % \begin{macrocode} -\define@key{markdownRenderers}{headerAttributeContextBegin}{% - \renewcommand\markdownRendererHeaderAttributeContextBegin{#1}}% -\define@key{markdownRenderers}{headerAttributeContextEnd}{% - \renewcommand\markdownRendererHeaderAttributeContextEnd{#1}}% +\define@key{markdownRenderers}{attributeIdentifier}{% + \renewcommand\markdownRendererAttributeIdentifier[1]{#1}}% +\define@key{markdownRenderers}{attributeClassName}{% + \renewcommand\markdownRendererAttributeClassName[1]{#1}}% +\define@key{markdownRenderers}{attributeKeyValue}{% + \renewcommand\markdownRendererAttributeKeyValue[2]{#1}}% \define@key{markdownRenderers}{documentBegin}{% \renewcommand\markdownRendererDocumentBegin{#1}}% \define@key{markdownRenderers}{documentEnd}{% @@ -13252,6 +13359,10 @@ The following ordered list will be preceded by roman numerals: \renewcommand\markdownRendererLineBreak{#1}}% \define@key{markdownRenderers}{ellipsis}{% \renewcommand\markdownRendererEllipsis{#1}}% +\define@key{markdownRenderers}{headerAttributeContextBegin}{% + \renewcommand\markdownRendererHeaderAttributeContextBegin{#1}}% +\define@key{markdownRenderers}{headerAttributeContextEnd}{% + \renewcommand\markdownRendererHeaderAttributeContextEnd{#1}}% \define@key{markdownRenderers}{nbsp}{% \renewcommand\markdownRendererNbsp{#1}}% \define@key{markdownRenderers}{leftBrace}{% @@ -13419,10 +13530,12 @@ The following ordered list will be preceded by roman numerals: % % \end{markdown} % \begin{macrocode} -\define@key{markdownRendererPrototypes}{headerAttributeContextBegin}{% - \renewcommand\markdownRendererHeaderAttributeContextBeginPrototype{#1}}% -\define@key{markdownRendererPrototypes}{headerAttributeContextEnd}{% - \renewcommand\markdownRendererHeaderAttributeContextEndPrototype{#1}}% +\define@key{markdownRendererPrototypes}{attributeIdentifier}{% + \renewcommand\markdownRendererAttributeIdentifierPrototype[1]{#1}}% +\define@key{markdownRendererPrototypes}{attributeClassName}{% + \renewcommand\markdownRendererAttributeClassNamePrototype[1]{#1}}% +\define@key{markdownRendererPrototypes}{attributeKeyValue}{% + \renewcommand\markdownRendererAttributeKeyValuePrototype[2]{#1}}% \define@key{markdownRendererPrototypes}{documentBegin}{% \renewcommand\markdownRendererDocumentBeginPrototype{#1}}% \define@key{markdownRendererPrototypes}{documentEnd}{% @@ -13433,6 +13546,10 @@ The following ordered list will be preceded by roman numerals: \renewcommand\markdownRendererLineBreakPrototype{#1}}% \define@key{markdownRendererPrototypes}{ellipsis}{% \renewcommand\markdownRendererEllipsisPrototype{#1}}% +\define@key{markdownRendererPrototypes}{headerAttributeContextBegin}{% + \renewcommand\markdownRendererHeaderAttributeContextBeginPrototype{#1}}% +\define@key{markdownRendererPrototypes}{headerAttributeContextEnd}{% + \renewcommand\markdownRendererHeaderAttributeContextEndPrototype{#1}}% \define@key{markdownRendererPrototypes}{nbsp}{% \renewcommand\markdownRendererNbspPrototype{#1}}% \define@key{markdownRendererPrototypes}{leftBrace}{% @@ -17048,11 +17165,28 @@ function M.writer.new(options) else cmd = "" end - if self.is_writing then table.insert(buf, {cmd, "{", s, "}"}) end + if self.is_writing then + table.sort(attributes) + local key, value + for i = 1, #attributes do + if attributes[i]:sub(1, 1) == "#" then + table.insert(buf, {"\\markdownRendererAttributeIdentifier{", + attributes[i]:sub(2), "}"}) + elseif attributes[i]:sub(1, 1) == "." then + table.insert(buf, {"\\markdownRendererAttributeClassName{", + attributes[i]:sub(2), "}"}) + else + key, value = attributes[i]:match("(%w+)=(%w+)") + table.insert(buf, {"\\markdownRendererAttributeKeyValue{", + key, "}{", value, "}"}) + end + end + end + return buf end % \end{macrocode} @@ -17349,12 +17483,12 @@ parsers.css_identifier = (parsers.hash + parsers.period) * (parsers.css_identifier_char - parsers.digit) * parsers.css_identifier_char^0)) -parsers.attribute_name_char = parsers.any - parsers.space +parsers.attribute_key_char = parsers.any - parsers.space - parsers.squote - parsers.dquote - parsers.more - parsers.slash - parsers.equal -parsers.attribute_value_char = parsers.any - parsers.dquote - - parsers.more +parsers.attribute_value_char = parsers.any - parsers.space + - parsers.dquote - parsers.more -- block followed by 0 or more optionally -- indented blocks with first line indented. @@ -17995,7 +18129,7 @@ parsers.dlchunk = Cs(parsers.line * (parsers.indentedline - parsers.blankline)^0 % \end{markdown} % \begin{macrocode} parsers.heading_attribute = C(parsers.css_identifier) - + C((parsers.attribute_name_char + + C((parsers.attribute_key_char - parsers.rbrace)^1 * parsers.equal * (parsers.attribute_value_char @@ -20512,6 +20646,7 @@ end emphasis = {\emph{#1}}, tickedBox = {$\boxtimes$}, halfTickedBox = {$\boxdot$}, + attributeIdentifier = {\label{#1}}, blockQuoteBegin = {\begin{quotation}}, blockQuoteEnd = {\end{quotation}}, inputVerbatim = {\VerbatimInput{#1}}, From 0f349c571e543c407aa3437b4795e8b68fd5ee3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADt=20Novotn=C3=BD?= Date: Tue, 22 Feb 2022 15:31:13 +0100 Subject: [PATCH 7/7] Add attribute renderers to unit tests --- .../markdownthemewitiko_markdown_test.sty | 114 +++++++++--------- tests/support/plain-setup.tex | 105 ++++++++-------- .../lunamark-markdown/header-attributes.test | 34 ++++++ .../testfiles/lunamark-markdown/no-slice.test | 2 + .../slice-existing-section.test | 1 + .../lunamark-markdown/slice-two-sections.test | 2 + .../slice-with-deferred-content.test | 1 + 7 files changed, 158 insertions(+), 101 deletions(-) diff --git a/tests/support/markdownthemewitiko_markdown_test.sty b/tests/support/markdownthemewitiko_markdown_test.sty index 092dcc961..9610a4380 100644 --- a/tests/support/markdownthemewitiko_markdown_test.sty +++ b/tests/support/markdownthemewitiko_markdown_test.sty @@ -1,9 +1,14 @@ \markdownSetupSnippet{snippet}{% renderers = {% - headerAttributeContextBegin = {% - \TYPE{headerAttributeContextBegin}}, - headerAttributeContextEnd = {% - \TYPE{headerAttributeContextEnd}}, + attributeIdentifier = {% + \TYPE{attributeIdentifier: #1}}, + attributeClassName = {% + \TYPE{attributeClassName: #1}}, + attributeKeyValue = {% + \TYPE{BEGIN attributeKeyValue}% + \TYPE{- key: #1}% + \TYPE{- value: #2}% + \TYPE{END attributeKeyValue}}, documentBegin = {% \TYPE{documentBegin}}, documentEnd = {% @@ -17,6 +22,10 @@ ellipsis = {% \TYPE{ellipsis}% \GOBBLE}, + headerAttributeContextBegin = {% + \TYPE{headerAttributeContextBegin}}, + headerAttributeContextEnd = {% + \TYPE{headerAttributeContextEnd}}, nbsp = {% \TYPE{nbsp}% \GOBBLE}, @@ -54,41 +63,38 @@ \TYPE{pipe}% \GOBBLE}, codeSpan = {% - \TYPE{codeSpan: #1}}, + \TYPE{codeSpan: #1}}, link = {% \TYPE{BEGIN link}% - \TYPE{- label: #1}% - \TYPE{- URI: #2}% - \TYPE{- title: #4}% + \TYPE{- label: #1}% + \TYPE{- URI: #2}% + \TYPE{- title: #4}% \TYPE{END link}}, image = {% \TYPE{BEGIN image}% - \TYPE{- label: #1}% - \TYPE{- URI: #2}% - \TYPE{- title: #4}% + \TYPE{- label: #1}% + \TYPE{- URI: #2}% + \TYPE{- title: #4}% \TYPE{END image}}, contentBlock = {% \TYPE{BEGIN contentBlock}% - \TYPE{- suffix: #1}% - \TYPE{- URI: #2}% - \TYPE{- title: #4}% - \TYPE{END contentBlock}% - }, + \TYPE{- suffix: #1}% + \TYPE{- URI: #2}% + \TYPE{- title: #4}% + \TYPE{END contentBlock}}, contentBlockOnlineImage = {% \TYPE{BEGIN contentBlockOnlineImage}% - \TYPE{- suffix: #1}% - \TYPE{- URI: #2}% - \TYPE{- title: #4}% - \TYPE{END contentBlockOnlineImage}% - }, + \TYPE{- suffix: #1}% + \TYPE{- URI: #2}% + \TYPE{- title: #4}% + \TYPE{END contentBlockOnlineImage}}, contentBlockCode = {% \TYPE{BEGIN contentBlockCode}% - \TYPE{- suffix: #1}% - \TYPE{- language: #2}% - \TYPE{- URI: #3}% - \TYPE{- title: #5}% - \TYPE{END contentBlockCode}% - }, + \TYPE{- suffix: #1}% + \TYPE{- language: #2}% + \TYPE{- URI: #3}% + \TYPE{- title: #5}% + \TYPE{END contentBlockCode}}, ulBegin = {% \TYPE{ulBegin}}, ulBeginTight = {% @@ -110,7 +116,7 @@ olItemEnd = {% \TYPE{olItemEnd}}, olItemWithNumber = {% - \TYPE{olItemWithNumber: #1}}, + \TYPE{olItemWithNumber: #1}}, olEnd = {% \TYPE{olEnd}}, olEndTight = {% @@ -120,7 +126,7 @@ dlBeginTight = {% \TYPE{dlBeginTight}}, dlItem = {% - \TYPE{dlItem: #1}}, + \TYPE{dlItem: #1}}, dlItemEnd = {% \TYPE{dlItemEnd}}, dlDefinitionBegin = {% @@ -132,36 +138,36 @@ dlEndTight = {% \TYPE{dlEndTight}}, emphasis = {% - \TYPE{emphasis: #1}}, + \TYPE{emphasis: #1}}, strongEmphasis = {% - \TYPE{strongEmphasis: #1}}, + \TYPE{strongEmphasis: #1}}, blockQuoteBegin = {% \TYPE{blockQuoteBegin}}, blockQuoteEnd = {% \TYPE{blockQuoteEnd}}, inputVerbatim = {% - \TYPE{inputVerbatim: #1}}, + \TYPE{inputVerbatim: #1}}, inputFencedCode = {% \TYPE{BEGIN fencedCode}% - \TYPE{- src: #1}% - \TYPE{- infostring: #2}% + \TYPE{- src: #1}% + \TYPE{- infostring: #2}% \TYPE{END fencedCode}}, headingOne = {% - \TYPE{headingOne: #1}}, + \TYPE{headingOne: #1}}, headingTwo = {% - \TYPE{headingTwo: #1}}, + \TYPE{headingTwo: #1}}, headingThree = {% - \TYPE{headingThree: #1}}, + \TYPE{headingThree: #1}}, headingFour = {% - \TYPE{headingFour: #1}}, + \TYPE{headingFour: #1}}, headingFive = {% - \TYPE{headingFive: #1}}, + \TYPE{headingFive: #1}}, headingSix = {% - \TYPE{headingSix: #1}}, + \TYPE{headingSix: #1}}, horizontalRule = {% \TYPE{horizontalRule}}, footnote = {% - \TYPE{footnote: #1}}, + \TYPE{footnote: #1}}, cite = {% \CITATIONS{#1}}, textCite = {% @@ -169,9 +175,9 @@ table = {% \TABLE{#1}{#2}{#3}}, inlineHtmlComment = {% - \TYPE{inlineHtmlComment: #1}}, + \TYPE{inlineHtmlComment: #1}}, inlineHtmlTag = {% - \TYPE{inlineHtmlTag: #1}}, + \TYPE{inlineHtmlTag: #1}}, tickedBox = {% \TYPE{tickedBox}% \GOBBLE}, @@ -183,20 +189,20 @@ \GOBBLE}, jekyllDataBoolean = {% \TYPE{BEGIN jekyllDataBoolean}% - \TYPE{- key: #1}% - \TYPE{- value: #2}% + \TYPE{- key: #1}% + \TYPE{- value: #2}% \TYPE{END jekyllDataBoolean}}, jekyllDataEmpty = {% - \TYPE{jekyllDataEmpty: #1}},% + \TYPE{jekyllDataEmpty: #1}},% jekyllDataNumber = {% \TYPE{BEGIN jekyllDataNumber}% - \TYPE{- key: #1}% - \TYPE{- value: #2}% + \TYPE{- key: #1}% + \TYPE{- value: #2}% \TYPE{END jekyllDataNumber}}, jekyllDataString = {% \TYPE{BEGIN jekyllDataString}% - \TYPE{- key: #1}% - \TYPE{- value: #2}% + \TYPE{- key: #1}% + \TYPE{- value: #2}% \TYPE{END jekyllDataString}}, jekyllDataBegin = {% \TYPE{jekyllDataBegin}}, @@ -204,15 +210,15 @@ \TYPE{jekyllDataEnd}}, jekyllDataSequenceBegin = {% \TYPE{BEGIN jekyllDataSequenceBegin}% - \TYPE{- key: #1}% - \TYPE{- length: #2}% + \TYPE{- key: #1}% + \TYPE{- length: #2}% \TYPE{END jekyllDataSequenceBegin}}, jekyllDataSequenceEnd = {% \TYPE{jekyllDataSequenceEnd}}, jekyllDataMappingBegin = {% \TYPE{BEGIN jekyllDataMappingBegin}% - \TYPE{- key: #1}% - \TYPE{- length: #2}% + \TYPE{- key: #1}% + \TYPE{- length: #2}% \TYPE{END jekyllDataMappingBegin}}, jekyllDataMappingEnd = {% \TYPE{jekyllDataMappingEnd}}, diff --git a/tests/support/plain-setup.tex b/tests/support/plain-setup.tex index 77cc42dbb..b2eee4245 100644 --- a/tests/support/plain-setup.tex +++ b/tests/support/plain-setup.tex @@ -1,7 +1,14 @@ -\def\markdownRendererHeaderAttributeContextBegin{% - \TYPE{headerAttributeContextBegin}}% -\def\markdownRendererHeaderAttributeContextEnd{% - \TYPE{headerAttributeContextEnd}}% +\def\markdownRendererAttributeIdentifier#1{% + \TYPE{attributeIdentifier: #1}}% +\def\markdownRendererAttributeClassName#1{% + \TYPE{attributeClassName: #1}}% +\def\markdownRendererAttributeKeyValue#1#2{% + \TYPE{BEGIN attributeKeyValue}% + \TYPE{- key: #1}% + \TYPE{- value: #2}% + \TYPE{END attributeKeyValue}}% +\def\markdownRendererDocumentBegin{% + \TYPE{documentBegin}}% \def\markdownRendererDocumentBegin{% \TYPE{documentBegin}}% \def\markdownRendererDocumentEnd{% @@ -12,6 +19,10 @@ \TYPE{lineBreak}}% \def\markdownRendererEllipsis#1{% \TYPE{ellipsis}}% +\def\markdownRendererHeaderAttributeContextBegin{% + \TYPE{headerAttributeContextBegin}}% +\def\markdownRendererHeaderAttributeContextEnd{% + \TYPE{headerAttributeContextEnd}}% \def\markdownRendererNbsp#1{% \TYPE{nbsp}}% \def\markdownRendererLeftBrace#1{% @@ -37,37 +48,37 @@ \def\markdownRendererPipe#1{% \TYPE{pipe}}% \def\markdownRendererCodeSpan#1{% - \TYPE{codeSpan: #1}}% + \TYPE{codeSpan: #1}}% \def\markdownRendererLink#1#2#3#4{% \TYPE{BEGIN link}% - \TYPE{- label: #1}% - \TYPE{- URI: #2}% - \TYPE{- title: #4}% + \TYPE{- label: #1}% + \TYPE{- URI: #2}% + \TYPE{- title: #4}% \TYPE{END link}}% \def\markdownRendererImage#1#2#3#4{% \TYPE{BEGIN image}% - \TYPE{- label: #1}% - \TYPE{- URI: #2}% - \TYPE{- title: #4}% + \TYPE{- label: #1}% + \TYPE{- URI: #2}% + \TYPE{- title: #4}% \TYPE{END image}}% \def\markdownRendererContentBlock#1#2#3#4{% \TYPE{BEGIN contentBlock}% - \TYPE{- suffix: #1}% - \TYPE{- URI: #2}% - \TYPE{- title: #4}% + \TYPE{- suffix: #1}% + \TYPE{- URI: #2}% + \TYPE{- title: #4}% \TYPE{END contentBlock}}% \def\markdownRendererContentBlockOnlineImage#1#2#3#4{% \TYPE{BEGIN contentBlockOnlineImage}% - \TYPE{- suffix: #1}% - \TYPE{- URI: #2}% - \TYPE{- title: #4}% + \TYPE{- suffix: #1}% + \TYPE{- URI: #2}% + \TYPE{- title: #4}% \TYPE{END contentBlockOnlineImage}}% \def\markdownRendererContentBlockCode#1#2#3#4#5{% \TYPE{BEGIN contentBlockCode}% - \TYPE{- suffix: #1}% - \TYPE{- language: #2}% - \TYPE{- URI: #3}% - \TYPE{- title: #5}% + \TYPE{- suffix: #1}% + \TYPE{- language: #2}% + \TYPE{- URI: #3}% + \TYPE{- title: #5}% \TYPE{END contentBlockCode}}% \def\markdownRendererUlBegin{% \TYPE{ulBegin}}% @@ -90,7 +101,7 @@ \def\markdownRendererOlItemEnd{% \TYPE{olItemEnd}}% \def\markdownRendererOlItemWithNumber#1{% - \TYPE{olItemWithNumber: #1}}% + \TYPE{olItemWithNumber: #1}}% \def\markdownRendererOlEnd{% \TYPE{olEnd}}% \def\markdownRendererOlEndTight{% @@ -100,7 +111,7 @@ \def\markdownRendererDlBeginTight{% \TYPE{dlBeginTight}}% \def\markdownRendererDlItem#1{% - \TYPE{dlItem: #1}}% + \TYPE{dlItem: #1}}% \def\markdownRendererDlItemEnd{% \TYPE{dlItemEnd}}% \def\markdownRendererDlDefinitionBegin{% @@ -112,36 +123,36 @@ \def\markdownRendererDlEndTight{% \TYPE{dlEndTight}}% \def\markdownRendererEmphasis#1{% - \TYPE{emphasis: #1}}% + \TYPE{emphasis: #1}}% \def\markdownRendererStrongEmphasis#1{% - \TYPE{strongEmphasis: #1}}% + \TYPE{strongEmphasis: #1}}% \def\markdownRendererBlockQuoteBegin{% \TYPE{blockQuoteBegin}}% \def\markdownRendererBlockQuoteEnd{% \TYPE{blockQuoteEnd}}% \def\markdownRendererInputVerbatim#1{% - \TYPE{inputVerbatim: #1}}% + \TYPE{inputVerbatim: #1}}% \def\markdownRendererInputFencedCode#1#2{% \TYPE{BEGIN fencedCode}% - \TYPE{- src: #1}% - \TYPE{- infostring: #2}% + \TYPE{- src: #1}% + \TYPE{- infostring: #2}% \TYPE{END fencedCode}}% \def\markdownRendererHeadingOne#1{% - \TYPE{headingOne: #1}}% + \TYPE{headingOne: #1}}% \def\markdownRendererHeadingTwo#1{% - \TYPE{headingTwo: #1}}% + \TYPE{headingTwo: #1}}% \def\markdownRendererHeadingThree#1{% - \TYPE{headingThree: #1}}% + \TYPE{headingThree: #1}}% \def\markdownRendererHeadingFour#1{% - \TYPE{headingFour: #1}}% + \TYPE{headingFour: #1}}% \def\markdownRendererHeadingFive#1{% - \TYPE{headingFive: #1}}% + \TYPE{headingFive: #1}}% \def\markdownRendererHeadingSix#1{% - \TYPE{headingSix: #1}}% + \TYPE{headingSix: #1}}% \def\markdownRendererHorizontalRule{% \TYPE{horizontalRule}}% \def\markdownRendererFootnote#1{% - \TYPE{footnote: #1}}% + \TYPE{footnote: #1}}% \def\markdownRendererCite#1{% \CITATIONS{#1}}% \def\markdownRendererTextCite#1{% @@ -149,7 +160,7 @@ \def\markdownRendererTable#1#2#3{% \TABLE{#1}{#2}{#3}}% \def\markdownRendererInlineHtmlComment#1{% - \TYPE{inlineHtmlComment: #1}}% + \TYPE{inlineHtmlComment: #1}}% \def\markdownRendererInlineHtmlTag#1{% \TYPE{inlineHtmlTag: #1}}% \def\markdownRendererTickedBox#1{% @@ -160,20 +171,20 @@ \TYPE{untickedBox}}% \def\markdownRendererJekyllDataBoolean#1#2{% \TYPE{BEGIN jekyllDataBoolean}% - \TYPE{- key: #1}% - \TYPE{- value: #2}% + \TYPE{- key: #1}% + \TYPE{- value: #2}% \TYPE{END jekyllDataBoolean}}% \def\markdownRendererJekyllDataEmpty#1{% - \TYPE{jekyllDataEmpty: #1}}% + \TYPE{jekyllDataEmpty: #1}}% \def\markdownRendererJekyllDataNumber#1#2{% \TYPE{BEGIN jekyllDataNumber}% - \TYPE{- key: #1}% - \TYPE{- value: #2}% + \TYPE{- key: #1}% + \TYPE{- value: #2}% \TYPE{END jekyllDataNumber}}% \def\markdownRendererJekyllDataString#1#2{% \TYPE{BEGIN jekyllDataString}% - \TYPE{- key: #1}% - \TYPE{- value: #2}% + \TYPE{- key: #1}% + \TYPE{- value: #2}% \TYPE{END jekyllDataString}}% \def\markdownRendererJekyllDataBegin{% \TYPE{jekyllDataBegin}}% @@ -181,15 +192,15 @@ \TYPE{jekyllDataEnd}}% \def\markdownRendererJekyllDataSequenceBegin#1#2{% \TYPE{BEGIN jekyllDataSequenceBegin}% - \TYPE{- key: #1}% - \TYPE{- length: #2}% + \TYPE{- key: #1}% + \TYPE{- length: #2}% \TYPE{END jekyllDataSequenceBegin}}% \def\markdownRendererJekyllDataSequenceEnd{% \TYPE{jekyllDataSequenceEnd}}% \def\markdownRendererJekyllDataMappingBegin#1#2{% \TYPE{BEGIN jekyllDataMappingBegin}% - \TYPE{- key: #1}% - \TYPE{- length: #2}% + \TYPE{- key: #1}% + \TYPE{- length: #2}% \TYPE{END jekyllDataMappingBegin}}% \def\markdownRendererJekyllDataMappingEnd{% \TYPE{jekyllDataMappingEnd}}% diff --git a/tests/testfiles/lunamark-markdown/header-attributes.test b/tests/testfiles/lunamark-markdown/header-attributes.test index caa2df393..72853bd5e 100644 --- a/tests/testfiles/lunamark-markdown/header-attributes.test +++ b/tests/testfiles/lunamark-markdown/header-attributes.test @@ -17,19 +17,25 @@ A level two heading {#fourth4-id .2not-a-class} #### A level four heading {#-6not-the-sixth-id} ##### A level five heading ## {#--7the-seventh-id} ###### A level six heading {#-_the-eighth-id attribute=value} + +# Attributes {#should #appear .in .alphabetical order=ing and=not #the .order of=typing} >>> documentBegin codeSpan: headerAttributes interblockSeparator headerAttributeContextBegin headingOne: A level one heading +attributeIdentifier: first-id interblockSeparator headerAttributeContextEnd headerAttributeContextBegin headingOne: A level one heading +attributeIdentifier: second_id2 interblockSeparator headerAttributeContextBegin headingTwo: A level two heading +attributeIdentifier: third-3id +attributeClassName: a-class interblockSeparator headerAttributeContextEnd headingTwo: A level two heading (leftBrace)(hash)fourth4-id .2not-a-class(rightBrace) @@ -40,10 +46,38 @@ headingFour: A level four heading (leftBrace)(hash)-6not-the-sixth-id(rightBrace interblockSeparator headerAttributeContextBegin headingFive: A level five heading +attributeIdentifier: --7the-seventh-id interblockSeparator headerAttributeContextBegin headingSix: A level six heading +attributeIdentifier: -_the-eighth-id +BEGIN attributeKeyValue +- key: attribute +- value: value +END attributeKeyValue +interblockSeparator headerAttributeContextEnd headerAttributeContextEnd headerAttributeContextEnd +headerAttributeContextBegin +headingOne: Attributes +attributeIdentifier: appear +attributeIdentifier: should +attributeIdentifier: the +attributeClassName: alphabetical +attributeClassName: in +attributeClassName: order +BEGIN attributeKeyValue +- key: and +- value: not +END attributeKeyValue +BEGIN attributeKeyValue +- key: of +- value: typing +END attributeKeyValue +BEGIN attributeKeyValue +- key: order +- value: ing +END attributeKeyValue +headerAttributeContextEnd documentEnd diff --git a/tests/testfiles/lunamark-markdown/no-slice.test b/tests/testfiles/lunamark-markdown/no-slice.test index 80e3e3cbd..97687c323 100644 --- a/tests/testfiles/lunamark-markdown/no-slice.test +++ b/tests/testfiles/lunamark-markdown/no-slice.test @@ -138,6 +138,7 @@ headingOne: This is an H1 interblockSeparator headerAttributeContextBegin headingTwo: This is an H2 +attributeIdentifier: first-h2 interblockSeparator headingThree: This is an H3 interblockSeparator @@ -172,6 +173,7 @@ interblockSeparator headerAttributeContextEnd headerAttributeContextBegin headingTwo: This is an H2 +attributeIdentifier: second-h2 interblockSeparator interblockSeparator ulBegin diff --git a/tests/testfiles/lunamark-markdown/slice-existing-section.test b/tests/testfiles/lunamark-markdown/slice-existing-section.test index b967aecf0..ec2de57af 100644 --- a/tests/testfiles/lunamark-markdown/slice-existing-section.test +++ b/tests/testfiles/lunamark-markdown/slice-existing-section.test @@ -142,6 +142,7 @@ belong to the previous footnote. documentBegin headerAttributeContextBegin headingTwo: This is an H2 +attributeIdentifier: first-h2 interblockSeparator headingThree: This is an H3 interblockSeparator diff --git a/tests/testfiles/lunamark-markdown/slice-two-sections.test b/tests/testfiles/lunamark-markdown/slice-two-sections.test index 9379e963c..0907ea556 100644 --- a/tests/testfiles/lunamark-markdown/slice-two-sections.test +++ b/tests/testfiles/lunamark-markdown/slice-two-sections.test @@ -142,6 +142,7 @@ belong to the previous footnote. documentBegin headerAttributeContextBegin headingTwo: This is an H2 +attributeIdentifier: first-h2 interblockSeparator headingThree: This is an H3 interblockSeparator @@ -185,6 +186,7 @@ interblockSeparator headerAttributeContextEnd headerAttributeContextBegin headingTwo: This is an H2 +attributeIdentifier: second-h2 interblockSeparator interblockSeparator ulBegin diff --git a/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test b/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test index 14d6b0cc9..b1615e438 100644 --- a/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test +++ b/tests/testfiles/lunamark-markdown/slice-with-deferred-content.test @@ -18,6 +18,7 @@ Here are the definitions: documentBegin headerAttributeContextBegin headingOne: This is another section +attributeIdentifier: section-with-deferred-content interblockSeparator footnote: This is the text of the footnote. BEGIN link