diff options
author | Karl Berry <karl@freefriends.org> | 2016-08-29 21:19:56 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-08-29 21:19:56 +0000 |
commit | 835ae450df95b8a97500efebbe995d9950c4e2b2 (patch) | |
tree | 2f9de4b0d4669f42f478401ce48926bed745aca0 /Master/texmf-dist/tex | |
parent | 8d7f98b66885b8a8f5e0cccb43f7c97060affb01 (diff) |
markdown (29aug16)
git-svn-id: svn://tug.org/texlive/trunk@41950 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r-- | Master/texmf-dist/tex/context/third/markdown/t-markdown.tex | 42 | ||||
-rw-r--r-- | Master/texmf-dist/tex/generic/markdown/markdown.tex | 146 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/markdown/markdown.sty | 150 | ||||
-rw-r--r-- | Master/texmf-dist/tex/luatex/markdown/markdown.lua | 344 |
4 files changed, 511 insertions, 171 deletions
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 bad0124577b..4f90f3b8f8f 100644 --- a/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex +++ b/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex @@ -67,7 +67,7 @@ tex.print(unescape("|input markdown")) end}% \fi -\ifnum\markdownMode<2 +\ifnum\markdownMode<2\relax \def\markdownMakeOther{% \catcode`|=12}% \fi @@ -90,10 +90,10 @@ \def\markdownRendererBackslashPrototype{\textbackslash}% \def\markdownRendererTildePrototype{\textasciitilde}% \def\markdownRendererPipePrototype{\char`|}% -\long\def\markdownRendererLinkPrototype#1#2#3#4{% +\def\markdownRendererLinkPrototype#1#2#3#4{% \useURL[#1][#3][][#4]#1\footnote[#1]{\ifx\empty#4\empty\else#4: \fi\tt<\hyphenatedurl{#3}>}}% -\long\def\markdownRendererImagePrototype#1#2#3#4{% +\def\markdownRendererImagePrototype#1#2#3#4{% \placefigure[][fig:#1]{#4}{\externalfigure[#3]}}% \def\markdownRendererUlBeginPrototype{\startitemize}% \def\markdownRendererUlBeginTightPrototype{\startitemize[packed]}% @@ -103,11 +103,11 @@ \def\markdownRendererOlBeginPrototype{\startitemize[n]}% \def\markdownRendererOlBeginTightPrototype{\startitemize[packed,n]}% \def\markdownRendererOlItemPrototype{\item}% -\long\def\markdownRendererOlItemWithNumberPrototype#1{\sym{#1.}}% +\def\markdownRendererOlItemWithNumberPrototype#1{\sym{#1.}}% \def\markdownRendererOlEndPrototype{\stopitemize}% \def\markdownRendererOlEndTightPrototype{\stopitemize}% \definedescription - [markdownConTeXtDlItemPrototype] + [MarkdownConTeXtDlItemPrototype] [location=hanging, margin=standard, headstyle=bold]% @@ -123,26 +123,34 @@ \startMarkdownConTeXtDlPrototype}% \def\markdownRendererDlBeginTightPrototype{% \startMarkdownConTeXtDlTightPrototype}% -\long\def\markdownRendererDlItemPrototype#1{% - \markdownConTeXtDlItemPrototype{#1}}% +\def\markdownRendererDlItemPrototype#1{% + \startMarkdownConTeXtDlItemPrototype{#1}}% +\def\markdownRendererDlItemEndPrototype{% + \stopMarkdownConTeXtDlItemPrototype}% \def\markdownRendererDlEndPrototype{% \stopMarkdownConTeXtDlPrototype}% \def\markdownRendererDlEndTightPrototype{% \stopMarkdownConTeXtDlTightPrototype}% -\long\def\markdownRendererEmphasisPrototype#1{{\em#1}}% -\long\def\markdownRendererStrongEmphasisPrototype#1{{\bf\em#1}}% +\def\markdownRendererEmphasisPrototype#1{{\em#1}}% +\def\markdownRendererStrongEmphasisPrototype#1{{\bf\em#1}}% \def\markdownRendererBlockQuoteBeginPrototype{\startquotation}% \def\markdownRendererBlockQuoteEndPrototype{\stopquotation}% -\long\def\markdownRendererInputVerbatimPrototype#1{\typefile{#1}}% -\long\def\markdownRendererHeadingOnePrototype#1{\chapter{#1}}% -\long\def\markdownRendererHeadingTwoPrototype#1{\section{#1}}% -\long\def\markdownRendererHeadingThreePrototype#1{\subsection{#1}}% -\long\def\markdownRendererHeadingFourPrototype#1{\subsubsection{#1}}% -\long\def\markdownRendererHeadingFivePrototype#1{\subsubsubsection{#1}}% -\long\def\markdownRendererHeadingSixPrototype#1{\subsubsubsubsection{#1}}% +\def\markdownRendererInputVerbatimPrototype#1{\typefile{#1}}% +\def\markdownRendererInputFencedCodePrototype#1#2{% + \ifx\relax#2\relax + \typefile{#1}% + \else + \typefile[#2][]{#1}% + \fi}% +\def\markdownRendererHeadingOnePrototype#1{\chapter{#1}}% +\def\markdownRendererHeadingTwoPrototype#1{\section{#1}}% +\def\markdownRendererHeadingThreePrototype#1{\subsection{#1}}% +\def\markdownRendererHeadingFourPrototype#1{\subsubsection{#1}}% +\def\markdownRendererHeadingFivePrototype#1{\subsubsubsection{#1}}% +\def\markdownRendererHeadingSixPrototype#1{\subsubsubsubsection{#1}}% \def\markdownRendererHorizontalRulePrototype{% \blackrule[height=1pt, width=\hsize]}% -\long\def\markdownRendererFootnotePrototype#1{\footnote{#1}}% +\def\markdownRendererFootnotePrototype#1{\footnote{#1}}% \stopmodule\protect \endinput %% diff --git a/Master/texmf-dist/tex/generic/markdown/markdown.tex b/Master/texmf-dist/tex/generic/markdown/markdown.tex index 247290d0b3b..12fcc8df129 100644 --- a/Master/texmf-dist/tex/generic/markdown/markdown.tex +++ b/Master/texmf-dist/tex/generic/markdown/markdown.tex @@ -45,29 +45,37 @@ %% %% The names of the source files used are shown above. %% -\def\markdownLastModified{2016/08/14}% -\def\markdownVersion{1.0.2}% +\def\markdownLastModified{2016/08/20}% +\def\markdownVersion{2.1.0}% \let\markdownBegin\relax \let\markdownEnd\relax \let\markdownInput\relax \def\markdownOptionHelperScriptFileName{\jobname.markdown.lua}% \def\markdownOptionInputTempFileName{\jobname.markdown.in}% \def\markdownOptionOutputTempFileName{\jobname.markdown.out}% -\def\markdownOptionCacheDir{_markdown-\jobname}% +\def\markdownOptionCacheDir{_markdown_\jobname}% \let\markdownOptionBlankBeforeBlockquote\undefined +\let\markdownOptionBlankBeforeCodeFence\undefined \let\markdownOptionBlankBeforeHeading\undefined +\let\markdownOptionCitations\undefined +\let\markdownOptionCitationNbsps\undefined \let\markdownOptionDefinitionLists\undefined +\let\markdownOptionFootnotes\undefined +\let\markdownOptionFencedCode\undefined \let\markdownOptionHashEnumerators\undefined \let\markdownOptionHybrid\undefined -\let\markdownOptionFootnotes\undefined \let\markdownOptionPreserveTabs\undefined \let\markdownOptionSmartEllipses\undefined \let\markdownOptionStartNumber\undefined \let\markdownOptionTightLists\undefined +\def\markdownRendererInterblockSeparator{% + \markdownRendererInterblockSeparatorPrototype}% \def\markdownRendererLineBreak{% \markdownRendererLineBreakPrototype}% \def\markdownRendererEllipsis{% \markdownRendererEllipsisPrototype}% +\def\markdownRendererNbsp{% + \markdownRendererNbspPrototype}% \def\markdownRendererLeftBrace{% \markdownRendererLeftBracePrototype}% \def\markdownRendererRightBrace{% @@ -102,6 +110,8 @@ \markdownRendererUlBeginTightPrototype}% \def\markdownRendererUlItem{% \markdownRendererUlItemPrototype}% +\def\markdownRendererUlItemEnd{% + \markdownRendererUlItemEndPrototype}% \def\markdownRendererUlEnd{% \markdownRendererUlEndPrototype}% \def\markdownRendererUlEndTight{% @@ -112,6 +122,8 @@ \markdownRendererOlBeginTightPrototype}% \def\markdownRendererOlItem{% \markdownRendererOlItemPrototype}% +\def\markdownRendererOlItemEnd{% + \markdownRendererOlItemEndPrototype}% \def\markdownRendererOlItemWithNumber{% \markdownRendererOlItemWithNumberPrototype}% \def\markdownRendererOlEnd{% @@ -124,6 +136,8 @@ \markdownRendererDlBeginTightPrototype}% \def\markdownRendererDlItem{% \markdownRendererDlItemPrototype}% +\def\markdownRendererDlItemEnd{% + \markdownRendererDlItemEndPrototype}% \def\markdownRendererDlDefinitionBegin{% \markdownRendererDlDefinitionBeginPrototype}% \def\markdownRendererDlDefinitionEnd{% @@ -142,6 +156,8 @@ \markdownRendererBlockQuoteEndPrototype}% \def\markdownRendererInputVerbatim{% \markdownRendererInputVerbatimPrototype}% +\def\markdownRendererInputFencedCode{% + \markdownRendererInputFencedCodePrototype}% \def\markdownRendererHeadingOne{% \markdownRendererHeadingOnePrototype}% \def\markdownRendererHeadingTwo{% @@ -158,8 +174,14 @@ \markdownRendererHorizontalRulePrototype}% \def\markdownRendererFootnote{% \markdownRendererFootnotePrototype}% +\def\markdownRendererCite{% + \markdownRendererCitePrototype}% +\def\markdownRendererTextCite{% + \markdownRendererTextCitePrototype}% +\def\markdownRendererInterblockSeparatorPrototype{}% \def\markdownRendererLineBreakPrototype{}% \def\markdownRendererEllipsisPrototype{}% +\def\markdownRendererNbspPrototype{}% \def\markdownRendererLeftBracePrototype{}% \def\markdownRendererRightBracePrototype{}% \def\markdownRendererDollarSignPrototype{}% @@ -171,40 +193,46 @@ \def\markdownRendererBackslashPrototype{}% \def\markdownRendererTildePrototype{}% \def\markdownRendererPipePrototype{}% -\long\def\markdownRendererCodeSpanPrototype#1{}% -\long\def\markdownRendererLinkPrototype#1#2#3#4{}% -\long\def\markdownRendererImagePrototype#1#2#3#4{}% +\def\markdownRendererCodeSpanPrototype#1{}% +\def\markdownRendererLinkPrototype#1#2#3#4{}% +\def\markdownRendererImagePrototype#1#2#3#4{}% \def\markdownRendererUlBeginPrototype{}% \def\markdownRendererUlBeginTightPrototype{}% \def\markdownRendererUlItemPrototype{}% +\def\markdownRendererUlItemEndPrototype{}% \def\markdownRendererUlEndPrototype{}% \def\markdownRendererUlEndTightPrototype{}% \def\markdownRendererOlBeginPrototype{}% \def\markdownRendererOlBeginTightPrototype{}% \def\markdownRendererOlItemPrototype{}% -\long\def\markdownRendererOlItemWithNumberPrototype#1{}% +\def\markdownRendererOlItemWithNumberPrototype#1{}% +\def\markdownRendererOlItemEndPrototype{}% \def\markdownRendererOlEndPrototype{}% \def\markdownRendererOlEndTightPrototype{}% \def\markdownRendererDlBeginPrototype{}% \def\markdownRendererDlBeginTightPrototype{}% -\long\def\markdownRendererDlItemPrototype#1{}% +\def\markdownRendererDlItemPrototype#1{}% +\def\markdownRendererDlItemEndPrototype{}% \def\markdownRendererDlDefinitionBeginPrototype{}% \def\markdownRendererDlDefinitionEndPrototype{}% \def\markdownRendererDlEndPrototype{}% \def\markdownRendererDlEndTightPrototype{}% -\long\def\markdownRendererEmphasisPrototype#1{}% -\long\def\markdownRendererStrongEmphasisPrototype#1{}% +\def\markdownRendererEmphasisPrototype#1{}% +\def\markdownRendererStrongEmphasisPrototype#1{}% \def\markdownRendererBlockQuoteBeginPrototype{}% \def\markdownRendererBlockQuoteEndPrototype{}% -\long\def\markdownRendererInputVerbatimPrototype#1{}% -\long\def\markdownRendererHeadingOnePrototype#1{}% -\long\def\markdownRendererHeadingTwoPrototype#1{}% -\long\def\markdownRendererHeadingThreePrototype#1{}% -\long\def\markdownRendererHeadingFourPrototype#1{}% -\long\def\markdownRendererHeadingFivePrototype#1{}% -\long\def\markdownRendererHeadingSixPrototype#1{}% +\def\markdownRendererInputVerbatimPrototype#1{}% +\def\markdownRendererInputFencedCodePrototype#1#2{}% +\def\markdownRendererHeadingOnePrototype#1{}% +\def\markdownRendererHeadingTwoPrototype#1{}% +\def\markdownRendererHeadingThreePrototype#1{}% +\def\markdownRendererHeadingFourPrototype#1{}% +\def\markdownRendererHeadingFivePrototype#1{}% +\def\markdownRendererHeadingSixPrototype#1{}% \def\markdownRendererHorizontalRulePrototype{}% -\long\def\markdownRendererFootnotePrototype#1{}% +\def\markdownRendererFootnotePrototype#1{}% +\def\markdownRendererCitePrototype#1{}% +\def\markdownRendererTextCitePrototype#1{}% \def\markdownInfo#1{}% \def\markdownWarning#1{}% \def\markdownError#1{}% @@ -235,8 +263,10 @@ \def\markdownError#1#2{% \errhelp{#2.}% \errmessage{(l.\the\inputlineno) markdown.tex error: #1}}% +\def\markdownRendererInterblockSeparatorPrototype{\par}% \def\markdownRendererLineBreakPrototype{\hfil\break}% \let\markdownRendererEllipsisPrototype\dots +\def\markdownRendererNbspPrototype{~}% \def\markdownRendererLeftBracePrototype{\char`{}% \def\markdownRendererRightBracePrototype{\char`}}% \def\markdownRendererDollarSignPrototype{\char`$}% @@ -248,63 +278,82 @@ \def\markdownRendererBackslashPrototype{\char`\\}% \def\markdownRendererTildePrototype{\char`~}% \def\markdownRendererPipePrototype{|}% -\long\def\markdownRendererCodeSpanPrototype#1{{\tt#1}}% -\long\def\markdownRendererLinkPrototype#1#2#3#4{#2}% -\long\def\markdownRendererImagePrototype#1#2#3#4{#2}% +\def\markdownRendererCodeSpanPrototype#1{{\tt#1}}% +\def\markdownRendererLinkPrototype#1#2#3#4{#2}% +\def\markdownRendererImagePrototype#1#2#3#4{#2}% \def\markdownRendererUlBeginPrototype{}% \def\markdownRendererUlBeginTightPrototype{}% \def\markdownRendererUlItemPrototype{}% +\def\markdownRendererUlItemEndPrototype{}% \def\markdownRendererUlEndPrototype{}% \def\markdownRendererUlEndTightPrototype{}% \def\markdownRendererOlBeginPrototype{}% \def\markdownRendererOlBeginTightPrototype{}% \def\markdownRendererOlItemPrototype{}% -\long\def\markdownRendererOlItemWithNumberPrototype#1{}% +\def\markdownRendererOlItemWithNumberPrototype#1{}% +\def\markdownRendererOlItemEndPrototype{}% \def\markdownRendererOlEndPrototype{}% \def\markdownRendererOlEndTightPrototype{}% \def\markdownRendererDlBeginPrototype{}% \def\markdownRendererDlBeginTightPrototype{}% -\long\def\markdownRendererDlItemPrototype#1{#1}% +\def\markdownRendererDlItemPrototype#1{#1}% +\def\markdownRendererDlItemEndPrototype{}% \def\markdownRendererDlDefinitionBeginPrototype{}% \def\markdownRendererDlDefinitionEndPrototype{\par}% \def\markdownRendererDlEndPrototype{}% \def\markdownRendererDlEndTightPrototype{}% -\long\def\markdownRendererEmphasisPrototype#1{{\it#1}}% -\long\def\markdownRendererStrongEmphasisPrototype#1{{\it#1}}% +\def\markdownRendererEmphasisPrototype#1{{\it#1}}% +\def\markdownRendererStrongEmphasisPrototype#1{{\it#1}}% \def\markdownRendererBlockQuoteBeginPrototype{\par\begingroup\it}% \def\markdownRendererBlockQuoteEndPrototype{\endgroup\par}% -\long\def\markdownRendererInputVerbatimPrototype#1{% -\par{\tt\input"#1"\relax}\par}% -\long\def\markdownRendererHeadingOnePrototype#1{#1}% -\long\def\markdownRendererHeadingTwoPrototype#1{#1}% -\long\def\markdownRendererHeadingThreePrototype#1{#1}% -\long\def\markdownRendererHeadingFourPrototype#1{#1}% -\long\def\markdownRendererHeadingFivePrototype#1{#1}% -\long\def\markdownRendererHeadingSixPrototype#1{#1}% +\def\markdownRendererInputVerbatimPrototype#1{% + \par{\tt\input"#1"\relax}\par}% +\def\markdownRendererInputFencedCodePrototype#1#2{% + \markdownRendererInputVerbatimPrototype{#1}}% +\def\markdownRendererHeadingOnePrototype#1{#1}% +\def\markdownRendererHeadingTwoPrototype#1{#1}% +\def\markdownRendererHeadingThreePrototype#1{#1}% +\def\markdownRendererHeadingFourPrototype#1{#1}% +\def\markdownRendererHeadingFivePrototype#1{#1}% +\def\markdownRendererHeadingSixPrototype#1{#1}% \def\markdownRendererHorizontalRulePrototype{}% -\long\def\markdownRendererFootnotePrototype#1{#1}% +\def\markdownRendererFootnotePrototype#1{#1}% +\def\markdownRendererCitePrototype#1{}% +\def\markdownRendererTextCitePrototype#1{}% \def\markdownLuaOptions{{% \ifx\markdownOptionBlankBeforeBlockquote\undefined\else blankBeforeBlockquote = \markdownOptionBlankBeforeBlockquote, \fi +\ifx\markdownOptionBlankBeforeCodeFence\undefined\else + blankBeforeCodeFence = \markdownOptionBlankBeforeCodeFence, +\fi \ifx\markdownOptionBlankBeforeHeading\undefined\else blankBeforeHeading = \markdownOptionBlankBeforeHeading, \fi \ifx\markdownOptionCacheDir\undefined\else cacheDir = "\markdownOptionCacheDir", \fi +\ifx\markdownOptionCitations\undefined\else + citations = \markdownOptionCitations, +\fi +\ifx\markdownOptionCitationNbsps\undefined\else + citationNbsps = \markdownOptionCitationNbsps, +\fi \ifx\markdownOptionDefinitionLists\undefined\else definitionLists = \markdownOptionDefinitionLists, \fi +\ifx\markdownOptionFootnotes\undefined\else + footnotes = \markdownOptionFootnotes, +\fi +\ifx\markdownOptionFencedCode\undefined\else + fencedCode = \markdownOptionFencedCode, +\fi \ifx\markdownOptionHashEnumerators\undefined\else hashEnumerators = \markdownOptionHashEnumerators, \fi \ifx\markdownOptionHybrid\undefined\else hybrid = \markdownOptionHybrid, \fi -\ifx\markdownOptionFootnotes\undefined\else - footnotes = \markdownOptionFootnotes, -\fi \ifx\markdownOptionPreserveTabs\undefined\else preserveTabs = \markdownOptionPreserveTabs, \fi @@ -335,19 +384,19 @@ local convert = md.new(\markdownLuaOptions) \markdownInfo{Using mode 1: Shell escape via os.execute}% \fi \csname newwrite\endcsname\markdownLuaExecuteFileStream -\ifnum\markdownMode=0\relax - \ifx\pdfshellescape\undefined - \ifx\shellescape\undefined +\ifx\pdfshellescape\undefined + \ifx\shellescape\undefined + \ifnum\markdownMode=0\relax \def\markdownExecuteShellEscape{1}% \else - \let\markdownExecuteShellEscape\shellescape + \def\markdownExecuteShellEscape{% + \directlua{tex.sprint(status.shell_escape or "1")}}% \fi \else - \let\markdownExecuteShellEscape\pdfshellescape + \let\markdownExecuteShellEscape\shellescape \fi \else - \def\markdownExecuteShellEscape{% - \directlua{tex.sprint(status.shell_escape)}}% + \let\markdownExecuteShellEscape\pdfshellescape \fi \ifnum\markdownMode=0\relax \def\markdownExecuteDirect#1{\immediate\write18{#1}}% @@ -403,7 +452,6 @@ local convert = md.new(\markdownLuaOptions) |else% |def^^M{% |markdownInfo{The ending token sequence was found}% - |immediate|write|markdownLuaExecuteFileStream{}% |immediate|closeout|markdownLuaExecuteFileStream% |endgroup% |markdownInput|markdownOptionInputTempFileName% @@ -443,8 +491,8 @@ local convert = md.new(\markdownLuaOptions) "([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1") |markdownLuaRegisterIBCallback{function(line) if line:match(ending_sequence) then - |markdownLuaUnregisterIBCallback - local input = table.concat(buffer, "\n") .. "\n\n" + |markdownLuaUnregisterIBCallback; + local input = table.concat(buffer, "\n") .. "\n" local output = convert(input) return [[\markdownInfo{The ending token sequence was found}]] .. output .. [[\markdownReadAndConvertAfter]] @@ -463,7 +511,7 @@ local convert = md.new(\markdownLuaOptions) |markdownInfo{Including markdown document "#1"}% |markdownLuaExecute{% |markdownPrepare - local input = assert(io.open("#1","r")):read("*a") .. "\n\n" + local input = assert(io.open("#1","r")):read("*a") print(convert(input:gsub("\r\n?", "\n")))}}% |endgroup \endinput diff --git a/Master/texmf-dist/tex/latex/markdown/markdown.sty b/Master/texmf-dist/tex/latex/markdown/markdown.sty index 08dc59ef1e8..34f443fef1b 100644 --- a/Master/texmf-dist/tex/latex/markdown/markdown.sty +++ b/Master/texmf-dist/tex/latex/markdown/markdown.sty @@ -59,18 +59,26 @@ \def\markdownOptionOutputTempFileName{#1}}% \define@key{markdownOptions}{blankBeforeBlockquote}[true]{% \def\markdownOptionBlankBeforeBlockquote{#1}}% +\define@key{markdownOptions}{blankBeforeCodeFence}[true]{% + \def\markdownOptionBlankBeforeCodeFence{#1}}% \define@key{markdownOptions}{blankBeforeHeading}[true]{% \def\markdownOptionBlankBeforeHeading{#1}}% +\define@key{markdownOptions}{citations}[true]{% + \def\markdownOptionCitations{#1}}% +\define@key{markdownOptions}{citationNbsps}[true]{% + \def\markdownOptionCitationNbsps{#1}}% \define@key{markdownOptions}{cacheDir}{% \def\markdownOptionCacheDir{#1}}% \define@key{markdownOptions}{definitionLists}[true]{% \def\markdownOptionDefinitionLists{#1}}% +\define@key{markdownOptions}{footnotes}[true]{% + \def\markdownOptionFootnotes{#1}}% +\define@key{markdownOptions}{fencedCode}[true]{% + \def\markdownOptionFencedCode{#1}}% \define@key{markdownOptions}{hashEnumerators}[true]{% \def\markdownOptionHashEnumerators{#1}}% \define@key{markdownOptions}{hybrid}[true]{% \def\markdownOptionHybrid{#1}}% -\define@key{markdownOptions}{footnotes}[true]{% - \def\markdownOptionFootnotes{#1}}% \define@key{markdownOptions}{preserveTabs}[true]{% \def\markdownOptionPreserveTabs{#1}}% \define@key{markdownOptions}{smartEllipses}[true]{% @@ -79,12 +87,14 @@ \def\markdownOptionStartNumber{#1}}% \define@key{markdownOptions}{tightLists}[true]{% \def\markdownOptionTightLists{#1}}% -\define@key{markdownOptions}{renderers}{% - \setkeys{markdownRenderers}{#1}}% +\define@key{markdownRenderers}{interblockSeparator}{% + \renewcommand\markdownRendererInterblockSeparator{#1}}% \define@key{markdownRenderers}{lineBreak}{% \renewcommand\markdownRendererLineBreak{#1}}% \define@key{markdownRenderers}{ellipsis}{% \renewcommand\markdownRendererEllipsis{#1}}% +\define@key{markdownRenderers}{nbsp}{% + \renewcommand\markdownRendererNbsp{#1}}% \define@key{markdownRenderers}{leftBrace}{% \renewcommand\markdownRendererLeftBrace{#1}}% \define@key{markdownRenderers}{rightBrace}{% @@ -119,6 +129,8 @@ \renewcommand\markdownRendererUlBeginTight{#1}}% \define@key{markdownRenderers}{ulItem}{% \renewcommand\markdownRendererUlItem{#1}}% +\define@key{markdownRenderers}{ulItemEnd}{% + \renewcommand\markdownRendererUlItemEnd{#1}}% \define@key{markdownRenderers}{ulEnd}{% \renewcommand\markdownRendererUlEnd{#1}}% \define@key{markdownRenderers}{ulEndTight}{% @@ -131,6 +143,8 @@ \renewcommand\markdownRendererOlItem{#1}}% \define@key{markdownRenderers}{olItemWithNumber}{% \renewcommand\markdownRendererOlItemWithNumber[1]{#1}}% +\define@key{markdownRenderers}{olItemEnd}{% + \renewcommand\markdownRendererOlItemEnd{#1}}% \define@key{markdownRenderers}{olEnd}{% \renewcommand\markdownRendererOlEnd{#1}}% \define@key{markdownRenderers}{olEndTight}{% @@ -141,6 +155,8 @@ \renewcommand\markdownRendererDlBeginTight{#1}}% \define@key{markdownRenderers}{dlItem}{% \renewcommand\markdownRendererDlItem[1]{#1}}% +\define@key{markdownRenderers}{dlItemEnd}{% + \renewcommand\markdownRendererDlItemEnd{#1}}% \define@key{markdownRenderers}{dlDefinitionBegin}{% \renewcommand\markdownRendererDlDefinitionBegin{#1}}% \define@key{markdownRenderers}{dlDefinitionEnd}{% @@ -159,6 +175,8 @@ \renewcommand\markdownRendererBlockQuoteEnd{#1}}% \define@key{markdownRenderers}{inputVerbatim}{% \renewcommand\markdownRendererInputVerbatim[1]{#1}}% +\define@key{markdownRenderers}{inputFencedCode}{% + \renewcommand\markdownRendererInputFencedCode[2]{#1}}% \define@key{markdownRenderers}{headingOne}{% \renewcommand\markdownRendererHeadingOne[1]{#1}}% \define@key{markdownRenderers}{headingTwo}{% @@ -175,12 +193,18 @@ \renewcommand\markdownRendererHorizontalRule{#1}}% \define@key{markdownRenderers}{footnote}{% \renewcommand\markdownRendererFootnote[1]{#1}}% -\define@key{markdownOptions}{rendererPrototypes}{% - \setkeys{markdownRendererPrototypes}{#1}}% +\define@key{markdownRenderers}{cite}{% + \renewcommand\markdownRendererCite[1]{#1}}% +\define@key{markdownRenderers}{textCite}{% + \renewcommand\markdownRendererTextCite[1]{#1}}% +\define@key{markdownRendererPrototypes}{interblockSeparator}{% + \renewcommand\markdownRendererInterblockSeparatorPrototype{#1}}% \define@key{markdownRendererPrototypes}{lineBreak}{% \renewcommand\markdownRendererLineBreakPrototype{#1}}% \define@key{markdownRendererPrototypes}{ellipsis}{% \renewcommand\markdownRendererEllipsisPrototype{#1}}% +\define@key{markdownRendererPrototypes}{nbsp}{% + \renewcommand\markdownRendererNbspPrototype{#1}}% \define@key{markdownRendererPrototypes}{leftBrace}{% \renewcommand\markdownRendererLeftBracePrototype{#1}}% \define@key{markdownRendererPrototypes}{rightBrace}{% @@ -202,19 +226,21 @@ \define@key{markdownRendererPrototypes}{tilde}{% \renewcommand\markdownRendererTildePrototype{#1}}% \define@key{markdownRendererPrototypes}{pipe}{% - \renewcommand\markdownRendererPipe{#1}}% + \renewcommand\markdownRendererPipePrototype{#1}}% \define@key{markdownRendererPrototypes}{codeSpan}{% \renewcommand\markdownRendererCodeSpanPrototype[1]{#1}}% \define@key{markdownRendererPrototypes}{link}{% - \renewcommand\markdownRendererLink[4]{#1}}% + \renewcommand\markdownRendererLinkPrototype[4]{#1}}% \define@key{markdownRendererPrototypes}{image}{% - \renewcommand\markdownRendererImage[4]{#1}}% + \renewcommand\markdownRendererImagePrototype[4]{#1}}% \define@key{markdownRendererPrototypes}{ulBegin}{% \renewcommand\markdownRendererUlBeginPrototype{#1}}% \define@key{markdownRendererPrototypes}{ulBeginTight}{% \renewcommand\markdownRendererUlBeginTightPrototype{#1}}% \define@key{markdownRendererPrototypes}{ulItem}{% \renewcommand\markdownRendererUlItemPrototype{#1}}% +\define@key{markdownRendererPrototypes}{ulItemEnd}{% + \renewcommand\markdownRendererUlItemEndPrototype{#1}}% \define@key{markdownRendererPrototypes}{ulEnd}{% \renewcommand\markdownRendererUlEndPrototype{#1}}% \define@key{markdownRendererPrototypes}{ulEndTight}{% @@ -227,6 +253,8 @@ \renewcommand\markdownRendererOlItemPrototype{#1}}% \define@key{markdownRendererPrototypes}{olItemWithNumber}{% \renewcommand\markdownRendererOlItemWithNumberPrototype[1]{#1}}% +\define@key{markdownRendererPrototypes}{olItemEnd}{% + \renewcommand\markdownRendererOlItemEndPrototype{#1}}% \define@key{markdownRendererPrototypes}{olEnd}{% \renewcommand\markdownRendererOlEndPrototype{#1}}% \define@key{markdownRendererPrototypes}{olEndTight}{% @@ -237,6 +265,8 @@ \renewcommand\markdownRendererDlBeginTightPrototype{#1}}% \define@key{markdownRendererPrototypes}{dlItem}{% \renewcommand\markdownRendererDlItemPrototype[1]{#1}}% +\define@key{markdownRendererPrototypes}{dlItemEnd}{% + \renewcommand\markdownRendererDlItemEndPrototype{#1}}% \define@key{markdownRendererPrototypes}{dlDefinitionBegin}{% \renewcommand\markdownRendererDlDefinitionBeginPrototype{#1}}% \define@key{markdownRendererPrototypes}{dlDefinitionEnd}{% @@ -255,6 +285,8 @@ \renewcommand\markdownRendererBlockQuoteEndPrototype{#1}}% \define@key{markdownRendererPrototypes}{inputVerbatim}{% \renewcommand\markdownRendererInputVerbatimPrototype[1]{#1}}% +\define@key{markdownRendererPrototypes}{inputFencedCode}{% + \renewcommand\markdownRendererInputFencedCodePrototype[2]{#1}}% \define@key{markdownRendererPrototypes}{headingOne}{% \renewcommand\markdownRendererHeadingOnePrototype[1]{#1}}% \define@key{markdownRendererPrototypes}{headingTwo}{% @@ -271,6 +303,10 @@ \renewcommand\markdownRendererHorizontalRulePrototype{#1}}% \define@key{markdownRendererPrototypes}{footnote}{% \renewcommand\markdownRendererFootnotePrototype[1]{#1}}% +\define@key{markdownRendererPrototypes}{cite}{% + \renewcommand\markdownRendererCitePrototype[1]{#1}}% +\define@key{markdownRendererPrototypes}{textCite}{% + \renewcommand\markdownRendererTextCitePrototype[1]{#1}}% \input markdown \def\markdownVersionSpace{ }% \ProvidesPackage{markdown}[\markdownLastModified\markdownVersionSpace v% @@ -299,6 +335,12 @@ \DeclareOption*{% \expandafter\markdownSetup\expandafter{\CurrentOption}}% \ProcessOptions\relax +\define@key{markdownOptions}{renderers}{% + \setkeys{markdownRenderers}{#1}% + \def\KV@prefix{KV@markdownOptions@}}% +\define@key{markdownOptions}{rendererPrototypes}{% + \setkeys{markdownRendererPrototypes}{#1}% + \def\KV@prefix{KV@markdownOptions@}}% \RequirePackage{url} \RequirePackage{graphicx} \RequirePackage{ifthen} @@ -357,31 +399,103 @@ blockQuoteBegin = {\begin{quotation}}, blockQuoteEnd = {\end{quotation}}, inputVerbatim = {\VerbatimInput{#1}}, + inputFencedCode = {% + \ifx\relax#2\relax + \VerbatimInput{#1}% + \else + \ifx\minted@jobname\undefined + \ifx\lst@version\undefined + \markdownRendererInputFencedCode{#1}{}% + \else + \lstinputlisting[language=#2]{#1}% + \fi + \else + \inputminted{#2}{#1}% + \fi + \fi}, horizontalRule = {\noindent\rule[0.5ex]{\linewidth}{1pt}}, - footnote = {\footnote{#1}}}}% + footnote = {\footnote{#1}}}} \ifx\chapter\undefined - \markdownSetup{rendererPrototypes={ + \markdownSetup{rendererPrototypes = { headingOne = {\section{#1}}, headingTwo = {\subsection{#1}}, headingThree = {\subsubsection{#1}}, headingFour = {\paragraph{#1}}, - headingFive = {\subparagraph{#1}}}}% + headingFive = {\subparagraph{#1}}}} \else - \markdownSetup{rendererPrototypes={ + \markdownSetup{rendererPrototypes = { headingOne = {\chapter{#1}}, headingTwo = {\section{#1}}, headingThree = {\subsection{#1}}, headingFour = {\subsubsection{#1}}, headingFive = {\paragraph{#1}}, - headingSix = {\subparagraph{#1}}}}% + headingSix = {\subparagraph{#1}}}} \fi +\newcount\markdownLaTeXCitationsCounter + +\def\markdownLaTeXBasicCitations#1#2#3#4{% + \advance\markdownLaTeXCitationsCounter by 1\relax + \ifx\relax#2\relax\else#2~\fi\cite[#3]{#4}% + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax + \expandafter\@gobble + \fi\markdownLaTeXBasicCitations} +\let\markdownLaTeXBasicTextCitations\markdownLaTeXBasicCitations + +\def\markdownLaTeXBibLaTeXCitations#1#2#3#4#5{% + \advance\markdownLaTeXCitationsCounter by 1\relax + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax + \autocites#1[#3][#4]{#5}% + \expandafter\@gobbletwo + \fi\markdownLaTeXBibLaTeXCitations{#1[#3][#4]{#5}}} +\def\markdownLaTeXBibLaTeXTextCitations#1#2#3#4#5{% + \advance\markdownLaTeXCitationsCounter by 1\relax + \ifnum\markdownLaTeXCitationsCounter>\markdownLaTeXCitationsTotal\relax + \textcites#1[#3][#4]{#5}% + \expandafter\@gobbletwo + \fi\markdownLaTeXBibLaTeXTextCitations{#1[#3][#4]{#5}}} + +\markdownSetup{rendererPrototypes = { + cite = {% + \markdownLaTeXCitationsCounter=1% + \def\markdownLaTeXCitationsTotal{#1}% + \ifx\autocites\undefined + \expandafter + \markdownLaTeXBasicCitations + \else + \expandafter\expandafter\expandafter + \markdownLaTeXBibLaTeXCitations + \expandafter{\expandafter}% + \fi}, + textCite = {% + \markdownLaTeXCitationsCounter=1% + \def\markdownLaTeXCitationsTotal{#1}% + \ifx\textcites\undefined + \expandafter + \markdownLaTeXBasicTextCitations + \else + \expandafter\expandafter\expandafter + \markdownLaTeXBibLaTeXTextCitations + \expandafter{\expandafter}% + \fi}}} +\let\markdownLuaRegisterIBCallbackPrevious + \markdownLuaRegisterIBCallback +\let\markdownLuaUnregisterIBCallbackPrevious + \markdownLuaUnregisterIBCallback \renewcommand\markdownLuaRegisterIBCallback[1]{% - luatexbase.add_to_callback("process_input_buffer", #1, % - "The markdown input processor")} + if luatexbase and luatexbase.add_to_callback then + luatexbase.add_to_callback("process_input_buffer", #1, % + "The markdown input processor") + else + \markdownLuaRegisterIBCallbackPrevious{#1} + end} \renewcommand\markdownLuaUnregisterIBCallback{% - luatexbase.remove_from_callback("process_input_buffer",% - "The markdown input processor")} + if luatexbase and luatexbase.add_to_callback then + luatexbase.remove_from_callback("process_input_buffer",% + "The markdown input processor") + else + \markdownLuaUnregisterIBCallbackPrevious; + end} \newcommand\markdownMakeOther{% \count0=128\relax \loop diff --git a/Master/texmf-dist/tex/luatex/markdown/markdown.lua b/Master/texmf-dist/tex/luatex/markdown/markdown.lua index 8a0f237c1d7..6a194bbf7ea 100644 --- a/Master/texmf-dist/tex/luatex/markdown/markdown.lua +++ b/Master/texmf-dist/tex/luatex/markdown/markdown.lua @@ -57,24 +57,30 @@ -- should contain your own preambles for the files it generates, not -- those in the standard .ins files. -- -if not modules then modules = { } end modules ['markdown'] = { - version = "1.0.2", +local metadata = { + version = "2.1.0", 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 Vít Novotný", license = "LPPL 1.3" } +if not modules then modules = { } end +modules['markdown'] = metadata local lpeg = require("lpeg") local unicode = require("unicode") local md5 = require("md5") local M = {} local defaultOptions = {} defaultOptions.blankBeforeBlockquote = false +defaultOptions.blankBeforeCodeFence = false defaultOptions.blankBeforeHeading = false defaultOptions.cacheDir = "." +defaultOptions.citationNbsps = true +defaultOptions.citations = false defaultOptions.definitionLists = false defaultOptions.hashEnumerators = false defaultOptions.hybrid = false +defaultOptions.fencedCode = false defaultOptions.footnotes = false defaultOptions.preserveTabs = false defaultOptions.smartEllipses = false @@ -222,6 +228,7 @@ function M.writer.new(options) return defaultOptions[key] end }) self.suffix = ".tex" self.space = " " + self.nbsp = "\\markdownRendererNbsp{}" function self.plain(s) return s end @@ -231,12 +238,11 @@ function M.writer.new(options) function self.pack(name) return [[\input"]] .. name .. [["\relax]] end - self.interblocksep = "\n\n" - self.containersep = "\n\n" + self.interblocksep = "\\markdownRendererInterblockSeparator\n{}" self.eof = [[\relax]] - self.linebreak = "\\markdownRendererLineBreak " + self.linebreak = "\\markdownRendererLineBreak\n{}" self.ellipsis = "\\markdownRendererEllipsis{}" - self.hrule = "\\markdownRendererHorizontalRule " + self.hrule = "\\markdownRendererHorizontalRule{}" local escaped_chars = { ["{"] = "\\markdownRendererLeftBrace{}", ["}"] = "\\markdownRendererRightBrace{}", @@ -282,7 +288,8 @@ function M.writer.new(options) "{",self.string(tit or ""),"}"} end local function ulitem(s) - return {"\\markdownRendererUlItem ",s} + return {"\\markdownRendererUlItem ",s, + "\\markdownRendererUlItemEnd "} end function self.bulletlist(items,tight) @@ -301,9 +308,11 @@ function M.writer.new(options) end local function olitem(s,num) if num ~= nil then - return {"\\markdownRendererOlItemWithNumber{",num,"}",s} + return {"\\markdownRendererOlItemWithNumber{",num,"}",s, + "\\markdownRendererOlItemEnd "} else - return {"\\markdownRendererOlItem ",s} + return {"\\markdownRendererOlItem ",s, + "\\markdownRendererOlItemEnd "} end end @@ -331,6 +340,7 @@ function M.writer.new(options) retVal[#retVal+1] = {"\\markdownRendererDlDefinitionBegin ",def, "\\markdownRendererDlDefinitionEnd "} end + retVal[#retVal+1] = "\\markdownRendererDlItemEnd " return retVal end @@ -339,13 +349,12 @@ function M.writer.new(options) for _,item in ipairs(items) do buffer[#buffer + 1] = dlitem(item.term, item.definitions) end - local contents = util.intersperse(buffer, self.containersep) if tight and options.tightLists then - return {"\\markdownRendererDlBeginTight\n\n", contents, - "\n\n\\markdownRendererDlEndTight\n"} + return {"\\markdownRendererDlBeginTight\n", buffer, + "\n\\markdownRendererDlEndTight"} else - return {"\\markdownRendererDlBegin\n\n", contents, - "\n\n\\markdownRendererDlEnd\n"} + return {"\\markdownRendererDlBegin\n", buffer, + "\n\\markdownRendererDlEnd"} end end function self.emphasis(s) @@ -362,6 +371,10 @@ function M.writer.new(options) local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim") return {"\\markdownRendererInputVerbatim{",name,"}"} end + function self.fencedCode(i, s) + local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim") + return {"\\markdownRendererInputFencedCode{",name,"}{",i,"}"} + end function self.heading(s,level) local cmd if level == 1 then @@ -384,6 +397,15 @@ function M.writer.new(options) function self.note(s) return {"\\markdownRendererFootnote{",s,"}"} end + function self.citations(text_cites, cites) + local buffer = {"\\markdownRenderer", text_cites and "TextCite" or "Cite", + "{", #cites, "}"} + for _,cite in ipairs(cites) do + buffer[#buffer+1] = {cite.suppress_author and "-" or "+", "{", + cite.prenote or "", "}{", cite.postnote or "", "}{", cite.name, "}"} + end + return buffer + end return self end @@ -410,41 +432,33 @@ function M.reader.new(writer, options) end end local syntax + local blocks_toplevel local blocks - local inlines + local inlines, inlines_no_link, inlines_nbsp - local parse_blocks = - function(str) - local res = lpeg.match(blocks, str) + local function create_parser(name, grammar) + return function(str) + local res = lpeg.match(grammar(), str) if res == nil then - error(format("parse_blocks failed on:\n%s", str:sub(1,20))) - else - return res - end - end - - local parse_inlines = - function(str) - local res = lpeg.match(inlines, str) - if res == nil then - error(format("parse_inlines failed on:\n%s", - str:sub(1,20))) + error(format("%s failed on:\n%s", name, str:sub(1,20))) else return res end end + end - local parse_inlines_no_link = - function(str) - local res = lpeg.match(inlines_no_link, str) - if res == nil then - error(format("parse_inlines_no_link failed on:\n%s", - str:sub(1,20))) - else - return res - end - end + local parse_blocks = create_parser("parse_blocks", + function() return blocks end) + local parse_blocks_toplevel = create_parser("parse_blocks_toplevel", + function() return blocks_toplevel end) + local parse_inlines = create_parser("parse_inlines", + function() return inlines end) + local parse_inlines_no_link = create_parser("parse_inlines_no_link", + function() return inlines_no_link end) + local parse_inlines_nbsp = create_parser("parse_inlines_nbsp", + function() return inlines_nbsp end) local percent = P("%") + local at = P("@") local asterisk = P("*") local dash = P("-") local plus = P("+") @@ -468,12 +482,14 @@ function M.reader.new(writer, options) local colon = P(":") local semicolon = P(";") local exclamation = P("!") + local tilde = P("~") local digit = R("09") local hexdigit = R("09","af","AF") local letter = R("AZ","az") local alphanumeric = R("AZ","az","09") local keyword = letter * alphanumeric^0 + local punctuation = S("!?,.:;") local doubleasterisks = P("**") local doubleunderscores = P("__") @@ -483,7 +499,8 @@ function M.reader.new(writer, options) local fail = any - 1 local always = P("") - local escapable = S("\\`*_{}[]()+_.!<>#-~:^") + local escapable = S("\\`*_{}[]()+_.!<>#-~:^@;") + local anyescaped = P("\\") / "" * escapable + any @@ -494,17 +511,14 @@ function M.reader.new(writer, options) local nonspacechar = any - spacing local tightblocksep = P("\001") - local specialchar - if options.smartEllipses then - specialchar = S("*_`&[]<!\\.") - else - specialchar = S("*_`&[]<!\\") - end + local specialchar = S("*_`&[]<!\\.@-") local normalchar = any - (specialchar + spacing + tightblocksep) local optionalspace = spacechar^0 - local spaces = spacechar^1 + local optionalspaceor = function(pattern) + return (spacechar + pattern)^0 + end local eof = - any local nonindentspace = space^-3 * - spacechar local indent = space^-3 * tab @@ -518,6 +532,10 @@ function M.reader.new(writer, options) local optionallyindentedline = indent^-1 /"" * C(linechar^1 * newline^-1) local sp = spacing^0 local spnl = optionalspace * (newline * optionalspace)^-1 + local spnlor = function(pattern) + local optional = optionalspaceor(pattern) + return optional * (newline * optional)^-1 + end local line = linechar^0 * newline + linechar^1 * eof local nonemptyline = line - blankline @@ -529,7 +547,7 @@ function M.reader.new(writer, options) local function indented_blocks(bl) return Cs( bl * (blankline^1 * indent * -blankline * bl)^0 - * blankline^1 ) + * (blankline^1 + eof) ) end local bulletchar = C(plus + asterisk + dash) @@ -565,7 +583,36 @@ function M.reader.new(writer, options) + (space - closeticks) + (backtick^1 - closeticks) - local inticks = openticks * space^-1 * C(intickschar^1) * closeticks + local inticks = openticks * space^-1 * C(intickschar^0) * closeticks + local function captures_geq_length(s,i,a,b) + return #a >= #b and i + end + + local infostring = (linechar - (backtick + space^1 * (newline + eof)))^0 + + local fenceindent + local function fencehead(char) + return C(nonindentspace) / function(s) fenceindent = #s end + * Cg(char^3, "fencelength") + * optionalspace * C(infostring) * optionalspace + * (newline + eof) + end + + local function fencetail(char) + return nonindentspace + * Cmt(C(char^3) * Cb("fencelength"), + captures_geq_length) + * optionalspace * (newline + eof) + + eof + end + + local function fencedline(char) + return C(line - fencetail(char)) + / function(s) + return s:gsub("^" .. string.rep(" ?", + fenceindent), "") + end + end local leader = space^-3 -- in balanced brackets, parentheses, quotes: @@ -616,6 +663,38 @@ function M.reader.new(writer, options) local optionaltitle = spnl * title * spacechar^0 + Cc("") + local citation_name = (Cs(dash^-1) + * at * Cs((anyescaped + - (rbracket + spacing + punctuation + semicolon))^1)) + + local citation_body_prenote + = Cs((alphanumeric^1 + + bracketed + + inticks + + (anyescaped + - (rbracket + semicolon + blankline^2)) + - (spnl * dash^-1 * at))^0) + + local citation_body_postnote + = Cs((alphanumeric^1 + + bracketed + + inticks + + (anyescaped + - (rbracket + semicolon + blankline^2)) + - (spnl * rbracket))^0) + + local citation_body_chunk + = citation_body_prenote + * spnl * citation_name + * spnlor(punctuation - (semicolon + rbracket)) + * citation_body_postnote + + local citation_body = citation_body_chunk + * (semicolon * spnl * citation_body_chunk)^0 + + local citation_headless_body + = citation_body_postnote + * (sp * semicolon * spnl * citation_body_chunk)^0 local rawnotes = {} local function strip_first_char(s) @@ -627,7 +706,7 @@ function M.reader.new(writer, options) return function() local found = rawnotes[normalize_tag(ref)] if found then - return writer.note(parse_blocks(found)) + return writer.note(parse_blocks_toplevel(found)) else return {"[", parse_inlines("^" .. ref), "]"} end @@ -713,21 +792,10 @@ function M.reader.new(writer, options) end end end - local Inline = V("Inline") - - local Str = normalchar^1 / writer.string - - local Ellipsis = P("...") / writer.ellipsis - - local Smart = Ellipsis - - local Symbol = (specialchar - tightblocksep) / writer.string - - local Code = inticks / writer.code - local bqstart = more local headerstart = hash + (line * (equal^1 + dash^1) * optionalspace * newline) + local fencestart = fencehead(backtick) + fencehead(tilde) if options.blankBeforeBlockquote then bqstart = fail @@ -737,24 +805,41 @@ function M.reader.new(writer, options) headerstart = fail end + if not options.fencedCode or options.blankBeforeCodeFence then + fencestart = fail + end + local Inline = V("Inline") + + local Str = normalchar^1 / writer.string + + local Symbol = (specialchar - tightblocksep) / writer.string + local Ellipsis = P("...") / writer.ellipsis + + local Smart = Ellipsis + local Code = inticks / writer.code local Endline = newline * -( -- newline, but not before... blankline -- paragraph break + tightblocksep -- nested list + eof -- end of document + bqstart + headerstart + + fencestart ) * spacechar^0 / writer.space local Space = spacechar^2 * Endline / writer.linebreak + spacechar^1 * Endline^-1 * eof / "" + spacechar^1 * Endline^-1 * optionalspace / writer.space + local NonbreakingSpace + = spacechar^2 * Endline / writer.linebreak + + spacechar^1 * Endline^-1 * eof / "" + + spacechar^1 * Endline^-1 * optionalspace / writer.nbsp + -- parse many p between starter and ender local function between(p, starter, ender) local ender2 = B(nonspacechar) * ender return (starter * #nonspacechar * Ct(p * (p - ender2)^0) * ender2) end - local Strong = ( between(Inline, doubleasterisks, doubleasterisks) + between(Inline, doubleunderscores, doubleunderscores) ) / writer.strong @@ -762,7 +847,6 @@ function M.reader.new(writer, options) local Emph = ( between(Inline, asterisk, asterisk) + between(Inline, underscore, underscore) ) / writer.emphasis - local urlchar = anyescaped - newline - more local AutoLinkUrl = less @@ -792,7 +876,6 @@ function M.reader.new(writer, options) -- parse a link or image (direct or indirect) local Link = DirectLink + IndirectLink - local DirectImage = exclamation * (tag / parse_inlines) * spnl @@ -806,43 +889,89 @@ function M.reader.new(writer, options) indirect_image local Image = DirectImage + IndirectImage - -- avoid parsing long strings of * or _ as emph/strong local UlOrStarLine = asterisk^4 + underscore^4 / writer.string local EscapedChar = S("\\") * C(escapable) / writer.string + local function citations(text_cites, raw_cites) + local function normalize(str) + if str == "" then + str = nil + else + str = (options.citationNbsps and parse_inlines_nbsp or + parse_inlines)(str) + end + return str + end + + local cites = {} + for i = 1,#raw_cites,4 do + cites[#cites+1] = { + prenote = normalize(raw_cites[i]), + suppress_author = raw_cites[i+1] == "-", + name = writer.string(raw_cites[i+2]), + postnote = normalize(raw_cites[i+3]), + } + end + return writer.citations(text_cites, cites) + end + + local TextCitations = Ct(Cc("") + * citation_name + * ((spnl + * lbracket + * citation_headless_body + * rbracket) + Cc(""))) / + function(raw_cites) + return citations(true, raw_cites) + end + + local ParenthesizedCitations + = Ct(lbracket + * citation_body + * rbracket) / + function(raw_cites) + return citations(false, raw_cites) + end + + local Citations = TextCitations + ParenthesizedCitations local Block = V("Block") local Verbatim = Cs( (blanklines * ((indentedline - blankline))^1)^1 ) / expandtabs / writer.verbatim + local TildeFencedCode + = fencehead(tilde) + * Cs(fencedline(tilde)^0) + * fencetail(tilde) + + local BacktickFencedCode + = fencehead(backtick) + * Cs(fencedline(backtick)^0) + * fencetail(backtick) + + local FencedCode = (TildeFencedCode + BacktickFencedCode) + / function(infostring, code) + return writer.fencedCode( + writer.string(infostring), + expandtabs(code)) + end -- strip off leading > and indents, and run through blocks local Blockquote = Cs(( ((leader * more * space^-1)/"" * linechar^0 * newline)^1 * (-blankline * linechar^1 * newline)^0 - * blankline^0 - )^1) / parse_blocks / writer.blockquote + * (blankline^0 / "") + )^1) / parse_blocks_toplevel / writer.blockquote local function lineof(c) - return (leader * (P(c) * optionalspace)^3 * newline * blankline^1) + return (leader * (P(c) * optionalspace)^3 * (newline * blankline^1 + + newline^-1 * eof)) end - local HorizontalRule = ( lineof(asterisk) + lineof(dash) + lineof(underscore) ) / writer.hrule - - local Reference = define_reference_parser / register_link - - local Paragraph = nonindentspace * Ct(Inline^1) * newline - * ( blankline^1 - + #hash - + #(leader * more * space^-1) - ) - / writer.paragraph - - local Plain = nonindentspace * Ct(Inline^1) / writer.plain local starter = bullet + enumerator -- we use \001 as a separator between a tight list item and a @@ -913,7 +1042,7 @@ function M.reader.new(writer, options) local DefinitionListItemLoose = C(line) * skipblanklines * Ct((defstart * indented_blocks(dlchunk) / - parse_blocks)^1) + parse_blocks_toplevel)^1) * Cc(false) / definition_list_item @@ -928,10 +1057,29 @@ function M.reader.new(writer, options) * (skipblanklines * -DefinitionListItemLoose * Cc(true)) ) / writer.definitionlist + local Reference = define_reference_parser / register_link local Blank = blankline / "" + NoteBlock + Reference + (tightblocksep / "\n") + local Paragraph = nonindentspace * Ct(Inline^1) * newline + * ( blankline^1 + + #hash + + #(leader * more * space^-1) + ) + / writer.paragraph + + local ToplevelParagraph + = nonindentspace * Ct(Inline^1) * (newline + * ( blankline^1 + + #hash + + #(leader * more * space^-1) + + eof + ) + + eof ) + / writer.paragraph + + local Plain = nonindentspace * Ct(Inline^1) / writer.plain -- parse Atx heading start and return level local HeadingStart = #hash * C(hash^-6) * -hash / length @@ -955,6 +1103,8 @@ function M.reader.new(writer, options) * HeadingLevel * optionalspace * newline / writer.heading + + local Heading = AtxHeading + SetextHeading syntax = { "Blocks", @@ -970,6 +1120,7 @@ function M.reader.new(writer, options) Block = V("Blockquote") + V("Verbatim") + + V("FencedCode") + V("HorizontalRule") + V("BulletList") + V("OrderedList") @@ -980,10 +1131,11 @@ function M.reader.new(writer, options) Blockquote = Blockquote, Verbatim = Verbatim, + FencedCode = FencedCode, HorizontalRule = HorizontalRule, BulletList = BulletList, OrderedList = OrderedList, - Heading = AtxHeading + SetextHeading, + Heading = Heading, DefinitionList = DefinitionList, DisplayHtml = DisplayHtml, Paragraph = Paragraph, @@ -996,6 +1148,7 @@ function M.reader.new(writer, options) + V("Strong") + V("Emph") + V("NoteRef") + + V("Citations") + V("Link") + V("Image") + V("Code") @@ -1012,6 +1165,7 @@ function M.reader.new(writer, options) Strong = Strong, Emph = Emph, NoteRef = NoteRef, + Citations = Citations, Link = Link, Image = Image, Code = Code, @@ -1028,6 +1182,14 @@ function M.reader.new(writer, options) syntax.DefinitionList = fail end + if not options.fencedCode then + syntax.FencedCode = fail + end + + if not options.citations then + syntax.Citations = fail + end + if not options.footnotes then syntax.NoteRef = fail end @@ -1036,6 +1198,10 @@ function M.reader.new(writer, options) syntax.Smart = fail end + local blocks_toplevel_t = util.table_copy(syntax) + blocks_toplevel_t.Paragraph = ToplevelParagraph + blocks_toplevel = Ct(blocks_toplevel_t) + blocks = Ct(syntax) local inlines_t = util.table_copy(syntax) @@ -1043,9 +1209,13 @@ function M.reader.new(writer, options) inlines_t.Inlines = Inline^0 * (spacing^0 * eof / "") inlines = Ct(inlines_t) - inlines_no_link_t = util.table_copy(inlines_t) + local inlines_no_link_t = util.table_copy(inlines_t) inlines_no_link_t.Link = fail inlines_no_link = Ct(inlines_no_link_t) + + local inlines_nbsp_t = util.table_copy(inlines_t) + inlines_nbsp_t.Space = NonbreakingSpace + inlines_nbsp = Ct(inlines_nbsp_t) function self.convert(input) references = {} local opt_string = {} @@ -1056,9 +1226,9 @@ function M.reader.new(writer, options) end end table.sort(opt_string) - local salt = table.concat(opt_string, ",") + local salt = table.concat(opt_string, ",") .. "," .. metadata.version local name = util.cache(options.cacheDir, input, salt, function(input) - return util.rope_to_string(parse_blocks(input)) .. writer.eof + return util.rope_to_string(parse_blocks_toplevel(input)) .. writer.eof end, ".md" .. writer.suffix) return writer.pack(name) end |