summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2016-06-11 23:15:05 +0000
committerKarl Berry <karl@freefriends.org>2016-06-11 23:15:05 +0000
commita0bab753834e0c87c19800c7748fccccee26b4be (patch)
tree24455a5f82eed5399e434c1ff8f7acefbef5e85e /Master/texmf-dist/tex
parentc636c196ee98440b64ff0252aec19b5d800b749f (diff)
markdown (6jun16)
git-svn-id: svn://tug.org/texlive/trunk@41376 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r--Master/texmf-dist/tex/context/third/markdown/t-markdown.tex140
-rw-r--r--Master/texmf-dist/tex/generic/markdown/markdown.tex392
-rw-r--r--Master/texmf-dist/tex/latex/markdown/markdown.sty331
-rw-r--r--Master/texmf-dist/tex/luatex/markdown/markdown.lua1057
4 files changed, 1920 insertions, 0 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
new file mode 100644
index 00000000000..115836433e6
--- /dev/null
+++ b/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex
@@ -0,0 +1,140 @@
+%%
+%% This is file `t-markdown.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% markdown.dtx (with options: `context')
+%%
+%% Copyright (C) 2016 Vít Novotný
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Vít Novotný.
+%%
+%% Send bug reports, requests for additions and questions
+%% either to the GitHub issue tracker at
+%%
+%% https://github.com/Witiko/markdown/issues
+%%
+%% or to the e-mail address <witiko@mail.muni.cz>.
+%%
+%% MODIFICATION ADVICE:
+%%
+%% If you want to customize this file, it is best to make a copy of
+%% the source file(s) from which it was produced. Use a different
+%% name for your copy(ies) and modify the copy(ies); this will ensure
+%% that your modifications do not get overwritten when you install a
+%% new release of the standard system. You should also ensure that
+%% your modified source file does not generate any modified file with
+%% the same name as a standard file.
+%%
+%% You will also need to produce your own, suitably named, .ins file to
+%% control the generation of files from your source file; this file
+%% should contain your own preambles for the files it generates, not
+%% those in the standard .ins files.
+%%
+%% The names of the source files used are shown above.
+%%
+\writestatus{loading}{ConTeXt User Module / markdown}%
+\unprotect
+\let\startmarkdown\relax
+\let\stopmarkdown\relax
+\def\dospecials{\do\ \do\\\do\{\do\}\do\$\do\&%
+ \do\#\do\^\do\_\do\%\do\~}%
+\ifx\directlua\undefined
+ \input markdown
+\else
+ \directlua{%
+ local function unescape(str)
+ return (str:gsub("|", string.char(92))) end
+ local old_callback = callback.find("process_input_buffer")
+ callback.register("process_input_buffer", function() end)
+ local new_callback = callback.find("process_input_buffer")
+ if new_callback == false then
+ tex.print(unescape([[|let|markdownDirectLua|directlua
+ |let|directlua|undefined
+ |input markdown
+ |let|directlua|markdownDirectLua
+ |let|markdownDirectLua|undefined]]))
+ else
+ callback.register("process_input_buffer", old_callback)
+ tex.print(unescape("|input markdown"))
+ end}%
+\fi
+\def\markdownInfo#1{\writestatus{markdown}{#1.}}%
+\def\markdownWarning#1{\writestatus{markdown\space warn}{#1.}}%
+\begingroup
+ \catcode`\|=0%
+ \catcode`\\=12%
+ |gdef|startmarkdown{%
+ |markdownReadAndConvert{\stopmarkdown}%
+ {|stopmarkdown}}%
+|endgroup
+\def\markdownRendererLineBreakPrototype{\blank}%
+\long\def\markdownRendererLinkPrototype#1#2#3{%
+ \useURL[#1][#2][][#3]#1\footnote[#1]{\ifx\empty#3\empty\else#3:
+ \fi\tt<\hyphenatedurl{#2}>}}%
+\long\def\markdownRendererImagePrototype#1#2#3{%
+ \placefigure[][fig:#1]{#3}{\externalfigure[#2]}}%
+\def\markdownRendererUlBeginPrototype{\startitemize}%
+\def\markdownRendererUlBeginTightPrototype{\startitemize[packed]}%
+\def\markdownRendererUlItemPrototype{\item}%
+\def\markdownRendererUlEndPrototype{\stopitemize}%
+\def\markdownRendererUlEndTightPrototype{\stopitemize}%
+\def\markdownRendererOlBeginPrototype{\startitemize[n]}%
+\def\markdownRendererOlBeginTightPrototype{\startitemize[packed,n]}%
+\def\markdownRendererOlItemPrototype{\item}%
+\long\def\markdownRendererOlItemWithNumberPrototype#1{\sym{#1.}}%
+\def\markdownRendererOlEndPrototype{\stopitemize}%
+\def\markdownRendererOlEndTightPrototype{\stopitemize}%
+\definedescription
+ [markdownConTeXtDlItemPrototype]
+ [location=hanging,
+ margin=standard,
+ headstyle=bold]%
+\definestartstop
+ [MarkdownConTeXtDlPrototype]
+ [before=\blank,
+ after=\blank]%
+\definestartstop
+ [MarkdownConTeXtDlTightPrototype]
+ [before=\blank\startpacked,
+ after=\stoppacked\blank]%
+\def\markdownRendererDlBeginPrototype{%
+ \startMarkdownConTeXtDlPrototype}%
+\def\markdownRendererDlBeginTightPrototype{%
+ \startMarkdownConTeXtDlTightPrototype}%
+\long\long\def\markdownRendererDlItemPrototype#1{%
+ \markdownConTeXtDlItemPrototype{#1}}%
+\def\markdownRendererDlEndPrototype{%
+ \stopMarkdownConTeXtDlPrototype}%
+\def\markdownRendererDlEndTightPrototype{%
+ \stopMarkdownConTeXtDlTightPrototype}%
+\long\def\markdownRendererEmphasisPrototype#1{{\em#1}}%
+\long\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\markdownRendererHorizontalRulePrototype{%
+ \blackrule[height=1pt, width=\hsize]}%
+\long\def\markdownRendererFootnotePrototype#1{\footnote{#1}}%
+\stopmodule\protect
+\endinput
+%%
+%% End of file `t-markdown.tex'.
diff --git a/Master/texmf-dist/tex/generic/markdown/markdown.tex b/Master/texmf-dist/tex/generic/markdown/markdown.tex
new file mode 100644
index 00000000000..1a90792aacf
--- /dev/null
+++ b/Master/texmf-dist/tex/generic/markdown/markdown.tex
@@ -0,0 +1,392 @@
+%%
+%% This is file `markdown.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% markdown.dtx (with options: `tex')
+%%
+%% Copyright (C) 2016 Vít Novotný
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Vít Novotný.
+%%
+%% Send bug reports, requests for additions and questions
+%% either to the GitHub issue tracker at
+%%
+%% https://github.com/Witiko/markdown/issues
+%%
+%% or to the e-mail address <witiko@mail.muni.cz>.
+%%
+%% MODIFICATION ADVICE:
+%%
+%% If you want to customize this file, it is best to make a copy of
+%% the source file(s) from which it was produced. Use a different
+%% name for your copy(ies) and modify the copy(ies); this will ensure
+%% that your modifications do not get overwritten when you install a
+%% new release of the standard system. You should also ensure that
+%% your modified source file does not generate any modified file with
+%% the same name as a standard file.
+%%
+%% You will also need to produce your own, suitably named, .ins file to
+%% control the generation of files from your source file; this file
+%% should contain your own preambles for the files it generates, not
+%% those in the standard .ins files.
+%%
+%% The names of the source files used are shown above.
+%%
+\def\markdownVersion{2016/06/03}%
+\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}%
+\let\markdownOptionBlankBeforeBlockquote\undefined
+\let\markdownOptionBlankBeforeHeading\undefined
+\let\markdownOptionDefinitionLists\undefined
+\let\markdownOptionHashEnumerator\undefined
+\let\markdownOptionHybrid\undefined
+\let\markdownOptionFootnotes\undefined
+\let\markdownOptionPreserveTabs\undefined
+\let\markdownOptionSmartEllipses\undefined
+\let\markdownOptionStartNumber\undefined
+\let\markdownOptionTightLists\undefined
+\def\markdownRendererLineBreak{%
+ \markdownRendererLineBreakPrototype}%
+\def\markdownRendererEllipsis{%
+ \markdownRendererEllipsisPrototype}%
+\def\markdownRendererCodeSpan{%
+ \markdownRendererCodeSpanPrototype}%
+\def\markdownRendererLink{%
+ \markdownRendererLinkPrototype}%
+\def\markdownRendererImage{%
+ \markdownRendererImagePrototype}%
+\def\markdownRendererUlBegin{%
+ \markdownRendererUlBeginPrototype}%
+\def\markdownRendererUlBeginTight{%
+ \markdownRendererUlBeginTightPrototype}%
+\def\markdownRendererUlItem{%
+ \markdownRendererUlItemPrototype}%
+\def\markdownRendererUlEnd{%
+ \markdownRendererUlEndPrototype}%
+\def\markdownRendererUlEndTight{%
+ \markdownRendererUlEndTightPrototype}%
+\def\markdownRendererOlBegin{%
+ \markdownRendererOlBeginPrototype}%
+\def\markdownRendererOlBeginTight{%
+ \markdownRendererOlBeginTightPrototype}%
+\def\markdownRendererOlItem{%
+ \markdownRendererOlItemPrototype}%
+\def\markdownRendererOlItemWithNumber{%
+ \markdownRendererOlItemWithNumberPrototype}%
+\def\markdownRendererOlEnd{%
+ \markdownRendererOlEndPrototype}%
+\def\markdownRendererOlEndTight{%
+ \markdownRendererOlEndTightPrototype}%
+\def\markdownRendererDlBegin{%
+ \markdownRendererDlBeginPrototype}%
+\def\markdownRendererDlBeginTight{%
+ \markdownRendererDlBeginTightPrototype}%
+\def\markdownRendererDlItem{%
+ \markdownRendererDlItemPrototype}%
+\def\markdownRendererDlEnd{%
+ \markdownRendererDlEndPrototype}%
+\def\markdownRendererDlEndTight{%
+ \markdownRendererDlEndTightPrototype}%
+\def\markdownRendererEmphasis{%
+ \markdownRendererEmphasisPrototype}%
+\def\markdownRendererStrongEmphasis{%
+ \markdownRendererStrongEmphasisPrototype}%
+\def\markdownRendererBlockQuoteBegin{%
+ \markdownRendererBlockQuoteBeginPrototype}%
+\def\markdownRendererBlockQuoteEnd{%
+ \markdownRendererBlockQuoteEndPrototype}%
+\def\markdownRendererInputVerbatim{%
+ \markdownRendererInputVerbatimPrototype}%
+\def\markdownRendererHeadingOne{%
+ \markdownRendererHeadingOnePrototype}%
+\def\markdownRendererHeadingTwo{%
+ \markdownRendererHeadingTwoPrototype}%
+\def\markdownRendererHeadingThree{%
+ \markdownRendererHeadingThreePrototype}%
+\def\markdownRendererHeadingFour{%
+ \markdownRendererHeadingFourPrototype}%
+\def\markdownRendererHeadingFive{%
+ \markdownRendererHeadingFivePrototype}%
+\def\markdownRendererHeadingSix{%
+ \markdownRendererHeadingSixPrototype}%
+\def\markdownRendererHorizontalRule{%
+ \markdownRendererHorizontalRulePrototype}%
+\def\markdownRendererFootnote{%
+ \markdownRendererFootnotePrototype}%
+\def\markdownRendererLineBreakPrototype{}%
+\def\markdownRendererEllipsisPrototype{}%
+\long\def\markdownRendererCodeSpanPrototype#1{}%
+\long\def\markdownRendererLinkPrototype#1#2#3{}%
+\long\def\markdownRendererImagePrototype#1#2#3{}%
+\def\markdownRendererUlBeginPrototype{}%
+\def\markdownRendererUlBeginTightPrototype{}%
+\def\markdownRendererUlItemPrototype{}%
+\def\markdownRendererUlEndPrototype{}%
+\def\markdownRendererUlEndTightPrototype{}%
+\def\markdownRendererOlBeginPrototype{}%
+\def\markdownRendererOlBeginTightPrototype{}%
+\def\markdownRendererOlItemPrototype{}%
+\long\def\markdownRendererOlItemWithNumberPrototype#1{}%
+\def\markdownRendererOlEndPrototype{}%
+\def\markdownRendererOlEndTightPrototype{}%
+\def\markdownRendererDlBeginPrototype{}%
+\def\markdownRendererDlBeginTightPrototype{}%
+\long\def\markdownRendererDlItemPrototype#1{}%
+\def\markdownRendererDlEndPrototype{}%
+\def\markdownRendererDlEndTightPrototype{}%
+\long\def\markdownRendererEmphasisPrototype#1{}%
+\long\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\markdownRendererHorizontalRulePrototype{}%
+\long\def\markdownRendererFootnotePrototype#1{}%
+\def\markdownInfo#1{}%
+\def\markdownWarning#1{}%
+\def\markdownError#1{}%
+\def\markdownLuaRegisterIBCallback#1{%
+ local old_callback = callback.find("process_input_buffer")
+ callback.register("process_input_buffer", #1)}%
+\def\markdownLuaUnregisterIBCallback{%
+ callback.register("process_input_buffer", old_callback)}%
+\let\markdownMakeOther\relax
+\let\markdownReadAndConvert\relax
+\begingroup
+ \catcode`\|=0\catcode`\\=12%
+ |gdef|markdownBegin{%
+ |markdownReadAndConvert{\markdownEnd}%
+ {|markdownEnd}}%
+|endgroup
+\def\markdownInfo#1{%
+ \message{(l.\the\inputlineno) markdown.tex info: #1.}}%
+\def\markdownWarning#1{%
+ \message{(l.\the\inputlineno) markdown.tex warning: #1}}%
+\def\markdownError#1#2{%
+ \errhelp{#2.}%
+ \errmessage{(l.\the\inputlineno) markdown.tex error: #1}}%
+\def\markdownRendererLineBreakPrototype{\hfil\break}%
+\let\markdownRendererEllipsisPrototype\dots
+\long\def\markdownRendererCodeSpanPrototype#1{{\tt#1}}%
+\long\def\markdownRendererLinkPrototype#1#2#3{#1}%
+\long\def\markdownRendererImagePrototype#1#2#3{#1}%
+\def\markdownRendererUlBeginPrototype{}%
+\def\markdownRendererUlBeginTightPrototype{}%
+\def\markdownRendererUlItemPrototype{}%
+\def\markdownRendererUlEndPrototype{}%
+\def\markdownRendererUlEndTightPrototype{}%
+\def\markdownRendererOlBeginPrototype{}%
+\def\markdownRendererOlBeginTightPrototype{}%
+\def\markdownRendererOlItemPrototype{}%
+\long\def\markdownRendererOlItemWithNumberPrototype#1{}%
+\def\markdownRendererOlEndPrototype{}%
+\def\markdownRendererOlEndTightPrototype{}%
+\def\markdownRendererDlBeginPrototype{}%
+\def\markdownRendererDlBeginTightPrototype{}%
+\long\def\markdownRendererDlItemPrototype#1{#1}%
+\def\markdownRendererDlEndPrototype{}%
+\def\markdownRendererDlEndTightPrototype{}%
+\long\def\markdownRendererEmphasisPrototype#1{{\it#1}}%
+\long\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\markdownRendererHorizontalRulePrototype{}%
+\long\def\markdownRendererFootnotePrototype#1{#1}%
+\def\markdownLuaOptions{{%
+ \ifx\markdownOptionBlankBeforeBlockquote\undefined\else
+ blankBeforeBlockquote = \markdownOptionBlankBeforeBlockquote,
+ \fi
+ \ifx\markdownOptionBlankBeforeHeading\undefined\else
+ blankBeforeHeading = \markdownOptionBlankBeforeHeading,
+ \fi
+ \ifx\markdownOptionCacheDir\undefined\else
+ cacheDir = "\markdownOptionCacheDir",
+ \fi
+ \ifx\markdownOptionDefinitionLists\undefined\else
+ definitionLists = \markdownOptionDefinitionLists,
+ \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
+ \ifx\markdownOptionSmartEllipses\undefined\else
+ smartEllipses = \markdownOptionSmartEllipses,
+ \fi
+ \ifx\markdownOptionStartNumber\undefined\else
+ startNumber = \markdownOptionStartNumber,
+ \fi
+ \ifx\markdownOptionTightLists\undefined\else
+ tightLists = \markdownOptionTightLists,
+ \fi}
+}%
+\def\markdownPrepare{%
+ local lfs = require("lfs")
+ local cacheDir = "\markdownOptionCacheDir"
+ if lfs.isdir(cacheDir) == true then else
+ assert(lfs.mkdir(cacheDir))
+ end
+ local md = require("markdown")
+ local convert = md.new(\markdownLuaOptions)
+}%
+\ifx\directlua\undefined
+ \csname newwrite\endcsname\markdownLuaExecuteFileStream
+ \csname newcount\endcsname\markdownLuaExecuteShellEscape
+ \ifx\pdfshellescape\undefined
+ \ifx\shellescape\undefined
+ \markdownLuaExecuteShellEscape=1%
+ \else
+ \markdownLuaExecuteShellEscape=\shellescape
+ \fi
+ \else
+ \markdownLuaExecuteShellEscape=\pdfshellescape
+ \fi
+ \def\markdownLuaExecute#1{%
+ \ifnum\markdownLuaExecuteShellEscape=1%
+ \immediate\openout\markdownLuaExecuteFileStream=%
+ \markdownOptionHelperScriptFileName
+ \markdownInfo{Writing a helper Lua script to the file
+ "\markdownOptionHelperScriptFileName"}%
+ \immediate\write\markdownLuaExecuteFileStream{%
+ local kpse = require('kpse')
+ kpse.set_program_name('luatex') #1}%
+ \immediate\closeout\markdownLuaExecuteFileStream
+ \markdownInfo{Executing a helper Lua script from the file
+ "\markdownOptionHelperScriptFileName" and storing the result in the
+ file "\markdownOptionOutputTempFileName"}%
+ \immediate\write18{texlua "\markdownOptionHelperScriptFileName" >
+ "\markdownOptionOutputTempFileName"}%
+ \input\markdownOptionOutputTempFileName\relax
+ \else
+ \markdownError{I can not access the shell}{Either run the TeX
+ compiler with the --shell-escape or the --enable-write18 flag,
+ or set shell_escape=t in the texmf.cnf file}%
+ \fi}%
+ \begingroup
+ \catcode`\^^I=12%
+ \gdef\markdownReadAndConvertTab{^^I}%
+ \endgroup
+ \begingroup
+ \catcode`\^^M=13%
+ \catcode`\^^I=13%
+ \catcode`|=0%
+ \catcode`\\=12%
+ |gdef|markdownReadAndConvert#1#2{%
+ |begingroup%
+ |immediate|openout|markdownLuaExecuteFileStream%
+ |markdownOptionInputTempFileName%
+ |markdownInfo{Buffering markdown input into the temporary %
+ input file "|markdownOptionInputTempFileName" and scanning %
+ for the closing token sequence "#1"}%
+ |def|do##1{|catcode`##1=12}|dospecials%
+ |catcode`| =12%
+ |markdownMakeOther%
+ |def|markdownReadAndConvertProcessLine##1#1##2#1##3|relax{%
+ |ifx|relax##3|relax%
+ |immediate|write|markdownLuaExecuteFileStream{##1}%
+ |else%
+ |def^^M{%
+ |markdownInfo{The ending token sequence was found}%
+ |immediate|write|markdownLuaExecuteFileStream{}%
+ |immediate|closeout|markdownLuaExecuteFileStream%
+ |endgroup%
+ |markdownInput|markdownOptionInputTempFileName%
+ #2}%
+ |fi%
+ ^^M}%
+ |catcode`|^^I=13%
+ |def^^I{|markdownReadAndConvertTab}%
+ |catcode`|^^M=13%
+ |def^^M##1^^M{%
+ |def^^M####1^^M{%
+ |markdownReadAndConvertProcessLine####1#1#1|relax}%
+ ^^M}%
+ ^^M}%
+ |endgroup
+\else
+ \def\markdownLuaExecute#1{\directlua{local print = tex.print #1}}%
+ \begingroup
+ \catcode`\_=12%
+ \catcode`\$=12%
+ \catcode`\^=12%
+ \catcode`\/=6%
+ \catcode`\#=12%
+ \catcode`\@=14%
+ \catcode`\%=12%
+ \catcode`|=0@
+ \catcode`\\=12@
+ |gdef|markdownReadAndConvert/1/2{@
+ |def|markdownReadAndConvertAfter{/2}@
+ |markdownInfo{Buffering markdown input and scanning for the
+ closing token sequence "/1"}@
+ |directlua{@
+ |markdownPrepare
+ local buffer = {}
+ local ending_sequence = "^.-" .. ([[/1]]):gsub(
+ "([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1")
+ |markdownLuaRegisterIBCallback{function(line)
+ if line:match(ending_sequence) then
+ |markdownLuaUnregisterIBCallback
+ local input = table.concat(buffer, "\n") .. "\n\n"
+ local output = convert(input)
+ return [[\markdownInfo{The ending token sequence was found}]] ..
+ output .. [[\markdownReadAndConvertAfter]]
+ else
+ buffer[#buffer+1] = line
+ return [[\]] .. (#buffer == 1 and "fi" or "relax")
+ end
+ end}}@
+ |iffalse}@
+ |endgroup
+\fi
+\begingroup
+ \catcode`|=0%
+ \catcode`\\=12%
+ |gdef|markdownInput#1{%
+ |markdownInfo{Including markdown document "#1"}%
+ |markdownLuaExecute{%
+ |markdownPrepare
+ local input = assert(io.open("#1","r")):read("*a") .. "\n\n"
+ print(convert(input:gsub("\r\n?", "\n")))}}%
+|endgroup
+\endinput
+%%
+%% End of file `markdown.tex'.
diff --git a/Master/texmf-dist/tex/latex/markdown/markdown.sty b/Master/texmf-dist/tex/latex/markdown/markdown.sty
new file mode 100644
index 00000000000..c568c8212b5
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/markdown/markdown.sty
@@ -0,0 +1,331 @@
+%%
+%% This is file `markdown.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% markdown.dtx (with options: `latex')
+%%
+%% Copyright (C) 2016 Vít Novotný
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Vít Novotný.
+%%
+%% Send bug reports, requests for additions and questions
+%% either to the GitHub issue tracker at
+%%
+%% https://github.com/Witiko/markdown/issues
+%%
+%% or to the e-mail address <witiko@mail.muni.cz>.
+%%
+%% MODIFICATION ADVICE:
+%%
+%% If you want to customize this file, it is best to make a copy of
+%% the source file(s) from which it was produced. Use a different
+%% name for your copy(ies) and modify the copy(ies); this will ensure
+%% that your modifications do not get overwritten when you install a
+%% new release of the standard system. You should also ensure that
+%% your modified source file does not generate any modified file with
+%% the same name as a standard file.
+%%
+%% You will also need to produce your own, suitably named, .ins file to
+%% control the generation of files from your source file; this file
+%% should contain your own preambles for the files it generates, not
+%% those in the standard .ins files.
+%%
+%% The names of the source files used are shown above.
+%%
+\NeedsTeXFormat{LaTeX2e}%
+\newenvironment{markdown}\relax\relax
+\newenvironment{markdown*}[1]\relax\relax
+\newcommand\markdownSetup[1]{%
+ \setkeys{markdownOptions}{#1}}%
+\RequirePackage{keyval}
+\define@key{markdownOptions}{helperScriptFileName}{%
+ \def\markdownOptionHelperScriptFileName{#1}}%
+\define@key{markdownOptions}{inputTempFileName}{%
+ \def\markdownOptionInputTempFileName{#1}}%
+\define@key{markdownOptions}{outputTempFileName}{%
+ \def\markdownOptionOutputTempFileName{#1}}%
+\define@key{markdownOptions}{blankBeforeBlockquote}[true]{%
+ \def\markdownOptionBlankBeforeBlockquote{#1}}%
+\define@key{markdownOptions}{blankBeforeHeading}[true]{%
+ \def\markdownOptionBlankBeforeHeading{#1}}%
+\define@key{markdownOptions}{cacheDir}{%
+ \def\markdownOptionCacheDir{#1}}%
+\define@key{markdownOptions}{definitionLists}[true]{%
+ \def\markdownOptionDefinitionLists{#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]{%
+ \def\markdownOptionSmartEllipses{#1}}%
+\define@key{markdownOptions}{startNumber}[true]{%
+ \def\markdownOptionStartNumber{#1}}%
+\define@key{markdownOptions}{tightLists}[true]{%
+ \def\markdownOptionTightLists{#1}}%
+\define@key{markdownOptions}{renderers}{%
+ \setkeys{markdownRenderers}{#1}}%
+\define@key{markdownRenderers}{lineBreak}{%
+ \renewcommand\markdownRendererLineBreak{#1}}%
+\define@key{markdownRenderers}{ellipsis}{%
+ \renewcommand\markdownRendererEllipsis{#1}}%
+\define@key{markdownRenderers}{codeSpan}{%
+ \renewcommand\markdownRendererCodeSpan[1]{#1}}%
+\define@key{markdownRenderers}{link}{%
+ \renewcommand\markdownRendererLink[3]{#1}}%
+\define@key{markdownRenderers}{image}{%
+ \renewcommand\markdownRendererImage[3]{#1}}%
+\define@key{markdownRenderers}{ulBegin}{%
+ \renewcommand\markdownRendererUlBegin{#1}}%
+\define@key{markdownRenderers}{ulBeginTight}{%
+ \renewcommand\markdownRendererUlBeginTight{#1}}%
+\define@key{markdownRenderers}{ulItem}{%
+ \renewcommand\markdownRendererUlItem{#1}}%
+\define@key{markdownRenderers}{ulEnd}{%
+ \renewcommand\markdownRendererUlEnd{#1}}%
+\define@key{markdownRenderers}{ulEndTight}{%
+ \renewcommand\markdownRendererUlEndTight{#1}}%
+\define@key{markdownRenderers}{olBegin}{%
+ \renewcommand\markdownRendererOlBegin{#1}}%
+\define@key{markdownRenderers}{olBeginTight}{%
+ \renewcommand\markdownRendererOlBeginTight{#1}}%
+\define@key{markdownRenderers}{olItem}{%
+ \renewcommand\markdownRendererOlItem{#1}}%
+\define@key{markdownRenderers}{olItemWithNumber}{%
+ \renewcommand\markdownRendererOlItemWithNumber[1]{#1}}%
+\define@key{markdownRenderers}{olEnd}{%
+ \renewcommand\markdownRendererOlEnd{#1}}%
+\define@key{markdownRenderers}{olEndTight}{%
+ \renewcommand\markdownRendererOlEndTight{#1}}%
+\define@key{markdownRenderers}{dlBegin}{%
+ \renewcommand\markdownRendererDlBegin{#1}}%
+\define@key{markdownRenderers}{dlBeginTight}{%
+ \renewcommand\markdownRendererDlBeginTight{#1}}%
+\define@key{markdownRenderers}{dlItem}{%
+ \renewcommand\markdownRendererDlItem[1]{#1}}%
+\define@key{markdownRenderers}{dlEnd}{%
+ \renewcommand\markdownRendererDlEnd{#1}}%
+\define@key{markdownRenderers}{dlEndTight}{%
+ \renewcommand\markdownRendererDlEndTight{#1}}%
+\define@key{markdownRenderers}{emphasis}{%
+ \renewcommand\markdownRendererEmphasis[1]{#1}}%
+\define@key{markdownRenderers}{strongEmphasis}{%
+ \renewcommand\markdownRendererStrongEmphasis[1]{#1}}%
+\define@key{markdownRenderers}{blockQuoteBegin}{%
+ \renewcommand\markdownRendererBlockQuoteBegin{#1}}%
+\define@key{markdownRenderers}{blockQuoteEnd}{%
+ \renewcommand\markdownRendererBlockQuoteEnd{#1}}%
+\define@key{markdownRenderers}{inputVerbatim}{%
+ \renewcommand\markdownRendererInputVerbatim[1]{#1}}%
+\define@key{markdownRenderers}{headingOne}{%
+ \renewcommand\markdownRendererHeadingOne[1]{#1}}%
+\define@key{markdownRenderers}{headingTwo}{%
+ \renewcommand\markdownRendererHeadingTwo[1]{#1}}%
+\define@key{markdownRenderers}{headingThree}{%
+ \renewcommand\markdownRendererHeadingThree[1]{#1}}%
+\define@key{markdownRenderers}{headingFour}{%
+ \renewcommand\markdownRendererHeadingFour[1]{#1}}%
+\define@key{markdownRenderers}{headingFive}{%
+ \renewcommand\markdownRendererHeadingFive[1]{#1}}%
+\define@key{markdownRenderers}{headingSix}{%
+ \renewcommand\markdownRendererHeadingSix[1]{#1}}%
+\define@key{markdownRenderers}{horizontalRule}{%
+ \renewcommand\markdownRendererHorizontalRule{#1}}%
+\define@key{markdownRenderers}{footnote}{%
+ \renewcommand\markdownRendererFootnote[1]{#1}}%
+\define@key{markdownOptions}{rendererPrototypes}{%
+ \setkeys{markdownRendererPrototypes}{#1}}%
+\define@key{markdownRendererPrototypes}{lineBreak}{%
+ \renewcommand\markdownRendererLineBreakPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{ellipsis}{%
+ \renewcommand\markdownRendererEllipsisPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{codeSpan}{%
+ \renewcommand\markdownRendererCodeSpanPrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{link}{%
+ \renewcommand\markdownRendererLink[3]{#1}}%
+\define@key{markdownRendererPrototypes}{image}{%
+ \renewcommand\markdownRendererImage[3]{#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}{ulEnd}{%
+ \renewcommand\markdownRendererUlEndPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{ulEndTight}{%
+ \renewcommand\markdownRendererUlEndTightPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{olBegin}{%
+ \renewcommand\markdownRendererOlBeginPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{olBeginTight}{%
+ \renewcommand\markdownRendererOlBeginTightPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{olItem}{%
+ \renewcommand\markdownRendererOlItemPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{olItemWithNumber}{%
+ \renewcommand\markdownRendererOlItemWithNumberPrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{olEnd}{%
+ \renewcommand\markdownRendererOlEndPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{olEndTight}{%
+ \renewcommand\markdownRendererOlEndTightPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{dlBegin}{%
+ \renewcommand\markdownRendererDlBeginPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{dlBeginTight}{%
+ \renewcommand\markdownRendererDlBeginTightPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{dlItem}{%
+ \renewcommand\markdownRendererDlItemPrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{dlEnd}{%
+ \renewcommand\markdownRendererDlEndPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{dlEndTight}{%
+ \renewcommand\markdownRendererDlEndTightPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{emphasis}{%
+ \renewcommand\markdownRendererEmphasisPrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{strongEmphasis}{%
+ \renewcommand\markdownRendererStrongEmphasisPrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{blockQuoteBegin}{%
+ \renewcommand\markdownRendererBlockQuoteBeginPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{blockQuoteEnd}{%
+ \renewcommand\markdownRendererBlockQuoteEndPrototype{#1}}%
+\define@key{markdownRendererPrototypes}{inputVerbatim}{%
+ \renewcommand\markdownRendererInputVerbatimPrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{headingOne}{%
+ \renewcommand\markdownRendererHeadingOnePrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{headingTwo}{%
+ \renewcommand\markdownRendererHeadingTwoPrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{headingThree}{%
+ \renewcommand\markdownRendererHeadingThreePrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{headingFour}{%
+ \renewcommand\markdownRendererHeadingFourPrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{headingFive}{%
+ \renewcommand\markdownRendererHeadingFivePrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{headingSix}{%
+ \renewcommand\markdownRendererHeadingSixPrototype[1]{#1}}%
+\define@key{markdownRendererPrototypes}{horizontalRule}{%
+ \renewcommand\markdownRendererHorizontalRulePrototype{#1}}%
+\define@key{markdownRendererPrototypes}{footnote}{%
+ \renewcommand\markdownRendererFootnotePrototype[1]{#1}}%
+\input markdown
+\ProvidesPackage{markdown}[\markdownVersion]%
+\renewcommand\markdownInfo[1]{\PackageInfo{markdown}{#1}}%
+\renewcommand\markdownWarning[1]{\PackageWarning{markdown}{#1}}%
+\renewcommand\markdownError[2]{\PackageError{markdown}{#1}{#2.}}%
+\let\markdownInputPlainTeX\markdownInput
+\renewcommand\markdownInput[2][]{%
+ \begingroup
+ \markdownSetup{#1}%
+ \markdownInputPlainTeX{#2}%
+ \endgroup}%
+\renewenvironment{markdown}{%
+ \markdownReadAndConvert@markdown{}}\relax
+\renewenvironment{markdown*}[1]{%
+ \markdownSetup{#1}%
+ \markdownReadAndConvert@markdown*}\relax
+\begingroup
+ \catcode`\|=0\catcode`\<=1\catcode`\>=2%
+ \catcode`\\=12|catcode`|{=12|catcode`|}=12%
+ |gdef|markdownReadAndConvert@markdown#1<%
+ |markdownReadAndConvert<\end{markdown#1}>%
+ <|end<markdown#1>>>%
+|endgroup
+\DeclareOption*{%
+ \expandafter\markdownSetup\expandafter{\CurrentOption}}%
+\ProcessOptions\relax
+\RequirePackage{url}
+\RequirePackage{graphicx}
+\RequirePackage{ifthen}
+\ifx\markdownOptionTightLists\undefined
+ \RequirePackage{paralist}
+\else
+ \ifthenelse{\equal{\markdownOptionTightLists}{false}}{}{
+ \RequirePackage{paralist}}
+\fi
+\RequirePackage{fancyvrb}
+\markdownSetup{rendererPrototypes={
+ lineBreak = {\\},
+ codeSpan = {\texttt{#1}},
+ link = {#1\footnote{\ifx\empty#3\empty\else#3:
+ \fi\texttt<\url{#2}\texttt>}},
+ image = {\begin{figure}
+ \begin{center}%
+ \includegraphics{#2}%
+ \end{center}%
+ \ifx\empty#3\empty\else
+ \caption{#3}%
+ \fi
+ \label{fig:#1}%
+ \end{figure}},
+ ulBegin = {\begin{itemize}},
+ ulBeginTight = {\begin{compactitem}},
+ ulItem = {\item},
+ ulEnd = {\end{itemize}},
+ ulEndTight = {\end{compactitem}},
+ olBegin = {\begin{enumerate}},
+ olBeginTight = {\begin{compactenum}},
+ olItem = {\item},
+ olItemWithNumber = {\item[#1.]},
+ olEnd = {\end{enumerate}},
+ olEndTight = {\end{compactenum}},
+ dlBegin = {\begin{description}},
+ dlBeginTight = {\begin{compactdesc}},
+ dlItem = {\item[#1]},
+ dlEnd = {\end{description}},
+ dlEndTight = {\end{compactdesc}},
+ emphasis = {\emph{#1}},
+ strongEmphasis = {%
+ \ifx\alert\undefined
+ \textbf{\emph{#1}}%
+ \else % Beamer support
+ \alert{\emph{#1}}
+ \fi},
+ blockQuoteBegin = {\begin{quotation}},
+ blockQuoteEnd = {\end{quotation}},
+ inputVerbatim = {\VerbatimInput{#1}},
+ horizontalRule = {\noindent\rule[0.5ex]{\linewidth}{1pt}},
+ footnote = {\footnote{#1}}}}%
+
+\ifx\chapter\undefined
+ \markdownSetup{rendererPrototypes={
+ headingOne = {\section{#1}},
+ headingTwo = {\subsection{#1}},
+ headingThree = {\subsubsection{#1}},
+ headingFour = {\paragraph{#1}},
+ headingFive = {\subparagraph{#1}}}}%
+\else
+ \markdownSetup{rendererPrototypes={
+ headingOne = {\chapter{#1}},
+ headingTwo = {\section{#1}},
+ headingThree = {\subsection{#1}},
+ headingFour = {\subsubsection{#1}},
+ headingFive = {\paragraph{#1}},
+ headingSix = {\subparagraph{#1}}}}%
+\fi
+\renewcommand\markdownLuaRegisterIBCallback[1]{%
+ luatexbase.add_to_callback("process_input_buffer", #1, %
+ "The markdown input processor")}
+\renewcommand\markdownLuaUnregisterIBCallback{%
+ luatexbase.remove_from_callback("process_input_buffer",%
+ "The markdown input processor")}
+\newcommand\markdownMakeOther{%
+ \count0=128\relax
+ \loop
+ \catcode\count0=11\relax
+ \advance\count0 by 1\relax
+ \ifnum\count0<256\repeat}%
+\endinput
+%%
+%% End of file `markdown.sty'.
diff --git a/Master/texmf-dist/tex/luatex/markdown/markdown.lua b/Master/texmf-dist/tex/luatex/markdown/markdown.lua
new file mode 100644
index 00000000000..e740d18c92e
--- /dev/null
+++ b/Master/texmf-dist/tex/luatex/markdown/markdown.lua
@@ -0,0 +1,1057 @@
+--
+-- Copyright (C) 2009-2016 John MacFarlane, Hans Hagen
+--
+-- Permission is hereby granted, free of charge, to any person obtaining
+-- a copy of this software and associated documentation files (the
+-- "Software"), to deal in the Software without restriction, including
+-- without limitation the rights to use, copy, modify, merge, publish,
+-- distribute, sublicense, and/or sell copies of the Software, and to
+-- permit persons to whom the Software is furnished to do so, subject to
+-- the following conditions:
+--
+-- The above copyright notice and this permission notice shall be included
+-- in all copies or substantial portions of the Software.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+-- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+-- 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 Vít Novotný
+--
+-- This work may be distributed and/or modified under the
+-- conditions of the LaTeX Project Public License, either version 1.3
+-- of this license or (at your option) any later version.
+-- The latest version of this license is in
+--
+-- http://www.latex-project.org/lppl.txt
+--
+-- and version 1.3 or later is part of all distributions of LaTeX
+-- version 2005/12/01 or later.
+--
+-- This work has the LPPL maintenance status `maintained'.
+-- The Current Maintainer of this work is Vít Novotný.
+--
+-- Send bug reports, requests for additions and questions
+-- either to the GitHub issue tracker at
+--
+-- https://github.com/witiko/markdown/issues
+--
+-- or to the e-mail address <witiko@mail.muni.cz>.
+--
+-- MODIFICATION ADVICE:
+--
+-- If you want to customize this file, it is best to make a copy of
+-- the source file(s) from which it was produced. Use a different
+-- name for your copy(ies) and modify the copy(ies); this will ensure
+-- that your modifications do not get overwritten when you install a
+-- new release of the standard system. You should also ensure that
+-- your modified source file does not generate any modified file with
+-- the same name as a standard file.
+--
+-- You will also need to produce your own, suitably named, .ins file to
+-- control the generation of files from your source file; this file
+-- 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.1",
+ 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"
+}
+local lpeg = require("lpeg")
+local unicode = require("unicode")
+local md5 = require("md5")
+local M = {}
+M.new = {}
+local defaultOptions = {}
+defaultOptions.blankBeforeBlockquote = false
+defaultOptions.blankBeforeHeading = false
+defaultOptions.cacheDir = "."
+defaultOptions.definitionLists = false
+defaultOptions.hashEnumerators = false
+defaultOptions.hybrid = false
+defaultOptions.footnotes = false
+defaultOptions.preserveTabs = false
+defaultOptions.smartEllipses = false
+defaultOptions.startNumber = true
+defaultOptions.tightLists = true
+local upper, gsub, format, length =
+ string.upper, string.gsub, string.format, string.len
+local concat = table.concat
+local P, R, S, V, C, Cg, Cb, Cmt, Cc, Ct, B, Cs, any =
+ lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Cg, lpeg.Cb,
+ lpeg.Cmt, lpeg.Cc, lpeg.Ct, lpeg.B, lpeg.Cs, lpeg.P(1)
+local util = {}
+function util.err(msg, exit_code)
+ io.stderr:write("markdown.lua: " .. msg .. "\n")
+ os.exit(exit_code or 1)
+end
+function util.cache(dir, string, salt, transform, suffix)
+ local digest = md5.sumhexa(string .. (salt or ""))
+ local name = util.pathname(dir, digest .. suffix)
+ local file = io.open(name, "r")
+ if file == nil then -- If no cache entry exists, then create a new one.
+ local file = assert(io.open(name, "w"))
+ local result = string
+ if transform ~= nil then
+ result = transform(result)
+ end
+ assert(file:write(result))
+ assert(file:close())
+ end
+ return name
+end
+function util.table_copy(t)
+ local u = { }
+ for k, v in pairs(t) do u[k] = v end
+ return setmetatable(u, getmetatable(t))
+end
+function util.expand_tabs_in_line(s, tabstop)
+ local tab = tabstop or 4
+ local corr = 0
+ return (s:gsub("()\t", function(p)
+ local sp = tab - (p - 1 + corr) % tab
+ corr = corr - 1 + sp
+ return string.rep(" ", sp)
+ end))
+end
+function util.walk(t, f)
+ local typ = type(t)
+ if typ == "string" then
+ f(t)
+ elseif typ == "table" then
+ local i = 1
+ local n
+ n = t[i]
+ while n do
+ util.walk(n, f)
+ i = i + 1
+ n = t[i]
+ end
+ elseif typ == "function" then
+ local ok, val = pcall(t)
+ if ok then
+ util.walk(val,f)
+ end
+ else
+ f(tostring(t))
+ end
+end
+function util.flatten(ary)
+ local new = {}
+ for _,v in ipairs(ary) do
+ if type(v) == "table" then
+ for _,w in ipairs(util.flatten(v)) do
+ new[#new + 1] = w
+ end
+ else
+ new[#new + 1] = v
+ end
+ end
+ return new
+end
+function util.rope_to_string(rope)
+ local buffer = {}
+ util.walk(rope, function(x) buffer[#buffer + 1] = x end)
+ return table.concat(buffer)
+end
+function util.rope_last(rope)
+ if #rope == 0 then
+ return nil
+ else
+ local l = rope[#rope]
+ if type(l) == "table" then
+ return util.rope_last(l)
+ else
+ return l
+ end
+ end
+end
+function util.intersperse(ary, x)
+ local new = {}
+ local l = #ary
+ for i,v in ipairs(ary) do
+ local n = #new
+ new[n + 1] = v
+ if i ~= l then
+ new[n + 2] = x
+ end
+ end
+ return new
+end
+function util.map(ary, f)
+ local new = {}
+ for i,v in ipairs(ary) do
+ new[i] = f(v)
+ end
+ return new
+end
+function util.escaper(char_escapes, string_escapes)
+ local char_escapes_list = ""
+ for i,_ in pairs(char_escapes) do
+ char_escapes_list = char_escapes_list .. i
+ end
+ local escapable = S(char_escapes_list) / char_escapes
+ if string_escapes then
+ for k,v in pairs(string_escapes) do
+ escapable = P(k) / v + escapable
+ end
+ end
+ local escape_string = Cs((escapable + any)^0)
+ return function(s)
+ return lpeg.match(escape_string, s)
+ end
+end
+function util.pathname(dir, file)
+ if #dir == 0 then
+ return file
+ else
+ return dir .. "/" .. file
+ end
+end
+M.writer = {}
+function M.writer.new(options)
+ local self = {}
+ options = options or {}
+ setmetatable(options, { __index = function (_, key)
+ return defaultOptions[key] end })
+ self.suffix = ".tex"
+ self.space = " "
+ function self.plain(s)
+ return s
+ end
+ function self.paragraph(s)
+ return s
+ end
+ function self.pack(name)
+ return [[\input"]] .. name .. [["\relax]]
+ end
+ self.interblocksep = "\n\n"
+ self.containersep = "\n\n"
+ self.eof = [[\relax]]
+ self.linebreak = "\\markdownRendererLineBreak "
+ self.ellipsis = "\\markdownRendererEllipsis{}"
+ self.hrule = "\\markdownRendererHorizontalRule "
+ local escaped = {
+ ["{"] = "\\{",
+ ["}"] = "\\}",
+ ["$"] = "\\$",
+ ["%"] = "\\%",
+ ["&"] = "\\&",
+ ["_"] = "\\_",
+ ["#"] = "\\#",
+ ["^"] = "\\^{}",
+ ["\\"] = "\\char92{}",
+ ["~"] = "\\char126{}",
+ ["|"] = "\\char124{}", }
+ local escape = util.escaper(escaped)
+ if options.hybrid then
+ self.string = function(s) return s end
+ else
+ self.string = escape
+ end
+ function self.code(s)
+ return {"\\markdownRendererCodeSpan{",escape(s),"}"}
+ end
+ function self.link(lab,src,tit)
+ return {"\\markdownRendererLink{",lab,"}",
+ "{",self.string(src),"}",
+ "{",self.string(tit),"}"}
+ end
+ function self.image(lab,src,tit)
+ return {"\\markdownRendererImage{",lab,"}",
+ "{",self.string(src),"}",
+ "{",self.string(tit),"}"}
+ end
+ local function ulitem(s)
+ return {"\\markdownRendererUlItem ",s}
+ end
+
+ function self.bulletlist(items,tight)
+ local buffer = {}
+ for _,item in ipairs(items) do
+ buffer[#buffer + 1] = ulitem(item)
+ end
+ local contents = util.intersperse(buffer,"\n")
+ if tight and options.tightLists then
+ return {"\\markdownRendererUlBeginTight\n",contents,
+ "\n\\markdownRendererUlEndTight "}
+ else
+ return {"\\markdownRendererUlBegin\n",contents,
+ "\n\\markdownRendererUlEnd "}
+ end
+ end
+ local function olitem(s,num)
+ if num ~= nil then
+ return {"\\markdownRendererOlItemWithNumber{",num,"}",s}
+ else
+ return {"\\markdownRendererOlItem ",s}
+ end
+ end
+
+ function self.orderedlist(items,tight,startnum)
+ local buffer = {}
+ local num = startnum
+ for _,item in ipairs(items) do
+ buffer[#buffer + 1] = olitem(item,num)
+ if num ~= nil then
+ num = num + 1
+ end
+ end
+ local contents = util.intersperse(buffer,"\n")
+ if tight and options.tightLists then
+ return {"\\markdownRendererOlBeginTight\n",contents,
+ "\n\\markdownRendererOlEndTight "}
+ else
+ return {"\\markdownRendererOlBegin\n",contents,
+ "\n\\markdownRendererOlEnd "}
+ end
+ end
+ local function dlitem(term,defs)
+ return {"\\markdownRendererDlItem{",term,"}\n",defs}
+ end
+
+ function self.definitionlist(items,tight)
+ local buffer = {}
+ for _,item in ipairs(items) do
+ buffer[#buffer + 1] = dlitem(item.term,
+ util.intersperse(item.definitions, self.interblocksep))
+ end
+ local contents = util.intersperse(buffer, self.containersep)
+ if tight and options.tightLists then
+ return {"\\markdownRendererDlBeginTight\n\n", contents,
+ "\n\n\\markdownRendererDlEndTight\n"}
+ else
+ return {"\\markdownRendererDlBegin\n\n", contents,
+ "\n\n\\markdownRendererDlEnd\n"}
+ end
+ end
+ function self.emphasis(s)
+ return {"\\markdownRendererEmphasis{",s,"}"}
+ end
+ function self.strong(s)
+ return {"\\markdownRendererStrongEmphasis{",s,"}"}
+ end
+ function self.blockquote(s)
+ return {"\\markdownRendererBlockQuoteBegin\n",s,
+ "\n\\markdownRendererBlockQuoteEnd "}
+ end
+ function self.verbatim(s)
+ local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim")
+ return {"\\markdownRendererInputVerbatim{",name,"}"}
+ end
+ function self.heading(s,level)
+ local cmd
+ if level == 1 then
+ cmd = "\\markdownRendererHeadingOne"
+ elseif level == 2 then
+ cmd = "\\markdownRendererHeadingTwo"
+ elseif level == 3 then
+ cmd = "\\markdownRendererHeadingThree"
+ elseif level == 4 then
+ cmd = "\\markdownRendererHeadingFour"
+ elseif level == 5 then
+ cmd = "\\markdownRendererHeadingFive"
+ elseif level == 6 then
+ cmd = "\\markdownRendererHeadingSix"
+ else
+ cmd = ""
+ end
+ return {cmd,"{",s,"}"}
+ end
+ function self.note(s)
+ return {"\\markdownRendererFootnote{",s,"}"}
+ end
+
+ return self
+end
+M.reader = {}
+function M.reader.new(writer, options)
+ local self = {}
+ options = options or {}
+ setmetatable(options, { __index = function (_, key)
+ return defaultOptions[key] end })
+ local function normalize_tag(tag)
+ return unicode.utf8.lower(
+ gsub(util.rope_to_string(tag), "[ \n\r\t]+", " "))
+ end
+ local expandtabs
+ if options.preserveTabs then
+ expandtabs = function(s) return s end
+ else
+ expandtabs = function(s)
+ if s:find("\t") then
+ return s:gsub("[^\n]*", util.expand_tabs_in_line)
+ else
+ return s
+ end
+ end
+ end
+ local syntax
+ local blocks
+ local inlines
+
+ local parse_blocks =
+ function(str)
+ local res = lpeg.match(blocks, 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)))
+ else
+ return res
+ 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 percent = P("%")
+ local asterisk = P("*")
+ local dash = P("-")
+ local plus = P("+")
+ local underscore = P("_")
+ local period = P(".")
+ local hash = P("#")
+ local ampersand = P("&")
+ local backtick = P("`")
+ local less = P("<")
+ local more = P(">")
+ local space = P(" ")
+ local squote = P("'")
+ local dquote = P('"')
+ local lparent = P("(")
+ local rparent = P(")")
+ local lbracket = P("[")
+ local rbracket = P("]")
+ local circumflex = P("^")
+ local slash = P("/")
+ local equal = P("=")
+ local colon = P(":")
+ local semicolon = P(";")
+ local exclamation = 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 doubleasterisks = P("**")
+ local doubleunderscores = P("__")
+ local fourspaces = P(" ")
+
+ local any = P(1)
+ local fail = any - 1
+ local always = P("")
+
+ local escapable = S("\\`*_{}[]()+_.!#-~:^")
+ local anyescaped = P("\\") / "" * escapable
+ + any
+
+ local tab = P("\t")
+ local spacechar = S("\t ")
+ local spacing = S(" \n\r\t")
+ local newline = P("\n")
+ local nonspacechar = any - spacing
+ local tightblocksep = P("\001")
+
+ local specialchar
+ if options.smartEllipses then
+ specialchar = S("*_`&[]!\\.")
+ else
+ specialchar = S("*_`&[]!\\")
+ end
+
+ local normalchar = any -
+ (specialchar + spacing + tightblocksep)
+ local optionalspace = spacechar^0
+ local spaces = spacechar^1
+ local eof = - any
+ local nonindentspace = space^-3 * - spacechar
+ local indent = space^-3 * tab
+ + fourspaces / ""
+ local linechar = P(1 - newline)
+
+ local blankline = optionalspace * newline / "\n"
+ local blanklines = blankline^0
+ local skipblanklines = (optionalspace * newline)^0
+ local indentedline = indent /"" * C(linechar^1 * newline^-1)
+ local optionallyindentedline = indent^-1 /"" * C(linechar^1 * newline^-1)
+ local sp = spacing^0
+ local spnl = optionalspace * (newline * optionalspace)^-1
+ local line = linechar^0 * newline
+ + linechar^1 * eof
+ local nonemptyline = line - blankline
+
+ local chunk = line * (optionallyindentedline - blankline)^0
+
+ -- block followed by 0 or more optionally
+ -- indented blocks with first line indented.
+ local function indented_blocks(bl)
+ return Cs( bl
+ * (blankline^1 * indent * -blankline * bl)^0
+ * blankline^1 )
+ end
+ local bulletchar = C(plus + asterisk + dash)
+
+ local bullet = ( bulletchar * #spacing * (tab + space^-3)
+ + space * bulletchar * #spacing * (tab + space^-2)
+ + space * space * bulletchar * #spacing * (tab + space^-1)
+ + space * space * space * bulletchar * #spacing
+ ) * -bulletchar
+
+ if options.hashEnumerators then
+ dig = digit + hash
+ else
+ dig = digit
+ end
+
+ local enumerator = C(dig^3 * period) * #spacing
+ + C(dig^2 * period) * #spacing * (tab + space^1)
+ + C(dig * period) * #spacing * (tab + space^-2)
+ + space * C(dig^2 * period) * #spacing
+ + space * C(dig * period) * #spacing * (tab + space^-1)
+ + space * space * C(dig^1 * period) * #spacing
+ local openticks = Cg(backtick^1, "ticks")
+
+ local function captures_equal_length(s,i,a,b)
+ return #a == #b and i
+ end
+
+ local closeticks = space^-1 *
+ Cmt(C(backtick^1) * Cb("ticks"), captures_equal_length)
+
+ local intickschar = (any - S(" \n\r`"))
+ + (newline * -blankline)
+ + (space - closeticks)
+ + (backtick^1 - closeticks)
+
+ local inticks = openticks * space^-1 * C(intickschar^1) * closeticks
+ local leader = space^-3
+
+ -- in balanced brackets, parentheses, quotes:
+ local bracketed = P{ lbracket
+ * ((anyescaped - (lbracket + rbracket
+ + blankline^2)) + V(1))^0
+ * rbracket }
+
+ local inparens = P{ lparent
+ * ((anyescaped - (lparent + rparent
+ + blankline^2)) + V(1))^0
+ * rparent }
+
+ local squoted = P{ squote * alphanumeric
+ * ((anyescaped - (squote + blankline^2))
+ + V(1))^0
+ * squote }
+
+ local dquoted = P{ dquote * alphanumeric
+ * ((anyescaped - (dquote + blankline^2))
+ + V(1))^0
+ * dquote }
+
+ -- bracketed 'tag' for markdown links, allowing nested brackets:
+ local tag = lbracket
+ * Cs((alphanumeric^1
+ + bracketed
+ + inticks
+ + (anyescaped - (rbracket + blankline^2)))^0)
+ * rbracket
+
+ -- url for markdown links, allowing balanced parentheses:
+ local url = less * Cs((anyescaped-more)^0) * more
+ + Cs((inparens + (anyescaped-spacing-rparent))^1)
+
+ -- quoted text possibly with nested quotes:
+ local title_s = squote * Cs(((anyescaped-squote) + squoted)^0) *
+ squote
+
+ local title_d = dquote * Cs(((anyescaped-dquote) + dquoted)^0) *
+ dquote
+
+ local title_p = lparent
+ * Cs((inparens + (anyescaped-rparent))^0)
+ * rparent
+
+ local title = title_d + title_s + title_p
+
+ local optionaltitle = spnl * title * spacechar^0
+ + Cc("")
+ local rawnotes = {}
+
+ local function strip_first_char(s)
+ return s:sub(2)
+ end
+
+ -- like indirect_link
+ local function lookup_note(ref)
+ return function()
+ local found = rawnotes[normalize_tag(ref)]
+ if found then
+ return writer.note(parse_blocks(found))
+ else
+ return {"[^", ref, "]"}
+ end
+ end
+ end
+
+ local function register_note(ref,rawnote)
+ rawnotes[normalize_tag(ref)] = rawnote
+ return ""
+ end
+
+ local RawNoteRef = #(lbracket * circumflex) * tag / strip_first_char
+
+ local NoteRef = RawNoteRef / lookup_note
+
+ local NoteBlock
+
+ if options.footnotes then
+ NoteBlock = leader * RawNoteRef * colon * spnl *
+ indented_blocks(chunk) / register_note
+ else
+ NoteBlock = fail
+ end
+ -- List of references defined in the document
+ local references
+
+ -- add a reference to the list
+ local function register_link(tag,url,title)
+ references[normalize_tag(tag)] = { url = url, title = title }
+ return ""
+ end
+
+ -- parse a reference definition: [foo]: /bar "title"
+ local define_reference_parser =
+ leader * tag * colon * spacechar^0 * url * optionaltitle * blankline^1
+
+ -- lookup link reference and return either
+ -- the link or nil and fallback text.
+ local function lookup_reference(label,sps,tag)
+ local tagpart
+ if not tag then
+ tag = label
+ tagpart = ""
+ elseif tag == "" then
+ tag = label
+ tagpart = "[]"
+ else
+ tagpart = {"[", parse_inlines(tag), "]"}
+ end
+ if sps then
+ tagpart = {sps, tagpart}
+ end
+ local r = references[normalize_tag(tag)]
+ if r then
+ return r
+ else
+ return nil, {"[", parse_inlines(label), "]", tagpart}
+ end
+ end
+
+ -- lookup link reference and return a link, if the reference is found,
+ -- or a bracketed label otherwise.
+ local function indirect_link(label,sps,tag)
+ return function()
+ local r,fallback = lookup_reference(label,sps,tag)
+ if r then
+ return writer.link(parse_inlines_no_link(label), r.url, r.title)
+ else
+ return fallback
+ end
+ end
+ end
+
+ -- lookup image reference and return an image, if the reference is found,
+ -- or a bracketed label otherwise.
+ local function indirect_image(label,sps,tag)
+ return function()
+ local r,fallback = lookup_reference(label,sps,tag)
+ if r then
+ return writer.image(writer.string(label), r.url, r.title)
+ else
+ return {"!", fallback}
+ 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)
+
+ if options.blankBeforeBlockquote then
+ bqstart = fail
+ end
+
+ if options.blankBeforeHeading then
+ headerstart = fail
+ end
+
+ local Endline = newline * -( -- newline, but not before...
+ blankline -- paragraph break
+ + tightblocksep -- nested list
+ + eof -- end of document
+ + bqstart
+ + headerstart
+ ) * spacechar^0 / writer.space
+
+ local Space = spacechar^2 * Endline / writer.linebreak
+ + spacechar^1 * Endline^-1 * eof / ""
+ + spacechar^1 * Endline^-1 * optionalspace / writer.space
+
+ -- 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
+
+ local Emph = ( between(Inline, asterisk, asterisk)
+ + between(Inline, underscore, underscore)
+ ) / writer.emphasis
+
+ local urlchar = anyescaped - newline - more
+
+ local AutoLinkUrl = less
+ * C(alphanumeric^1 * P("://") * urlchar^1)
+ * more
+ / function(url)
+ return writer.link(writer.string(url), url)
+ end
+
+ local AutoLinkEmail = less
+ * C((alphanumeric + S("-._+"))^1 * P("@") * urlchar^1)
+ * more
+ / function(email)
+ return writer.link(writer.string(email),
+ "mailto:"..email)
+ end
+
+ local DirectLink = (tag / parse_inlines_no_link) -- no links inside links
+ * spnl
+ * lparent
+ * (url + Cc("")) -- link can be empty [foo]()
+ * optionaltitle
+ * rparent
+ / writer.link
+
+ local IndirectLink = tag * (C(spnl) * tag)^-1 / indirect_link
+
+ -- parse a link or image (direct or indirect)
+ local Link = DirectLink + IndirectLink
+
+ local DirectImage = exclamation
+ * (tag / parse_inlines)
+ * spnl
+ * lparent
+ * (url + Cc("")) -- link can be empty [foo]()
+ * optionaltitle
+ * rparent
+ / writer.image
+
+ local IndirectImage = exclamation * tag * (C(spnl) * tag)^-1 /
+ 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 Block = V("Block")
+
+ local Verbatim = Cs( (blanklines
+ * ((indentedline - blankline))^1)^1
+ ) / expandtabs / writer.verbatim
+
+ -- 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
+
+ local function lineof(c)
+ return (leader * (P(c) * optionalspace)^3 * newline * blankline^1)
+ 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
+ -- nested list under it.
+ local NestedList = Cs((optionallyindentedline - starter)^1)
+ / function(a) return "\001"..a end
+
+ local ListBlockLine = optionallyindentedline
+ - blankline - (indent^-1 * starter)
+
+ local ListBlock = line * ListBlockLine^0
+
+ local ListContinuationBlock = blanklines * (indent / "") * ListBlock
+
+ local function TightListItem(starter)
+ return -HorizontalRule
+ * (Cs(starter / "" * ListBlock * NestedList^-1) /
+ parse_blocks)
+ * -(blanklines * indent)
+ end
+
+ local function LooseListItem(starter)
+ return -HorizontalRule
+ * Cs( starter / "" * ListBlock * Cc("\n")
+ * (NestedList + ListContinuationBlock^0)
+ * (blanklines / "\n\n")
+ ) / parse_blocks
+ end
+
+ local BulletList = ( Ct(TightListItem(bullet)^1)
+ * Cc(true) * skipblanklines * -bullet
+ + Ct(LooseListItem(bullet)^1)
+ * Cc(false) * skipblanklines ) /
+ writer.bulletlist
+
+ local function orderedlist(items,tight,startNumber)
+ if options.startNumber then
+ startNumber = tonumber(startNumber) or 1 -- fallback for '#'
+ else
+ startNumber = nil
+ end
+ return writer.orderedlist(items,tight,startNumber)
+ end
+
+ local OrderedList = Cg(enumerator, "listtype") *
+ ( Ct(TightListItem(Cb("listtype")) *
+ TightListItem(enumerator)^0)
+ * Cc(true) * skipblanklines * -enumerator
+ + Ct(LooseListItem(Cb("listtype")) *
+ LooseListItem(enumerator)^0)
+ * Cc(false) * skipblanklines
+ ) * Cb("listtype") / orderedlist
+
+ local defstartchar = S("~:")
+ local defstart = ( defstartchar * #spacing * (tab + space^-3)
+ + space * defstartchar * #spacing * (tab + space^-2)
+ + space * space * defstartchar * #spacing *
+ (tab + space^-1)
+ + space * space * space * defstartchar * #spacing
+ )
+
+ local dlchunk = Cs(line * (indentedline - blankline)^0)
+
+ local function definition_list_item(term, defs, tight)
+ return { term = parse_inlines(term), definitions = defs }
+ end
+
+ local DefinitionListItemLoose = C(line) * skipblanklines
+ * Ct((defstart *
+ indented_blocks(dlchunk) /
+ parse_blocks)^1)
+ * Cc(false)
+ / definition_list_item
+
+ local DefinitionListItemTight = C(line)
+ * Ct((defstart * dlchunk /
+ parse_blocks)^1)
+ * Cc(true)
+ / definition_list_item
+
+ local DefinitionList = ( Ct(DefinitionListItemLoose^1) * Cc(false)
+ + Ct(DefinitionListItemTight^1)
+ * (skipblanklines *
+ -DefinitionListItemLoose * Cc(true))
+ ) / writer.definitionlist
+ local Blank = blankline / ""
+ + NoteBlock
+ + Reference
+ + (tightblocksep / "\n")
+ -- parse Atx heading start and return level
+ local HeadingStart = #hash * C(hash^-6) * -hash / length
+
+ -- parse setext header ending and return level
+ local HeadingLevel = equal^1 * Cc(1) + dash^1 * Cc(2)
+
+ local function strip_atx_end(s)
+ return s:gsub("[#%s]*\n$","")
+ end
+
+ -- parse atx header
+ local AtxHeading = Cg(HeadingStart,"level")
+ * optionalspace
+ * (C(line) / strip_atx_end / parse_inlines)
+ * Cb("level")
+ / writer.heading
+
+ -- parse setext header
+ local SetextHeading = #(line * S("=-"))
+ * Ct(line / parse_inlines)
+ * HeadingLevel
+ * optionalspace * newline
+ / writer.heading
+ syntax =
+ { "Blocks",
+
+ Blocks = Blank^0 *
+ Block^-1 *
+ (Blank^0 / function()
+ return writer.interblocksep
+ end * Block)^0 *
+ Blank^0 *
+ eof,
+
+ Blank = Blank,
+
+ Block = V("Blockquote")
+ + V("Verbatim")
+ + V("HorizontalRule")
+ + V("BulletList")
+ + V("OrderedList")
+ + V("Heading")
+ + V("DefinitionList")
+ + V("Paragraph")
+ + V("Plain"),
+
+ Blockquote = Blockquote,
+ Verbatim = Verbatim,
+ HorizontalRule = HorizontalRule,
+ BulletList = BulletList,
+ OrderedList = OrderedList,
+ Heading = AtxHeading + SetextHeading,
+ DefinitionList = DefinitionList,
+ DisplayHtml = DisplayHtml,
+ Paragraph = Paragraph,
+ Plain = Plain,
+
+ Inline = V("Str")
+ + V("Space")
+ + V("Endline")
+ + V("UlOrStarLine")
+ + V("Strong")
+ + V("Emph")
+ + V("NoteRef")
+ + V("Link")
+ + V("Image")
+ + V("Code")
+ + V("AutoLinkUrl")
+ + V("AutoLinkEmail")
+ + V("EscapedChar")
+ + V("Smart")
+ + V("Symbol"),
+
+ Str = Str,
+ Space = Space,
+ Endline = Endline,
+ UlOrStarLine = UlOrStarLine,
+ Strong = Strong,
+ Emph = Emph,
+ NoteRef = NoteRef,
+ Link = Link,
+ Image = Image,
+ Code = Code,
+ AutoLinkUrl = AutoLinkUrl,
+ AutoLinkEmail = AutoLinkEmail,
+ InlineHtml = InlineHtml,
+ HtmlEntity = HtmlEntity,
+ EscapedChar = EscapedChar,
+ Smart = Smart,
+ Symbol = Symbol,
+ }
+
+ if not options.definitionLists then
+ syntax.DefinitionList = fail
+ end
+
+ if not options.footnotes then
+ syntax.NoteRef = fail
+ end
+
+ if not options.smartEllipses then
+ syntax.Smart = fail
+ end
+
+ blocks = Ct(syntax)
+
+ local inlines_t = util.table_copy(syntax)
+ inlines_t[1] = "Inlines"
+ inlines_t.Inlines = Inline^0 * (spacing^0 * eof / "")
+ inlines = Ct(inlines_t)
+
+ inlines_no_link_t = util.table_copy(inlines_t)
+ inlines_no_link_t.Link = fail
+ inlines_no_link = Ct(inlines_no_link_t)
+ function self.convert(input)
+ references = {}
+ local opt_string = {}
+ for k,_ in pairs(defaultOptions) do
+ local v = options[k]
+ if k ~= "cacheDir" then
+ opt_string[#opt_string+1] = k .. "=" .. tostring(v)
+ end
+ end
+ table.sort(opt_string)
+ local salt = table.concat(opt_string, ",")
+ local name = util.cache(options.cacheDir, input, salt, function(input)
+ return util.rope_to_string(parse_blocks(input)) .. writer.eof
+ end, ".md" .. writer.suffix)
+ return writer.pack(name)
+ end
+ return self
+end
+function M.new(options)
+ local writer = M.writer.new(options)
+ local reader = M.reader.new(writer, options)
+ return reader.convert
+end
+
+return M