From 64d47978d293b786a19dd5881a3eb81117bd34bb Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 1 Mar 2022 21:49:14 +0000 Subject: markdown (1mar22) (branch) git-svn-id: svn://tug.org/texlive/branches/branch2021.final@62317 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/context/third/markdown/t-markdown.tex | 2 +- .../texmf-dist/tex/generic/markdown/markdown.tex | 35 +++- Master/texmf-dist/tex/latex/markdown/markdown.sty | 192 ++++++++++++++++---- Master/texmf-dist/tex/luatex/markdown/markdown.lua | 196 +++++++++++++++------ 4 files changed, 342 insertions(+), 83 deletions(-) (limited to 'Master/texmf-dist/tex') diff --git a/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex b/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex index f92f89dda62..6c55e9a8d48 100644 --- a/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex +++ b/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex @@ -125,7 +125,7 @@ \markdownInput{#3}% \fi}% \def\markdownRendererImagePrototype#1#2#3#4{% - \placefigure[][fig:#1]{#4}{\externalfigure[#3]}}% + \placefigure[][]{#4}{\externalfigure[#3]}}% \def\markdownRendererUlBeginPrototype{\startitemize}% \def\markdownRendererUlBeginTightPrototype{\startitemize[packed]}% \def\markdownRendererUlItemPrototype{\item}% diff --git a/Master/texmf-dist/tex/generic/markdown/markdown.tex b/Master/texmf-dist/tex/generic/markdown/markdown.tex index 1586d5579a7..bc837936a98 100644 --- a/Master/texmf-dist/tex/generic/markdown/markdown.tex +++ b/Master/texmf-dist/tex/generic/markdown/markdown.tex @@ -45,8 +45,8 @@ %% %% The names of the source files used are shown above. %% -\def\markdownLastModified{2022/01/30}% -\def\markdownVersion{2.13.0-0-g1f680a8}% +\def\markdownLastModified{2022/02/28}% +\def\markdownVersion{2.14.0-0-g9635d76}% \let\markdownBegin\relax \let\markdownEnd\relax \let\markdownInput\relax @@ -79,6 +79,7 @@ \let\markdownOptionJekyllData\undefined \let\markdownOptionPipeTables\undefined \let\markdownOptionPreserveTabs\undefined +\let\markdownOptionRelativeReferences\undefined \let\markdownOptionShiftHeadings\undefined \let\markdownOptionSlice\undefined \let\markdownOptionSmartEllipses\undefined @@ -239,11 +240,34 @@ \markdownRendererTablePrototype}% \def\markdownRendererInlineHtmlComment{% \markdownRendererInlineHtmlCommentPrototype}% +\def\markdownRendererBlockHtmlCommentBegin{% + \markdownRendererBlockHtmlCommentBeginPrototype}% +\def\markdownRendererBlockHtmlCommentEnd{% + \markdownRendererBlockHtmlCommentEndPrototype}% +\def\markdownRendererInlineHtmlTag{% + \markdownRendererInlineHtmlTagPrototype}% +\def\markdownRendererInputBlockHtmlElement{% + \markdownRendererInputBlockHtmlElementPrototype}% +\def\markdownRendererAttributeIdentifier{% + \markdownRendererAttributeIdentifierPrototype}% +\def\markdownRendererAttributeClassName{% + \markdownRendererAttributeClassNamePrototype}% +\def\markdownRendererAttributeKeyValue{% + \markdownRendererAttributeKeyValuePrototype}% +\def\markdownRendererHeaderAttributeContextBegin{% + \markdownRendererHeaderAttributeContextBeginPrototype}% +\def\markdownRendererHeaderAttributeContextEnd{% + \markdownRendererHeaderAttributeContextEndPrototype}% +\def\markdownRendererAttributeIdentifierPrototype#1{}% +\def\markdownRendererAttributeClassNamePrototype#1{}% +\def\markdownRendererAttributeKeyValuePrototype#1#2{}% \def\markdownRendererDocumentBeginPrototype{}% \def\markdownRendererDocumentEndPrototype{}% \def\markdownRendererInterblockSeparatorPrototype{}% \def\markdownRendererLineBreakPrototype{}% \def\markdownRendererEllipsisPrototype{}% +\def\markdownRendererHeaderAttributeContextBeginPrototype{}% +\def\markdownRendererHeaderAttributeContextEndPrototype{}% \def\markdownRendererNbspPrototype{}% \def\markdownRendererLeftBracePrototype{}% \def\markdownRendererRightBracePrototype{}% @@ -311,6 +335,10 @@ \def\markdownRendererTextCitePrototype#1{}% \def\markdownRendererTablePrototype#1#2#3{}% \def\markdownRendererInlineHtmlCommentPrototype#1{}% +\def\markdownRendererBlockHtmlCommentBeginPrototype{\iffalse}% +\def\markdownRendererBlockHtmlCommentEndPrototype{\fi}% +\def\markdownRendererInlineHtmlTagPrototype#1{}% +\def\markdownRendererInputBlockHtmlElementPrototype#1{}% \def\markdownRendererTickedBoxPrototype{}% \def\markdownRendererHalfTickedBoxPrototype{}% \def\markdownRendererUntickedBoxPrototype{}% @@ -485,6 +513,9 @@ \ifx\markdownOptionPreserveTabs\undefined\else preserveTabs = \markdownOptionPreserveTabs, \fi +\ifx\markdownOptionRelativeReferences\undefined\else + relativeReferences = \markdownOptionRelativeReferences, +\fi \ifx\markdownOptionShiftHeadings\undefined\else shiftHeadings = "\markdownOptionShiftHeadings", \fi diff --git a/Master/texmf-dist/tex/latex/markdown/markdown.sty b/Master/texmf-dist/tex/latex/markdown/markdown.sty index 7ddde4014b1..8645918a346 100644 --- a/Master/texmf-dist/tex/latex/markdown/markdown.sty +++ b/Master/texmf-dist/tex/latex/markdown/markdown.sty @@ -47,6 +47,7 @@ %% \RequirePackage{keyval} \RequirePackage{xstring} +\RequirePackage{expl3} \newenvironment{markdown}\relax\relax \newenvironment{markdown*}[1]\relax\relax \newcommand\markdownSetup[1]{% @@ -75,7 +76,7 @@ \fi} \newif\ifmarkdownLaTeXLoaded \markdownLaTeXLoadedfalse -\AtEndOfPackage{\markdownLaTeXLoadedtrue}% +\AtEndOfPackage{\markdownLaTeXLoadedtrue} \define@key{markdownOptions}{theme}{% \IfSubStr{#1}{/}{}{% \markdownError @@ -86,22 +87,18 @@ markdowntheme\markdownLaTeXThemePackageName}% \expandafter\markdownLaTeXThemeLoad\expandafter{% \markdownLaTeXThemePackageName}{#1/}}% -\newcommand\markdownLaTeXThemeName{}% -\newcommand\markdownLaTeXThemeLoad[2]{% - \ifmarkdownLaTeXLoaded - \def\markdownLaTeXThemeName{#2}% - \RequirePackage{#1}% - \def\markdownLaTeXThemeName{}% - \else - \AtEndOfPackage{% - \def\markdownLaTeXThemeName{#2}% - \RequirePackage{#1}% - \def\markdownLaTeXThemeName{}}% - \fi}% \@onlypreamble\KV@markdownOptions@theme \define@key{markdownOptions}{snippet}{% - \expandafter\markdownSetup\expandafter{% - \the\csname markdownLaTeXSetupSnippet#1\endcsname}}% + \@ifundefined + {markdownLaTeXSetupSnippet#1}{% + \markdownError + {Can't invoke setup snippet #1}% + {The setup snippet is undefined}% + }{% + \expandafter\markdownSetup\expandafter{% + \the\csname markdownLaTeXSetupSnippet#1\endcsname}% + }% + }% \define@key{markdownOptions}{helperScriptFileName}{% \def\markdownOptionHelperScriptFileName{#1}}% \define@key{markdownOptions}{inputTempFileName}{% @@ -158,6 +155,8 @@ \def\markdownOptionPipeTables{#1}}% \define@key{markdownOptions}{preserveTabs}[true]{% \def\markdownOptionPreserveTabs{#1}}% +\define@key{markdownOptions}{relativeReferences}[true]{% + \def\markdownOptionRelativeReferences{#1}}% \define@key{markdownOptions}{smartEllipses}[true]{% \def\markdownOptionSmartEllipses{#1}}% \define@key{markdownOptions}{shiftHeadings}{% @@ -188,6 +187,12 @@ \DeclareOption{frozencache}{\markdownSetup{frozenCache}} \define@key{markdownOptions}{frozenCacheFileName}{% \def\markdownOptionFrozenCacheFileName{#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}{% @@ -198,6 +203,10 @@ \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}{% @@ -332,12 +341,26 @@ \renewcommand\markdownRendererTable[3]{#1}}% \define@key{markdownRenderers}{inlineHtmlComment}{% \renewcommand\markdownRendererInlineHtmlComment[1]{#1}}% +\define@key{markdownRenderers}{blockHtmlCommentBegin}{% + \renewcommand\markdownRendererBlockHtmlCommentBegin{#1}}% +\define@key{markdownRenderers}{blockHtmlCommentEnd}{% + \renewcommand\markdownRendererBlockHtmlCommentEnd{#1}}% +\define@key{markdownRenderers}{inlineHtmlTag}{% + \renewcommand\markdownRendererInlineHtmlTag[1]{#1}}% +\define@key{markdownRenderers}{inputBlockHtmlElement}{% + \renewcommand\markdownRendererInputBlockHtmlElement[1]{#1}}% \define@key{markdownRenderers}{tickedBox}{% \renewcommand\markdownRendererTickedBox{#1}}% \define@key{markdownRenderers}{halfTickedBox}{% \renewcommand\markdownRendererHalfTickedBox{#1}}% \define@key{markdownRenderers}{untickedBox}{% \renewcommand\markdownRendererUntickedBox{#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}{% @@ -348,6 +371,10 @@ \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}{% @@ -482,6 +509,14 @@ \renewcommand\markdownRendererTablePrototype[3]{#1}}% \define@key{markdownRendererPrototypes}{inlineHtmlComment}{% \renewcommand\markdownRendererInlineHtmlCommentPrototype[1]{#1}}% +\define@key{markdownRendererPrototypes}{blockHtmlCommentBegin}{% + \renewcommand\markdownRendererBlockHtmlCommentBeginPrototype{#1}}% +\define@key{markdownRendererPrototypes}{blockHtmlCommentEnd}{% + \renewcommand\markdownRendererBlockHtmlCommentEndPrototype{#1}}% +\define@key{markdownRendererPrototypes}{inlineHtmlTag}{% + \renewcommand\markdownRendererInlineHtmlTagPrototype[1]{#1}}% +\define@key{markdownRendererPrototypes}{inputBlockHtmlElement}{% + \renewcommand\markdownRendererInputBlockHtmlElementPrototype[1]{#1}}% \define@key{markdownRendererPrototypes}{tickedBox}{% \renewcommand\markdownRendererTickedBoxPrototype{#1}}% \define@key{markdownRendererPrototypes}{halfTickedBox}{% @@ -515,6 +550,37 @@ |markdownReadAndConvert<\end{markdown#1}>% <|end>>% |endgroup +\ExplSyntaxOn +\newcommand\markdownLaTeXThemeName{} +\seq_new:N \g__markdown_latex_themes_seq +\seq_put_right:NV + \g__markdown_latex_themes_seq + \markdownLaTeXThemeName +\newcommand\markdownLaTeXThemeLoad[2]{ + \def\@tempa{% + \def\markdownLaTeXThemeName{#2} + \seq_put_right:NV + \g__markdown_latex_themes_seq + \markdownLaTeXThemeName + \RequirePackage{#1} + \seq_pop_right:NN + \g__markdown_latex_themes_seq + \l_tmpa_tl + \seq_get_right:NN + \g__markdown_latex_themes_seq + \l_tmpa_tl + \exp_args:NNV + \def + \markdownLaTeXThemeName + \l_tmpa_tl} + \ifmarkdownLaTeXLoaded + \@tempa + \else + \exp_args:No + \AtEndOfPackage + { \@tempa } + \fi} +\ExplSyntaxOff \DeclareOption*{% \expandafter\markdownSetup\expandafter{\CurrentOption}}% \ProcessOptions\relax @@ -609,7 +675,6 @@ \ifx\empty#4\empty\else \caption{#4}% \fi - \label{fig:#1}% \end{figure}}, ulBegin = {\begin{itemize}}, ulEnd = {\end{itemize}}, @@ -623,6 +688,28 @@ emphasis = {\emph{#1}}, tickedBox = {$\boxtimes$}, halfTickedBox = {$\boxdot$}, + headerAttributeContextBegin = { + \markdownSetup{ + rendererPrototypes = { + attributeIdentifier = {% + \begingroup + \def\next####1{% + \def####1########1{% + \endgroup + ####1{########1}% + \label{##1}% + }% + }% + \next\markdownRendererHeadingOne + \next\markdownRendererHeadingTwo + \next\markdownRendererHeadingThree + \next\markdownRendererHeadingFour + \next\markdownRendererHeadingFive + \next\markdownRendererHeadingSix + }, + }, + }% + }, blockQuoteBegin = {\begin{quotation}}, blockQuoteEnd = {\end{quotation}}, inputVerbatim = {\VerbatimInput{#1}}, @@ -688,6 +775,28 @@ \fi \fi } +\@ifundefined{HCode}{}{ + \markdownSetup{ + rendererPrototypes = { + inlineHtmlTag = {% + \ifvmode + \IgnorePar + \EndP + \fi + \HCode{#1}% + }, + inputBlockHtmlElement = {% + \ifvmode + \IgnorePar + \fi + \EndP + \special{t4ht*<#1}% + \par + \ShowPar + }, + }, + } +} \newcount\markdownLaTeXCitationsCounter \RequirePackage{gobble} @@ -905,14 +1014,34 @@ \expandafter{\expandafter}% }}}} \RequirePackage{url} -\def\markdownRendererLinkPrototype{% +\RequirePackage{expl3} +\ExplSyntaxOn +\def\markdownRendererLinkPrototype{ \begingroup \catcode`\#=12 - \def\next##1##2##3##4{% - ##1\footnote{% - \ifx\empty##4\empty\else##4: \fi\texttt<\url{##3}\texttt>}% - \endgroup}% - \next} + \def\next##1##2##3##4{ + \endgroup + \tl_set:Nx + \l_tmpa_tl + { \str_range:nnn { ##3 } { 1 } { 1 } } + \str_if_eq:NNTF + \l_tmpa_tl + \c_hash_str + { + \exp_args:No + \markdownLaTeXRendererRelativeLink + { \str_range:nnn { ##3 } { 2 } { -1 } } + }{ + \markdownLaTeXRendererAbsoluteLink { ##1 } { ##2 } { ##3 } { ##4 } + } + } + \next +} +\ExplSyntaxOff +\def\markdownLaTeXRendererAbsoluteLink#1#2#3#4{% + #1\footnote{\ifx\empty#4\empty\else#4: \fi\texttt<\url{#3}\texttt>}} +\def\markdownLaTeXRendererRelativeLink#1{% + \ref{#1}} \newcount\markdownLaTeXRowCounter \newcount\markdownLaTeXRowTotal \newcount\markdownLaTeXColumnCounter @@ -920,14 +1049,16 @@ \newtoks\markdownLaTeXTable \newtoks\markdownLaTeXTableAlignment \newtoks\markdownLaTeXTableEnd -\@ifpackageloaded{booktabs}{ - \let\markdownLaTeXTopRule\toprule - \let\markdownLaTeXMidRule\midrule - \let\markdownLaTeXBottomRule\bottomrule -}{ - \let\markdownLaTeXTopRule\hline - \let\markdownLaTeXMidRule\hline - \let\markdownLaTeXBottomRule\hline +\AtBeginDocument{% + \@ifpackageloaded{booktabs}{% + \def\markdownLaTeXTopRule{\toprule}% + \def\markdownLaTeXMidRule{\midrule}% + \def\markdownLaTeXBottomRule{\bottomrule}% + }{% + \def\markdownLaTeXTopRule{\hline}% + \def\markdownLaTeXMidRule{\hline}% + \def\markdownLaTeXBottomRule{\hline}% + }% } \markdownSetup{rendererPrototypes={ table = {% @@ -990,7 +1121,6 @@ \expandafter\@gobble \fi\markdownLaTeXRenderTableCell} \fi -\RequirePackage{expl3} \ExplSyntaxOn \seq_new:N \g__markdown_jekyll_data_datatypes_seq \tl_const:Nn \c__markdown_jekyll_data_sequence_tl { sequence } diff --git a/Master/texmf-dist/tex/luatex/markdown/markdown.lua b/Master/texmf-dist/tex/luatex/markdown/markdown.lua index aac73da3c9f..161a0d39a29 100644 --- a/Master/texmf-dist/tex/luatex/markdown/markdown.lua +++ b/Master/texmf-dist/tex/luatex/markdown/markdown.lua @@ -20,7 +20,7 @@ -- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- --- Copyright (C) 2016-2021 Vít Novotný +-- Copyright (C) 2016-2022 Vít Novotný -- -- This work may be distributed and/or modified under the -- conditions of the LaTeX Project Public License, either version 1.3 @@ -58,11 +58,11 @@ -- those in the standard .ins files. -- local metadata = { - version = "2.13.0-0-g1f680a8", + version = "2.14.0-0-g9635d76", comment = "A module for the conversion from markdown to plain TeX", author = "John MacFarlane, Hans Hagen, Vít Novotný", copyright = {"2009-2016 John MacFarlane, Hans Hagen", - "2016-2021 Vít Novotný"}, + "2016-2022 Vít Novotný"}, license = "LPPL 1.3c" } @@ -102,6 +102,7 @@ defaultOptions.inlineFootnotes = false defaultOptions.jekyllData = false defaultOptions.pipeTables = false defaultOptions.preserveTabs = false +defaultOptions.relativeReferences = false defaultOptions.shiftHeadings = 0 defaultOptions.slice = "^ $" defaultOptions.smartEllipses = false @@ -2527,15 +2528,28 @@ function M.writer.new(options) local contents = util.intersperse(buffer,"\n") if tight and options.tightLists then return {"\\markdownRendererOlBeginTight\n",contents, - "\n\\markdownRendererOlEndTight "} + "\n\\markdownRendererOlEndTight "} else return {"\\markdownRendererOlBegin\n",contents, - "\n\\markdownRendererOlEnd "} + "\n\\markdownRendererOlEnd "} end end function self.inline_html_comment(contents) return {"\\markdownRendererInlineHtmlComment{",contents,"}"} end + function self.block_html_comment(contents) + if not self.is_writing then return "" end + return {"\\markdownRendererBlockHtmlCommentBegin\n",contents, + "\n\\markdownRendererBlockHtmlCommentEnd "} + end + function self.inline_html_tag(contents) + return {"\\markdownRendererInlineHtmlTag{",self.string(contents),"}"} + end + function self.block_html_element(s) + if not self.is_writing then return "" end + local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim") + return {"\\markdownRendererInputBlockHtmlElement{",name,"}"} + end local function dlitem(term, defs) local retVal = {"\\markdownRendererDlItem{",term,"}"} for _, def in ipairs(defs) do @@ -2593,8 +2607,23 @@ function M.writer.new(options) return {"\\markdownRendererInputFencedCode{",name,"}{",i,"}"} end function self.document(d) - return {"\\markdownRendererDocumentBegin\n", d, - "\\markdownRendererDocumentEnd"} + local active_attributes = self.active_attributes + local buf = {"\\markdownRendererDocumentBegin\n", d} + + -- pop attributes for sections that have ended + if options.headerAttributes and self.is_writing then + while #active_attributes > 0 do + local attributes = active_attributes[#active_attributes] + if #attributes > 0 then + table.insert(buf, "\\markdownRendererHeaderAttributeContextEnd") + end + table.remove(active_attributes, #active_attributes) + end + end + + table.insert(buf, "\\markdownRendererDocumentEnd") + + return buf end function self.jekyllData(d, t, p) if not self.is_writing then return "" end @@ -2678,51 +2707,100 @@ function M.writer.new(options) return buf end - self.active_headings = {} - function self.heading(s,level,attributes) - local active_headings = self.active_headings + self.active_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 "" 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 - -- push empty identifiers for implied sections - table.insert(active_headings, {}) + local buf = {} + + -- push empty attributes for implied sections + while #active_attributes < level-1 do + table.insert(active_attributes, {}) end - while #active_headings >= level do - -- pop identifiers for sections that have ended - local active_identifiers = active_headings[#active_headings] - if active_identifiers[slice_begin_identifier] ~= nil + -- pop attributes for sections that have ended + while #active_attributes >= level do + local active_identifiers = active_attributes[#active_attributes] + -- 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, "\\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, "\\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, "\\markdownRendererHeaderAttributeContextBegin") + end + end self.is_writing = true end - if active_identifiers[slice_end_identifier] ~= nil - and slice_end_type == "$" then - self.is_writing = false + end + + -- 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, "\\markdownRendererHeaderAttributeContextEnd") + end end - table.remove(active_headings, #active_headings) + self.is_writing = false 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 + -- 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, "\\markdownRendererHeaderAttributeContextBegin") end - if identifiers[slice_begin_identifier] ~= nil + + -- 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, "\\markdownRendererHeaderAttributeContextBegin") + end + end 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) - if not self.is_writing then return "" 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 local cmd level = level + options.shiftHeadings @@ -2741,7 +2819,11 @@ function M.writer.new(options) else cmd = "" end - return {cmd,"{",s,"}"} + if self.is_writing then + table.insert(buf, {cmd, "{", s, "}"}) + end + + return buf end function self.note(s) return {"\\markdownRendererFootnote{",s,"}"} @@ -2758,7 +2840,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 function self.set_state(s) @@ -2920,12 +3002,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. @@ -3375,11 +3457,6 @@ end parsers.in_matched_block_tags = parsers.less * Cmt(#parsers.openelt_block, parse_matched_tags) -parsers.displayhtml = parsers.htmlcomment / "" - + parsers.emptyelt_block - + parsers.openelt_exact("hr") - + parsers.in_matched_block_tags - + parsers.htmlinstruction parsers.hexentity = parsers.ampersand * parsers.hash * S("Xx") * C(parsers.hexdigit^1) * parsers.semicolon parsers.decentity = parsers.ampersand * parsers.hash @@ -3446,7 +3523,7 @@ parsers.defstart = ( parsers.defstartchar * #parsers.spacing parsers.dlchunk = Cs(parsers.line * (parsers.indentedline - parsers.blankline)^0) 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 @@ -3845,6 +3922,14 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline "mailto:"..email) end + larsers.AutoLinkRelativeReference + = parsers.less + * C(parsers.urlchar^1) + * parsers.more + / function(url) + return writer.link(writer.escape(url), url) + end + larsers.DirectLink = (parsers.tag / parse_inlines_no_link) -- no links inside links * parsers.spnl * parsers.lparent @@ -3901,12 +3986,12 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline larsers.EscapedChar = parsers.backslash * C(parsers.escapable) / writer.string - larsers.InlineHtml = parsers.emptyelt_any + larsers.InlineHtml = parsers.emptyelt_any / writer.inline_html_tag + (parsers.htmlcomment / parse_inlines_no_html) / writer.inline_html_comment + parsers.htmlinstruction - + parsers.openelt_any - + parsers.closeelt_any + + parsers.openelt_any / writer.inline_html_tag + + parsers.closeelt_any / writer.inline_html_tag larsers.HtmlEntity = parsers.hexentity / entities.hex_entity / writer.string + parsers.decentity / entities.dec_entity / writer.string @@ -3916,7 +4001,12 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline * parsers.contentblock_tail / writer.contentblock - larsers.DisplayHtml = parsers.displayhtml + larsers.DisplayHtml = (parsers.htmlcomment / parse_blocks) + / writer.block_html_comment + + parsers.emptyelt_block / writer.block_html_element + + parsers.openelt_exact("hr") / writer.block_html_element + + parsers.in_matched_block_tags / writer.block_html_element + + parsers.htmlinstruction larsers.Verbatim = Cs( (parsers.blanklines * ((parsers.indentedline - parsers.blankline))^1)^1 @@ -4180,6 +4270,7 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline + V("Code") + V("AutoLinkUrl") + V("AutoLinkEmail") + + V("AutoLinkRelativeReference") + V("InlineHtml") + V("HtmlEntity") + V("EscapedChar") @@ -4200,6 +4291,7 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline + V("Code") + V("AutoLinkUrl") + V("AutoLinkEmail") + + V("AutoLinkRelativeReference") + V("InlineHtml") + V("HtmlEntity") + V("EscapedChar") @@ -4221,6 +4313,8 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline Code = larsers.Code, AutoLinkUrl = larsers.AutoLinkUrl, AutoLinkEmail = larsers.AutoLinkEmail, + AutoLinkRelativeReference + = larsers.AutoLinkRelativeReference, InlineHtml = larsers.InlineHtml, HtmlEntity = larsers.HtmlEntity, EscapedChar = larsers.EscapedChar, @@ -4278,6 +4372,10 @@ larsers.PipeTable = Ct(larsers.table_row * parsers.newline syntax.Smart = parsers.fail end + if not options.relativeReferences then + syntax.AutoLinkRelativeReference = parsers.fail + end + local blocks_toplevel_t = util.table_copy(syntax) blocks_toplevel_t.Paragraph = larsers.ToplevelParagraph larsers.blocks_toplevel = Ct(blocks_toplevel_t) -- cgit v1.2.3