% \iffalse %<*driver> \documentclass{ltxdockit} \usepackage[american]{babel} \usepackage{amsmath,btxdockit,doc,fancyvrb,graphicx,hologo,microtype,minted} % Set up the style. \usepackage{xcolor} \definecolor{spot}{rgb}{0,0.2,0.6} \usepackage{fontspec} \defaultfontfeatures[\rmfamily,\sffamily,\ttfamily]{} \emergencystretch=1em \fvset{gobble=0,frame=single} \setcounter{secnumdepth}{4} \addtokomafont{title}{\sffamily} \addtokomafont{paragraph}{\spotcolor} \addtokomafont{section}{\spotcolor} \addtokomafont{subsection}{\spotcolor} \addtokomafont{subsubsection}{\spotcolor} \addtokomafont{descriptionlabel}{\spotcolor} \setkomafont{caption}{\bfseries\sffamily\spotcolor} \setkomafont{captionlabel}{\bfseries\sffamily\spotcolor} \hypersetup{citecolor=spot} \let\oldCodelineNo\theCodelineNo \def\theCodelineNo{\textcolor[gray]{0.5}{\oldCodelineNo}} \makeatletter\renewcommand\fps@figure{htbp}\makeatother \setkeys{Gin}{ width = \columnwidth, height = 0.65\paperheight, keepaspectratio, } % Define some markup. \let\pkg\relax % A package name \def\inline#1{% Inline code \textcolor{spot}{\text{\texttt{#1}}}} \newcommand\acro[1]{% An acronym \markdownRendererAcronymPrototype{#1}} % Set up index. \DisableCrossrefs \usepackage{makeidx} \usepackage[columns=1, totoc]{idxlayout} \makeindex \ExplSyntaxOn \seq_new:N \g__markdown_techdoc_seen_options_seq \newcommand\mdef[1]{% A TeX macro definition \index{#1@\cs{#1}|textit}% \phantomsection \label{macro:#1} \__markdown_csname_to_option_str:nNT { #1 } \l_tmpa_tl { \seq_if_in:NVF \g__markdown_techdoc_seen_options_seq \l_tmpa_tl { % For `\mdef{markdownOption...}`, also do `\label{opt:...}`, unless % such label was previously defined by `\Optitem` or `\Valitem`. \tl_put_left:Nn \l_tmpa_tl { opt: } \exp_args:NV \label \l_tmpa_tl } } \textcolor{spot}{\cs{#1}}} \ExplSyntaxOff \newcommand\mref[1]{% A TeX macro reference \index{#1@\cs{#1}}% \hyperref[macro:#1]{\textcolor{spot}{\cs{#1}}}} \newcommand\envmdef[1]{% A LaTeX environment definition \index{#1@\texttt{#1}|textit}% \phantomsection\label{environment:#1}\inline{#1}} \newcommand\envmref[1]{% A LaTeX environment reference \index{#1@\texttt{#1}}% \hyperref[environment:#1]{\inline{#1}}} \newcommand\luamdef[1]{% A Lua object / method definition \index{#1@\texttt{#1}|textit}% \phantomsection\label{lua:#1}\inline{#1}} \newcommand\luamref[1]{% A Lua object / method reference \index{#1@\texttt{#1}}% \hyperref[lua:#1]{\inline{#1}}} \ExplSyntaxOn \newcommand\Optitem[2][]{\penalty -1000\relax % An option item definition \index{#2@\texttt{#2}|textit}% \phantomsection\label{opt:#2}% \str_set:Nn \l_tmpa_str { #2 } \seq_gput_right:NV \g__markdown_techdoc_seen_options_seq \l_tmpa_str \optitem[#1]{#2}} \newcommand\Valitem[2][]{\penalty -1000\relax % A value item definition \index{#2@\texttt{#2}}% \phantomsection\label{opt:#2}% \str_set:Nn \l_tmpa_str { #2 } \seq_gput_right:NV \g__markdown_techdoc_seen_options_seq \l_tmpa_str \valitem[#1]{#2}} \ExplSyntaxOff \newcommand\Opt[1]{% An option / value item reference \index{#1@\texttt{#1}}% \hyperref[opt:#1]{\inline{#1}}} % Set up markdown. \usepackage[ citations, definitionLists, experimental, notes, headerAttributes, hybrid, inlineNotes, jekyllData, linkAttributes, relativeReferences, stripPercentSigns, underscores = false, ]{markdown} \markdownSetup{ import = { witiko/diagrams@v2, witiko/graphicx/http, witiko/markdown/techdoc = { options as lua-options }, }, } % Set up Unicode characters. \usepackage{newunicodechar} \newunicodechar{☒}{\markdownRendererTickedBox} \newunicodechar{⌛}{\markdownRendererHalfTickedBox} \newunicodechar{☐}{\markdownRendererUntickedBox} \usepackage{emoji} \makeatletter \@ifpackagelater{emoji}{2020/03/16}{ \newunicodechar{😉}{\emoji{winking-face}} }{ \newunicodechar{😉}{;-)} } \makeatother % Set up the catcodes. \catcode`\_=12 % We won't be typesetting much math and Lua contains lots of `_`. \catcode`\^^B=8 % When we occasionally need subscripts, we will use `^^B` (STX). % Set up the title page. \begin{markdown} --- title: A Markdown Interpreter for \TeX url: https://github.com/witiko/markdown authors: [Vít Starý Novotný, Andrej Genčur] email: witiko@mail.muni.cz revision: \markdownVersion date: \markdownLastModified --- \end{markdown} \CodelineIndex % Set up the figures. \usepackage{tikz} \usepackage{mathabx,pgf-umlsd,tikz} \usetikzlibrary{automata,arrows.meta,positioning,shapes.geometric} % Set up the bibliography. \usepackage[ backend=biber, style=numeric, sorting=none, autolang=other, sortlocale=auto]{biblatex} \addbibresource{markdown.bib} \begin{document} \DocInput{markdown.dtx} \printbibliography[heading=bibintoc] \printindex \end{document} % %<*manual-css> html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } body { color: #444; font-family: Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif; font-size: 12px; line-height: 1.7; padding: 1em; margin: auto; max-width: 42em; background: #fefefe; } a { color: #0645ad; } a:visited { color: #0b0080; } a:hover { color: #06e; } a:active { color: #faa700; } a:focus { outline: thin dotted; } *::-moz-selection { background: rgba(255, 255, 0, 0.3); color: #000; } *::selection { background: rgba(255, 255, 0, 0.3); color: #000; } a::-moz-selection { background: rgba(255, 255, 0, 0.3); color: #0645ad; } a::selection { background: rgba(255, 255, 0, 0.3); color: #0645ad; } p { margin: 1em 0; } img { max-width: 100%; } h1, h2, h3, h4, h5, h6 { color: #111; line-height: 125%; margin-top: 2em; font-weight: normal; } h4, h5, h6 { font-weight: bold; } h1 { font-size: 2.5em; } h2 { font-size: 2em; } h3 { font-size: 1.5em; } h4 { font-size: 1.2em; } h5 { font-size: 1em; } h6 { font-size: 0.9em; } blockquote { color: #666666; margin: 0; padding-left: 3em; border-left: 0.5em #EEE solid; } hr { display: block; height: 2px; border: 0; border-top: 1px solid #aaa; border-bottom: 1px solid #eee; margin: 1em 0; padding: 0; } pre, code, kbd, samp { color: #000; font-family: monospace, monospace; _font-family: 'courier new', monospace; font-size: 0.98em; } pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; counter-reset: line; } .sourceCode.linenos > span { counter-increment: line; } .sourceCode.linenos > span:before{ content: counter(line) " "; } b, strong { font-weight: bold; } dfn { font-style: italic; } ins { background: #ff9; color: #000; text-decoration: none; } mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; } sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sup { top: -0.5em; } sub { bottom: -0.25em; } ul, ol { margin: 1em 0; padding: 0 0 0 2em; } li p:last-child { margin-bottom: 0; } ul ul, ol ol { margin: .3em 0; } dl { margin-bottom: 1em; } dt { font-weight: bold; margin-bottom: .8em; } dd { margin: 0 0 .8em 2em; } dd:last-child { margin-bottom: 0; } img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; } figure { display: block; text-align: center; margin: 1em 0; } figure img { border: none; margin: 0 auto; } figcaption { font-size: 0.8em; font-style: italic; margin: 0 0 .8em; } table { margin-bottom: 2em; border-bottom: 1px solid #ddd; border-right: 1px solid #ddd; border-spacing: 0; border-collapse: collapse; } table th { padding: .2em 1em; background-color: #eee; border-top: 1px solid #ddd; border-left: 1px solid #ddd; } table td { padding: .2em 1em; border-top: 1px solid #ddd; border-left: 1px solid #ddd; vertical-align: top; } .author { font-size: 1.2em; text-align: center; } @media only screen and (min-width: 480px) { body { font-size: 14px; } } @media only screen and (min-width: 768px) { body { font-size: 16px; } } @media print { * { background: transparent !important; color: black !important; filter: none !important; -ms-filter: none !important; } body { font-size: 12pt; max-width: 100%; } a, a:visited { text-decoration: underline; } hr { height: 1px; border: 0; border-bottom: 1px solid black; } a[href]:after { content: " (" attr(href) ")"; } abbr[title]:after { content: " (" attr(title) ")"; } .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } pre, blockquote { border: 1px solid #999; padding-right: 1em; page-break-inside: avoid; } tr, img { page-break-inside: avoid; } img { max-width: 100% !important; } @page :left { margin: 15mm 20mm 15mm 10mm; } @page :right { margin: 15mm 10mm 15mm 20mm; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3 { page-break-after: avoid; } } .tex sub, .latex sub, .latex sup { text-transform: uppercase; } .tex sub, .latex sub { vertical-align: -0.1ex; margin-left: -0.1667em; margin-right: -0.125em; } .tex, .latex, .tex sub, .latex sub { font-size: 1em; } .latex sup { font-size: 0.85em; vertical-align: -0.35em; margin-left: -0.36em; margin-right: -0.15em; } abbr { text-transform: lowercase; font-variant: small-caps; } % %<*techdoc-block-diagram> \begingroup \ifx\du\undefined\newlength{\du}\fi \setlength{\du}{15\unitlength} \begin{tikzpicture} \pgftransformxscale{1.000000} \pgftransformyscale{-1.23800} \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \definecolor{dialinecolor}{rgb}{1.000000, 1.000000, 1.000000} \pgfsetfillcolor{dialinecolor} \definecolor{dialinecolor}{rgb}{1.000000, 1.000000, 1.000000} \pgfsetfillcolor{dialinecolor} \fill (4.282853\du,-3.750000\du)--(4.282853\du,-1.850000\du)--(11.971656\du,-1.850000\du)--(11.971656\du,-3.750000\du)--cycle; \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetmiterjoin \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (4.282853\du,-3.750000\du)--(4.282853\du,-1.850000\du)--(11.971656\du,-1.850000\du)--(11.971656\du,-3.750000\du)--cycle; \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \node at (8.127254\du,-2.705000\du){\LaTeX{} layer}; \definecolor{dialinecolor}{rgb}{1.000000, 1.000000, 1.000000} \pgfsetfillcolor{dialinecolor} \fill (-5.055135\du,-3.788555\du)--(-5.055135\du,-1.888555\du)--(2.894865\du,-1.888555\du)--(2.894865\du,-3.788555\du)--cycle; \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetmiterjoin \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (-5.055135\du,-3.788555\du)--(-5.055135\du,-1.888555\du)--(2.894865\du,-1.888555\du)--(2.894865\du,-3.788555\du)--cycle; \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \node at (-1.080135\du,-2.743555\du){\Hologo{ConTeXt} layer}; \definecolor{dialinecolor}{rgb}{1.000000, 1.000000, 1.000000} \pgfsetfillcolor{dialinecolor} \fill (-8.200000\du,-0.224996\du)--(-8.200000\du,1.675004\du)--(11.870000\du,1.675004\du)--(11.870000\du,-0.224996\du)--cycle; \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetmiterjoin \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (-8.200000\du,-0.224996\du)--(-8.200000\du,1.675004\du)--(11.870000\du,1.675004\du)--(11.870000\du,-0.224996\du)--cycle; \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \node at (1.835000\du,0.820004\du){Plain \TeX{} layer}; \definecolor{dialinecolor}{rgb}{1.000000, 1.000000, 1.000000} \pgfsetfillcolor{dialinecolor} \fill (-11.150000\du,3.325006\du)--(-11.150000\du,5.225006\du)--(11.800000\du,5.225006\du)--(11.800000\du,3.325006\du)--cycle; \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetmiterjoin \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (-11.150000\du,3.325006\du)--(-11.150000\du,5.225006\du)--(11.800000\du,5.225006\du)--(11.800000\du,3.325006\du)--cycle; \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \node at (0.325000\du,4.370006\du){Lua layer}; \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetbuttcap { \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetfillcolor{dialinecolor} \pgfsetarrowsstart{stealth} \pgfsetarrowsend{stealth} \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (-9.906400\du,-5.181570\du)--(-9.937836\du,3.024193\du); } \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetbuttcap { \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetfillcolor{dialinecolor} \pgfsetarrowsstart{stealth} \pgfsetarrowsend{stealth} \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (-6.919693\du,-5.181570\du)--(-6.938734\du,-0.450800\du); } \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetbuttcap { \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetfillcolor{dialinecolor} \pgfsetarrowsstart{stealth} \pgfsetarrowsend{stealth} \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (-1.063746\du,-5.175791\du)--(-1.063746\du,-3.975793\du); } \definecolor{dialinecolor}{rgb}{1.000000, 1.000000, 1.000000} \pgfsetfillcolor{dialinecolor} \fill (-10.972500\du,-7.267480\du)--(-10.972500\du,-5.367480\du)--(11.977500\du,-5.367480\du)--(11.977500\du,-7.267480\du)--cycle; \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetmiterjoin \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (-10.972500\du,-7.267480\du)--(-10.972500\du,-5.367480\du)--(11.977500\du,-5.367480\du)--(11.977500\du,-7.267480\du)--cycle; \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \node at (0.502500\du,-6.322480\du){User code}; \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetbuttcap { \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetfillcolor{dialinecolor} \pgfsetarrowsstart{stealth} \pgfsetarrowsend{stealth} \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (8.149986\du,-5.159541\du)--(8.149986\du,-3.959543\du); } \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetbuttcap { \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetfillcolor{dialinecolor} \pgfsetarrowsstart{stealth} \pgfsetarrowsend{stealth} \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (-1.074995\du,-1.634548\du)--(-1.074995\du,-0.434550\du); } \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetbuttcap { \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetfillcolor{dialinecolor} \pgfsetarrowsstart{stealth} \pgfsetarrowsend{stealth} \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (8.138736\du,-1.618298\du)--(8.138736\du,-0.418300\du); } \pgfsetlinewidth{0.040000\du} \pgfsetdash{}{0pt} \pgfsetdash{}{0pt} \pgfsetbuttcap { \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetfillcolor{dialinecolor} \pgfsetarrowsstart{stealth} \pgfsetarrowsend{stealth} \definecolor{dialinecolor}{rgb}{0.000000, 0.000000, 0.000000} \pgfsetstrokecolor{dialinecolor} \draw (1.689638\du,1.881695\du)--(1.689638\du,3.081693\du); } \end{tikzpicture} \endgroup % %<*techdoc-bibliography> @online{starynovotny24, author = {Starý Novotný, Vít and Enrico Gregorio and Max Chernoff and P. Spratte, Jonathan}, title = {Convert control sequence with a variable number of undelimited parameters into a token list}, url = {https://tex.stackexchange.com/q/716362/70941}, urldate = {2024-04-28}, } @online{starynovotny25, author = {Starý Novotný, Vít}, title = {Routing \acro{YAML} metadata to expl3 key–values}, titleaddon = {Markdown Enhancement Proposal}, url = {https://github.com/witiko/markdown/discussions/517}, date = {2024-10-14}, urldate = {2025-01-06}, } @book{tantau21, author = {Till Tantau and Joseph Wright and Vedran Miletić}, title = {The Beamer class}, date = {2021-02-10}, url = {https://mirrors.ctan.org/macros/latex/contrib/beamer/doc/beameruserguide.pdf}, urldate = {2021-02-11}} @online{sotkov17, author = {Sotkov, Anton}, title = {File transclusion syntax for Markdown}, date = {2017-01-19}, url = {https://github.com/iainc/Markdown-Content-Blocks}, urldate = {2018-01-08}} @book{luatex25, author = {{Lua\TeX{} development team}}, title = {Lua\TeX{} reference manual}, date = {2025-02-01}, note = {Version 1.21}, url = {http://mirrors.ctan.org/systems/doc/luatex/luatex.pdf}, urldate = {2025-05-12}} @book{latex17, author = {Braams, Johannes and Carlisle, David and Jeffrey, Alan and Lamport, Leslie and Mittelbach, Frank and Rowley, Chris and Schöpf, Rainer}, title = {The \Hologo{LaTeX2e} Sources}, date = {2017-04-15}, url = {https://mirrors.ctan.org/macros/latex/base/source2e.pdf}, urldate = {2018-01-08}} @book{mittelbach17, author = {Mittelbach, Frank}, title = {The \texttt{doc} and \texttt{shortvrb} Packages}, date = {2017-04-15}, url = {https://mirrors.ctan.org/macros/latex/base/doc.pdf}, urldate = {2018-02-19}} @book{mittelbach24, author = {Mittelbach, Frank}, title = {\LaTeX's hook management}, date = {2024-06-26}, url = {https://mirrors.ctan.org/macros/latex/base/lthooks-code.pdf}, urldate = {2024-10-02}} @book{poore17, author = {Poore, Geoffrey M.}, title = {The \texttt{minted} Package}, subtitle = {Highlighted source code in \LaTeX}, date = {2017-07-19}, version = {v2.5}, url = {https://mirrors.ctan.org/macros/latex/contrib/minted/minted.pdf}, urldate = {2020-09-01}} @online{macfarlane22, title = {Pandoc}, subtitle = {a universal document converter}, author = {John MacFarlane}, year = {2022}, url = {https://pandoc.org/}, urldate = {2022-10-05}} @online{novotny15, author = {Novotný, Vít}, year = {2015}, title = {TeXový interpret jazyka Markdown (markdown.sty)}, location = {Brno, Czech Republic}, publisher = {Masaryk University}, url = {https://www.muni.cz/en/research/projects/32984}, urldate = {2018-02-19}} @book{ierusalimschy13, author = {Ierusalimschy, Roberto}, year = {2013}, title = {Programming in Lua}, edition = {3}, isbn = {978-85-903798-5-0}, pagetotal = {xviii, 347}, location = {Rio de Janeiro}, publisher = {PUC-Rio}} @book{knuth86a, author = {Knuth, Donald Ervin}, year = {1986}, title = {The \TeX{}book}, edition = {3}, isbn = {0-201-13447-0}, pagetotal = {ix, 479}, series = {Computers \& Typesetting}, volume = {A}, location = {Reading, MA}, publisher = {Addison-Wesley}} @book{knuth86b, author = {Knuth, Donald Ervin}, year = {1986}, title = {\TeX: The Program}, isbn = {978-0-201-13437-7}, pagetotal = {xvi, 594}, series = {Computers \& Typesetting}, volume = {B}, location = {Reading, MA}, publisher = {Addison-Wesley}} @book{eijkhout92, author = {Victor Eijkhout}, title = {\TeX{} by Topic}, subtitle = {A \TeX nician's Reference}, isbn = {978-0-201-56882-0}, pagetotal = {307}, date = {1992-02-01}, location = {Wokingham, England}, publisher = {Addison-Wesley}} @inproceedings{sharif10, author = {Sharif, Bonita and Maletic, Jonathan I.}, booktitle = {2010 IEEE 18th International Conference on Program Comprehension}, title = {An Eye Tracking Study on camelCase and under\_score Identifier Styles}, year = {2010}, pages = {196-205}, doi = {10.1109/ICPC.2010.41}} @online{novotny24, author = {Starý Novotný, Vít}, title = {Versioned Themes}, titleaddon = {Markdown Enhancement Proposal}, date = {2024-10-13}, urldate = {2024-10-21}, url = {https://github.com/Witiko/markdown/discussions/514}} @book{latex24, author = {Frank Mittelbach and Ulrike Fischer and {\LaTeX{} Project}}, title = {The \texttt{documentmetadata-support} code}, date = {2024-06-01}, url = {https://mirrors.ctan.org/macros/latex/required/latex-lab/documentmetadata-support-code.pdf}, urldate = {2024-10-21}} @online{latex25, author = {{\LaTeX{} Project}}, title = {l3kernel}, subtitle = {\LaTeX3 programming conventions}, date = {2024-12-25}, url = {https://ctan.org/pkg/l3kernel}, urldate = {2025-01-06}} @online{latex26, author = {{\LaTeX{} Project}}, title = {The \LaTeX3 Interfaces}, date = {2026-01-19}, url = {https://mirrors.ctan.org/macros/latex/required/l3kernel/interface3.pdf}, urldate = {2026-02-18}} @online{unicode24, author = {{Unicode Consortium}}, title = {The Unicode Standard}, subtitle = {Version 16.0 -- Core Specification}, date = {2024-09-10}, url = {https://www.unicode.org/versions/Unicode16.0.0/UnicodeStandard-16.0.pdf}, urldate = {2025-05-07}} @online{context23, author = {Hans Hagen}, title = {\Hologo{ConTeXt} Lua Documents}, date = {2023-07-08}, url = {https://www.pragma-ade.nl/general/manuals/cld-mkiv.pdf}, urldate = {2025-09-22}} % %<@@=markdown> %<*themes-witiko-markdown-techdoc> \ProvidesPackage{markdownthemewitiko_markdown_techdoc}[2022/12/13] \RequirePackage{etoolbox} \gdef\ltd@title@author{\@gobble}% \markdownSetup{ acronyms += { API, ASCII, CDATA, CLI, CSV, cURL, GNU, HTML, HTTP, HTTPS, JSON, MD5, NFC, NFD, NFKS, NFKD, OS, PCDATA, PEG, PEGs, PHP, SVG, UML, PlantUML, UNIX, URI, URL, UTF8, YAML, }, renderers = { head*Four = {\paragraph{#1}\leavevmode}, }, rendererPrototypes = { codeSpan = {\inline{#1}}, jekyllData(End) = {% \AfterEndPreamble{% \hypersetup{pdfauthor=\ltd@title@author}% \printtitlepage \tableofcontents {\def\addcontentsline##1##2##3{}\listoffigures}% }% }, }, } \ExplSyntaxOn \keys_define:nn { markdown / techdoc } { authors / unknown .code:n = { \tl_gput_right:Nn \ltd@title@author { ,~#1 } }, title .code:n = { \tl_gset:Nn \ltd@title@title { #1 } \tl_gset:Nn \ltd@title@subtitle { } \hypersetup { pdftitle = { #1 } } }, date .tl_gset:N = \ltd@title@date, email .tl_gset:N = \ltd@title@email, revision .tl_gset:N = \ltd@title@revision, url .tl_gset:N = \ltd@title@url, } \cs_generate_variant:Nn \cs_gset:Npn { NpV } \yamlSetup { jekyllDataKeyValue = markdown / techdoc } \markdownSetup { rendererPrototypes = { headerAttributeContextEnd = { \seq_map_inline:Nn \g_@@_header_identifiers_seq { \label { sec:##1 } } \seq_gclear:N \g_@@_header_identifiers_seq }, }, } \ExplSyntaxOff \renewcommand\markdownLaTeXRendererDirectOrIndirectLink[4]{% #1\footnote{See \url{#3}.}} \RequirePackage{varioref} \vrefwarning \markdownSetupSnippet{options}{ rendererPrototypes = { dlBegin = {\begin{optionlist}}, dlItem = { #1 \begingroup \markdownSetup{ renderers = { dlBegin = { \begingroup \markdownSetup{ renderers = { dlItem = {\item[####1]}, dlItemEnd = {}}} \begin{valuelist} }, dlEnd = { \end{valuelist} \endgroup }, }, }% }, dlItemEnd = {\endgroup}, dlEnd = {\end{optionlist}}, } } % %<*manual> --- title: Markdown Package User Manual author: Vít Starý Novotný, Andrej Genčur date: \markdownVersion{} \markdownLastModified{} --- % \fi % \begin{markdown} Introduction ============ The [Markdown package][pkg] converts [CommonMark][] markup to \TeX{} commands. The functionality is provided both as a Lua module and as plain \TeX{}, \LaTeX{}, and \Hologo{ConTeXt} macro packages that can be used to directly typeset \TeX{} documents containing markdown markup. Unlike other converters, the Markdown package does not require any external programs, and makes it easy to redefine how each and every markdown element is rendered. Creative abuse of the markdown syntax is encouraged. 😉 [commonmark]: https://commonmark.org/ (CommonMark: A strongly defined, highly compatible specification of Markdown) [pkg]: https://ctan.org/pkg/markdown (CTAN: Package markdown) % This document is a technical documentation for the \pkg{Markdown} package. It % consists of three sections. This section introduces the package and outlines % its prerequisites. Section <#sec:interfaces> describes the interfaces % exposed by the package. Section <#sec:implementation> describes the % implementation of the package. The technical documentation contains only a % limited number of tutorials and code examples. You can find more of these in % the [user manual.][manual] % % [manual]: http://mirrors.ctan.org/macros/generic/markdown/markdown.html % % \end{markdown} % \iffalse This document is a user manual for the [Markdown package][pkg]. It provides tutorials and code examples. For an in-depth description of the package requirements, interfaces, and implementation, please refer to the [technical documentation][techdoc]. [techdoc]: http://mirrors.ctan.org/macros/generic/markdown/markdown.pdf (A Markdown Interpreter for TeX) % %<*lua,lua-cli,lua-loader,lua-unicode-data> % \fi % \begin{macrocode} local metadata = { version = "(((VERSION)))", comment = "A module for the conversion from markdown " .. "to plain TeX", author = "John MacFarlane, Hans Hagen, Vít Starý Novotný, " .. "Andrej Genčur", copyright = {"2009-2016 John MacFarlane, Hans Hagen", "2016-2026 Vít Starý Novotný, Andrej Genčur"}, license = "LPPL 1.3c" } % \end{macrocode} % \iffalse % %<*lua> % \fi % \begin{macrocode} if not modules then modules = { } end modules['markdown'] = metadata % \end{macrocode} % \iffalse % %<*manual> Requirements ------------ The package requires either [our official Docker image][docker], which contains the latest development version of the Markdown package, or a \TeX{} distribution: [\TeX{} Live][tl] ≥ 2023 is known to work with the current version of the Markdown package and so are recent versions of [Mik\TeX{}][mik]. If you are using an older, incomplete, or atypical \TeX{} distribution, please consult the [technical documentation][techdoc] for a detailed list of requirements. You are also advised to use Lua\TeX{} with the Markdown Package for \TeX{}. Using pdf\TeX{}, \Hologo{XeTeX} and other \TeX{} engines comes with several limitations: 1. The filenames of your .tex files may not contain spaces, see also [#573][issue-573]. 2. If `-output-directory` is provided, it may not contain spaces and it won't be automatically detected by Mik\TeX{}, see also [miktex/miktex#1630][issue-1630].[^issue-1630] [docker]: https://hub.docker.com/r/witiko/markdown/tags (witiko/markdown - Docker Image) [tl]: https://www.tug.org/texlive/ (TeX Live - TeX Users Group) [mik]: https://miktex.org/ (Home - MiKTeXorg) [issue-573]: https://github.com/Witiko/markdown/issues/573 (Compilation fails if the file name contains spaces) [issue-1630]: https://github.com/MiKTeX/miktex/issues/1630 (Environmental variable TEXMF_OUTPUT_DIRECTORY not set by MikTeX binaries) [^issue-1630]: To support `-output-directory` in MikTeX with engines other than Lua\TeX{}, you set either the environmental variable `TEXMF_OUTPUT_DIRECTORY` or the \TeX{} macro `\markdownOptionOutputDir` to the same value. Installation ------------ If the Markdown package is not included in your \TeX{} distribution, you will need to install it. From [Releases][], download [an archive `markdown.zip` for this version of the Markdown package (\markdownShortVersion{})][this-release] or a different version that you wish to install. Then, unzip the archive. If you downloaded an archive for a different version of the Markdown package, you should now locate a file named `markdown.html` with the user manual for that version, open it, and follow the installation steps in it rather than the steps from this manual. [releases]: https://github.com/witiko/markdown/releases (Releases - witiko/markdown) [this-release]: https://github.com/witiko/markdown/releases/download/\markdownShortVersion{}/markdown.zip (Release \markdownShortVersion{} - witiko/markdown) Alternatively, download the package from the repository using Git, enter the directory named `markdown` and run the `make base` command using GNU Make: ``` sh git clone https://github.com/witiko/markdown cd markdown make base `````` Either of the two abovelisted approaches should produce the following files: * `markdown.lua`, `markdown-parser.lua`, and `markdown-unicode-data.lua`: The Lua module * `markdown-cli.lua` and `markdown2tex.lua`: The Lua command-line interface * `markdown.tex`: The plain \TeX{} macro package * `markdown.sty`: The \LaTeX{} package * `markdownthemewitiko_markdown_defaults.tex`, `markdownthemewitiko_markdown_defaults.sty`, and `t-markdownthemewitiko_markdown_defaults.tex`: The `witiko/markdown/defaults` theme * `t-markdown.tex`: The \Hologo{ConTeXt} module ### Local Installation To perform a local installation, place the above files into your \TeX{} directory structure. This is generally where the individual files should be placed: * `⟨TEXMF⟩/tex/luatex/markdown/markdown.lua` * `⟨TEXMF⟩/tex/luatex/markdown/markdown-parser.lua` * `⟨TEXMF⟩/tex/luatex/markdown/markdown-unicode-data.lua` * `⟨TEXMF⟩/scripts/markdown/markdown-cli.lua` * `⟨TEXMF⟩/scripts/markdown/markdown2tex.lua` * `⟨TEXMF⟩/tex/generic/markdown/markdown.tex` * `⟨TEXMF⟩/tex/generic/markdown/markdownthemewitiko_markdown_defaults.tex` * `⟨TEXMF⟩/tex/latex/markdown/markdown.sty` * `⟨TEXMF⟩/tex/latex/markdown/markdownthemewitiko_markdown_defaults.sty` * `⟨TEXMF⟩/tex/context/third/markdown/t-markdown.tex` * `⟨TEXMF⟩/tex/context/third/markdown/t-markdownthemewitiko_markdown_defaults.tex` `⟨TEXMF⟩` corresponds to a root directory of one of your \TeX{} directory structure (TDS) trees. You may list the locations of all TDS trees using a command such as `kpsewhich -var-value=TEXMF` (in \TeX{} Live) or `mtxrun --resolve-path TEXMF` (in \Hologo{ConTeXt} Standalone). For more information, consult the manual of your \TeX{} distribution. ### Portable Installation Alternatively, you can also store the above files in the same folder as your \TeX{} document and distribute them together. This way your document can be portably typeset on legacy \TeX{} distributions. This is where the individual files should be placed: * `./markdown.lua` * `./markdown-parser.lua` * `./markdown-unicode-data.lua` * `./markdown-cli.lua` * `./markdown2tex.lua` * `./markdown/markdown.tex` * `./markdown.sty` * `./t-markdown.tex` * `./markdownthemewitiko_markdown_defaults.tex` * `./markdownthemewitiko_markdown_defaults.sty` * `./t-markdownthemewitiko_markdown_defaults.tex` The file `markdown.tex` *must* be placed in a directory named `markdown`. ### Installing Dependencies (\Hologo{ConTeXt} Standalone) The Markdown package has a number of external dependencies. Here are the package names of these dependencies in the \TeX{} Live distribution: ``` /DEPENDS.txt ``` Some TeX distributions, such as \TeX{} Live installed with a scheme smaller than `scheme-full` or \Hologo{ConTeXt} Standalone, may lack some or all of these dependencies. To complete the installation of the Markdown package with such distributions, you should follow these steps: 1. For each package that is a hard dependency of the Markdown package (i.e. has the prefix `hard` in the above list), download an archive from the web address `https://mirror.ctan.org/systems/texlive/tlnet/archive/⟨package name⟩.tar.xz`. 2. Unpack the downloaded package archives to the directory `⟨TEXMF⟩`. `⟨TEXMF⟩` corresponds to a root directory of one of your \TeX{} directory structure (TDS) trees. You may list the locations of all TDS trees using a command such as `kpsewhich -var-value=TEXMF` (in \TeX{} Live) or `mtxrun --resolve-path TEXMF` (in \Hologo{ConTeXt} Standalone). For more information, consult the manual of your \TeX{} distribution. To unpack the package archive, you would use a command such as `tar xJf ⟨package name⟩.tar.xz -C ⟨TEXMF⟩` on GNU/Linux and other Un*x systems. Some package archives may contain extra top-level directories such as `texmf-dist` and `tlpkg`. For these packages, you should only extract the contents of the directory `texmf-dist` to `⟨TEXMF⟩`. Here, you might use a command such as `tar xJf ⟨package name⟩.tar.xz -C ⟨TEXMF⟩ --wildcards 'texmf-dist/*' --strip-components=1` on GNU/Linux and other Un*x systems. 3. Run a command such as `texhash` (in \TeX{} Live) or `mtxrun --generate` and `context --generate --luatex` (in \Hologo{ConTeXt} Standalone) to make the installed packages visible to \TeX{}. For more information, consult the manual of your \TeX{} distribution. % %<*lua> % \fi % \begin{markdown} % % Requirements %------------- % % This section gives an overview of all resources required by the package. % %### Lua Requirements {#lua-prerequisites} % % The Lua part of the package requires that the following Lua modules are % available from within the Lua\TeX{} engine (though not necessarily in the % LuaMeta\TeX{} engine). % % \pkg{LPeg${}\geq{}$0.10} % %: A pattern-matching library for the writing of recursive descent parsers % via the Parsing Expression Grammars (PEGs). It is used by the % \pkg{Lunamark} library to parse the markdown input. % \pkg{LPeg${}\geq{}$0.10} is included in Lua\TeX${}\geq{}$0.72.0 (\TeX % Live${}\geq{}2013$). % % \end{markdown} % \iffalse % %<*lua,lua-unicode-data> % \fi % \begin{macrocode} local lpeg = require("lpeg") % \end{macrocode} % \begin{markdown} % % \pkg{MD5} % %: A library that provides MD5 crypto functions. It is used by the % \pkg{Lunamark} library to compute the digest of the input for caching % purposes. \pkg{MD5} is included in all releases of Lua\TeX{} (\TeX % Live${}\geq{}2008$). % % \end{markdown} % \iffalse % %<*lua,lua-loader> % \fi % \begin{macrocode} local md5 = require("md5") % \end{macrocode} % \iffalse % %<*lua,lua-unicode-data-generator> % \fi % \begin{markdown} % % \pkg{Kpathsea} % %: A package that implements the loading of third-party Lua libraries % and looking up files in the \TeX{} directory structure. % % Only load the package outside the \Hologo{ConTeXt} format, where we can % use the resolvers API [@context23, Section 11.5]. % % \end{markdown} % \begin{macrocode} if resolvers == nil then (function() % \end{macrocode} % \begin{markdown} % % If \pkg{Kpathsea} has not been loaded before or if Lua\TeX{} has not yet % been initialized, configure \pkg{Kpathsea} on top of loading it. Since % \Hologo{ConTeXt} MkIV provides a `kpse` global that acts as a % stub for \pkg{Kpathsea} and the \pkg{lua-uni-case} library expects that % `kpse` is a reference to the full \pkg{Kpathsea} library, we load % \pkg{Kpathsea} to the `kpse` global. % % \end{markdown} % \begin{macrocode} local should_initialize = package.loaded.kpse == nil or tex.initialize ~= nil kpse = require("kpse") if should_initialize then kpse.set_program_name("luatex") end end)() end % \end{macrocode} % \begin{markdown} % % All the abovelisted modules are statically linked into the current version of % the Lua\TeX{} engine~[@luatex25, Section 4.3]. Beside these, we also include % the following third-party Lua libraries: % % \pkg{api7/lua-tinyyaml} % %: A library that provides a regex-based recursive descent YAML % (subset) parser that is used to read YAML metadata when the % \Opt{jekyllData} option is enabled. % % \end{markdown} % \iffalse % %<*depends> % \fi % \begin{macrocode} hard lua-tinyyaml % \end{macrocode} % \iffalse % %<*tex> % \fi % \begin{markdown} % %### Plain \TeX{} Requirements {#tex-prerequisites} % % The plain \TeX{} part of the package requires that the plain \TeX{} % format (or its superset) is loaded, all the Lua prerequisites (see % Section <#sec:lua-prerequisites>), and the following packages: % % \pkg{expl3} % %: A package that enables the expl3 language [@latex25] from the \LaTeX3 % kernel in \TeX{} Live${}\leq{}2019$. It is used to implement reflection % capabilities that allow us to enumerate and inspect high-level concepts % such as options, renderers, and renderer prototypes. % % \end{markdown} % \iffalse % %<*depends> % \fi % \begin{macrocode} hard l3kernel % \end{macrocode} % \iffalse % %<*context> % \fi % \begin{macrocode} \unprotect % \end{macrocode} % \iffalse % %<*context,tex> % \fi % \begin{macrocode} \expandafter\ifx\csname ExplSyntaxOn\endcsname\relax \input expl3-generic \fi % \end{macrocode} % \iffalse % %<*tex> % \fi % \begin{markdown} % % \pkg{lt3luabridge} % %: A package that allows us to execute Lua code with Lua\TeX{} as well as % with other \TeX{} engines that provide the *shell escape* capability, % which allows them to execute code with the system's shell. % % Note that this support for \TeX{} engines other than Lua\TeX{} comes with % some limitations with respect to file and directory names. Specifically, % the filenames of your .tex files [may not contain spaces][1]. If % `-output-directory` is provided, it may not contain spaces either. % % [1]: https://github.com/Witiko/markdown/issues/573 (Compilation fails if the file name contains spaces) % % \end{markdown} % \iffalse % %<*depends> % \fi % \begin{macrocode} hard lt3luabridge % \end{macrocode} % \iffalse % %<*tex> % \fi % \begin{markdown} % % The plain \TeX{} part of the package also requires the following Lua module: % % \pkg{Lua File System} % %: A library that provides access to the filesystem via OS-specific % syscalls. It is used by the plain \TeX{} code to create the cache % directory specified by the \Opt{cacheDir} option before interfacing with % the \pkg{Lunamark} library. \pkg{Lua File System} is included in all % releases of Lua\TeX{} (\TeX Live${}\geq{}2008$). % % The plain \TeX{} code makes use of the `isdir` method that was added % to the \pkg{Lua File System} library by the Lua\TeX{} engine % developers~[@luatex25, Section 4.2.4]. % % The \pkg{Lua File System} module is statically linked into the Lua\TeX{} % engine~[@luatex25, Section 4.3]. % % Unless you convert markdown documents to \TeX{} manually using the Lua % command-line interface (see Section <#sec:lua-cli-interface>), the plain % \TeX{} part of the package will require that either the Lua\TeX{} % `\directlua` primitive or the shell access file stream 18 is available in % your \TeX{} engine. If only the shell access file stream is available in your % \TeX{} engine (as is the case with \hologo{pdfTeX} and \Hologo{XeTeX}), then % unless your \TeX{} engine is globally configured to enable shell access, you % will need to provide the `-shell-escape` parameter to your engine when % typesetting a document. % % \end{markdown} % \iffalse % %<*latex> % \fi % \begin{markdown} % %### \LaTeX{} Requirements {#latex-prerequisites} % % The \LaTeX{} part of the package requires that the \Hologo{LaTeX2e} format is % loaded, a \TeX{} engine that extends \Hologo{eTeX}, and all the plain \TeX{} % prerequisites (see Section <#sec:tex-prerequisites>). % \end{markdown} % \iffalse % \fi % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \RequirePackage{expl3} % \end{macrocode} % \iffalse % %<*depends> % \fi % \begin{markdown} % % The following packages are soft prerequisites. They are only used to provide % default token renderer prototypes (see sections % <#sec:texrendererprototypes> and % <#sec:latex-token-renderer-prototypes>) or \LaTeX{} themes (see Section % <#sec:latexthemes>) and will not be loaded if the option `plain` has been % enabled (see Section <#sec:plain>): % % \pkg{url} % %: A package that provides the `\url` macro for the typesetting of links. % % \end{markdown} % \begin{macrocode} soft url % \end{macrocode} % \begin{markdown} % % \pkg{graphicx} % %: A package that provides the `\includegraphics` macro for the typesetting % of images. Furthermore, it also provides a key--value interface that is % used in the default renderer prototypes for image attribute contexts. % % \end{markdown} % \begin{macrocode} soft graphics % \end{macrocode} % \begin{markdown} % % \pkg{enumitem} and \pkg{paralist} % %: Packages that provide macros for the default renderer prototypes for % tight and fancy lists. % % The package \pkg{paralist} will be used unless the option % \Opt{experimental} has been enabled, in which case, the package % \pkg{enumitem} will be used. Furthermore, enabling any test phase % [@latex24] will also cause \pkg{enumitem} to be used. In a future % major version, \pkg{enumitem} will replace \pkg{paralist} altogether. % % \end{markdown} % \begin{macrocode} soft enumitem soft paralist % \end{macrocode} % \begin{markdown} % % \pkg{fancyvrb} % %: A package that provides the `\VerbatimInput` macros for the verbatim % inclusion of files containing code. % % \end{markdown} % \begin{macrocode} soft fancyvrb % \end{macrocode} % \begin{markdown} % % \pkg{csvsimple} % %: A package that provides the `\csvautotabular` macro for typesetting % CSV files in the default renderer prototypes for iA\\,Writer % content blocks. % % \end{markdown} % \begin{macrocode} soft csvsimple soft pgf # required by `csvsimple`, which loads `pgfkeys.sty` soft tools # required by `csvsimple`, which loads `shellesc.sty` soft etoolbox # required by `csvsimple`, which loads `etoolbox.sty` % \end{macrocode} % \begin{markdown} % % \pkg{amsmath} and \pkg{amssymb} % %: Packages that provide symbols used for drawing ticked and unticked % boxes. % % \end{markdown} % \begin{macrocode} soft amsmath soft amsfonts % \end{macrocode} % \begin{markdown} % % \pkg{graphicx} % %: A package that provides extended support for graphics. It is used in % the `witiko/diagrams`, and `witiko/graphicx/http` plain \TeX{} themes, % see Section <#sec:themes>. % % \end{markdown} % \begin{macrocode} soft graphics soft epstopdf # required by `graphics` and `graphicx`, which load `epsopdf-base.sty` soft epstopdf-pkg # required by `graphics` and `graphicx`, which load `epsopdf-base.sty` % \end{macrocode} % \begin{markdown} % % \pkg{soul} and \pkg{xcolor} % %: Packages that are used in the default renderer prototypes for % strike-throughs and marked text in pdf\TeX. % % \end{markdown} % \begin{macrocode} soft soul soft xcolor % \end{macrocode} % \begin{markdown} % % \pkg{lua-ul} and \pkg{luacolor} % %: Packages that are used in the default renderer prototypes for % strike-throughs and marked text in Lua\TeX. % % \end{markdown} % \begin{macrocode} soft lua-ul soft luacolor % \end{macrocode} % \begin{markdown} % % \pkg{ltxcmds} % %: A package that is used to detect whether the \pkg{minted} and % \pkg{listings} packages are loaded in the default renderer prototype % for fenced code blocks. % % \end{markdown} % \begin{macrocode} soft ltxcmds % \end{macrocode} % \begin{markdown} % % \pkg{luaxml} % %: A package that is used to convert HTML to \LaTeX{} in the default % renderer prototypes for content blocks, raw blocks, and inline raw spans. % % \end{markdown} % \begin{macrocode} soft luaxml % \end{macrocode} % \begin{markdown} % % \pkg{verse} % %: A package that is used in the default renderer prototypes for % line blocks. % % \end{markdown} % \begin{macrocode} soft verse % \end{macrocode} % \begin{markdown} % % \end{markdown} % \iffalse % %<*context> % \fi % \begin{markdown} % %### \Hologo{ConTeXt} Prerequisites % The \Hologo{ConTeXt} part of the package requires that either the Mark II or % the Mark IV format is loaded, all the plain \TeX{} prerequisites (see % Section <#sec:tex-prerequisites>), and the following \Hologo{ConTeXt} % modules: % % \pkg{m-database} % %: A module that provides the default token renderer prototype for % iA\\,Writer content blocks with the CSV filename extension (see % Section <#sec:texrendererprototypes>). % % Feedback %--------- % Please use the \pkg{Markdown} project page on % [GitHub](https://github.com/witiko/markdown/issues) to report bugs and submit % feature requests. If you do not want to report a bug or request a feature but % are simply in need of assistance, you might want to consider posting your % question to the [\TeX-\LaTeX{} Stack Exchange.](https://tex.stackexchange.com) % community question answering web site under the `markdown` tag. % % Acknowledgements %----------------- % The Lunamark Lua module provides speedy markdown parsing for the package. I % would like to thank John Macfarlane, the creator of Lunamark, for releasing % Lunamark under a permissive license, which enabled its use in the Markdown % package. % % Extensive user documentation for the Markdown package was kindly written by % Lian Tze Lim and published by Overleaf. % % Funding by the Faculty of Informatics at the Masaryk~University % in~Brno~[@novotny15] is gratefully acknowledged. % % Support for content slicing (Lua options \Opt{shiftHeadings} and \Opt{slice}) % and pipe tables (Lua options \Opt{pipeTables} and \Opt{tableCaptions}) was % graciously sponsored by David Vins and Omedym. % % The \TeX{} implementation of the package draws inspiration from several % sources including the source code of \Hologo{LaTeX2e}, the \pkg{minted} % package by Geoffrey M. Poore, which likewise tackles the issue of % interfacing with an external interpreter from \TeX{}, the \pkg{filecontents} % package by Scott Pakin and others. % % Interfaces {#interfaces} %============ % % This part of the documentation describes the interfaces exposed by the package % along with usage notes and examples. It is aimed at the user of the package. % % Since neither \TeX{} nor Lua provide interfaces as a language construct, the % separation to interfaces and implementations is a *gentlemen's agreement*. It % serves as a means of structuring this documentation and as a promise to the % user that if they only access the package through the interface, the future % minor versions of the package should remain backwards compatible. % % Figure <#fig:block-diagram> shows the high-level structure of the Markdown % package: The translation from markdown to \TeX{} *token renderers* is exposed % by the Lua layer. The plain \TeX{} layer exposes the conversion capabilities % of Lua as \TeX{} macros. The \LaTeX{} and \Hologo{ConTeXt} layers provide % syntactic sugar on top of plain \TeX{} macros. The user can interface with % any and all layers. % % \end{markdown} % \begin{figure} % \centering % \input markdown-figure-block-diagram % \caption{A block diagram of the \pkg{Markdown} package} % \label{fig:block-diagram} % \end{figure} % \iffalse % %<*manual> First Document -------------- In this section, we will take the necessary steps to typeset our first markdown document in \TeX{}. This will serve as our first hands-on experience with the package and also as a reassurance that the package has been correctly installed. If you are using [our official Docker image][docker], you need to prefix all commands in this section with `docker run --rm -v "$PWD"/workdir:/workdir -w /workdir witiko/markdown`. For example, instead of `luatex document.tex`, you would execute the following command: ``` sh docker run --rm -v "$PWD"/workdir:/workdir -w /workdir witiko/markdown \ luatex document.tex `````` ### Using Lua Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \begingroup \catcode`\%=12 \catcode`\#=12 \input hello \endgroup \bye ``````` #### Using the Lua Module Using a text editor, create a text document named `hello.lua` with the following content: ``` lua #!/usr/bin/env texlua local kpse = require("kpse") kpse.set_program_name("luatex") local markdown = require("markdown") local convert = markdown.new() print(convert("Hello *world*!")) ``````` Next, invoke LuaTeX from the terminal: ``` sh texlua hello.lua > hello.tex luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” Invoking pdfTeX should have the same effect: ``` sh texlua hello.lua > hello.tex pdftex document.tex `````` #### Using the Lua Command-Line Interface Using a text editor, create a text document named `hello.md` with the following content: ``` md Hello *world*! `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex -- hello.md hello.tex luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” Invoking pdfTeX should have the same effect: ``` sh markdown2tex -- hello.md hello.tex pdftex document.tex `````` ### Using Plain \TeX{} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \markdownBegin Hello *world*! \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” Instead of LuaTeX, you may also use pdfTeX: ``` sh pdftex --shell-escape document.tex ``````` This should also produce a PDF document named `document.pdf` with the same content. *** Instead of writing your markdown document between `\markdownBegin` and `\markdownEnd`, you can also include markdown documents using the `\markdownInput` macro, similarly to how you might use the `\input` TeX primitive to include \TeX{} documents. Using a text editor, create a text document named `hello.md` with the following content: ``` md Hello *world*! `````` Create also a text document named `document.tex` with the following content: ``` tex \input markdown \markdownInput{hello.md} \bye ``````` Next, invoke LuaTeX or pdfTeX from the terminal like in the previous example. A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” ### Using \LaTeX{} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} Hello *world*! \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” Instead of LuaTeX, you may also use pdfTeX: ``` sh pdflatex --shell-escape document.tex `````` This should also produce a PDF document named `document.pdf` with the same content. *** Instead of writing your markdown document between `\begin{markdown}` and `\end{markdown}`, you can also include markdown documents using the `\markdownInput` macro, similarly to how you might use the `\input` TeX primitive to include \LaTeX{} documents. Using a text editor, create a text document named `hello.md` with the following content: ``` md Hello *world*! `````` Create also a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} \markdownInput{hello.md} \end{markdown} \end{document} ``````` Next, invoke LuaTeX or pdfTeX from the terminal like in the previous example. A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” *** As the next step, try typesetting the example documents distributed along with the Markdown package: ``` sh git clone https://github.com/witiko/markdown cd markdown/examples lualatex latex-luatex.tex `````` A PDF document named `latex-luatex.pdf` should be produced. Open the text documents `latex-luatex.tex` and `example.md` in a text editor to see how the example documents are structured. Try changing the documents and typesetting them as follows: ``` sh lualatex latex-luatex.tex `````` to see the effect of your changes. ### Using \Hologo{ConTeXt} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \startmarkdown Hello *world*! \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” *** Instead of writing your markdown document between `\startmarkdown` and `\stopmarkdown`, you can also include markdown documents using the `\inputmarkdown` macro, similarly to how you might use the `\input` TeX primitive to include \Hologo{ConTeXt} documents. Using a text editor, create a text document named `hello.md` with the following content: ``` md Hello *world*! `````` Create also a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \inputmarkdown{hello.md} \stoptext ``````` Next, invoke LuaTeX from the terminal like in the previous example. A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” *** As the next step, try typesetting the example documents distributed along with the Markdown package: ``` sh git clone https://github.com/witiko/markdown cd markdown/examples context --luatex context.tex `````` A PDF document named `context.pdf` should be produced. Open the text documents `context.tex` and `example.md` in a text editor to see how the example documents are structured. Try changing the documents and typesetting them as follows: ``` sh context --luatex context.tex `````` to see the effect of your changes. Examples ======== In this section, I will describe the individual parts of the Markdown package. Each part will be shown by example, leaving the implementation details to the [technical documentation][techdoc]. /markdown-interfaces.md /markdown-options.md /markdown-tokens.md % %<*lua> % \fi % \begin{markdown} % % Lua Interface {#luainterface} %--------------- % % \end{markdown} % \iffalse % %<*manual-interfaces> Interfaces ---------- In this section, I will describe the individual interfaces exposed by the Markdown package starting with the low-level Lua interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces intended for the ordinary user. ### Lua The Lua programming language is what drives the conversion from markdown to \TeX{} in the Markdown package. Based on the [Lunamark][] Lua library by John MacFarlane, the Lua implementation is largely independent on \TeX{}, and can be used separately from typesetting a document. Lua provides two interfaces: a Lua module and a command-line interface (CLI). [Lunamark]: https://github.com/jgm/lunamark (Lua library for conversion between markup formats) % %<*lua,lua-loader,lua-unicode-data> % \fi % \begin{markdown} % % The Lua interface provides the conversion from UTF8 % encoded markdown to plain \TeX{}. This interface is used by the plain \TeX{} % implementation (see Section <#sec:teximplementation>) and will be of % interest to the developers of other packages and Lua modules. % % The Lua interface is implemented by the `markdown` Lua module. % % \end{markdown} % \begin{macrocode} local M = {metadata = metadata} % \end{macrocode} % \iffalse % %<*lua> % \fi % \begin{markdown} % %### Conversion from Markdown to Plain \TeX{} {#lua-conversion} % % The Lua interface exposes the \luamdef{new}`(options)` function. This % function returns a conversion function from markdown to plain \TeX{} according % to the table `options` that contains options recognized by the Lua interface % (see Section <#sec:lua-options>). The `options` parameter is optional; when % unspecified, the behaviour will be the same as if `options` were an empty % table. % % The following example Lua code converts the markdown string `Hello % *world*!` to a \TeX{} output using the default options and prints the \TeX{} % output: % ``` lua % local md = require("markdown") % local convert = md.new() % print(convert("Hello *world*!")) % ``````` % %### User-Defined Syntax Extensions {#lua-user-extensions} % % For the purpose of user-defined syntax extensions, the Lua interface also % exposes the \luamdef{reader} object, which performs the lexical and % syntactic analysis of markdown text and which exposes the % \luamdef{reader->insert_pattern} and \luamdef{reader->add_special_character} % methods for extending the PEG grammar of markdown. % % The read-only \luamdef{walkable_syntax} hash table stores those rules of the % PEG grammar of markdown that can be represented as an ordered choice % of terminal symbols. These rules can be modified by user-defined syntax % extensions. % % \end{markdown} % \begin{macrocode} local walkable_syntax = { Block = { "Blockquote", "Verbatim", "ThematicBreak", "BulletList", "OrderedList", "DisplayHtml", "Heading", }, BlockOrParagraph = { "Block", "Paragraph", "Plain", }, Inline = { "Str", "Space", "Endline", "EndlineBreak", "LinkAndEmph", "Code", "AutoLinkUrl", "AutoLinkEmail", "AutoLinkRelativeReference", "InlineHtml", "HtmlEntity", "EscapedChar", "Smart", "Symbol", }, } % \end{macrocode} % \begin{markdown} % % The \luamref{reader->insert_pattern} method inserts a PEG pattern into % the grammar of markdown. The method receives two mandatory arguments: a % selector string in the form `"`\meta{left-hand side terminal symbol} % \meta{`before`, `after`, or `instead of`} \meta{right-hand side terminal % symbol}`"` and a PEG pattern to insert, and an optional third argument % with a name of the PEG pattern for debugging purposes (see the % \Opt{debugExtensions} option). The name does not need to be unique and shall % not be interpreted by the Markdown package; you can treat it as a comment. % % For example. if we'd like to insert `pattern` into the grammar between the % `Inline -> LinkAndEmph` and `Inline -> Code` rules, we would call % \luamref{reader->insert_pattern} with `"Inline after LinkAndEmph"` (or `"Inline % before Code"`) and `pattern` as the arguments. % % The \luamref{reader->add_special_character} method adds a new character with % special meaning to the grammar of markdown. The method receives the character % as its only argument. % % \end{markdown} % \iffalse % %<*manual-interfaces> #### Lua Module A Lua module is a software library that can be used from in other programs. The `markdown` Lua module makes it possible to convert markdown to \TeX{} from within Lua\TeX{} documents and Lua scripts. The `markdown` Lua module exposes the `new(`\meta{options}`)` method, which creates a converter function from markdown to \TeX{}. The properties of the converter function are specified by the Lua table `options`. The parameter is optional; when unspecified, the behaviour will be the same as if \meta{options} were an empty table. Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input example \endgroup \bye ``````` Using a text editor, create a text document named `example.lua` with the following content: ``` lua #!/usr/bin/env texlua local kpse = require("kpse") kpse.set_program_name("luatex") local markdown = require("markdown") local input, convert_nomath, convert_math, paragraph input = [[$\sqrt{-1}$ *equals* $i$.]] convert_nomath = markdown.new() convert_math = markdown.new({texMathDollars = true}) paragraph = [[\par]] print( convert_nomath(input) .. paragraph .. convert_math(input) ) ``````` Next, invoke LuaTeX from the terminal: ``` sh texlua example.lua > example.tex luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt{-1}\$ *equals* \$i\$. > > 1 > *equals* > i. Invoking pdfTeX should have the same effect: ``` sh texlua example.lua > example.tex pdftex document.tex `````` *** Rather than use the `texlua` interpreter, we can also access the `markdown` Lua module directly from our document. Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \directlua{ local markdown = require("markdown") local input, convert_nomath, convert_math, paragraph input = [[$\string\sqrt{-1}$ *equals* $i$.]] convert_nomath = markdown.new() convert_math = markdown.new({texMathDollars = true}) paragraph = [[\par]] tex.sprint( convert_nomath(input) .. paragraph .. convert_math(input) ) } \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt{-1}\$ *equals* \$i\$. > > 1 > *equals* > i. In this case, we cannot use pdfTeX, because pdfTeX does not define the `\directlua` \TeX{} command. #### Lua Command-Line Interface The Lua command-line interface (CLI) of the Markdown package makes the functionality of the Lua module accessible from the command line. This makes it possible to convert documents from markdown to \TeX{} manually without any knowledge of the Lua programming language. The Lua command-line interface accepts the same options as the `markdown` Lua module, but now the options are specified as command-line parameters. Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input nomath \par \input math \endgroup \bye ``````` Using a text editor, create a text document named `example.md` with the following content: ``` md $\sqrt{-1}$ *equals* $i$. `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex -- example.md nomath.tex markdown2tex tex_math_dollars=true -- example.md math.tex luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt{-1}\$ *equals* \$i\$. > > 1 > *equals* > i. Invoking pdfTeX should have the same effect: ``` sh markdown2tex -- example.md nomath.tex markdown2tex tex_math_dollars=true -- example.md math.tex pdftex document.tex `````` % %<*lua> % \fi % \begin{markdown} % %### Options {#lua-options} % % The Lua interface recognizes the following options. When unspecified, the % value of a key is taken from the \luamdef{defaultOptions} and % \luamdef{experimentalOptions} tables. % % \end{markdown} % \iffalse % %<*manual-options> ## Options In this section, I will describe all the options recognized by the Markdown package. % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} local defaultOptions = {} local experimentalOptions = {} setmetatable(experimentalOptions, { __index = function (_, key) return defaultOptions[key] end }) % \end{macrocode} % \begingroup % \markdownSetup{snippet=lua-options} % \iffalse % %<*manual-options> ### Lua Lua options control the conversion from markdown to \TeX{}. They are supported by all interfaces of the Markdown package starting with the low-level Lua interfaces and all the way up to the \LaTeX{} and \Hologo{ConTeXt} interfaces. % %<*tex> % \fi % \begin{markdown} % % To enable the enumeration of Lua options, we will maintain the % \mdef{g_\@\@_lua_options_seq} sequence. % % \end{markdown} % \begin{macrocode} \ExplSyntaxOn \seq_new:N \g_@@_lua_options_seq % \end{macrocode} % \begin{markdown} % % To enable the reflection of default/experimental Lua options and their types, % we will maintain the \mdef{g_\@\@_default_lua_options_prop}, % \mdef{g_\@\@_experimental_lua_options_seq} and % \mdef{g_\@\@_lua_option_types_prop} property lists and sequences, % respectively. % % \end{markdown} % \begin{macrocode} \prop_new:N \g_@@_lua_option_types_prop \prop_new:N \g_@@_default_lua_options_prop \seq_new:N \g_@@_experimental_lua_options_seq \seq_new:N \g_@@_option_layers_seq \tl_const:Nn \c_@@_option_layer_lua_tl { lua } \seq_gput_right:NV \g_@@_option_layers_seq \c_@@_option_layer_lua_tl \cs_new:Nn \@@_add_lua_option:nnn { \@@_add_option:Vnnn \c_@@_option_layer_lua_tl { #1 } { #2 } { #3 } } \cs_new:Nn \@@_add_option:nnnn { \seq_gput_right:cn { g_@@_ #1 _options_seq } { #2 } \prop_gput:cnn { g_@@_ #1 _option_types_prop } { #2 } { #3 } \prop_gput:cnn { g_@@_default_ #1 _options_prop } { #2 } { #4 } \@@_typecheck_option:n { #2 } } \cs_generate_variant:Nn \@@_add_option:nnnn { Vnnn } \cs_new:Nn \@@_add_experimental_lua_option:n { \@@_add_experimental_option:Vn \c_@@_option_layer_lua_tl { #1 } } \cs_new:Nn \@@_add_experimental_option:nn { \seq_gput_right:cn { g_@@_ #1 _options_seq } { #2 } \seq_gput_right:cn { g_@@_experimental_ #1 _options_seq } { #2 } \prop_gput:cnn { g_@@_ #1 _option_types_prop } { #2 } { boolean } } \cs_generate_variant:Nn \@@_add_experimental_option:nn { Vn } \tl_const:Nn \c_@@_option_value_true_tl { true } \tl_const:Nn \c_@@_option_value_false_tl { false } \cs_new:Nn \@@_typecheck_option:n { \@@_get_option_type:nN { #1 } \l_tmpa_tl \str_case_e:Vn \l_tmpa_tl { { \c_@@_option_type_boolean_tl } { \@@_get_option_value:nN { #1 } \l_tmpa_tl \bool_if:nF { \str_if_eq_p:eV { \l_tmpa_tl } \c_@@_option_value_true_tl || \str_if_eq_p:eV { \l_tmpa_tl } \c_@@_option_value_false_tl } { \msg_error:nnne { markdown } { failed-typecheck-for-boolean-option } { #1 } { \l_tmpa_tl } } } } } \msg_new:nnn { markdown } { failed-typecheck-for-boolean-option } { Option~#1~has~value~#2,~ but~a~boolean~(true~or~false)~was~expected. } \cs_generate_variant:Nn \str_case_e:nn { Vn } \cs_generate_variant:Nn \msg_error:nnnn { nnne } \prg_generate_conditional_variant:Nnn \str_if_eq:nn { eV } { p } \seq_new:N \g_@@_option_types_seq \tl_const:Nn \c_@@_option_type_clist_tl { clist } \seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_clist_tl \tl_const:Nn \c_@@_option_type_counter_tl { counter } \seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_counter_tl \tl_const:Nn \c_@@_option_type_boolean_tl { boolean } \seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_boolean_tl \tl_const:Nn \c_@@_option_type_number_tl { number } \seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_number_tl \tl_const:Nn \c_@@_option_type_path_tl { path } \seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_path_tl \tl_const:Nn \c_@@_option_type_slice_tl { slice } \seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_slice_tl \tl_const:Nn \c_@@_option_type_string_tl { string } \seq_gput_right:NV \g_@@_option_types_seq \c_@@_option_type_string_tl \cs_new:Nn \@@_get_option_type:nN { \bool_set_false:N \l_tmpa_bool \seq_map_inline:Nn \g_@@_option_layers_seq { \prop_get:cnNT { g_@@_ ##1 _option_types_prop } { #1 } \l_tmpa_tl { \bool_set_true:N \l_tmpa_bool \seq_map_break: } } \bool_if:NF \l_tmpa_bool { \msg_error:nnn { markdown } { undefined-option } { #1 } } \seq_if_in:NVF \g_@@_option_types_seq \l_tmpa_tl { \msg_error:nnnV { markdown } { unknown-option-type } { #1 } \l_tmpa_tl } \tl_set_eq:NN #2 \l_tmpa_tl } \msg_new:nnn { markdown } { unknown-option-type } { Option~#1~has~unknown~type~#2. } \msg_new:nnn { markdown } { undefined-option } { Option~#1~is~undefined. } \cs_generate_variant:Nn \msg_error:nnnn { nnnV } \cs_new:Nn \@@_get_default_option_value:nN { \bool_set_false:N \l_tmpa_bool \seq_map_inline:Nn \g_@@_option_layers_seq { \seq_if_in:cnT { g__markdown_experimental_ ##1 _options_seq } { #1 } { \@@_get_option_value:nN { experimental } #2 \bool_set_true:N \l_tmpa_bool \seq_map_break: } \prop_get:cnNT { g_@@_default_ ##1 _options_prop } { #1 } #2 { \bool_set_true:N \l_tmpa_bool \seq_map_break: } } \bool_if:NF \l_tmpa_bool { \msg_error:nnn { markdown } { undefined-option } { #1 } } } \cs_new:Nn \@@_get_option_value:nN { \@@_option_tl_to_csname:nN { #1 } \l_tmpa_tl \cs_if_free:cTF { \l_tmpa_tl } { \@@_get_default_option_value:nN { #1 } #2 } { \@@_get_option_type:nN { #1 } \l_tmpa_tl \str_if_eq:NNTF \c_@@_option_type_counter_tl \l_tmpa_tl { \@@_option_tl_to_csname:nN { #1 } \l_tmpa_tl \tl_set:Nx #2 { \the \cs:w \l_tmpa_tl \cs_end: } } { \@@_option_tl_to_csname:nN { #1 } \l_tmpa_tl \tl_set:Nv #2 { \l_tmpa_tl } } } } \cs_new:Nn \@@_option_tl_to_csname:nN { \tl_set:Nn \l_tmpa_tl { \str_uppercase:n { #1 } } \tl_set:Nx #2 { markdownOption \tl_head:f { \l_tmpa_tl } \tl_tail:n { #1 } } } \regex_const:Nn \c_@@_option_regex { ^markdownOption } \prg_new_conditional:Nnn \@@_csname_to_option_str:nN { T } { \tl_if_regex_match:nNTF { #1 } \c_@@_option_regex { \tl_set:Nn \l_tmpa_tl { #1 } \tl_regex_replace_once:NNn \l_tmpa_tl \c_@@_option_regex { } \tl_set:Nn \l_tmpb_tl { \str_lowercase:f { \l_tmpa_tl } } \str_set:Nx #2 { \tl_head:f { \l_tmpb_tl } \tl_tail:V \l_tmpa_tl } \prg_return_true: } { \prg_return_false: } } % \end{macrocode} % \begin{markdown} % % To make it easier to support different coding styles in the interface, % engines, we define the \mdef{\@\@_with_various_cases:nn} function % that allows us to generate different variants of a string using % different cases. % % \end{markdown} % \begin{macrocode} \cs_new:Nn \@@_with_various_cases:nn { \seq_clear:N \l_tmpa_seq \seq_map_inline:Nn \g_@@_cases_seq { \tl_set:Nn \l_tmpa_tl { #1 } \use:c { ##1 } \l_tmpa_tl \seq_put_right:NV \l_tmpa_seq \l_tmpa_tl } \seq_map_inline:Nn \l_tmpa_seq { #2 } } % \end{macrocode} % \begin{markdown} % % By default, camelCase and snake\\\_case are supported. % Additional cases can be added by adding functions to the % \mdef{g_\@\@_cases_seq} sequence. % % \end{markdown} % \begin{macrocode} \seq_new:N \g_@@_cases_seq \cs_new:Nn \@@_camel_case:N { \regex_replace_all:nnN { _ ([a-z]) } { \c { str_uppercase:n } \cB\{ \1 \cE\} } #1 \tl_set:Nx #1 { #1 } } \seq_gput_right:Nn \g_@@_cases_seq { @@_camel_case:N } \cs_new:Nn \@@_snake_case:N { \regex_replace_all:nnN { ([a-z])([A-Z]) } { \1 _ \c { str_lowercase:n } \cB\{ \2 \cE\} } #1 \tl_set:Nx #1 { #1 } } \seq_gput_right:Nn \g_@@_cases_seq { @@_snake_case:N } % \end{macrocode} % \iffalse % %<*manual-options> % \fi % \begin{markdown} % %### General Behavior % % \end{markdown} % \iffalse #### Option `eagerCache` `eagerCache` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{eagerCache}{\opt{true}, \opt{false}} % : true : Converted markdown documents will be cached in \Opt{cacheDir}. This can be useful for post-processing the converted documents and for recovering historical versions of the documents from the cache. Furthermore, it can also significantly improve the processing speed for documents that require multiple compilation runs, since each markdown document is only converted once. However, it also produces a large number of auxiliary files on the disk and obscures the output of the Lua command-line interface when it is used for plumbing. This behavior will always be used if the \Opt{finalizeCache} option is enabled. : false : Converted markdown documents will not be cached. This decreases the number of auxiliary files that we produce and makes it easier to use the Lua command-line interface for plumbing. However, it makes it impossible to post-process the converted documents and recover historical versions of the documents from the cache. Furthermore, it can significantly reduce the processing speed for documents that require multiple compilation runs, since each markdown document is converted multiple times needlessly. This behavior will only be used when the \Opt{finalizeCache} option is disabled. % \end{markdown} % \iffalse ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `hello.md` with the following content: ``` md Hello *world*! `````` Next, invoke LuaTeX from the terminal with the \Opt{eagerCache} option disabled: ``` sh markdown2tex eagerCache=false -- hello.md hello.tex ``````` A \TeX{} document named `hello.tex` should be produced and contain the following code: ``` tex Hello \markdownRendererEmphasis{world}!\relax ``` *** Invoke LuaTeX from the terminal again, this time with the \Opt{eagerCache} option enabled: ``` tex markdown2tex eagerCache=true -- hello.md hello.tex ``` A \TeX{} document named `hello.tex` should be produced and contain the following code: ``` tex \input ./⟨hash⟩.md.tex\relax ``` Additionally, a \TeX{} document named `⟨hash⟩.md.tex` should be produced and contain the following code: ``` tex Hello \markdownRendererEmphasis{world}!\relax ``` % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { eagerCache } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.eagerCache = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `experimental` `experimental` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{experimental}{\opt{true}, \opt{false}} % : true : Experimental features that are planned to be the new default in the next major release of the Markdown package will be enabled. At the moment, this has the following effects: 1. The version `experimental` of the theme `witiko/markdown/defaults` will be loaded. 2. Warnings for hard-deprecated features will become errors. 3. The experimental option \Opt{htmlOverLinks} will be enabled. In the future, the effects may extend to other areas as well. : false : Experimental features will be disabled. % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { experimental } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.experimental = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `singletonCache` `singletonCache` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{singletonCache}{\opt{true}, \opt{false}} % : true : Conversion functions produced by the function \luamref{new}`(options)` will be cached in an LRU cache of size 1 keyed by `options`. This is more time- and space-efficient than always producing a new conversion function but may expose bugs related to the idempotence of conversion functions. This has been the default behavior since version 3.0.0 of the Markdown package. : false : Every call to the function \luamref{new}`(options)` will produce a new conversion function that will not be cached. This is slower than caching conversion functions and may expose bugs related to memory leaks in the creation of conversion functions, see also [#226 (comment)][226-comment]. This was the default behavior until version 3.0.0 of the Markdown package. [226-comment]: https://github.com/witiko/markdown/pull/226#issuecomment-1599641634 % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { singletonCache } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.singletonCache = true % \end{macrocode} % \iffalse % %<*lua> % \fi % \begin{macrocode} local singletonCache = { convert = nil, options = nil, } % \end{macrocode} % \iffalse % %<*manual-options> #### Option `unicodeNormalization` `unicodeNormalization` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{unicodeNormalization}{\opt{true}, \opt{false}} % : true : Markdown documents will be normalized using one of the four [Unicode normalization forms][unicode-normalization] before conversion. The Unicode normalization norm used is determined by option \Opt{unicodeNormalizationForm}. : false : Markdown documents will not be Unicode-normalized before conversion. [unicode-normalization]: https://unicode.org/faq/normalization.html % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { unicodeNormalization } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.unicodeNormalization = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `unicodeNormalizationForm` `unicodeNormalizationForm` (default value: `nfc`) % \fi % \begin{markdown} % % \Optitem[nfc]{unicodeNormalizationForm}{\opt{nfc}, \opt{nfd}, \opt{nfkc}, \opt{nfkd}} % : nfc : When option \Opt{unicodeNormalization} has been enabled, markdown documents will be normalized using Unicode Normalization Form C (NFC) before conversion. : nfd : When option \Opt{unicodeNormalization} has been enabled, markdown documents will be normalized using Unicode Normalization Form D (NFD) before conversion. : nfkc : When option \Opt{unicodeNormalization} has been enabled, markdown documents will be normalized using Unicode Normalization Form KC (NFKC) before conversion. : nfkd : When option \Opt{unicodeNormalization} has been enabled, markdown documents will be normalized using Unicode Normalization Form KD (NFKD) before conversion. % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { unicodeNormalizationForm } { string } { nfc } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.unicodeNormalizationForm = "nfc" % \end{macrocode} % \iffalse % %<*manual-options> % \fi % \begin{markdown} % %### File and Directory Names % % \end{markdown} % \iffalse #### Option `cacheDir` `cacheDir` (default value: `"."`) % \fi % \begin{markdown} % % \Valitem[.]{cacheDir}{path} % : A path to the directory containing auxiliary cache files. If the last segment of the path does not exist, it will be created by the Lua command-line and plain \TeX{} implementations. The Lua implementation expects that the entire path already exists. When iteratively writing and typesetting a markdown document, the cache files are going to accumulate over time. You are advised to clean the cache directory every now and then, or to set it to a temporary filesystem (such as `/tmp` on UN*X systems), which gets periodically emptied. % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local convert = markdown.new({cacheDir = "cache"}) local input = "Hello *world*!" tex.sprint(convert(input)) } \endgroup \bye ``````` Create an empty directory named `cache` next to our text document. Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” Several cache files of the Markdown package will also be produced in the `cache` directory as we requested using the `cacheDir` option. ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \begingroup \catcode`\%=12 \catcode`\#=12 \input hello \endgroup \bye ``````` Using a text editor, create a text document named `hello.md` with the following content: ``` md Hello *world*! `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex cacheDir=cache -- hello.md hello.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A directory named `cache` containing several cache files of the Markdown package will also be produced as we requested using the `cacheDir` option. ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionCacheDir{cache} \markdownBegin Hello *world*! \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A directory named `cache` containing several cache files of the Markdown package will also be produced as we requested using the `cacheDir` option. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[cacheDir=cache]{markdown} \begin{document} \begin{markdown} Hello *world*! \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A directory named `cache` containing several cache files of the Markdown package will also be produced as we requested using the `cacheDir` option. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[cacheDir = cache] \starttext \startmarkdown Hello *world*! \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A directory named `cache` containing several cache files of the Markdown package will also be produced as we requested using the `cacheDir` option. % %<*tex> % \fi % \begin{macrocode} \str_new:N \g_@@_unquoted_jobname_str \str_gset:NV \g_@@_unquoted_jobname_str \c_sys_jobname_str \bool_new:N \g_@@_jobname_quoted_bool \regex_replace_all:nnNTF { \A ("|') ( .* ) ("|') \Z } { \2 } \g_@@_unquoted_jobname_str { \bool_gset_true:N \g_@@_jobname_quoted_bool } { \bool_gset_false:N \g_@@_jobname_quoted_bool } \@@_add_lua_option:nnn { cacheDir } { path } { \markdownOptionOutputDir / _markdown_ \str_use:N \g_@@_unquoted_jobname_str } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.cacheDir = "." % \end{macrocode} % \iffalse % %<*manual-options> #### Option `contentBlocksLanguageMap` `contentBlocksLanguageMap` (default value: `"markdown-languages.json"`) % \fi % \begin{markdown} % % \Valitem[markdown-languages.json]{contentBlocksLanguageMap}{filename} % : The filename of the JSON file that maps filename extensions to programming language names in the iA\\,Writer content blocks when the \Opt{contentBlocks} option is enabled. % See Section <#sec:texcontentblockrenderers> for more information. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `table.csv` with the following content: ``` csv Name,Surname,Born Albert,Einstein,1879 Marie,Curie,1867 Thomas,Edison,1847 ``````` Create also a text document named `language-map.json` with the following content: ``` js { "tex": "LaTeX" } `````` Create also a text document named `code.tex` with the following content: ``` tex This is an example code listing in \LaTeX. ``````` Create also a text document named `part.md` with the following content: ``` md This is a *transcluded markdown document*. `````` Create also a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{minted} \usepackage[contentBlocks]{markdown} \markdownSetup{ contentBlocksLanguageMap = {language-map.json}, } \begin{document} \begin{markdown} /table.csv (An example table) /code.tex (An example code listing) /part.md (A file transclusion example) \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex --shell-escape document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > | Name | Surname | Born | > | ------ | ---------| ---- | > | Albert | Einstein | 1879 | > | Marie | Curie | 1867 | > | Thomas | Edison | 1847 | > > Table 1: An example table > > ``` tex > This is an example code listing in \LaTeX. > ``````` > > This is a *transcluded markdown document*. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `table.csv` with the following content: ``` csv Name,Surname,Born Albert,Einstein,1879 Marie,Curie,1867 Thomas,Edison,1847 ``````` Create also a text document named `language-map.json` with the following content: ``` js { "tex": "ConTeXt" } `````` Create also a text document named `code.tex` with the following content: ``` tex This is an example code listing in \ConTeXt. ``````` Create also a text document named `part.md` with the following content: ``` md This is a *transcluded markdown document*. `````` Create also a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown [ contentBlocks = yes, contentBlocksLanguageMap = language-map.json, ] \definetyping [ConTeXt] \setuptyping [ConTeXt] [option=TEX] \starttext \startmarkdown /table.csv (An example table) /code.tex (An example code listing) /part.md (A file transclusion example) \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > | Name | Surname | Born | > | ------ | ---------| ---- | > | Albert | Einstein | 1879 | > | Marie | Curie | 1867 | > | Thomas | Edison | 1847 | > > Table 1: An example table > > ``` tex > This is an example code listing in \ConTeXt. > ``````` > > This is a *transcluded markdown document*. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { contentBlocksLanguageMap } { path } { markdown-languages.json } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.contentBlocksLanguageMap = "markdown-languages.json" % \end{macrocode} % \iffalse % %<*manual-options> #### Option `debugExtensionsFileName` `debugExtensionsFileName` (default value: `"debug-extensions.json"`) % \fi % \begin{markdown} % % \Valitem[debug-extensions.json]{debugExtensionsFileName}{filename} % : The filename of the JSON file that will be produced when the \Opt{debugExtensions} option is enabled. This file will contain the extensible subset of the PEG grammar of markdown % (see the \luamref{walkable_syntax} hash table) after built-in syntax extensions % (see Section <#sec:lua-built-in-extensions>) % \iffalse (see options \Opt{citations}, \Opt{contentBlocks}, \Opt{definitionLists}, etc.) % \fi and user-defined syntax extensions % (see Section <#sec:lua-user-extensions>) % \iffalse (see option \Opt{extensions}) % \fi have been applied. % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { debugExtensionsFileName } { path } { \markdownOptionOutputDir / \str_use:N \g_@@_unquoted_jobname_str .debug-extensions.json } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.debugExtensionsFileName = "debug-extensions.json" % \end{macrocode} % \iffalse % %<*manual-options> #### Option `frozenCacheFileName` `frozenCacheFileName` (default value: `"frozenCache.tex"`) % \fi % \begin{markdown} % % \Valitem[frozenCache.tex]{frozenCacheFileName}{path} % : A path to an output file (frozen cache) that will be created when the \Opt{finalizeCache} option is enabled and will contain a mapping between an enumeration of markdown documents and their auxiliary cache files. The frozen cache makes it possible to later typeset a plain \TeX{} document that contains markdown documents without invoking Lua using the \Opt{frozenCache} plain \TeX{} option. As a result, the plain \TeX{} document becomes more portable, but further changes in the order and the content of markdown documents will not be reflected. % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local convert = markdown.new({finalizeCache = true, frozenCacheFileName = "cache.tex"}) local input = "Hello *world*!" tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A frozen cache will also be produced in the `cache.tex` output file as we requested using the `finalizeCache` and `frozenCacheFileName` options. ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \begingroup \catcode`\%=12 \catcode`\#=12 \input hello \endgroup \bye ``````` Using a text editor, create a text document named `hello.md` with the following content: ``` md Hello *world*! `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex finalizeCache=true frozenCacheFileName=cache.tex -- hello.md hello.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A frozen cache will also be produced in the `cache.tex` output file as we requested using the `finalizeCache` and `frozenCacheFileName` options. ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionFinalizeCache{true} \def\markdownOptionFrozenCacheFileName{cache.tex} \markdownBegin Hello *world*! \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A frozen cache will also be produced in the `cache.tex` output file as we requested using the `finalizeCache` and `frozenCacheFileName` options. Next, create a new text document `frozen-document.tex` with the following content: ``` tex \input markdown \def\markdownOptionFrozenCache{true} \def\markdownOptionFrozenCacheFileName{cache.tex} \markdownBegin Hi *world*! \markdownEnd \bye ``````` Last, invoke pdfTeX without shell access from the terminal: ``` sh pdftex -no-shell-escape frozen-document.tex `````` A PDF document named `frozen-document.pdf` should be produced and contain the text “Hello *world*!” Since we used the contents of the frozen cache using the `\markdownOptionFrozenCache` option, we were able to typeset the document without accessing the shell or invoking Lua, but the change in the content of the markdown document from “Hello *world*!” to “Hi *world*!” was not reflected. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass[finalizecache]{article} \usepackage[frozenCacheFileName=cache.tex]{markdown} \begin{document} \begin{markdown} Hello *world*! \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A frozen cache will also be produced in the `cache.tex` output file as we requested using the `finalizecache` and `frozenCacheFileName` options. Next, create a new text document `frozen-document.tex` with the following content: ``` tex \documentclass[frozencache]{article} \usepackage[frozenCacheFileName=cache.tex]{markdown} \begin{document} \begin{markdown} Hi *world*! \end{markdown} \end{document} ``````` Last, invoke pdfTeX without shell access from the terminal: ``` sh pdflatex -no-shell-escape frozen-document.tex `````` A PDF document named `frozen-document.pdf` should be produced and contain the text “Hello *world*!” Since we used the contents of the frozen cache using the `frozencache` option, we were able to typeset the document without accessing the shell or invoking Lua, but the change in the content of the markdown document from “Hello *world*!” to “Hi *world*!” was not reflected. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown [ finalizeCache = yes, frozenCacheFileName = cache.tex, ] \starttext \startmarkdown Hello *world*! \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A frozen cache will also be produced in the `cache.tex` output file as we requested using the `finalizeCache` and `frozenCacheFileName` options. Next, create a new text document `frozen-document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown [ frozenCache = yes, frozenCacheFileName = cache.tex, ] \starttext \startmarkdown Hi *world*! \stopmarkdown \stoptext ``````` Last, invoke LuaTeX from the terminal: ``` sh context --luatex frozen-document.tex `````` A PDF document named `frozen-document.pdf` should be produced and contain the text “Hello *world*!” Since we used the contents of the frozen cache using the `\markdownOptionFrozenCache` option, we were able to typeset the document without accessing the shell or invoking Lua, but the change in the content of the markdown document from “Hello *world*!” to “Hi *world*!” was not reflected. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { frozenCacheFileName } { path } { \markdownOptionCacheDir / frozenCache.tex } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.frozenCacheFileName = "frozenCache.tex" % \end{macrocode} % \iffalse % %<*manual-options> % \fi % \begin{markdown} % %### Parser Options % % \end{markdown} % \iffalse #### Option `acronyms` `acronyms` (default value: `{}`) % \fi % \begin{markdown} % \Valitem[\{\}]{acronyms}{acronyms} % : Acronyms, initialisms, and other all-caps sequences that will be recognized in markdown text and formatted accordingly. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage{markdown} \markdownSetup { % Format the following words as acronyms. acronyms = {HTML, YAML}, renderers = { % Format acronyms as small caps. acronym = \textsc{\MakeLowercase{#1}}, }, } \begin{document} \begin{markdown} HTML and YAML are two staples of modern tooling that often get mentioned in the same breath, even though they live in very different layers of the stack. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex --shell-escape document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > HTML and YAML are two staples of modern tooling > that often get mentioned in the same breath, even though they live in very > different layers of the stack. % %<*tex> % \fi % \begin{macrocode} \cs_generate_variant:Nn \@@_add_lua_option:nnn { nnV } \@@_add_lua_option:nnV { acronyms } { clist } \c_empty_clist % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.acronyms = {} % \end{macrocode} % \iffalse % %<*manual-options> #### Option `autoIdentifiers` `autoIdentifiers` (default value: `false`) % \fi % \begin{markdown} % \Optitem[false]{autoIdentifiers}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [auto identifiers syntax extension][pandoc-auto-identifiers]: ``` md The following heading received the identifier `sesame-street`: # 123 Sesame Street `````` : false : Disable the Pandoc auto identifiers syntax extension. See also the option \Opt{gfmAutoIdentifiers}. [pandoc-auto-identifiers]: https://pandoc.org/MANUAL.html#extension-auto_identifiers % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { autoIdentifiers } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.autoIdentifiers = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `blankBeforeBlockquote` `blankBeforeBlockquote` (default value: `false`) % \fi % \begin{markdown} % \Optitem[false]{blankBeforeBlockquote}{\opt{true}, \opt{false}} % : true : Require a blank line between a paragraph and the following blockquote. : false : Do not require a blank line between a paragraph and the following blockquote. % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local newline = [[^^J^^J]] local convert, input convert = markdown.new() input = "A paragraph." .. newline .. "> A quote." .. newline tex.sprint(convert(input)) convert = markdown.new({blankBeforeBlockquote = true}) input = "A paragraph." .. newline .. "> Not a quote." .. newline tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > > A quote. > > A paragraph > Not a quote. ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ``` md A paragraph. > A quote? `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex -- content.md optionfalse.tex markdown2tex blankBeforeBlockquote=true -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > > A quote? > > A paragraph. > A quote? ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \markdownBegin A paragraph. > A quote. \markdownEnd \def\markdownOptionBlankBeforeBlockquote{true} \markdownBegin A paragraph. > Not a quote. \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > > A quote. > > A paragraph > Not a quote. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} A paragraph. > A quote. \end{markdown} \begin{markdown}[blankBeforeBlockquote] A paragraph. > Not a quote. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > > A quote. > > A paragraph > Not a quote. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \startmarkdown A paragraph. > A quote. \stopmarkdown \setupmarkdown[blankBeforeBlockquote = yes] \startmarkdown A paragraph. > Not a quote. \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > > A quote. > > A paragraph > Not a quote. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { blankBeforeBlockquote } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeBlockquote = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `blankBeforeCodeFence` `blankBeforeCodeFence` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{blankBeforeCodeFence}{\opt{true}, \opt{false}} % : true : Require a blank line between a paragraph and the following fenced code block. : false : Do not require a blank line between a paragraph and the following fenced code block. % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local newline = [[^^J^^J]] local convert, input convert = markdown.new({fencedCode = true}) input = "A paragraph." .. newline .. "```" .. newline .. "A fenced code." .. newline .. "```" .. newline tex.sprint(convert(input)) convert = markdown.new({ fencedCode = true, blankBeforeCodeFence = true}) input = "A paragraph." .. newline .. "```" .. newline .. "Not a fenced code." .. newline .. "```" .. newline tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > ``` > A fenced code. > ``` > > A paragraph. ``` Not a fenced code. ``` ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ```` md A paragraph. ``` A code fence? ``` ``````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex fencedCode=true -- content.md optionfalse.tex markdown2tex fencedCode=true blankBeforeCodeFence=true -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > ``` > A code fence? > ``` > > A paragraph. ``` A code fence? ``` ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \input markdown \def\markdownOptionFencedCode{true} \markdownBegin A paragraph. ``` A fenced code. ``` \markdownEnd \def\markdownOptionBlankBeforeCodeFence{true} \markdownBegin A paragraph. ``` Not a fenced code. ``` \markdownEnd \bye ```````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > ``` > A fenced code. > ``` > > A paragraph. ``` Not a fenced code. ``` ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage[fencedCode]{markdown} \begin{document} \begin{markdown} A paragraph. ``` A fenced code. ``` \end{markdown} \begin{markdown}[blankBeforeCodeFence] A paragraph. ``` Not a fenced code. ``` \end{markdown} \end{document} ```````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > ``` > A fenced code. > ``` > > A paragraph. ``` Not a fenced code. ``` ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \usemodule[t][markdown] \setupmarkdown[fencedCode = yes] \starttext \startmarkdown A paragraph. ``` A fenced code. ``` \stopmarkdown \setupmarkdown[blankBeforeCodeFence = yes] \startmarkdown A paragraph. ``` Not a fenced code. ``` \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > ``` > A fenced code. > ``` > > A paragraph. ``` Not a fenced code. ``` % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { blankBeforeCodeFence } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeCodeFence = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `blankBeforeDivFence` `blankBeforeDivFence` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{blankBeforeDivFence}{\opt{true}, \opt{false}} % : true : Require a blank line before the closing fence of a fenced div. : false : Do not require a blank line before the closing fence of a fenced div. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage[fencedDivs]{markdown} \begin{document} \begin{markdown} A paragraph. ::: {.identifier} A fenced div. ::: \end{markdown} \begin{markdown}[blankBeforeDivFence] A paragraph. ::: {.identifier} Not a fenced div. ::: \end{markdown} \end{document} ```````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > A fenced div. > > A paragraph. > > ::: {.identifier} Not a fenced div. ::: % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { blankBeforeDivFence } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeDivFence = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `blankBeforeHeading` `blankBeforeHeading` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{blankBeforeHeading}{\opt{true}, \opt{false}} % : true : Require a blank line between a paragraph and the following header. : false : Do not require a blank line between a paragraph and the following header. % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \def\markdownRendererHeadingOne#1{{\bf #1}\par} \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local newline = [[^^J^^J]] local convert, input convert = markdown.new() input = "A paragraph." .. newline .. "A heading." .. newline .. "==========" .. newline tex.sprint(convert(input)) convert = markdown.new({blankBeforeHeading = true}) input = "A paragraph." .. newline .. "Not a heading." .. newline .. "==============" .. newline tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > A heading. > ========== > > A paragraph. Not a heading. ============== ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ``` md A paragraph. A heading? ========== `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex -- content.md optionfalse.tex markdown2tex blankBeforeHeading=true -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > A heading? > ========== > > A paragraph. A heading? ========== ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \markdownBegin A paragraph. A heading. ========== \markdownEnd \def\markdownOptionBlankBeforeHeading{true} \markdownBegin A paragraph. Not a heading. ============== \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > A heading. > ========== > > A paragraph. Not a heading. ============== ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} A paragraph. A heading. ========== \end{markdown} \begin{markdown}[blankBeforeHeading] A paragraph. Not a heading. ============== \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > A heading. > ========== > > A paragraph. Not a heading. ============== ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \startmarkdown A paragraph. A heading. ========== \stopmarkdown \setupmarkdown[blankBeforeHeading = yes] \startmarkdown A paragraph. Not a heading. ============== \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > A heading. > ========== > > A paragraph. Not a heading. ============== % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { blankBeforeHeading } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeHeading = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `blankBeforeHtmlBlock` `blankBeforeHtmlBlock` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{blankBeforeHtmlBlock}{\opt{true}, \opt{false}} % : true : Require a blank line between a paragraph and the following [CommonMark HTML block][html-block]. : false : Do not require a blank line between a paragraph and the following CommonMark HTML block. [html-block]: https://spec.commonmark.org/0.31.2/#html-blocks % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[blankBeforeHtmlBlock]{markdown} \usepackage{marginnote} \markdownSetup{ renderers = { inlineHtmlComment = \marginnote{#1}, }, } \begin{document} \begin{markdown} A useful use of block HTML comments are side notes. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following body text: > A useful use of HTML comments are side notes. The horizontal margins should contain the following text: > Side notes are displayed in the horizontal margins next to the relevant > passages, which makes them *easier for the reader to find* than notes. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { blankBeforeHtmlBlock } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeHtmlBlock = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `blankBeforeList` `blankBeforeList` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{blankBeforeList}{\opt{true}, \opt{false}} % : true : Require a blank line between a paragraph and the following list. : false : Do not require a blank line between a paragraph and the following list. % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local newline = [[^^J^^J]] local convert, input convert = markdown.new() input = "A paragraph." .. newline .. "- a list" .. newline tex.sprint(convert(input)) convert = markdown.new({ blankBeforeList = true}) input = "A paragraph." .. newline .. "- not a list" .. newline tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > - a list > > A paragraph. - not a list ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ```` md A paragraph. - a list? ``````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex -- content.md optionfalse.tex markdown2tex blankBeforeList=true -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > - a list? > > A paragraph. - a list? ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \input markdown \markdownBegin A paragraph. - a list \markdownEnd \def\markdownOptionBlankBeforeList{true} \markdownBegin A paragraph. - not a list \markdownEnd \bye ```````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > - a list > > A paragraph. - not a list ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} A paragraph. - a list \end{markdown} \begin{markdown}[blankBeforeList] A paragraph. - not a list \end{markdown} \end{document} ```````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > - a list > > A paragraph. - not a list ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \usemodule[t][markdown] \starttext \startmarkdown A paragraph. - a list \stopmarkdown \setupmarkdown[blankBeforeList = yes] \startmarkdown A paragraph. - not a list \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A paragraph. > > - a list > > A paragraph. - not a list % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { blankBeforeList } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.blankBeforeList = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `bracketedSpans` `bracketedSpans` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{bracketedSpans}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [bracketed span syntax extension][pandoc-bracketed-spans]: ``` md [This is *some text*]{.class key=val} `````` : false : Disable the Pandoc bracketed span syntax extension. [pandoc-bracketed-spans]: https://pandoc.org/MANUAL.html#extension-bracketed_spans % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage[bracketedSpans]{markdown} \usepackage{expl3} \ExplSyntaxOn \markdownSetup{ renderers = { bracketedSpanAttributeContextBegin = { \group_begin: \color_group_begin: \markdownSetup{ renderers = { attributeKeyValue = { \str_if_eq:nnT { ##1 } { color } { \color_select:n { ##2 } } }, }, } }, bracketedSpanAttributeContextEnd = { \color_group_end: \group_end: }, }, } \ExplSyntaxOff \begin{document} \begin{markdown} Here is some [colored text]{color=red}. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > Here is some colored text. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { bracketedSpans } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.bracketedSpans = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `breakableBlockquotes` `breakableBlockquotes` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{breakableBlockquotes}{\opt{true}, \opt{false}} % : true : A blank line separates block quotes. : false : Blank lines in the middle of a block quote are ignored. % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \def\markdownRendererHeadingOne#1{{\bf #1}\par} \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local newline = [[^^J^^J]] local convert, input convert = markdown.new({breakableBlockquotes = false}) input = "> A single" .. newline .. newline .. "> block quote." .. newline tex.sprint(convert(input)) convert = markdown.new() input = "> A block quote." .. newline .. newline .. "> Another block quote." .. newline tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > > A single block quote. > > > A block quote. > > > Another block quote. ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ``` md > A single block quote > or two block quotes? `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex breakableBlockquotes=false -- content.md optionfalse.tex markdown2tex -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > > A single block quote or two block quotes? > > > A single block quote > > > or two block quotes? ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionBreakableBlockquotes{false} \markdownBegin > A single > block quote. \markdownEnd \def\markdownOptionBreakableBlockquotes{true} \markdownBegin > A block quote. > Another block quote. \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > > A single block quote. > > > A block quote. > > > Another block quote. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown}[breakableBlockquotes = false] > A single > block quote. \end{markdown} \begin{markdown} > A block quote. > Another block quote. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > > A single block quote. > > > A block quote. > > > Another block quote. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \setupmarkdown[breakableBlockquotes = no] \startmarkdown > A single > block quote. \stopmarkdown \setupmarkdown[breakableBlockquotes = yes] \startmarkdown > A block quote. > Another block quote. \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > > A single block quote. > > > A block quote. > > > Another block quote. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { breakableBlockquotes } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.breakableBlockquotes = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `citationNbsps` `citationNbsps` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[false]{citationNbsps}{\opt{true}, \opt{false}} % : true : Replace regular spaces with non-breaking spaces inside the prenotes and postnotes of citations produced via the pandoc citation syntax extension. : false : Do not replace regular spaces with non-breaking spaces inside the prenotes and postnotes of citations produced via the pandoc citation syntax extension. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.bib` with the following content: ``` bib @book{knuth:tex, author = "Knuth, Donald Ervin", title = "The \TeX book, volume A of Computers and typesetting", publisher = "Addison-Wesley", year = "1984" } ``````` Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[citations]{markdown} \begin{document} \begin{markdown} The TeXbook [@knuth:tex, p. 123 and 130] is good. \end{markdown} \begin{markdown}[citationNbsps = false] The TeXbook [@knuth:tex, p. 123 and 130] is good. \end{markdown} \bibliographystyle{plain} \bibliography{document.bib} \end{document} ``````` Next, invoke LuaTeX and BibTeX from the terminal: ``` sh lualatex document.tex bibtex document.aux lualatex document.tex lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text, where the middot (`·`) denotes a non-breaking space: > The TeXbook [1, p.·123·and·130] is good. > > The TeXbook [1, p. 123 and 130] is good. > > ### References > [1] Donald·Ervin Knuth. _The TeXbook, volume A of Computers and typesetting._ > Addison-Wesley, 1984. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { citationNbsps } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.citationNbsps = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `citations` `citations` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{citations}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [citation syntax extension][pandoc-citations]: ``` md Here is a simple parenthetical citation [@doe99] and here is a string of several [see @doe99, pp. 33-35; also @smith04, chap. 1]. A parenthetical citation can have a [prenote @doe99] and a [@smith04 postnote]. The name of the author can be suppressed by inserting a dash before the name of an author as follows [-@smith04]. Here is a simple text citation @doe99 and here is a string of several @doe99 [pp. 33-35; also @smith04, chap. 1]. Here is one with the name of the author suppressed -@doe99. `````` : false : Disable the Pandoc citation syntax extension. [pandoc-citations]: https://pandoc.org/MANUAL.html#extension-citations % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.bib` with the following content: ``` bib @book{knuth:tex, author = "Knuth, Donald Ervin", title = "The \TeX book, volume A of Computers and typesetting", publisher = "Addison-Wesley", year = "1984" } ``````` Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[backend=biber]{biblatex} \addbibresource{document.bib} \usepackage[citations]{markdown} \begin{document} \begin{markdown} The TeXbook [@knuth:tex, p. 123 and 130] was written by @knuth:tex. \end{markdown} \printbibliography \end{document} ``````` Next, invoke LuaTeX and Biber from the terminal: ``` sh lualatex document.tex biber document.bcf lualatex document.tex lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > The TeXbook [1, p.·123 and 130] was written by Knuth [1]. > > ### References > [1] Donald Ervin Knuth. _The \TeX{}book, volume A of Computers and typesetting._ > Addison-Wesley, 1984. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { citations } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.citations = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `codeSpans` `codeSpans` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{codeSpans}{\opt{true}, \opt{false}} % : true : Enable the code span syntax: ~~~ md Use the `printf()` function. ``There is a literal backtick (`) here.`` ~~~ : false : Disable the code span syntax. This allows you to easily use the quotation mark ligatures in texts that do not contain code spans: ~~~ ``This is a quote.'' ~~~~~~ % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local convert = markdown.new() local input = "``This is a code span.'' " .. "``This is no longer a code span.''" tex.sprint(convert(input)) } \par \directlua{ local markdown = require("markdown") local convert = markdown.new({codeSpans = false}) local input = "``This is a quote.'' " .. "``This is another quote.''" tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > ``This is a code span.'' ``This is no longer a code span.'' > > “This is a quote.” “This is another quote.” ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \par \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ``` md ``Is this a code span?'' ``Or a quote?'' `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex codeSpans=false -- content.md optionfalse.tex markdown2tex -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > “Is this a code span?” “Or a quote?” > > ``Is this a code span?'' ``Or a quote?'' ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \markdownBegin ``This is a code span.'' ``This is no longer a code span.'' \markdownEnd \def\markdownOptionCodeSpans{false} \markdownBegin ``This is a quote.'' ``This is another quote.'' \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > ``This is a code span.'' ``This is no longer a code span.'' > > “This is a quote.” “This is another quote.” ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} ``This is a code span.'' ``This is no longer a code span.'' \end{markdown} \begin{markdown}[codeSpans=false] ``This is a quote.'' ``This is another quote.'' \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > ``This is a code span.'' ``This is no longer a code span.'' > > “This is a quote.” “This is another quote.” ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \startmarkdown ``This is a code span.'' ``This is no longer a code span.'' \stopmarkdown \setupmarkdown[codeSpans = no] \startmarkdown ``This is a quote.'' ``This is another quote.'' \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > ``This is a code span.'' ``This is no longer a code span.'' > > “This is a quote.” “This is another quote.” % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { codeSpans } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.codeSpans = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `contentBlocks` `contentBlocks` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{contentBlocks}{\opt{true}, \opt{false}} % : true : Enable the % iA\\,Writer content blocks syntax extension~[@sotkov17]: % \iffalse iA\\,Writer content blocks syntax extension: % \fi ``` md http://example.com/minard.jpg (Napoleon's disastrous Russian campaign of 1812) /Flowchart.png "Engineering Flowchart" /Savings Account.csv 'Recent Transactions' /Example.swift /Lorem Ipsum.txt `````` : false : Disable the iA\\,Writer content blocks syntax extension. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `table.csv` with the following content: ``` csv Name,Surname,Born Albert,Einstein,1879 Marie,Curie,1867 Thomas,Edison,1847 ``````` Create also a text document named `markdown-languages.json` with the following content: ``` js { "tex": "LaTeX" } `````` Create also a text document named `code.tex` with the following content: ``` tex This is an example code listing in \LaTeX. ``````` Create also a text document named `part.md` with the following content: ``` md This is a *transcluded markdown document*. `````` Create also a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{minted} \usepackage[contentBlocks]{markdown} \begin{document} \begin{markdown} /table.csv (An example table) /code.tex (An example code listing) /part.md (A file transclusion example) \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex --shell-escape document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > | Name | Surname | Born | > | ------ | ---------| ---- | > | Albert | Einstein | 1879 | > | Marie | Curie | 1867 | > | Thomas | Edison | 1847 | > > Table 1: An example table > > ``` tex > This is an example code listing in \LaTeX. > ``````` > > This is a *transcluded markdown document*. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `table.csv` with the following content: ``` csv Name,Surname,Born Albert,Einstein,1879 Marie,Curie,1867 Thomas,Edison,1847 ``````` Create also a text document named `markdown-languages.json` with the following content: ``` js { "tex": "ConTeXt" } `````` Create also a text document named `code.tex` with the following content: ``` tex This is an example code listing in \ConTeXt. ``````` Create also a text document named `part.md` with the following content: ``` md This is a *transcluded markdown document*. `````` Create also a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[contentBlocks = yes] \definetyping [ConTeXt] \setuptyping [ConTeXt] [option=TEX] \starttext \startmarkdown /table.csv (An example table) /code.tex (An example code listing) /part.md (A file transclusion example) \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > | Name | Surname | Born | > | ------ | ---------| ---- | > | Albert | Einstein | 1879 | > | Marie | Curie | 1867 | > | Thomas | Edison | 1847 | > > Table 1: An example table > > ``` tex > This is an example code listing in \ConTeXt. > ``````` > > This is a *transcluded markdown document*. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { contentBlocks } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.contentBlocks = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `contentLevel` `contentLevel` (default value: `block`) % \fi % \begin{markdown} % % \Optitem[block]{contentLevel}{\opt{block}, \opt{inline}} % : block : Treat content as a sequence of blocks. ``` md - this is a list - it contains two items `````` : inline : Treat all content as inline content. ``` md - this is a text - not a list `````` % \end{markdown} % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionContentLevel{inline} \markdownBegin - this is - a text \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \- this is - a text ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} - this is - a list \end{markdown} \begin{markdown}[contentLevel=inline] - this is - a text \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > - this is > - a list > > \- this is - a text ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \startmarkdown - this is - a list \stopmarkdown \setupmarkdown[contentLevel = inline] \startmarkdown - this is - a text \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > - this is > - a list > > \- this is - a text % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { contentLevel } { string } { block } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.contentLevel = "block" % \end{macrocode} % \iffalse % %<*manual-options> #### Option `debugExtensions` `debugExtensions` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{debugExtensions}{\opt{true}, \opt{false}} % : true : Produce a JSON file that will contain the extensible subset of the PEG grammar of markdown % (see the \luamref{walkable_syntax} hash table) after built-in syntax extensions % (see Section <#sec:lua-built-in-extensions>) % \iffalse (see options \Opt{citations}, \Opt{contentBlocks}, \Opt{definitionLists}, etc.) % \fi and user-defined syntax extensions % (see Section <#sec:lua-user-extensions>) % \iffalse (see option \Opt{extensions}) % \fi have been applied. This helps you to see how the different extensions interact. The name of the produced JSON file is controlled by the \Opt{debugExtensionsFileName} option. : false : Do not produce a JSON file with the PEG grammar of markdown. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `strike-through.lua` with the following content: ``` lua local strike_through = { api_version = 2, grammar_version = 4, finalize_grammar = function(reader) local nonspacechar = lpeg.P(1) - lpeg.S("\t ") local doubleslashes = lpeg.P("//") local function between(p, starter, ender) ender = lpeg.B(nonspacechar) * ender return (starter * #nonspacechar * lpeg.Ct(p * (p - ender)^0) * ender) end local read_strike_through = between( lpeg.V("Inline"), doubleslashes, doubleslashes ) / function(s) return {"\\st{", s, "}"} end reader.insert_pattern("Inline after LinkAndEmph", read_strike_through, "StrikeThrough") reader.add_special_character("/") end } return strike_through ``````` Using a text editor, create also a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{soul} \usepackage[extension = strike-through.lua, debugExtensions]{markdown} \begin{document} \begin{markdown} This is //a lunar roving vehicle// strike-through text. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is ~~a lunar roving vehicle~~ strike-through text. Furthermore, a JSON document named `document.debug-extensions.json` should also be produced and contain the following text: ``` json { "Block": [ "Blockquote", "Verbatim", "FencedCode (built-in fenced_code syntax extension)", "ThematicBreak", "BulletList", "OrderedList", "DisplayHtml", "Heading" ], "BlockOrParagraph": [ "Block", "Paragraph", "Plain" ], "EndlineExceptions": [ "EndlineExceptions (built-in fenced_code syntax extension)" ], "Inline": [ "Str", "Space", "Endline", "EndlineBreak", "LinkAndEmph", "StrikeThrough (user-defined \"./strike-through.lua\" syntax extension)", "Code", "AutoLinkUrl", "AutoLinkEmail", "AutoLinkRelativeReference", "InlineHtml", "HtmlEntity", "EscapedChar", "Smart", "Symbol" ] } ```````` This output shows us that our user-defined syntax extension has been correctly inserted to the grammar of markdown. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { debugExtensions } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.debugExtensions = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `definitionLists` `definitionLists` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{definitionLists}{\opt{true}, \opt{false}} % : true : Enable the pandoc definition list syntax extension: ``` md Term 1 : Definition 1 Term 2 with *inline markup* : Definition 2 { some code, part of Definition 2 } Third paragraph of definition 2. ````` : false : Disable the pandoc definition list syntax extension. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[definitionLists]{markdown} \begin{document} \begin{markdown} Term 1 : Definition 1 Term 2 with *inline markup* : Definition 2 { some code, part of Definition 2 } Third paragraph of definition 2. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > Term 1 > > : Definition 1 > > Term 2 with *inline markup* > > : Definition 2 > > { some code, part of Definition 2 } > > Third paragraph of definition 2. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[definitionLists = yes] \starttext \startmarkdown Term 1 : Definition 1 Term 2 with *inline markup* : Definition 2 { some code, part of Definition 2 } Third paragraph of definition 2. \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > Term 1 > > : Definition 1 > > Term 2 with *inline markup* > > : Definition 2 > > { some code, part of Definition 2 } > > Third paragraph of definition 2. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { definitionLists } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.definitionLists = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `ensureJekyllData` `ensureJekyllData` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{ensureJekyllData}{\opt{true}, \opt{false}} % : true : When the \Opt{jekyllData} and \Opt{expectJekyllData} options are enabled, then a markdown document must begin directly with YAML metadata and must contain nothing but YAML metadata. Otherwise, an error is produced. : false : When the \Opt{jekyllData} and \Opt{expectJekyllData} options are enabled, then a markdown document may begin directly with YAML metadata and may contain nothing but YAML metadata. Otherwise, the markdown document is processed as markdown text. % See also the plain \TeX{} macros \mref{yamlBegin}, \mref{yamlEnd}, and % \mref{yamlInput} in Section <#sec:tex-typesetting>, the \LaTeX{} environment % \envmref{yaml} in Section <#sec:latex-typesetting>, and the \Hologo{ConTeXt} % macros \mref{startyaml}, \mref{stopyaml}, and \mref{inputyaml} in Section % <#sec:context-typesetting> to see how the options \Opt{jekyllData}, % \Opt{expectJekyllData}, and \Opt{ensureJekyllData} can be used together to % implement high-level interfaces for processing YAML documents. % % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { ensureJekyllData } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.ensureJekyllData = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `expectJekyllData` `expectJekyllData` (default value: `false`) % \fi % \markdownBegin % % \Optitem[false]{expectJekyllData}{\opt{true}, \opt{false}} % : true : When the \Opt{jekyllData} option is enabled, then a markdown document may begin directly with YAML metadata and may contain nothing but YAML metadata. ~~~~~ latex \documentclass{article} \usepackage[jekyllData, expectJekyllData]{markdown} \begin{document} \begin{markdown} - this - is - YAML ... - followed - by - Markdown \end{markdown} \begin{markdown} - this - is - YAML \end{markdown} \end{document} ~~~~~~~~~~~ : false : When the \Opt{jekyllData} option is enabled, then a markdown document may begin with YAML metadata if and only if the metadata begin with the end-of-directives marker (`---`) and they end with either the end-of-directives or the end-of-document marker (`...`): ~~~~~ latex \documentclass{article} \usepackage[jekyllData]{markdown} \begin{document} \begin{markdown} --- - this - is - YAML ... - followed - by - Markdown \end{markdown} \begin{markdown} - this - is - Markdown \end{markdown} \end{document} ~~~~~~~~~~~ % See also the plain \TeX{} macros \mref{yamlBegin}, \mref{yamlEnd}, and % \mref{yamlInput} in Section <#sec:tex-typesetting>, the \LaTeX{} environment % \envmref{yaml} in Section <#sec:latex-typesetting>, and the \Hologo{ConTeXt} % macros \mref{startyaml}, \mref{stopyaml}, and \mref{inputyaml} in Section % <#sec:context-typesetting> to see how the options \Opt{jekyllData}, % \Opt{expectJekyllData}, and \Opt{ensureJekyllData} can be used together to % implement high-level interfaces for processing YAML documents. % % \markdownEnd % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `jane-doe.yml` with the following content: ``` yaml name: Jane Doe age: 99 ``` Using a text editor, create also a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[jekyllData]{markdown} \markdownSetup{ jekyllDataRenderers = { name = {\gdef\name{#1}}, code = {\gdef\age{#1}}, }, renderers = { jekyllDataEnd = {\name{} is \age{} years old.}, } } \begin{document} \markdownInput[expectJekyllData]{jane-doe.yml} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > Jane Doe is 99 years old. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { expectJekyllData } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.expectJekyllData = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `extensions` `extensions` (default value: `{}`) % \fi % \begin{markdown} % % \Valitem[\{\}]{extensions}{filenames} % : The filenames of user-defined syntax extensions that will be applied to the markdown reader. If the \pkg{kpathsea} library is available, files will be searched for not only in the current working directory but also in the \TeX{} directory structure. % A user-defined syntax extension is a Lua file in the following format: % % ``` lua % local strike_through = { % api_version = 2, % grammar_version = 4, % finalize_grammar = function(reader) % local nonspacechar = lpeg.P(1) - lpeg.S("\t ") % local doubleslashes = lpeg.P("//") % local function between(p, starter, ender) % ender = lpeg.B(nonspacechar) * ender % return (starter * #nonspacechar % * lpeg.Ct(p * (p - ender)^0) * ender) % end % % local read_strike_through = between( % lpeg.V("Inline"), doubleslashes, doubleslashes % ) / function(s) return {"\\st{", s, "}"} end % % reader.insert_pattern("Inline after LinkAndEmph", % read_strike_through, % "StrikeThrough") % reader.add_special_character("/") % end % } % % return strike_through % ``````` % % The `api_version` and `grammar_version` fields specify the version of the % user-defined syntax extension API and the markdown grammar for which % the extension was written. See the current API and grammar versions % below: % % \end{markdown} % \iffalse % %<*lua> % \fi % \begin{macrocode} metadata.user_extension_api_version = 2 metadata.grammar_version = 4 % \end{macrocode} % \iffalse % %<*manual-options> % \fi % \begin{markdown} % % Any changes to the syntax extension API or grammar will cause the % corresponding current version to be incremented. After Markdown 3.0.0, % any changes to the API and the grammar will be either backwards-compatible % or constitute a breaking change that will cause the major version of the % Markdown package to increment (to 4.0.0). % % The `finalize_grammar` field is a function that finalizes the grammar of % markdown using the interface of a Lua \luamref{reader} object, such as % the \luamref{reader->insert_pattern} and % \luamref{reader->add_special_character} methods, % see Section <#sec:lua-user-extensions>. % % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `strike-through.lua` with the following content: ``` lua local strike_through = { api_version = 2, grammar_version = 4, finalize_grammar = function(reader) local nonspacechar = lpeg.P(1) - lpeg.S("\t ") local doubleslashes = lpeg.P("//") local function between(p, starter, ender) ender = lpeg.B(nonspacechar) * ender return (starter * #nonspacechar * lpeg.Ct(p * (p - ender)^0) * ender) end local read_strike_through = between( lpeg.V("Inline"), doubleslashes, doubleslashes ) / function(s) return {"\\st{", s, "}"} end reader.insert_pattern("Inline after LinkAndEmph", read_strike_through, "StrikeThrough") reader.add_special_character("/") end } return strike_through ``````` Using a text editor, create also a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{soul} \usepackage[extension = strike-through.lua]{markdown} \begin{document} \begin{markdown} This is //a lunar roving vehicle// strike-through text. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is ~~a lunar roving vehicle~~ strike-through text. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnV { extensions } { clist } \c_empty_clist % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.extensions = {} % \end{macrocode} % \iffalse % %<*manual-options> #### Option `fancyLists` `fancyLists` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{fancyLists}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [fancy list syntax extension][pandoc-fancy-lists]: ``` md a) first item b) second item c) third item `````` : false : Disable the Pandoc fancy list syntax extension. [pandoc-fancy-lists]: https://pandoc.org/MANUAL.html#org-fancy-lists % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage{minted} \usepackage[fancyLists]{markdown} \begin{document} \begin{markdown} a) first item b) second item c) third item \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex --shell-escape document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > a) first item > b) second item > c) third item ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \usemodule[t][markdown] \setupmarkdown[fancyLists = yes] \starttext \startmarkdown a) first item b) second item c) third item \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > a) first item > b) second item > c) third item % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { fancyLists } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.fancyLists = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `fencedCode` `fencedCode` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{fencedCode}{\opt{true}, \opt{false}} % : true : Enable the commonmark fenced code block extension: ~~~~~~~~ md ~~~ js if (a > 3) { moveShip(5 * gravity, DOWN); } ~~~~~~ ``` html
            
              // Some comments
              line 1 of code
              line 2 of code
              line 3 of code
            
          
``` ~~~~~~~~~~~ : false : Disable the commonmark fenced code block extension. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage{minted} \usepackage{markdown} \begin{document} \begin{markdown} ~~~ js if (a > 3) { moveShip(5 * gravity, DOWN); } ~~~~~~ ``` html
    
      // Some comments
      line 1 of code
      line 2 of code
      line 3 of code
    
  
``` \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex --shell-escape document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > ``` js > if (a > 3) { > moveShip(5 * gravity, DOWN); > } > ``` > > ``` html >
>   
>     // Some comments
>     line 1 of code
>     line 2 of code
>     line 3 of code
>   
> 
> ``` ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \usemodule[t][markdown] \definetyping [js] \definetyping [html] \setuptyping [html] [option=XML] \starttext \startmarkdown ~~~ js if (a > 3) { moveShip(5 * gravity, DOWN); } ~~~~~~ ``` html
    
      // Some comments
      line 1 of code
      line 2 of code
      line 3 of code
    
  
``` \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > ``` js > if (a > 3) { > moveShip(5 * gravity, DOWN); > } > ``` > > ``` html >
>   
>     // Some comments
>     line 1 of code
>     line 2 of code
>     line 3 of code
>   
> 
> ``` % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { fencedCode } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.fencedCode = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `fencedCodeAttributes` `fencedCodeAttributes` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{fencedCodeAttributes}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [fenced code attribute syntax extension][pandoc-fenced-code-attributes]: ```````` md ~~~~ {#mycode .haskell .numberLines startFrom=100} qsort [] = [] qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``````````` : false : Disable the Pandoc fenced code attribute syntax extension. [pandoc-fenced-code-attributes]: https://pandoc.org/MANUAL.html#extension-fenced_code_attributes % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage[fencedCode, fencedCodeAttributes]{markdown} \usepackage{minted} \markdownSetup{ renderers = { fencedCodeAttributeContextBegin = {% \begingroup \markdownSetup{ renderers = { attributeKeyValue = {% \setminted{{#1} = {#2}}% }, }, }% }, fencedCodeAttributeContextEnd = {% \endgroup }, }, } \begin{document} \begin{markdown} ~~~ js {linenos=true} if (a > 3) { moveShip(5 * gravity, DOWN); } ~~~~~~ \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex --shell-escape document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > ``` js {.linenos} > 1. if (a > 3) { > 2. moveShip(5 * gravity, DOWN); > 3. } > `````` % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { fencedCodeAttributes } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.fencedCodeAttributes = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `fencedDivs` {#fenced-divs} `fencedDivs` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{fencedDivs}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [fenced div syntax extension][pandoc-fenced-divs]: ``` md ::::: {#special .sidebar} Here is a paragraph. And another. ::::: `````` : false : Disable the Pandoc fenced div syntax extension. [pandoc-fenced-divs]: https://pandoc.org/MANUAL.html#extension-fenced_divs % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage[fencedDivs]{markdown} \begin{document} \begin{markdown}{slice=special} Here is a regular paragraph. ::::: {#special} Here is a special paragraph. ::::: And here is another regular paragraph. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex --shell-escape document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > Here is a special paragraph. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { fencedDivs } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.fencedDivs = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `finalizeCache` `finalizeCache` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{finalizeCache}{\opt{true}, \opt{false}} % : Whether an output file specified with the \Opt{frozenCacheFileName} option (frozen cache) that contains a mapping between an enumeration of markdown documents and their auxiliary cache files will be created. The frozen cache makes it possible to later typeset a plain \TeX{} document that contains markdown documents without invoking Lua using the \Opt{frozenCache} plain \TeX{} option. As a result, the plain \TeX{} document becomes more portable, but further changes in the order and the content of markdown documents will not be reflected. % \end{markdown} % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionFinalizeCache{true} \markdownBegin Hello *world*! \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A frozen cache will also be produced as we requested using the `finalizeCache` option. Next, change the content of `document.tex` as follows: ``` tex \input markdown \def\markdownOptionFrozenCache{true} \markdownBegin Hi *world*! \markdownEnd \bye ``````` Last, invoke pdfTeX without shell access from the terminal: ``` sh pdftex -no-shell-escape document.tex `````` A new PDF document named `document.pdf` should be produced and contain the same text “Hello *world*!” Since we used the contents of the frozen cache using the `\markdownOptionFrozenCache` option, we were able to typeset the document without accessing the shell or invoking Lua, but the change in the content of the markdown document from “Hello *world*!” to “Hi *world*!” was not reflected. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass[finalizecache]{article} \usepackage{markdown} \begin{document} \begin{markdown} Hello *world*! \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A frozen cache will also be produced as we requested using the `finalizecache` option. Next, change the content of `document.tex` as follows: ``` tex \documentclass[frozencache]{article} \usepackage{markdown} \begin{document} \begin{markdown} Hi *world*! \end{markdown} \end{document} ``````` Last, invoke pdfTeX without shell access from the terminal: ``` sh pdflatex -no-shell-escape document.tex `````` A new PDF document named `document.pdf` should be produced and contain the same text “Hello *world*!” Since we used the contents of the frozen cache using the `\markdownOptionFrozenCache` option, we were able to typeset the document without accessing the shell or invoking Lua, but the change in the content of the markdown document from “Hello *world*!” to “Hi *world*!” was not reflected. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[finalizeCache = yes] \starttext \startmarkdown Hello *world*! \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A frozen cache will also be produced in the `cache.tex` output file as we requested using the `finalizeCache` option. Next, change the content of `document.tex` as follows: ``` tex \usemodule[t][markdown] \setupmarkdown[frozenCache = yes] \starttext \startmarkdown Hi *world*! \stopmarkdown \stoptext ``````` Last, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A new PDF document named `document.pdf` should be produced and contain the same text “Hello *world*!” Since we used the contents of the frozen cache using the `\markdownOptionFrozenCache` option, we were able to typeset the document without accessing the shell or invoking Lua, but the change in the content of the markdown document from “Hello *world*!” to “Hi *world*!” was not reflected. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { finalizeCache } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.finalizeCache = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `frozenCacheCounter` `frozenCacheCounter` (default value: `0`) % \fi % \begin{markdown} % % \Valitem[0]{frozenCacheCounter}{number} % : The number of the current markdown document that will be stored in an output file (frozen cache) when the \Opt{finalizeCache} is enabled. When the document number is 0, then a new frozen cache will be created. Otherwise, the frozen cache will be appended. Each frozen cache entry will define a \TeX{} macro `\markdownFrozenCache`\meta{number} that will typeset markdown document number \meta{number}. % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local firstConvert = markdown.new({finalizeCache = true, frozenCacheCounter = 0}) local firstInput = "Hello" local secondConvert = markdown.new({finalizeCache = true, frozenCacheCounter = 1}) local secondInput = "*world*!" tex.sprint(firstConvert(firstInput) .. [[ ]] .. secondConvert(secondInput)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” A frozen cache with two entries will also be produced as we requested using the `frozenCacheCounter` option. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { frozenCacheCounter } { counter } { 0 } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.frozenCacheCounter = 0 % \end{macrocode} % \iffalse % %<*manual-options> #### Option `gfmAutoIdentifiers` `gfmAutoIdentifiers` (default value: `false`) % \fi % \begin{markdown} % \Optitem[false]{gfmAutoIdentifiers}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [GitHub-flavored auto identifiers syntax extension][pandoc-gfm-auto-identifiers]: ``` md The following heading received the identifier `123-sesame-street`: # 123 Sesame Street `````` : false : Disable the Pandoc GitHub-flavored auto identifiers syntax extension. See also the option \Opt{autoIdentifiers}. [pandoc-gfm-auto-identifiers]: https://pandoc.org/MANUAL.html#extension-gfm_auto_identifiers % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { gfmAutoIdentifiers } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.gfmAutoIdentifiers = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `hashEnumerators` `hashEnumerators` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{hashEnumerators}{\opt{true}, \opt{false}} % : true : Enable the use of hash symbols (`#`) as ordered item list markers: ``` md #. Bird #. McHale #. Parish `````` : false : Disable the use of hash symbols (`#`) as ordered item list markers. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} #. Bird #. McHale #. Parish \end{markdown} \begin{markdown}[hashEnumerators] #. Bird #. McHale #. Parish \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > . Bird > ======== > . McHale > ======== > . Parish > ======== > > #. Bird > #. McHale > #. Parish ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \startmarkdown #. Bird #. McHale #. Parish \stopmarkdown \setupmarkdown[hashEnumerators = yes] \startmarkdown #. Bird #. McHale #. Parish \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > . Bird > ======== > . McHale > ======== > . Parish > ======== > > #. Bird > #. McHale > #. Parish % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { hashEnumerators } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.hashEnumerators = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `headerAttributes` {#header-attributes} `headerAttributes` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{headerAttributes}{\opt{true}, \opt{false}} % : true : Enable the assignment of HTML attributes to headings: ``` md # My first heading {#foo} ## My second heading ## {#bar .baz} Yet another heading {key=value} =================== `````` : false : Disable the assignment of HTML attributes to headings. % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { headerAttributes } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.headerAttributes = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `html` `html` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{html}{\opt{true}, \opt{false}} % : true : Enable the recognition of HTML entities, inline HTML tags, and block HTML elements, comments, declarations, processing instructions, and CDATA sections in the input. HTML entities will be replaced with the corresponding Unicode codepoints and other HTML content will be ignored by default. : false : Disable the recognition of HTML markup. Any recognized HTML content in the input will be rendered as plain text. % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local convert = markdown.new({html = false}) local newline = [[^^J^^J]] local input = "
*There is no block tag support.*
" .. newline .. "*There is no support.*" .. newline .. "_There is no support._" .. newline .. "_There is no support._" tex.sprint(convert(input)) } \par \directlua{ local markdown = require("markdown") local convert = markdown.new() local input = "
*There is block tag support.*
" .. newline .. "*There is support.*" .. newline .. "_There is support._" .. newline .. "_There is support._" tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > \
There is no block tag support.\
> There is no \\ support. > There is no \ support. > There is no support. > > There is support. There is support. There is support. ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \par \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ``` html
*Is there block tag support?*
*Is there support?* _Is there support?_ _Is there support?_ ```````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex html=false -- content.md optionfalse.tex markdown2tex -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > \
Is there block tag support?\
> Is there \\ support? > Is there \ support? > Is there support? > > Is there support? Is there support? Is there support? ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \def\markdownOptionHtml{false} \markdownBegin
*There is no block tag support.*
*There is no support.* _There is no support._ _There is no support._ \markdownEnd \def\markdownOptionHtml{true} \markdownBegin
*There is block tag support.*
*There is support.* _There is support._ _There is support._ \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \
There is no block tag support.\
> There is no \\ support. > There is no \ support. > There is no support. > > There is support. There is support. There is support. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown}[html = false]
*There is no block tag support.*
*There is no support.* _There is no support._ _There is no support._ \end{markdown} \begin{markdown}
*There is block tag support.*
*There is support.* _There is support._ _There is support._ \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \
There is no block tag support.\
> There is no \\ support. > There is no \ support. > There is no support. > > There is support. There is support. There is support. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \setupmarkdown[html = no] \startmarkdown
*There is no block tag support.*
*There is no support.* _There is no support._ _There is no support._ \stopmarkdown \setupmarkdown[html = yes] \startmarkdown
*There is block tag support.*
*There is support.* _There is support._ _There is support._ \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > \
There is no block tag support.\
> There is no \\ support. > There is no \ support. > There is no support. > > There is support. There is support. There is support. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { html } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.html = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `htmlOutput` `htmlOutput` (default value: `basic`) % \fi % \begin{markdown} % % \Optitem[basic]{htmlOutput}{\opt{basic}, \opt{commonmark}} % : basic : When the \Opt{html} option is enabled, produce % \iffalse basic coarse-grained renderers for all HTML. % \fi % basic coarse-grained renderers for all HTML, see % Section <#sec:basic-html-renderers>. : commonmark : When the \Opt{html} option is enabled, produce fine-grained renderers for each top-level non-terminal element of CommonMark's grammar for % \iffalse [HTML blocks][html-blocks] and [raw HTML][raw-html]. % \fi % [HTML blocks][html-blocks] and [raw HTML][raw-html], see sections % <#sec:commonmark-block-html-renderers> and % <#sec:commonmark-raw-html-renderers>, respectively. [html-blocks]: https://spec.commonmark.org/0.31.2/#html-blocks [raw-html]: https://spec.commonmark.org/0.31.2/#raw-html % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { htmlOutput } { string } { basic } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.htmlOutput = "basic" % \end{macrocode} % \iffalse % %<*manual-options> #### Option `htmlOverLinks` `htmlOverLinks` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{htmlOverLinks}{\opt{true}, \opt{false}} % : true : When the option \Opt{html} is enabled and a text can be understood either as a hyperlink or HTML, interpret it as HTML. This is especially relevant when the option \Opt{relativeReferences} is enabled, since it makes e.g. `` a valid hyperlink. : false : When the option \Opt{html} is enabled and a text can be understood either as a hyperlink or HTML, interpret it as a hyperlink. This is an experimental option. Whenever the option \Opt{experimental} is enabled and this option is unspecified, it will be enabled. Like other experimental options, this option will be enabled by default and soft-deprecated in the next major release of the Markdown package. % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_experimental_lua_option:n { htmlOverLinks } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.htmlOverLinks = false experimentalOptions.htmlOverLinks = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `hybrid` `hybrid` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{hybrid}{\opt{true}, \opt{false}} % : true : Disable the escaping of special plain \TeX{} characters, which makes it possible to intersperse your markdown markup with \TeX{} code. The intended usage is in documents prepared manually by a human author. In such documents, it can often be desirable to mix \TeX{} and markdown markup freely. : false : Enable the escaping of special plain \TeX{} characters outside verbatim environments, so that they are not interpreted by \TeX{}. This is encouraged when typesetting automatically generated content or markdown documents that were not prepared with this package in mind. The \Opt{hybrid} option makes it difficult to untangle \TeX{} input from markdown text, which makes documents written with the \Opt{hybrid} option less interoperable and more difficult to read for authors. Therefore, the option has been soft-deprecated in version 3.7.1 of the Markdown package: It will never be removed but using it prints a warning and is discouraged. Consider one of the following better alternatives for mixing \TeX{} and markdown: - With the \Opt{contentBlocks} option, authors can move large blocks of TeX code to separate files and include them in their markdown documents as external resources: ``` md Here is a mathematical formula: /math-formula.tex ``` - With the \Opt{rawAttribute} option, authors can denote raw text spans and code blocks that will be interpreted as \TeX{} code: `````` md `$H_2 O$`{=tex} is a liquid. Here is a mathematical formula: ``` {=tex} \[distance[i] = \begin{dcases} a & b \\ c & d \end{dcases} \] ``` `````` - With options \Opt{texMathDollars}, \Opt{texMathSingleBackslash}, and \Opt{texMathDoubleBackslash}, authors can freely type \TeX{} commands between dollar signs or backslash-escaped brackets: ``` md $H_2 O$ is a liquid. Here is a mathematical formula: \[distance[i] = \begin{dcases} a & b \\ c & d \end{dcases} \] ``` % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local input, convert_safe, convert_unsafe, paragraph input = [[$\string\sqrt{-1}$ *equals* $i$.]] convert_safe = markdown.new() convert_unsafe = markdown.new({hybrid = true}) paragraph = [[\par]] tex.sprint( convert_safe(input) .. paragraph .. convert_unsafe(input) ) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt {-1}\$ *equals* \$i\$. > > 1 > *equals* > i. ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \par \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ``` md $\sqrt{-1}$ *equals* $i$. `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex -- content.md optionfalse.tex markdown2tex hybrid=true -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt {-1}\$ *equals* \$i\$. > > 1 > *equals* > i. ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \markdownBegin $\sqrt{-1}$ *equals* $i$. \markdownEnd \def\markdownOptionHybrid{true} \markdownBegin $\sqrt{-1}$ *equals* $i$. \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt {-1}\$ *equals* \$i\$. > > 1 > *equals* > i. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} $\sqrt{-1}$ *equals* $i$. \end{markdown} \begin{markdown}[hybrid] $\sqrt{-1}$ *equals* $i$. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt {-1}\$ *equals* \$i\$. > > 1 > *equals* > i. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \startmarkdown $\sqrt{-1}$ *equals* $i$. \stopmarkdown \setupmarkdown[hybrid = yes] \startmarkdown $\sqrt{-1}$ *equals* $i$. \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt {-1}\$ *equals* \$i\$. > > 1 > *equals* > i. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { hybrid } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.hybrid = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `inlineCodeAttributes` `inlineCodeAttributes` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{inlineCodeAttributes}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [inline code span attribute extension][pandoc-inline-code-attributes]: ``` md `<$>`{.haskell} `````` : false : Enable the Pandoc inline code span attribute extension. [pandoc-inline-code-attributes]: https://pandoc.org/MANUAL.html#extension-inline_code_attributes % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage[inlineCodeAttributes]{markdown} \usepackage{expl3} \ExplSyntaxOn \markdownSetup{ renderers = { codeSpanAttributeContextBegin = { \group_begin: \color_group_begin: \markdownSetup{ renderers = { attributeKeyValue = { \str_if_eq:nnT { ##1 } { color } { \color_select:n { ##2 } } }, }, } }, codeSpanAttributeContextEnd = { \color_group_end: \group_end: }, }, } \ExplSyntaxOff \begin{document} \begin{markdown} Here is some `colored text`{color=red}. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > Here is some `colored text`. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { inlineCodeAttributes } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.inlineCodeAttributes = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `inlineNotes` `inlineNotes` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{inlineNotes}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [inline note syntax extension][pandoc-inline-notes]: ``` md Here is an inline note.^[Inline notes are easier to write, since you don't have to pick an identifier and move down to type the note.] `````` : false : Disable the Pandoc inline note syntax extension. [pandoc-inline-notes]: https://pandoc.org/MANUAL.html#extension-inline_notes % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[inlineNotes]{markdown} \begin{document} \begin{markdown} Here is an inline note.^[Inline notes are easier to write, since you don't have to pick an identifier and move down to type the note.] \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > Here is an inline note.^[Inline notes are easier to > write, since you don't have to pick an identifier and > move down to type the note.] ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[inlineNotes = yes] \starttext \startmarkdown Here is an inline note.^[Inline notes are easier to write, since you don't have to pick an identifier and move down to type the note.] \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > Here is an inline note.^[Inline notes are easier to > write, since you don't have to pick an identifier and > move down to type the note.] % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { inlineNotes } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.inlineNotes = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `jekyllData` `jekyllData` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{jekyllData}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [YAML metadata block syntax extension][pandoc-yaml-metadata-block] for entering metadata in YAML: ~~~~~~ yaml --- title: 'This is the title: it contains a colon' author: - Author One - Author Two keywords: [nothing, nothingness] abstract: | This is the abstract. It consists of two paragraphs. --- ~~~~~~~~~~~ : false : Disable the Pandoc YAML metadata block syntax extension for entering metadata in YAML. [pandoc-yaml-metadata-block]: https://pandoc.org/MANUAL.html#extension-yaml_metadata_block % See also the plain \TeX{} macros \mref{yamlBegin}, \mref{yamlEnd}, and % \mref{yamlInput} in Section <#sec:tex-typesetting>, the \LaTeX{} environment % \envmref{yaml} in Section <#sec:latex-typesetting>, and the \Hologo{ConTeXt} % macros \mref{startyaml}, \mref{stopyaml}, and \mref{inputyaml} in Section % <#sec:context-typesetting> to see how the options \Opt{jekyllData}, % \Opt{expectJekyllData}, and \Opt{ensureJekyllData} can be used together to % implement high-level interfaces for processing YAML documents. % % \end{markdown} % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionJekyllData{true} \ExplSyntaxOn \keys_define:nn { markdown/jekyllData } { name .code:n = { \gdef\name{#1} }, age .code:n = { \gdef\age{#1} }, } \ExplSyntaxOff \def\markdownRendererJekyllDataEnd{% \name{} is \age{} years old.} \markdownBegin --- name: Jane Doe age: 99 --- \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > Jane Doe is 99 years old. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[jekyllData]{markdown} \markdownSetup{ jekyllDataRenderers = { name = {\gdef\name{#1}}, code = {\gdef\age{#1}}, }, renderers = { jekyllDataEnd = {\name{} is \age{} years old.}, } } \begin{document} \begin{markdown} --- name: Jane Doe age: 99 --- \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > Jane Doe is 99 years old. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[jekyllData = yes] \ExplSyntaxOn \keys_define:nn { markdown/jekyllData } { name .code:n = { \gdef\name{#1} }, age .code:n = { \gdef\age{#1} }, } \ExplSyntaxOff \def\markdownRendererJekyllDataEnd{% \name{} is \age{} years old.} \starttext \startmarkdown --- name: Jane Doe age: 99 --- \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > Jane Doe is 99 years old. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { jekyllData } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.jekyllData = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `linkAttributes` `linkAttributes` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{linkAttributes}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [link and image attribute syntax extension][pandoc-link-attributes]: ``` md An inline ![image](foo.jpg){#id .class height=20px} and a reference ![image][ref] with attributes. [ref]: foo.jpg "optional title" {#id .class key=val} `````` : false : Enable the Pandoc link and image attribute syntax extension. [pandoc-link-attributes]: https://pandoc.org/MANUAL.html#extension-link_attributes % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage[linkAttributes]{markdown} \usepackage{expl3, graphicx} \ExplSyntaxOn \markdownSetup{ renderers = { imageAttributeContextBegin = { \group_begin: \markdownSetup{ renderers = { attributeKeyValue = { \setkeys { Gin } { { ##1 } = { ##2 } } }, }, } }, imageAttributeContextEnd = { \group_end: }, }, } \ExplSyntaxOff \begin{document} \begin{markdown} Here is an example image: ![example image](example-image){width=5cm height=4cm} \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain an example image (from [Martin Scharrer's mwe package][mwe]) displayed at size 5cm × 4cm. [mwe]: https://ctan.org/pkg/mwe (mwe – Packages and image files for MWEs) % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { linkAttributes } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.linkAttributes = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `lineBlocks` `lineBlocks` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{lineBlocks}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [line block syntax extension][pandoc-line-blocks]: ``` md | this is a line block that | spans multiple | even discontinuous | lines `````` : false : Disable the Pandoc line block syntax extension. [pandoc-line-blocks]: https://pandoc.org/MANUAL.html#extension-line_blocks % \end{markdown} % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionLineBlocks{true} \markdownBegin | I would spread the cloths under your feet: | But I, being poor, have only my dreams; | I have spread my dreams under your feet; | Tread softly because you tread on my dreams. \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > | I would spread the cloths under your feet: > | But I, being poor, have only my dreams; > | I have spread my dreams under your feet; > | Tread softly because you tread on my dreams. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[lineBlocks]{markdown} \begin{document} \begin{markdown} | I would spread the cloths under your feet: | But I, being poor, have only my dreams; | I have spread my dreams under your feet; | Tread softly because you tread on my dreams. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > | I would spread the cloths under your feet: > | But I, being poor, have only my dreams; > | I have spread my dreams under your feet; > | Tread softly because you tread on my dreams. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[lineBlocks = yes] \starttext \startmarkdown | I would spread the cloths under your feet: | But I, being poor, have only my dreams; | I have spread my dreams under your feet; | Tread softly because you tread on my dreams. \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > | I would spread the cloths under your feet: > | But I, being poor, have only my dreams; > | I have spread my dreams under your feet; > | Tread softly because you tread on my dreams. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { lineBlocks } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.lineBlocks = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `mark` `mark` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{mark}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [mark syntax extension][pandoc-mark]: ``` md This ==is highlighted text.== `````` : false : Disable the Pandoc mark syntax extension. [pandoc-mark]: https://pandoc.org/MANUAL.html#extension-mark % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[mark]{markdown} \begin{document} \begin{markdown} This ==is highlighted text.== \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is highlighted text. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { mark } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.mark = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `notes` `notes` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{notes}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [note syntax extension][pandoc-footnotes]: ``` md Here is a note reference,[^1] and another.[^longnote] [^1]: Here is the note. [^longnote]: Here's one with multiple blocks. Subsequent paragraphs are indented to show that they belong to the previous note. { some.code } The whole paragraph can be indented, or just the first line. In this way, multi-paragraph notes work like multi-paragraph list items. This paragraph won't be part of the note, because it isn't indented. `````` : false : Disable the Pandoc note syntax extension. [pandoc-footnotes]: https://pandoc.org/MANUAL.html#extension-footnotes % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[notes]{markdown} \begin{document} \begin{markdown} Here is a note reference,[^1] and another.[^longnote] [^1]: Here is the note. [^longnote]: Here's one with multiple blocks. Subsequent paragraphs are indented to show that they belong to the previous note. { some.code } The whole paragraph can be indented, or just the first line. In this way, multi-paragraph notes work like multi-paragraph list items. This paragraph won't be part of the note, because it isn't indented. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > Here is a note reference,[^1] and another.[^longnote] > > Subsequent paragraphs are indented to show that they > belong to the previous note. > > { some.code } > > The whole paragraph can be indented, or just the > first line. In this way, multi-paragraph notes > work like multi-paragraph list items. > > This paragraph won't be part of the note, because it > isn't indented. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[notes = yes] \starttext \startmarkdown Here is a note reference,[^1] and another.[^longnote] [^1]: Here is the note. [^longnote]: Here's one with multiple blocks. Subsequent paragraphs are indented to show that they belong to the previous note. { some.code } The whole paragraph can be indented, or just the first line. In this way, multi-paragraph notes work like multi-paragraph list items. This paragraph won't be part of the note, because it isn't indented. \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > Here is a note reference,[^1] and another.[^longnote] > > Subsequent paragraphs are indented to show that they > belong to the previous note. > > { some.code } > > The whole paragraph can be indented, or just the > first line. In this way, multi-paragraph notes > work like multi-paragraph list items. > > This paragraph won't be part of the note, because it > isn't indented. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { notes } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.notes = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `pipeTables` {#pipe-tables} `pipeTables` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{pipeTables}{\opt{true}, \opt{false}} % : true : Enable the PHP Markdown pipe table syntax extension: ``` md | Right | Left | Default | Center | |------:|:-----|---------|:------:| | 12 | 12 | 12 | 12 | | 123 | 123 | 123 | 123 | | 1 | 1 | 1 | 1 | `````` : false : Disable the PHP Markdown pipe table syntax extension. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[pipeTables]{markdown} \begin{document} \begin{markdown} | Right | Left | Default | Center | |------:|:-----|---------|:------:| | 12 | 12 | 12 | 12 | | 123 | 123 | 123 | 123 | | 1 | 1 | 1 | 1 | \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > | Right | Left | Default | Center | > |------:|:-----|---------|:------:| > | 12 | 12 | 12 | 12 | > | 123 | 123 | 123 | 123 | > | 1 | 1 | 1 | 1 | ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[pipeTables = yes] \starttext \startmarkdown | Right | Left | Default | Center | |------:|:-----|---------|:------:| | 12 | 12 | 12 | 12 | | 123 | 123 | 123 | 123 | | 1 | 1 | 1 | 1 | \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > | Right | Left | Default | Center | > |------:|:-----|---------|:------:| > | 12 | 12 | 12 | 12 | > | 123 | 123 | 123 | 123 | > | 1 | 1 | 1 | 1 | % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { pipeTables } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.pipeTables = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `preserveTabs` `preserveTabs` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{preserveTabs}{\opt{true}, \opt{false}} % : true : Preserve tabs in code block and fenced code blocks. : false : Convert any tabs in the input to spaces. % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { preserveTabs } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.preserveTabs = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `rawAttribute` `rawAttribute` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{rawAttribute}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [raw attribute syntax extension][pandoc-raw-attribute]: ``` md `$H_2 O$`{=tex} is a liquid. ``` To enable raw blocks, the \Opt{fencedCode} option must also be enabled: ~~~~~~~~ md Here is a mathematical formula: ``` {=tex} \[distance[i] = \begin{dcases} a & b \\ c & d \end{dcases} \] ``` ~~~~~~~~~~~ The \Opt{rawAttribute} option is a good alternative to the \Opt{hybrid} option. Unlike the \Opt{hybrid} option, which affects the entire document, the \Opt{rawAttribute} option allows you to isolate the parts of your documents that use \TeX. : false : Disable the Pandoc raw attribute syntax extension. [pandoc-raw-attribute]: https://pandoc.org/MANUAL.html#extension-raw_attribute % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage[rawAttribute, fencedCode]{markdown} \usepackage{expl3} \begin{document} \begin{markdown} `$H_2 O$`{=tex} is a liquid. ``` {=html}

Here is some HTML content that will be ignored.

``` \end{markdown} \end{document} ```````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > H~2~O is a liquid. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { rawAttribute } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.rawAttribute = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `relativeReferences` `relativeReferences` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{relativeReferences}{\opt{true}, \opt{false}} % : true : Enable [relative references][rfc3986] in autolinks: ``` md I conclude in Section <#conclusion>. Conclusion {#conclusion} ========== In this paper, we have discovered that most grandmas would rather eat dinner with their grandchildren than get eaten. Begone, wolf! ``` : false : Disable relative references in autolinks. [rfc3986]: https://datatracker.ietf.org/doc/html/rfc3986#section-4.2 % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[headerAttributes, relativeReferences]{markdown} \begin{document} \begin{markdown} I conclude in Section <#conclusion>. Conclusion {#conclusion} ========== In this paper, we have discovered that most grandmas would rather eat dinner with their grandchildren than get eaten. Begone, wolf! \end{markdown} \end{document} ``````` Next, invoke LuaTeX twice from the terminal: ``` sh lualatex document.tex lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > I conclude in Section 1. > > # 1. Conclusion > > In this paper, we have discovered that most grandmas would rather eat dinner > with their grandchildren than get eaten. Begone, wolf! % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { relativeReferences } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.relativeReferences = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `shiftHeadings` `shiftHeadings` (default value: `0`) % \fi % \begin{markdown} % % \Valitem[0]{shiftHeadings}{shift amount} % : All headings will be shifted by \meta{shift amount}, which can be both positive and negative. Headings will not be shifted beyond level 6 or below level 1. % \end{markdown} % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `example.md` with the following content: ``` md ## A section ``` Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \font\normal=cmr10\normal \font\big=cmr10 at 12pt \def\markdownRendererHeadingTwo#1{{\big #1\par}} \font\bigger=cmr10 scaled 1440 \def\markdownRendererHeadingOne#1{{\bigger #1\par}} \def\markdownOptionShiftHeadings{-1} \markdownInput{example.md} \def\markdownOptionShiftHeadings{0} \markdownInput{example.md} \def\markdownOptionShiftHeadings{+1} \markdownInput{example.md} \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > # A section > ## A section > ### A section ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{filecontents}[overwrite,nosearch,noheader]{example.md} ## A section \end{filecontents} \begin{document} \markdownInput[shiftHeadings=-1]{example.md} \markdownInput{example.md} \markdownInput[shiftHeadings=+1]{example.md} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > # A section > ## A section > ### A section ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `example.md` with the following content: ``` md ## A section ``` Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \inputmarkdown[shiftHeadings = -1]{example.md} \inputmarkdown[shiftHeadings = 0]{example.md} \inputmarkdown[shiftHeadings = +1]{example.md} \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > # A section > ## A section > ### A section % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { shiftHeadings } { number } { 0 } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.shiftHeadings = 0 % \end{macrocode} % \iffalse % %<*manual-options> #### Option `slice` `slice` (default value: `^ $`) % \fi % \begin{markdown} % % \Valitem[\textasciicircum{} \\$]{slice}{the beginning and the end of a slice} % : Two space-separated selectors that specify the slice of a document that will be processed, whereas the remainder of the document will be ignored. The following selectors are recognized: - The circumflex (`^`) selects the beginning of a document. - The dollar sign (`$`) selects the end of a document. - `^`\meta{identifier} selects the beginning of % a section (see the \Opt{headerAttributes} option) % \iffalse a [section](#header-attributes) % \fi % or a fenced div (see the \Opt{fencedDivs} option) with the HTML % attribute `#`\meta{identifier}. % \iffalse or a [fenced div](#fenced-divs) with the HTML attribute `#`\meta{identifier}. % \fi - `$`\meta{identifier} selects the end of a section with the HTML attribute `#`\meta{identifier}. - \meta{identifier} corresponds to `^`\meta{identifier} for the first selector and to `$`\meta{identifier} for the second selector. Specifying only a single selector, \meta{identifier}, is equivalent to specifying the two selectors \meta{identifier} \meta{identifier}, which is equivalent to `^`\meta{identifier} `$`\meta{identifier}, i.e. the entire section with the HTML attribute `#`\meta{identifier} will be selected. % \end{markdown} % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `hamlet.md` with the following content: ``` md # The Tragedy of Hamlet Shakespeare's longest play. ## Act III {#act-3} Hamlet kills Polonius. ## Act V {#act-5} Hamlet dies. ## Act I {#act-1} Hamlet talks to ghost. ``` Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionHeaderAttributes{true} \font\normal=cmr10\normal \font\big=cmr10 at 12pt \def\markdownRendererHeadingTwo#1{{\big #1\par}} \font\bigger=cmr10 scaled 1440 \def\markdownRendererHeadingOne#1{{\bigger #1\par}} \def\markdownOptionSlice{^ ^act-3} \markdownInput{hamlet.md} \def\markdownOptionSlice{act-1} \markdownInput{hamlet.md} \def\markdownOptionSlice{act-3 act-5} \markdownInput{hamlet.md} \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > # The Tragedy of Hamlet > Shakespeare's longest play. > > ## Act I > Hamlet talks to ghost. > > ## Act III > Hamlet kills Polonius. > > ## Act V > Hamlet dies. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[headerAttributes]{markdown} \begin{filecontents}[overwrite,nosearch,noheader]{hamlet.md} # The Tragedy of Hamlet Shakespeare's longest play. ## Act III {#act-3} Hamlet kills Polonius. ## Act V {#act-5} Hamlet dies. ## Act I {#act-1} Hamlet talks to ghost. \end{filecontents} \begin{document} \markdownInput[slice=^ ^act-3]{hamlet.md} \markdownInput[slice=act-1]{hamlet.md} \markdownInput[slice=act-3 act-5]{hamlet.md} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > # The Tragedy of Hamlet > Shakespeare's longest play. > > ## Act I > Hamlet talks to ghost. > > ## Act III > Hamlet kills Polonius. > > ## Act V > Hamlet dies. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `hamlet.md` with the following content: ``` md # The Tragedy of Hamlet Shakespeare's longest play. ## Act III {#act-3} Hamlet kills Polonius. ## Act V {#act-5} Hamlet dies. ## Act I {#act-1} Hamlet talks to ghost. ``` Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[headerAttributes = yes] \starttext \inputmarkdown[slice = ^ ^act-3]{example.md} \inputmarkdown[slice = act-1]{example.md} \inputmarkdown[slice = act-3 act-5]{example.md} \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > # The Tragedy of Hamlet > Shakespeare's longest play. > > ## Act I > Hamlet talks to ghost. > > ## Act III > Hamlet kills Polonius. > > ## Act V > Hamlet dies. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { slice } { slice } { ^~$ } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.slice = "^ $" % \end{macrocode} % \iffalse % %<*manual-options> #### Option `smartEllipses` `smartEllipses` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{smartEllipses}{\opt{true}, \opt{false}} % : true : Convert any ellipses in the input to the \mref{markdownRendererEllipsis} \TeX{} macro. : false : Preserve all ellipses in the input. % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \def\markdownRendererEllipsis{. . .} \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local convert = markdown.new() local input = "These are just three regular dots ..." tex.sprint(convert(input)) } \par \directlua{ local markdown = require("markdown") local convert = markdown.new({smartEllipses = true}) local input = "... and this is a victorian ellipsis." tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > These are just three regular dots ... > > . . . and this is a victorian ellipsis. ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \def\markdownRendererEllipsis{. . .} \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \par \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ``` md Are these just three regular dots, a victorian ellipsis, or ... ? `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex -- content.md optionfalse.tex markdown2tex smartEllipses=true -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > Are these just three regular dots, a victorian ellipsis, or ... ? > > Are these just three regular dots, a victorian ellipsis, or . . . ? ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownRendererEllipsis{. . .} \markdownBegin These are just three regular dots ... \markdownEnd \def\markdownOptionSmartEllipses{true} \markdownBegin ... and this is a victorian ellipsis. \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > These are just three regular dots ... > > . . . and this is a victorian ellipsis. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \markdownSetup{ renderers = { ellipsis = {. . .} } } \begin{document} \begin{markdown} These are just three regular dots ... \end{markdown} \begin{markdown}[smartEllipses] ... and this is a victorian ellipsis. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > These are just three regular dots ... > > . . . and this is a victorian ellipsis. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \def\markdownRendererEllipsis{. . .} \starttext \startmarkdown These are just three regular dots ... \stopmarkdown \setupmarkdown[smartEllipses = yes] \startmarkdown ... and this is a victorian ellipsis. \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > These are just three regular dots ... > > . . . and this is a victorian ellipsis. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { smartEllipses } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.smartEllipses = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `startNumber` `startNumber` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{startNumber}{\opt{true}, \opt{false}} % : true : Make the number in the first item of an ordered lists significant. The item numbers will be passed to the \mref{markdownRendererOlItemWithNumber} \TeX{} macro. : false : Ignore the numbers in the ordered list items. Each item will only produce a \mref{markdownRendererOlItem} \TeX{} macro. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} The following list respects the numbers specified in the markup: 3. third item 4. fourth item 5. fifth item \end{markdown} \begin{markdown}[startNumber=false] The following list does not respect the numbers specified in the markup: 3. third item 4. fourth item 5. fifth item \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > The following list respects the numbers specified in the markup: > > 3. third item > 4. fourth item > 5. fifth item > > The following list does not respect the numbers specified in the markup: > > 1. third item > 2. fourth item > 3. fifth item ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \starttext \startmarkdown The following list respects the numbers specified in the markup: 3. third item 4. fourth item 5. fifth item \stopmarkdown \setupmarkdown[startNumber = no] \startmarkdown The following list respects the numbers specified in the markup: 3. third item 4. fourth item 5. fifth item \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > The following list respects the numbers specified in the markup: > > 3. third item > 4. fourth item > 5. fifth item > > The following list does not respect the numbers specified in the markup: > > 1. third item > 2. fourth item > 3. fifth item % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { startNumber } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.startNumber = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `strikeThrough` `strikeThrough` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{strikeThrough}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [strike-through syntax extension][pandoc-strikeout]: ``` md This ~~is deleted text.~~ `````` : false : Disable the Pandoc strike-through syntax extension. [pandoc-strikeout]: https://pandoc.org/MANUAL.html#extension-strikeout % \end{markdown} % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionStrikeThrough{true} \input soul.sty \def\markdownRendererStrikeThrough#1{\st{#1}} \markdownBegin This is ~~a lunar roving vehicle~~ strike-through text. \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is ~~a lunar roving vehicle~~ strike-through text. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[strikeThrough]{markdown} \usepackage{soul} \markdownSetup{ renderers = { strikeThrough = {\st{#1}}, }, } \begin{document} \begin{markdown} This is ~~a lunar roving vehicle~~ strike-through text. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is ~~a lunar roving vehicle~~ strike-through text. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[strikeThrough = yes] \def\markdownRendererStrikeThrough#1{\overstrikes{#1}} \starttext \startmarkdown This is ~~a lunar roving vehicle~~ strike-through text. \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is ~~a lunar roving vehicle~~ strike-through text. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { strikeThrough } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.strikeThrough = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `stripIndent` `stripIndent` (default value: `false`) % \fi % \markdownBegin % % \Optitem[false]{stripIndent}{\opt{true}, \opt{false}} % : true : Strip the minimal indentation of non-blank lines from all lines in a markdown document. Requires that the \Opt{preserveTabs} Lua option is disabled: ``` tex \documentclass{article} \usepackage[stripIndent]{markdown} \begin{document} \begin{markdown} Hello *world*! \end{markdown} \end{document} ``````` : false : Do not strip any indentation from the lines in a markdown document. % \markdownEnd % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionStripIndent{true} \markdownBegin Hello *world*! \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[stripIndent]{markdown} \begin{document} \begin{markdown} Hello *world*! \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[stripIndent = yes] \starttext \startmarkdown Hello *world*! \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { stripIndent } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.stripIndent = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `subscripts` `subscripts` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{subscripts}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [subscript syntax extension][pandoc-subscript]: ``` md H~2~O is a liquid. `````` : false : Disable the Pandoc subscript syntax extension. [pandoc-subscript]: https://pandoc.org/MANUAL.html#extension-superscript-subscript % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[subscripts]{markdown} \begin{document} \begin{markdown} H~2~O is a liquid. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > H~2~O is a liquid. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[subscripts = yes] \starttext \startmarkdown H~2~O is a liquid. \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > H~2~O is a liquid. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { subscripts } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.subscripts = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `superscripts` `superscripts` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{superscripts}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [superscript syntax extension][pandoc-superscript]: ``` md 2^10^ is 1024. `````` : false : Disable the Pandoc superscript syntax extension. [pandoc-superscript]: https://pandoc.org/MANUAL.html#extension-superscript-subscript % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[superscripts]{markdown} \begin{document} \begin{markdown} 2^10^ is 1024. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > 2^10^ is 1024. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[superscripts = yes] \starttext \startmarkdown 2^10^ is 1024. \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > 2^10^ is 1024. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { superscripts } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.superscripts = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `tableAttributes` `tableAttributes` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{tableAttributes}{\opt{true}, \opt{false}} % : true : Enable the assignment of HTML attributes to % table captions (see the \Opt{tableCaptions} option): % \iffalse [table captions](#table-captions): % \fi ``` md | Right | Left | Default | Center | |------:|:-----|---------|:------:| | 12 | 12 | 12 | 12 | | 123 | 123 | 123 | 123 | | 1 | 1 | 1 | 1 | : Demonstration of pipe table syntax. {#example-table} ``` : false : Disable the assignment of HTML attributes to table captions. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[ pipeTables, tableCaptions, tableAttributes, relativeReferences, ]{markdown} \usepackage{expl3} \ExplSyntaxOn \markdownSetup{ renderers = { tableAttributeContextBegin = { \group_begin: \markdownSetup{ renderers = { attributeIdentifier = { \markdownSetup{ renderers = { tableAttributeContextEnd = { \label{##1} \group_end: }, }, } }, }, } }, tableAttributeContextEnd = { \group_end: }, }, } \ExplSyntaxOff \begin{document} \begin{markdown} See Table <#example-table>. | Right | Left | Default | Center | |------:|:-----|---------|:------:| | 12 | 12 | 12 | 12 | | 123 | 123 | 123 | 123 | | 1 | 1 | 1 | 1 | : Demonstration of pipe table syntax. {#example-table} \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > See Table 1. > > | Right | Left | Default | Center | > |------:|:-----|---------|:------:| > | 12 | 12 | 12 | 12 | > | 123 | 123 | 123 | 123 | > | 1 | 1 | 1 | 1 | > > : Table 1. Demonstration of pipe table syntax. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { tableAttributes } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.tableAttributes = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `tableCaptions` {#table-captions} `tableCaptions` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{tableCaptions}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [table caption syntax extension][pandoc-table-captions] for % pipe tables (see the \Opt{pipeTables} option): % \iffalse [pipe tables](#pipe-tables): % \fi ``` md | Right | Left | Default | Center | |------:|:-----|---------|:------:| | 12 | 12 | 12 | 12 | | 123 | 123 | 123 | 123 | | 1 | 1 | 1 | 1 | : Demonstration of pipe table syntax. `````` : false : Disable the Pandoc table caption syntax extension. [pandoc-table-captions]: https://pandoc.org/MANUAL.html#extension-table_captions % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[pipeTables, tableCaptions]{markdown} \begin{document} \begin{markdown} | Right | Left | Default | Center | |------:|:-----|---------|:------:| | 12 | 12 | 12 | 12 | | 123 | 123 | 123 | 123 | | 1 | 1 | 1 | 1 | : Demonstration of pipe table syntax. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > | Right | Left | Default | Center | > |------:|:-----|---------|:------:| > | 12 | 12 | 12 | 12 | > | 123 | 123 | 123 | 123 | > | 1 | 1 | 1 | 1 | > > : Demonstration of pipe table syntax. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown [ pipeTables = yes, tableCaptions = yes, ] \starttext \startmarkdown | Right | Left | Default | Center | |------:|:-----|---------|:------:| | 12 | 12 | 12 | 12 | | 123 | 123 | 123 | 123 | | 1 | 1 | 1 | 1 | : Demonstration of pipe table syntax. \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > | Right | Left | Default | Center | > |------:|:-----|---------|:------:| > | 12 | 12 | 12 | 12 | > | 123 | 123 | 123 | 123 | > | 1 | 1 | 1 | 1 | > > : Demonstration of pipe table syntax. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { tableCaptions } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.tableCaptions = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `taskLists` `taskLists` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{taskLists}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [task list syntax extension][pandoc-task-lists]: ``` md - [ ] an unticked task list item - [X] a ticked task list item `````` Our implementation also supports half-ticked task list items: ``` md - [/] a half-checked task list item - [.] another half-checked task list item `````` : false : Disable the Pandoc task list syntax extension. [pandoc-task-lists]: https://pandoc.org/MANUAL.html#extension-task_lists % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[taskLists]{markdown} \markdownSetup{ renderers = { untickedBox = No, halfTickedBox = Maybe, tickedBox = Yes, }, } \begin{document} \begin{markdown} - [ ] you can't. - [/] I can? - [X] I can! \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > - No you can't. > - Maybe I can? > - Yes I can! ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[taskLists = yes] \def\markdownRendererUntickedBox{No} \def\markdownRendererHalftickedBox{Maybe} \def\markdownRendererTickedBox{Yes} \starttext \startmarkdown - [ ] you can't. - [/] I can? - [X] I can! \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > - No you can't. > - Maybe I can? > - Yes I can! % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { taskLists } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.taskLists = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `texComments` `texComments` (default value: `false`) % \fi % \markdownBegin % % \Optitem[false]{texComments}{\opt{true}, \opt{false}} % : true : Strip \TeX{}-style comments. ``` tex \documentclass{article} \usepackage[texComments]{markdown} \begin{document} \begin{markdown} Hel% this is a comment lo *world*! \end{markdown} \end{document} ``````` Always enabled when \Opt{hybrid} is enabled. : false : Do not strip \TeX{}-style comments. % \markdownEnd % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionTexComments{true} \markdownBegin Hel% this is a comment lo *world*! \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[texComments]{markdown} \begin{document} \begin{markdown} Hel% this is a comment lo *world*! \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[texComments = yes] \starttext \startmarkdown Hel% this is a comment lo *world*! \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { texComments } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.texComments = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `texMathDollars` `texMathDollars` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{texMathDollars}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [dollar math syntax extension][pandoc-tex-math-dollars]: ``` md inline math: $E=mc^2$ display math: $$E=mc^2$$ ``` : false : Disable the Pandoc dollar math syntax extension. [pandoc-tex-math-dollars]: https://pandoc.org/MANUAL.html#extension-tex_math_dollars % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local newline = [[^^J^^J]] local convert = markdown.new({texMathDollars = true}) local input = [[$E=mc^2$]] .. newline .. newline .. [[$$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx$$]] tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > $E=mc^2$ > > $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx$$ ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \par \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ``` md $E=mc^2$ $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx$$ `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex -- content.md optionfalse.tex markdown2tex texMathDollars=true -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > \$E=mc^2\$ > > \$\$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\$\$ > > $E=mc^2$ > > $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx$$ ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionTexMathDollars{true} \markdownBegin $E=mc^2$ $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx$$ \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > $E=mc^2$ > > $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx$$ ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[texMathDollars]{markdown} \begin{document} \begin{markdown} $E=mc^2$ $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx$$ \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > $E=mc^2$ > > $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx$$ ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[texMathDollars = yes] \starttext \startmarkdown $E=mc^2$ $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx$$ \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > $E=mc^2$ > > $$\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx$$ % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { texMathDollars } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.texMathDollars = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `texMathDoubleBackslash` `texMathDoubleBackslash` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{texMathDoubleBackslash}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [double backslash math syntax extension][pandoc-tex-math-double-backslash]: ``` md inline math: \\(E=mc^2\\) display math: \\[E=mc^2\\] ``` : false : Disable the Pandoc double backslash math syntax extension. [pandoc-tex-math-double-backslash]: https://pandoc.org/MANUAL.html#extension-tex_math_double_backslash % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local newline = [[^^J^^J]] local convert = markdown.new({texMathDoubleBackslash = true}) local input = [[\\(E=mc^2\\)]] .. newline .. newline .. [[\\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\]]] tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > \(E=mc^2\) > > \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \par \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ``` md \\(E=mc^2\\) \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\] `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex -- content.md optionfalse.tex markdown2tex texMathDoubleBackslash=true -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > \\(E=mc^2\\) > > \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\] > > \(E=mc^2\) > > \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionTexMathDoubleBackslash{true} \markdownBegin \\(E=mc^2\\) \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\] \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \(E=mc^2\) > > \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[texMathDoubleBackslash]{markdown} \begin{document} \begin{markdown} \\(E=mc^2\\) \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\] \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \(E=mc^2\) > > \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[texMathDoubleBackslash = yes] \starttext \startmarkdown \\(E=mc^2\\) \\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\\] \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > \(E=mc^2\) > > \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { texMathDoubleBackslash } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.texMathDoubleBackslash = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `texMathSingleBackslash` `texMathSingleBackslash` (default value: `false`) % \fi % \begin{markdown} % % \Optitem[false]{texMathSingleBackslash}{\opt{true}, \opt{false}} % : true : Enable the Pandoc [single backslash math syntax extension][pandoc-tex-math-single-backslash]: ``` md inline math: \(E=mc^2\) display math: \[E=mc^2\] ``` : false : Disable the Pandoc single backslash math syntax extension. [pandoc-tex-math-single-backslash]: https://pandoc.org/MANUAL.html#extension-tex_math_single_backslash % \end{markdown} % \iffalse ##### Lua Module Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \directlua{ local markdown = require("markdown") local newline = [[^^J^^J]] local convert = markdown.new({texMathSingleBackslash = true}) local input = [[\(E=mc^2\)]] .. newline .. newline .. [[\[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\]]] tex.sprint(convert(input)) } \endgroup \bye ``````` Then, invoke LuaTeX from the terminal: ``` sh luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > \(E=mc^2\) > > \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### Lua CLI Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \begingroup \catcode`\%=12 \catcode`\#=12 \input optionfalse \par \input optiontrue \endgroup \bye ``````` Using a text editor, create a text document named `content.md` with the following content: ``` md \(E=mc^2\) \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] `````` Next, invoke LuaTeX from the terminal: ``` sh markdown2tex -- content.md optionfalse.tex markdown2tex texMathSingleBackslash=true -- content.md optiontrue.tex luatex document.tex ``````` A PDF document named `document.pdf` should be produced and contain the following text: > (E=mc^2) > > [\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx] > > \(E=mc^2\) > > \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionTexMathSingleBackslash{true} \markdownBegin \(E=mc^2\) \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \(E=mc^2\) > > \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[texMathSingleBackslash]{markdown} \begin{document} \begin{markdown} \(E=mc^2\) \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \(E=mc^2\) > > \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[texMathSingleBackslash = yes] \starttext \startmarkdown \(E=mc^2\) \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > \(E=mc^2\) > > \[\hat{f} \left ( \xi \right )= \int_{-\infty}^{\infty} f\left ( x \right ) e^{-i2\pi \xi x} dx\] % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { texMathSingleBackslash } { boolean } { false } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.texMathSingleBackslash = false % \end{macrocode} % \iffalse % %<*manual-options> #### Option `tightLists` `tightLists` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{tightLists}{\opt{true}, \opt{false}} % : true : Unordered and ordered lists whose items do not consist of multiple paragraphs will be considered *tight*. Tight lists will produce tight renderers that may produce different output than lists that are not tight: ``` md - This is - a tight - unordered list. - This is not a tight - unordered list. ``` : false : Unordered and ordered lists whose items consist of multiple paragraphs will be treated the same way as lists that consist of multiple paragraphs. % \end{markdown} % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \begin{document} \begin{markdown} The following list is tight: - first item - second item - third item The following list is loose: - first item - second item that spans multiple paragraphs - third item \end{markdown} \begin{markdown}[tightLists=false] The following list is now also loose: - first item - second item - third item \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > The following list is tight: > > - first item > - second item > - third item > > The following list is loose: > > - first item > - second item that spans > > multiple paragraphs > - third item > > The following list is now also loose: > > - first item > > - second item > > - third item % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { tightLists } { boolean } { true } % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.tightLists = true % \end{macrocode} % \iffalse % %<*manual-options> #### Option `underscores` `underscores` (default value: `true`) % \fi % \begin{markdown} % % \Optitem[true]{underscores}{\opt{true}, \opt{false}} % : true : Both underscores and asterisks can be used to denote emphasis and strong emphasis: ``` md *single asterisks* _single underscores_ **double asterisks** __double underscores__ `````` : false : Only asterisks can be used to denote emphasis and strong emphasis. This makes it easy to write math with the \Opt{hybrid} option without the need to constantly escape subscripts. % \end{markdown} % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionHybrid{true} \markdownBegin This is _emphasized text_ and this is a math subscript: $m\_n$. \markdownEnd \def\markdownOptionUnderscores{false} \markdownBegin This is *emphasized text* and this is a math subscript: $m_n$. \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is _emphasized text_ and this is a math subscript: *mₙ*. > > This is _emphasized text_ and this is a math subscript: *mₙ*. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[hybrid]{markdown} \begin{document} \begin{markdown} This is _emphasized text_ and this is a math subscript: $m\_n$. \end{markdown} \begin{markdown}[underscores=false] This is *emphasized text* and this is a math subscript: $m_n$. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is _emphasized text_ and this is a math subscript: *mₙ*. > > This is _emphasized text_ and this is a math subscript: *mₙ*. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[hybrid = yes] \starttext \startmarkdown This is _emphasized text_ and this is a math subscript: $m\_n$. \stopmarkdown \setupmarkdown[underscores = yes] \startmarkdown This is *emphasized text* and this is a math subscript: $m_n$. \stopmarkdown \stoptext ```````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex ````` A PDF document named `document.pdf` should be produced and contain the following text: > This is _emphasized text_ and this is a math subscript: *mₙ*. > > This is _emphasized text_ and this is a math subscript: *mₙ*. % %<*tex> % \fi % \begin{macrocode} \@@_add_lua_option:nnn { underscores } { boolean } { true } \ExplSyntaxOff % \end{macrocode} % \iffalse % %<*lua,lua-cli,lua-loader> % \fi % \begin{macrocode} defaultOptions.underscores = true % \end{macrocode} % \endgroup % \iffalse % %<*lua-cli-manpage> % \fi % \begin{markdown} % %### Command-Line Interface {#lua-cli-interface} % % The high-level operation of the Markdown package involves the communication % between several programming layers: the plain \TeX{} layer hands markdown % documents to the Lua layer. Lua converts the documents to \TeX{}, and hands % the converted documents back to plain \TeX{} layer for typesetting, see % Figure <#fig:sequence-diagram-tex-interface>. % % This procedure has the advantage of being fully automated. However, it also % has several important disadvantages: The converted \TeX{} documents are % cached on the file system, taking up increasing amount of space. Unless the % \TeX{} engine includes a Lua interpreter, the package also requires shell % access, which opens the door for a malicious actor to access the system. % Last, but not least, the complexity of the procedure impedes debugging. % % A solution to the above problems is to decouple the conversion from the % typesetting. For this reason, a command-line Lua interface for converting a % markdown document to \TeX{} is also provided, see % Figure <#fig:sequence-diagram-lua-cli>. % % \end{markdown} % \begin{figure} % \centering % \begin{sequencediagram} % \newthread{user}{User}{} % \newinst[4]{tex}{\TeX{}}{} % \newinst[4]{lua}{Lua}{} % \begin{call}{user}{\footnotesize\cs{jobname.tex}}{tex}{\footnotesize\cs{jobname.pdf}} % \begin{call}{tex}{\footnotesize\cs{jobname.markdown.in}}{lua}{\footnotesize\cs{jobname.markdown.out}} % \end{call} % \begin{call}{tex}{\footnotesize\cs{input}\cs{jobname.markdown.out}}{tex}{} % \end{call} % \end{call} % \end{sequencediagram} % \caption[A sequence diagram of typesetting a document using the \TeX{} % interface]{A sequence diagram of the Markdown package typesetting a % markdown document using the \TeX{} interface} % \label{fig:sequence-diagram-tex-interface} % \end{figure} % \begin{figure} % \centering % \begin{sequencediagram} % \newthread{user}{User}{} % \newinst[4]{tex}{\TeX{}}{} % \newinst[4]{lua}{Lua}{} % \begin{call}{user}{\footnotesize$\langle$\textit{document}$\rangle$\texttt{.md}}{lua}{\footnotesize$\langle$\textit{document}$\rangle$\texttt{.tex}} % \end{call} % \begin{call}{user}{\footnotesize\cs{jobname.tex}}{tex}{\footnotesize\cs{jobname.pdf}} % \begin{call}{tex}{\footnotesize\cs{input} $\langle$\textit{document}$\rangle$}{tex}{} % \end{call} % \end{call} % \end{sequencediagram} % \caption[A sequence diagram of typesetting a document using the Lua CLI]% % {A sequence diagram of the Markdown package typesetting a markdown document % using the Lua command-line interface} % \label{fig:sequence-diagram-lua-cli} % \end{figure} % \begin{macrocode} .TH MARKDOWN2TEX 1 "(((LASTMODIFIED)))" .SH NAME markdown2tex \- convert .md files to .tex .SH SYNOPSIS % \end{macrocode} % \iffalse % %<*lua-cli> % \fi % \begin{macrocode} local HELP_STRING = "Usage: " .. [[ % \end{macrocode} % \iffalse % %<*lua-cli,lua-cli-manpage> % \fi % \begin{macrocode} markdown2tex [OPTIONS] -- [INPUT_FILE] [OUTPUT_FILE] % \end{macrocode} % \iffalse % %<*lua-cli-manpage> % \fi % \begin{macrocode} .SH DESCRIPTION % \end{macrocode} % \iffalse % %<*lua-cli,lua-cli-manpage> % \fi % \begin{macrocode} OPTIONS are documented in Section 2.2.1 of the Markdown Package User Manual (https://ctan.org/pkg/markdown). When OUTPUT_FILE is unspecified, the result of the conversion will be written to the standard output. When INPUT_FILE is also unspecified, the result of the conversion will be read from the standard input. % \end{macrocode} % \iffalse % %<*lua-cli> % \fi % \begin{macrocode} Report bugs to: witiko@mail.muni.cz Markdown package home page: ]] local VERSION_STRING = [[ markdown2tex (Markdown) ]] .. metadata.version .. [[ Copyright (C) ]] .. table.concat(metadata.copyright, "\nCopyright (C) ") .. [[ License: ]] .. metadata.license local function warn(s) io.stderr:write("Warning: " .. s .. "\n") end local function error(s) io.stderr:write("Error: " .. s .. "\n") os.exit(1) end % \end{macrocode} % \begin{markdown} % % To make it easier to copy-and-paste options from Pandoc [@macfarlane22] such % as `fancy_lists`, `header_attributes`, and `pipe_tables`, we accept % snake\\\_case in addition to camelCase variants of options. As a bonus, % studies [@sharif10] also show that snake\\\_case is faster to read than % camelCase. % % \end{markdown} % \begin{macrocode} local function camel_case(option_name) local cased_option_name = option_name:gsub("_(%l)", function(match) return match:sub(2, 2):upper() end) return cased_option_name end local function snake_case(option_name) local cased_option_name = option_name:gsub("%l%u", function(match) return match:sub(1, 1) .. "_" .. match:sub(2, 2):lower() end) return cased_option_name end local cases = {camel_case, snake_case} local various_case_options = {} for option_name, _ in pairs(defaultOptions) do for _, case in ipairs(cases) do various_case_options[case(option_name)] = option_name end end local process_options = true local options = {} local input_filename local output_filename for i = 1, #arg do if process_options then % \end{macrocode} % \begin{markdown} % After the optional `-`{}`-` argument has been specified, the remaining % arguments are assumed to be input and output filenames. This argument is % optional, but encouraged, because it helps resolve ambiguities when % deciding whether an option or a filename has been specified. % \end{markdown} % \begin{macrocode} if arg[i] == "--" then process_options = false goto continue % \end{macrocode} % \begin{markdown} % Unless the `-`{}`-` argument has been specified before, an argument % containing the equals sign (`=`) is assumed to be an option specification in % a \meta{key}`=`\meta{value} format. The available options are listed in % Section <#sec:lua-options>. % \end{markdown} % \begin{macrocode} elseif arg[i]:match("=") then local key, value = arg[i]:match("(.-)=(.*)") if defaultOptions[key] == nil and various_case_options[key] ~= nil then key = various_case_options[key] end % \end{macrocode} % \begin{markdown} % The \luamref{defaultOptions} table is consulted to identify whether \meta{value} % should be parsed as a string, number, table, or boolean. % \end{markdown} % \begin{macrocode} local default_type = type(defaultOptions[key]) if default_type == "boolean" then options[key] = (value == "true") elseif default_type == "number" then options[key] = tonumber(value) elseif default_type == "table" then options[key] = {} for item in value:gmatch("[^ ,]+") do table.insert(options[key], item) end else if default_type ~= "string" then if default_type == "nil" then warn('Option "' .. key .. '" not recognized.') else warn('Option "' .. key .. '" type not recognized, ' .. 'please file a report to the package maintainer.') end warn('Parsing the ' .. 'value "' .. value ..'" of option "' .. key .. '" as a string.') end options[key] = value end goto continue % \end{macrocode} % \begin{markdown} % Unless the `-`{}`-` argument has been specified before, an argument % `-`{}`-help`, or `-h` causes a brief documentation for how to invoke the % program to be printed to the standard output. % \end{markdown} % \begin{macrocode} elseif arg[i] == "--help" or arg[i] == "-h" then print(HELP_STRING) os.exit() % \end{macrocode} % \begin{markdown} % Unless the `-`{}`-` argument has been specified before, an argument % `-`{}`-version`, or `-v` causes the program to print information about its % name, version, origin and legal status, all on standard output. % \end{markdown} % \begin{macrocode} elseif arg[i] == "--version" or arg[i] == "-v" then print(VERSION_STRING) os.exit() end end % \end{macrocode} % \begin{markdown} % The first argument that matches none of the above patterns is assumed to be % the input filename. The input filename should correspond to the Markdown % document that is going to be converted to a \TeX{} document. % \end{markdown} % \begin{macrocode} if input_filename == nil then input_filename = arg[i] % \end{macrocode} % \begin{markdown} % The first argument that matches none of the above patterns is assumed to be % the output filename. The output filename should correspond to the \TeX{} % document that will result from the conversion. % \end{markdown} % \begin{macrocode} elseif output_filename == nil then output_filename = arg[i] else error('Unexpected argument: "' .. arg[i] .. '".') end ::continue:: end % \end{macrocode} % \begin{markdown} % % The command-line Lua interface is implemented by the files `markdown-cli.lua` % and `markdown2tex.lua`, which can be invoked from the command line as follows: % ``` sh % markdown2tex cacheDir=. -- hello.md hello.tex % `````` % \noindent to convert the Markdown document `hello.md` to a \TeX{} document % `hello.tex`. After the Markdown package for our \TeX{} format has been % loaded, the converted document can be typeset as follows: % ``` tex % \input hello % ``````` % % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{markdown} % % Plain \TeX{} Interface {#texinterface} %------------------------ % % \end{markdown} % \iffalse % %<*manual-interfaces> ### Plain \TeX{} The plain \TeX{} interface provides \TeX{} commands that typeset markdown documents by using the Lua interface behind the scenes. Unlike the Lua interface, the plain TeX interface does not provide low-level tools for converting markdown to \TeX{}. Instead, its goal is to provide high-level typesetting capabilities. The plain \TeX{} interface accepts the same options as the `markdown` Lua module, in addition to its own options, but now the options are specified as \TeX{} commands. Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \markdownBegin $\sqrt{-1}$ *equals* $i$. \markdownEnd \def\markdownOptionTexMathDollars{true} \markdownBegin $\sqrt{-1}$ *equals* $i$. \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt{-1}\$ *equals* \$i\$. > > 1 > *equals* > i. Invoking pdfTeX should have the same effect: ``` sh pdftex --shell-escape document.tex `````` % %<*tex> % \fi % \begin{markdown} % % The plain \TeX{} interface provides macros for the typesetting of markdown % input from within plain \TeX{}, for setting the Lua interface options (see % Section <#sec:lua-options>) used during the conversion from markdown to % plain \TeX{} and for changing the way markdown the tokens are rendered. % % \end{markdown} % \begin{macrocode} \def\markdownLastModified{(((LASTMODIFIED)))}% \def\markdownVersion{(((VERSION)))}% % \end{macrocode} % \begin{markdown} % % The plain \TeX{} interface is implemented by the `markdown.tex` file that can % be loaded as follows: % ``` tex % \input markdown % ``````` % \noindent It is expected that the special plain \TeX{} characters have the % expected category codes, when `\input`ting the file. % %### Typesetting Markdown and YAML {#tex-typesetting} % % The interface exposes the \mdef{markdownBegin}, \mdef{markdownEnd}, % \mdef{yamlBegin}, \mdef{yamlEnd}, \mdef{markinline}, \mdef{markdownInput}, % \mdef{yamlInput}, and \mdef{markdownEscape} macros. % %#### Typesetting Markdown and YAML directly % % The \mref{markdownBegin} macro marks the beginning of a markdown document % fragment and the \mref{markdownEnd} macro marks its end. % % \end{markdown} % \begin{macrocode} \let\markdownBegin\relax \let\markdownEnd\relax % \end{macrocode} % \begin{markdown} % % You may prepend your own code to the \mref{markdownBegin} macro and redefine the % \mref{markdownEnd} macro to produce special effects before and after the % markdown block. % % There are several limitations to the macros you need to be aware of: % % The first limitation concerns the \mref{markdownEnd} macro, which must be % visible directly from the input line buffer (it may not be produced as a % result of input expansion). Otherwise, it will not be recognized as the end % of the markdown string. As a corrolary, the \mref{markdownEnd} string % may not appear anywhere inside the markdown input. % % Another limitation concerns spaces at the right end of an input line. In % markdown, these are used to produce a forced line break. However, any such % spaces are removed before the lines enter the input buffer of % \TeX{}~[@knuth86a, p. 46]. As a corrolary, the \mref{markdownBegin} macro also % ignores them. % % The \mref{markdownBegin} and \mref{markdownEnd} macros will also consume the rest % of the lines at which they appear. In the following example plain \TeX{} % code, the characters `c`, `e`, and `f` will not appear in the output. % % ``` tex % \input markdown % a % b \markdownBegin c % d % e \markdownEnd f % g % \bye % ``````` % % Note that you may also not nest the \mref{markdownBegin} and \mref{markdownEnd} % macros. % % The following example plain \TeX{} code showcases the usage of the % \mref{markdownBegin} and \mref{markdownEnd} macros: % % ``` tex % \input markdown % \markdownBegin % _Hello_ **world** ... % \markdownEnd % \bye % ``````` % % The \mref{yamlBegin} macro marks the beginning of an YAML document % fragment and the \mref{yamlEnd} macro marks its end. % % \end{markdown} % \begin{macrocode} \let\yamlBegin\relax \def\yamlEnd{\markdownEnd\endgroup} % \end{macrocode} % \begin{markdown} % % The \mref{yamlBegin} and \mref{yamlEnd} macros are subject to the same % limitations as the \mref{markdownBegin} and \mref{markdownEnd} macros. % % The following example plain \TeX{} code showcases the usage of the % \mref{markdownBegin} and \mref{markdownEnd} macros: % % ``` tex % \input markdown % \yamlBegin % title: _Hello_ **world** ... % author: John Doe % \yamlEnd % \bye % ``````` % % The above code has the same effect as the below code: % % ``` tex % \input markdown % \yamlSetup{jekyllData, expectJekyllData, ensureJekyllData} % \markdownBegin % title: _Hello_ **world** ... % author: John Doe % \markdownEnd % \bye % ``````` % % You can use the \mref{markinline} macro to input inline markdown content. % % \end{markdown} % \begin{macrocode} \let\markinline\relax % \end{macrocode} % \begin{markdown} % % The following example plain \TeX{} code showcases the usage of the % \mref{markinline} macro: % % ``` tex % \input markdown % \markinline{_Hello_ **world**} % \bye % ``````` % % The above code has the same effect as the below code: % % ``` tex % \input markdown % \markdownSetup{contentLevel=inline} % \markdownBegin % _Hello_ **world** ... % \markdownEnd % \bye % ``````` % % The \mref{markinline} macro is subject to the same limitations as the % \mref{markdownBegin} and \mref{markdownEnd} macros. % %#### Typesetting Markdown and YAML from external documents % % You can use the \mref{markdownInput} macro to include markdown documents, % similarly to how you might use the `\input` \TeX{} primitive to include % \TeX{} documents. The \mref{markdownInput} macro accepts a single parameter % with the filename of a markdown document and expands to the result of the % conversion of the input markdown document to plain \TeX{}. % % \end{markdown} % \begin{macrocode} \let\markdownInput\relax % \end{macrocode} % \begin{markdown} % % The macro \mref{markdownInput} is not subject to the limitations of the % \mref{markdownBegin} and \mref{markdownEnd} macros. % % The following example plain \TeX{} code showcases the usage of the % \mref{markdownInput} macro: % % ``` tex % \input markdown % \markdownInput{hello.md} % \bye % ``````` % % You can use the \mref{yamlInput} macro to include YAML documents. % similarly to how you might use the `\input` \TeX{} primitive to include % \TeX{} documents. The \mref{yamlInput} macro accepts a single parameter with % the filename of a YAML document and expands to the result of the % conversion of the input YAML document to plain \TeX{}. % % \end{markdown} % \begin{macrocode} \def\yamlInput#1{% \begingroup \yamlSetup{jekyllData, expectJekyllData, ensureJekyllData}% \markdownInput{#1}% \endgroup }% % \end{macrocode} % \begin{markdown} % % The macro \mref{yamlInput} is also not subject to the limitations of the % \mref{markdownBegin} and \mref{markdownEnd} macros. % % The following example plain \TeX{} code showcases the usage of the % \mref{markdownInput} macro: % % ``` tex % \input markdown % \yamlInput{hello.yml} % \bye % ``````` % % The above code has the same effect as the below code: % % ``` tex % \input markdown % \yamlSetup{jekyllData, expectJekyllData, ensureJekyllData} % \markdownInput{hello.yml} % \bye % ``````` % %#### Typesetting TeX from inside Markdown and YAML documents % % The \mref{markdownEscape} macro accepts a single parameter with the filename % of a \TeX{} document and executes the \TeX{} document in the middle of a % markdown document fragment. Unlike the `\input` built-in of \TeX, % \mref{markdownEscape} guarantees that the standard catcode regime of your % \TeX{} format will be used. % % \end{markdown} % \begin{macrocode} \let\markdownEscape\relax % \end{macrocode} % \begin{markdown} % %### Options {#tex-options} % % The plain \TeX{} options are represented by \TeX{} commands. Some of them map % directly to the options recognized by the Lua interface (see % Section <#sec:lua-options>), while some of them are specific to the plain % \TeX{} interface. % % To determine whether plain \TeX{} is the top layer or if there are other % layers above plain \TeX{}, we take a look on whether the % \mdef{c_@@_top_layer_tl} token list has already been defined. If not, % we will assume that plain \TeX{} is the top layer. % % \end{markdown} % \begin{macrocode} \ExplSyntaxOn \tl_const:Nn \c_@@_option_layer_plain_tex_tl { plain_tex } \cs_generate_variant:Nn \tl_const:Nn { NV } \tl_if_exist:NF \c_@@_top_layer_tl { \tl_const:NV \c_@@_top_layer_tl \c_@@_option_layer_plain_tex_tl } % \end{macrocode} % \begin{markdown} % % To enable the enumeration of plain \TeX{} options, we will maintain the % \mdef{g_\@\@_plain_tex_options_seq} sequence. % % \end{markdown} % \begin{macrocode} \seq_new:N \g_@@_plain_tex_options_seq % \end{macrocode} % \begin{markdown} % % To enable the reflection of default/experimental plain \TeX{} options and % their types, we will maintain the % \mdef{g_\@\@_default_plain_tex_options_prop}, % \mdef{g_\@\@_experimental_plain_tex_options_seq} and % \mdef{g_\@\@_plain_tex_option_types_prop} property lists and sequences, % respectively. % % \end{markdown} % \begin{macrocode} \prop_new:N \g_@@_plain_tex_option_types_prop \prop_new:N \g_@@_default_plain_tex_options_prop \seq_new:N \g_@@_experimental_plain_tex_options_seq \seq_gput_right:NV \g_@@_option_layers_seq \c_@@_option_layer_plain_tex_tl \cs_new:Nn \@@_add_plain_tex_option:nnn { \@@_add_option:Vnnn \c_@@_option_layer_plain_tex_tl { #1 } { #2 } { #3 } } % \end{macrocode} % \iffalse % %<*manual-options> ### Plain \TeX{} Plain \TeX{} options control the communication between the \TeX{} interface and the `markdown` Lua module. They are supported by all higher-level interfaces of the Markdown package, i.e. the plain \TeX{}, \LaTeX{} and \Hologo{ConTeXt} interfaces. #### Setting Lua options from plain \TeX{} As a rule of thumb, you can set all Lua options directly from plain \TeX{}. For example, to set the \Opt{taskLists} Lua option to `true`, you would include the following code in your plain \TeX{} document: ``` tex \def\markdownOptionTaskLists{true} ``` % %<*tex> % \fi % \begin{markdown} % % The plain \TeX{} options may be also be specified via the \mdef{markdownSetup} % macro. Here, the plain \TeX{} options are represented by a comma-delimited % list of \meta{key}`=`\meta{value} pairs. For boolean options, the % `=`\meta{value} part is optional, and \meta{key} will be interpreted as % \meta{key}`=true` if the `=`\meta{value} part has been omitted. % The \mref{markdownSetup} macro receives the options to set up as its only % argument. % % \end{markdown} % \begin{macrocode} \cs_new:Nn \@@_setup:n { \keys_set:nn { markdown/options } { #1 } } \cs_gset_eq:NN \markdownSetup \@@_setup:n % \end{macrocode} % \begin{markdown} % % The command \mdef{yamlSetup} is also available as an alias for the command % \mref{markdownSetup}. % % \end{markdown} % \begin{macrocode} \cs_gset_eq:NN \yamlSetup \markdownSetup % \end{macrocode} % % \iffalse % %<*manual-options> Alternatively, you can also set plain \TeX{} options using the `\markdownSetup` \TeX{} macro. For example, to set the \Opt{taskLists} Lua option to `true`, you would include the following code in your plain \TeX{} document: ``` tex \markdownSetup{taskLists = true} ``` % %<*tex> % \fi % \begin{markdown} % % The % \mdef{markdownIfOption}`{`\meta{name}`}{`\meta{iftrue}`}{`\meta{iffalse}`}` % macro is provided for testing, whether the value of % `\markdownOption`\meta{name} is `true`. If the value is `true`, then % \meta{iftrue} is expanded, otherwise \meta{iffalse} is expanded. % % \end{markdown} % \begin{macrocode} \prg_new_conditional:Nnn \@@_if_option:n { TF, T, F } { \@@_get_option_type:nN { #1 } \l_tmpa_tl \str_if_eq:NNF \l_tmpa_tl \c_@@_option_type_boolean_tl { \msg_error:nnxx { markdown } { expected-boolean-option } { #1 } { \l_tmpa_tl } } \@@_get_option_value:nN { #1 } \l_tmpa_tl \str_if_eq:NNTF \l_tmpa_tl \c_@@_option_value_true_tl { \prg_return_true: } { \prg_return_false: } } \msg_new:nnn { markdown } { expected-boolean-option } { Option~#1~has~type~#2,~ but~a~boolean~was~expected. } \let \markdownIfOption \@@_if_option:nTF % \end{macrocode} % \begin{markdown} % %#### Finalizing and Freezing the Cache % The \mdef{markdownOptionFinalizeCache} option corresponds to the Lua % interface \Opt{finalizeCache} option, which creates an output file % \Opt{frozenCacheFileName} (frozen cache) that contains a mapping % between an enumeration of the markdown documents in the plain \TeX{} document % and their auxiliary files cached in the \Opt{cacheDir} directory. % % \iffalse % %<*manual-options> #### Finalizing and Freezing the Cache % \fi % The \mdef{markdownOptionFrozenCache} option uses the mapping previously % created by the \Opt{finalizeCache} option, % \iffalse created by the Lua interface \Opt{finalizeCache} option, % \fi and uses it to typeset the plain \TeX{} document without invoking Lua. As a result, the plain \TeX{} document becomes more portable, but further changes in the order and the content of markdown documents will not be reflected. It defaults to `false`. % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_plain_tex_option:nnn { frozenCache } { boolean } { false } % \end{macrocode} % \iffalse % %<*manual-options> % \fi % \begin{markdown} % % The standard usage of the above two options is as follows: % \iffalse The standard usage of the \Opt{finalizeCache} and \Opt{frozenCache} options is as follows: % \fi 1. Remove the \Opt{cacheDir} cache directory with stale auxiliary cache files. % 2. Enable the \Opt{finalizeCache} option. % \iffalse 2. Enable the \Opt{finalizeCache} option. % \fi 3. Typeset the plain \TeX{} document to populate and finalize the cache. 4. Enable the \Opt{frozenCache} option. 5. Publish the source code of the plain \TeX{} document and the \Opt{cacheDir} directory. % \iffalse For more information, see the examples for the \Opt{finalizeCache} option. % \fi #### File and Directory Names % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{markdown} % % The \mdef{markdownOptionInputTempFileName} macro sets the filename of the % temporary input file that is created during the buffering of markdown text % from a \TeX{} source. It defaults to `\jobname.markdown.in`. % % The expansion of this macro must not contain quotation marks (`"`) or % backslash symbols (`\`). % % \end{markdown} % \begin{macrocode} \tl_set:Nn \l_tmpa_tl { \str_use:N \g_@@_unquoted_jobname_str .markdown.in } \bool_if:NT \g_@@_jobname_quoted_bool { \tl_put_left:Nn \l_tmpa_tl { " } \tl_put_right:Nn \l_tmpa_tl { " } } \cs_generate_variant:Nn \@@_add_plain_tex_option:nnn { nnV } \@@_add_plain_tex_option:nnV { inputTempFileName } { path } \l_tmpa_tl % \end{macrocode} % \begin{markdown} % % The \mdef{markdownOptionOutputDir} macro sets the path to the directory that % will contain the auxiliary cache files produced by the Lua implementation and % also the auxiliary files produced by the plain \TeX{} implementation. The % option defaults to `.` or, since \TeX{} Live 2024, to the value of the % `-output-directory` option of your \TeX{} engine. % % In Mik\TeX{}, this automatic detection is [currently only supported with % Lua\TeX{}][1]. If you need to use Mik\TeX{} and cannot use Lua\TeX{}, you can % either a) fix the automatic detection by setting the environmental variable % `TEXMF_OUTPUT_DIRECTORY` manually or by setting the % \mref{markdownOptionOutputDir} option manually. % % The path must be set to the same value as the `-output-directory` option of % your \TeX{} engine for the package to function correctly. We need this macro % to make the Lua implementation aware where it should store the helper files. % The same limitations apply here as in the case of the % \Opt{inputTempFileName} macro. % % [1]: https://github.com/MiKTeX/miktex/issues/1630 (Environmental variable TEXMF_OUTPUT_DIRECTORY not set by MikTeX binaries) % % \end{markdown} % \begin{macrocode} \@@_add_plain_tex_option:nnn { outputDir } { path } { . } % \end{macrocode} % \iffalse % %<*manual-options> The plain \TeX{} interface provides the following commands that you can use to specify the location of temporary files produced during the conversion from Markdown to \TeX{}: - `\markdownOptionInputTempFileName`, - `\markdownOptionOutputDir`, - `\markdownOptionCacheDir`, and - `\markdownOptionFrozenCacheFileName`. The `\markdownOptionCacheDir` and `\markdownOptionFrozenCacheFileName` commands correspond to the `cacheDir` and `frozenCacheFileName` Lua options. Using a text editor, create a folder named `output-directory` and a text document named `document.tex` with the following content: ``` tex \input lmfonts \input markdown \def\markdownOptionInputTempFileName{temporary-input.md} \def\markdownOptionOutputDir{output-directory} \def\markdownOptionCacheDir{output-directory/cache-directory} \def\markdownOptionEagerCache{true} \def\markdownOptionFinalizeCache{true} \def\markdownOptionFrozenCacheFileName{output-directory/cache-directory/frozen-cache.tex} \markdownBegin Hello *world*! \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex --output-directory output-directory document.tex `````` A text document named `temporary-input.md` should be produced in the folder named `output-directory` and contain the following text: > Hello \*world\*! A folder named `output-directory/cache-directory` should also be produced and contain fragments of the converted markdown document. LuaTeX does not need other temporary files to perform the conversion from markdown to \TeX{}. To produce the remaining temporary files, invoke pdfTeX from the terminal: ``` sh pdftex --output-directory output-directory --shell-escape document.tex `````` Text document named `temporary-output.md` should be produced in the folder named `output-directory`. The document will contain the input markdown document converted to \TeX{}. % \fi % \begin{markdown} #### No default token renderer prototypes {#plain} The Markdown package provides default definitions for token renderer prototypes using the `witiko/markdown/defaults` % theme (see Section~<#sec:themes>). % \iffalse theme. % \fi Although these default definitions provide a useful starting point for authors, they use extra resources, especially with higher-level \TeX{} formats such as \LaTeX{} and \Hologo{ConTeXt}. Furthermore, the default definitions may change at any time, which may pose a problem for maintainers of Markdown themes and templates who may require a stable output. The \mdef{markdownOptionPlain} macro specifies whether higher-level \TeX{} formats should only use the plain \TeX{} default definitions or whether they should also use the format-specific default definitions. Whereas plain \TeX{} default definitions only provide definitions for simple elements such as emphasis, strong emphasis, and paragraph separators, format-specific default definitions add support for more complex elements such as lists, tables, and citations. On the flip side, plain \TeX{} default definitions load no extra resources and are rather stable, whereas format-specific default definitions load extra resources and are subject to a more rapid change. Here is how you would enable the macro in a \LaTeX{} document: ``` tex \usepackage[plain]{markdown} ``````` Here is how you would enable the macro in a \Hologo{ConTeXt} document: ``` tex \def\markdownOptionPlain{true} \usemodule[t][markdown] ``````` The macro must be set before or during the loading of the package. Setting the macro after loading the package has no effect. % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_plain_tex_option:nnn { plain } { boolean } { false } % \end{macrocode} % \iffalse % %<*manual-options> % \fi % \begin{markdown} The \mdef{markdownOptionNoDefaults} macro specifies whether we should prevent the loading of default definitions or not. This is useful in contexts, where we want to have total control over how all elements are rendered. Here is how you would enable the macro in a \LaTeX{} document: ``` tex \usepackage[noDefaults]{markdown} ``````` Here is how you would enable the macro in a \Hologo{ConTeXt} document: ``` tex \def\markdownOptionNoDefaults{true} \usemodule[t][markdown] ``````` The macro must be set before or during the loading of the package. Setting the macro after loading the package has no effect. % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \@@_add_plain_tex_option:nnn { noDefaults } { boolean } { false } % \end{macrocode} % \begin{markdown} % %#### Miscellaneous Options % % The \mdef{markdownOptionStripPercentSigns} macro controls whether a percent % sign (`\%`) at the beginning of a line will be discarded when buffering % Markdown input (see sections <#sec:buffering-block> and % <#sec:buffering-inline>) or not. Notably, this enables the use of markdown % when writing \TeX{} package documentation using the \pkg{Doc} % \LaTeX{}~package~[@mittelbach17] or similar. The recognized values of the % macro are `true` (discard) and `false` (retain). It defaults to `false`. % % \end{markdown} % \begin{macrocode} \seq_gput_right:Nn \g_@@_plain_tex_options_seq { stripPercentSigns } \prop_gput:Nnn \g_@@_plain_tex_option_types_prop { stripPercentSigns } { boolean } \prop_gput:Nnx \g_@@_default_plain_tex_options_prop { stripPercentSigns } { false } % \end{macrocode} % \iffalse % %<*manual-options> #### Package Documentation The \mdef{markdownOptionStripPercentSigns} macro controls whether a percent sign (`\%`) at the beginning of a line will be discarded when reading Markdown input from a \TeX{} document. This enables the use of markdown when writing \TeX{} package documentation using the [Doc \LaTeX{} package][doc] by Frank Mittelbach. The recognized values of the macro are `true` (discard) and `false` (retain). It defaults to `false`. [doc]: https://ctan.org/pkg/doc (doc – Format LaTeX documentation) Using a text editor, create a text document named `document.dtx` with the following content: ``` tex % \iffalse \documentclass{ltxdoc} \usepackage[stripPercentSigns]{markdown} \begin{document} \DocInput{document.dtx} \end{document} % \fi % % \begin{markdown} % Hello *world*! % \end{markdown} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.dtx `````` A PDF document named `document.pdf` should be produced and contain the text “Hello *world*!” % %<*tex> % \fi % \begin{markdown} % %#### Generating Plain \TeX{} Option Macros and Key-Values % % We define the command \mdef{@@_define_option_commands_and_keyvals:} that % defines plain \TeX{} macros and the key--value interface % of the \mref{markdownSetup} macro for the above plain \TeX{} options. % % The command also defines macros and key--values that map % directly to the options recognized by the Lua interface, such as % `\markdownOptionHybrid` for the \Opt{hybrid} Lua option (see Section % <#sec:lua-options>), which are not processed by the plain \TeX{} % implementation, only passed along to Lua. % % Furthermore, the command also defines options and key--values % for subsequently loaded layers that correspond to higher-level \TeX{} formats % such as \LaTeX{} and \Hologo{ConTeXt}. % % For the macros that correspond to the non-boolean options recognized by the % Lua interface, the same limitations apply here in the case of the % \Opt{inputTempFileName} macro. % % \end{markdown} % \begin{macrocode} \cs_new:Nn \@@_define_option_commands_and_keyvals: { \seq_map_inline:Nn \g_@@_option_layers_seq { \seq_map_inline:cn { g_@@_ ##1 _options_seq } { \@@_define_option_command:n { ####1 } % \end{macrocode} % \begin{markdown} % % To make it easier to copy-and-paste options from Pandoc [@macfarlane22] such % as `fancy_lists`, `header_attributes`, and `pipe_tables`, we accept % snake\\\_case in addition to camelCase variants of options. As a bonus, % studies [@sharif10] also show that snake\\\_case is faster to read than % camelCase. % % \end{markdown} % \begin{macrocode} \@@_with_various_cases:nn { ####1 } { \@@_define_option_keyval:nnn { ##1 } { ####1 } { ########1 } } } } } \cs_new:Nn \@@_define_option_command:n { % \end{macrocode} % \begin{markdown} % % For experimental options, redirect the option command to the option command % \mdef{markdownOptionExperimental}. % % \end{markdown} % \begin{macrocode} \bool_set_false:N \l_tmpa_bool \seq_map_inline:Nn \g_@@_option_layers_seq { \seq_if_in:cnT { g_@@_experimental_ ##1 _options_seq } { #1 } { \bool_set_true:N \l_tmpa_bool \seq_map_break: } } \bool_if:NTF \l_tmpa_bool { \_@@_option_tl_to_csname:nN { #1 } \l_tmpa_tl \cs_if_exist:cF { \l_tmpa_tl } { \cs_gset:cpn { \l_tmpa_tl } { \markdownOptionExperimental } } } { % \end{macrocode} % \begin{markdown} % % Use the \pkg{lt3luabridge} library to determine the default value of the % \mref{markdownOptionOutputDir} macro. % % \end{markdown} % \begin{macrocode} \str_if_eq:nnTF { #1 } { outputDir } { \@@_define_option_command_output_dir: } { % \end{macrocode} % \begin{markdown} % % Do not override options defined before loading the package. % % \end{markdown} % \begin{macrocode} \@@_option_tl_to_csname:nN { #1 } \l_tmpa_tl \cs_if_exist:cF { \l_tmpa_tl } { \@@_get_default_option_value:nN { #1 } \l_tmpa_tl \@@_set_option_value:nV { #1 } \l_tmpa_tl } } } } \ExplSyntaxOff \input lt3luabridge.tex % \end{macrocode} % \begin{markdown} % % Use the \pkg{lt3luabridge} library to determine the default value of the % \mref{markdownOptionOutputDir} macro by using one of the following: % % 1. The `status.output_directory` variable~[@luatex25, Section 10.2], which is % available since Lua\TeX{} 1.18.0 from TeX~Live 2024 and in other \TeX{} % distributions like Mik\TeX{} since ca March 2024. We are only able to read % this variable in Lua\TeX{} and not other \TeX{} engines. % % 2. The `TEXMF_OUTPUT_DIRECTORY` environmental variable, which is available % since \TeX{}~Live 2024. We are only able to read this variable in \TeX{} Live % and not some other \TeX{} distributions like Mik\TeX{}. % % \end{markdown} % \begin{macrocode} \ExplSyntaxOn \cs_new:Nn \@@_define_option_command_output_dir: { \cs_if_free:NT \markdownOptionOutputDir { \bool_if:nTF { \cs_if_exist_p:N \luabridge_tl_set:Nn && ( \int_compare_p:nNn { \g_luabridge_method_int } = { \c_luabridge_method_directlua_int } || \sys_if_shell_unrestricted_p: ) } { % \end{macrocode} % \begin{markdown} % % Set most catcodes to category 12 (other) to ensure that special characters in % the output directory name such as backslashes (`\`) are not interpreted as % control sequences. % % \end{markdown} % \begin{macrocode} \group_begin: \cctab_select:N \c_str_cctab \luabridge_tl_set:Nn \l_tmpa_tl { print( (status.output_directory) or~os.getenv("TEXMF_OUTPUT_DIRECTORY") or~"." ) } \tl_gset:NV \markdownOptionOutputDir \l_tmpa_tl \group_end: } { \tl_gset:Nn \markdownOptionOutputDir { . } } } } \cs_new:Nn \@@_set_option_value:nn { \@@_define_option:n { #1 } \@@_get_option_type:nN { #1 } \l_tmpa_tl \str_if_eq:NNTF \c_@@_option_type_counter_tl \l_tmpa_tl { \@@_option_tl_to_csname:nN { #1 } \l_tmpa_tl \int_gset:cn { \l_tmpa_tl } { #2 } } { \@@_option_tl_to_csname:nN { #1 } \l_tmpa_tl \cs_set:cpn { \l_tmpa_tl } { #2 } } } \cs_new:Nn \@@_prepend_option_value:nn { \@@_get_option_value:nN { #1 } \l_tmpa_clist \clist_put_left:Nn \l_tmpa_clist { #2 } \@@_set_option_value:nV { #1 } \l_tmpa_clist } \cs_new:Nn \@@_append_option_value:nn { \@@_get_option_value:nN { #1 } \l_tmpa_clist \clist_put_right:Nn \l_tmpa_clist { #2 } \@@_set_option_value:nV { #1 } \l_tmpa_clist } \cs_generate_variant:Nn \@@_set_option_value:nn { nV } \cs_new:Nn \@@_define_option:n { \@@_option_tl_to_csname:nN { #1 } \l_tmpa_tl \cs_if_free:cT { \l_tmpa_tl } { \@@_get_option_type:nN { #1 } \l_tmpb_tl \str_if_eq:NNT \c_@@_option_type_counter_tl \l_tmpb_tl { \@@_option_tl_to_csname:nN { #1 } \l_tmpa_tl \int_new:c { \l_tmpa_tl } } } } \cs_new:Nn \@@_define_option_keyval:nnn { \prop_get:cnN { g_@@_ #1 _option_types_prop } { #2 } \l_tmpa_tl \str_if_eq:VVTF \l_tmpa_tl \c_@@_option_type_boolean_tl { \keys_define:nn { markdown/options } { % \end{macrocode} % \begin{markdown} % % For boolean options, we also accept `yes` as an alias for % `true` and `no` as an alias for `false`. % % \end{markdown} % \begin{macrocode} #3 .code:n = { \tl_set:Nx \l_tmpa_tl { \str_case:nnF { ##1 } { { yes } { true } { no } { false } } { ##1 } } \@@_set_option_value:nV { #2 } \l_tmpa_tl }, #3 .value_required:n = { false }, #3 .default:n = { true }, } } { \keys_define:nn { markdown/options } { #3 .value_required:n = { true }, #3 .code:n = { \@@_set_option_value:nn { #2 } { ##1 } }, } } % \end{macrocode} % \begin{markdown} % % For comma-list options, we assume that \meta{key} is a regular English % noun in plural (such as `extensions`) and we also define the % \meta{singular key}`=`\meta{value} interface, where \meta{singular key} is % \meta{key} after stripping the trailing -s (such as `extension`). Rather % than setting the option to \meta{value}, this interface appends \meta{value} % to the current value as the rightmost item in the list. % % \end{markdown} % \begin{macrocode} \str_if_eq:VVT \l_tmpa_tl \c_@@_option_type_clist_tl { \tl_set:Nn \l_tmpa_tl { #3 } \tl_reverse:N \l_tmpa_tl \str_if_eq:enF { \tl_head:V \l_tmpa_tl } { s } { \msg_error:nnn { markdown } { malformed-name-for-clist-option } { #3 } } \tl_set:Nx \l_tmpa_tl { \tl_tail:V \l_tmpa_tl } \tl_reverse:N \l_tmpa_tl \tl_set_eq:NN \l_tmpb_tl \l_tmpa_tl \tl_put_right:Nn \l_tmpa_tl { .value_required:n = { true } } \tl_put_right:Nn \l_tmpb_tl { .code:n = { \@@_append_option_value:nn { #2 } { ##1 } } } \keys_define:nV { markdown/options } \l_tmpa_tl \keys_define:nV { markdown/options } \l_tmpb_tl % \end{macrocode} % \begin{markdown} % % To achieve parity with token renderers and renderer prototypes (see sections % <#sec:plain-tex-renderers> and <#sec:plain-tex-renderer-prototypes>, % respectively) the syntax % \meta{key}`+=`\meta{value} and % \meta{key}`$=`\meta{value} with the same appending semantics as % \meta{singular key}`=`\meta{value} is also supported. % % \end{markdown} % \begin{macrocode} \keys_define:nn { markdown/options } { #3~+ .value_required:n = { true }, #3~+ .code:n = { \@@_append_option_value:nn { #2 } { ##1 } }, #3 + .value_required:n = { true }, #3 + .code:n = { \@@_append_option_value:nn { #2 } { ##1 } }, #3~$ .value_required:n = { true }, #3~$ .code:n = { \@@_append_option_value:nn { #2 } { ##1 } }, #3 $ .value_required:n = { true }, #3 $ .code:n = { \@@_append_option_value:nn { #2 } { ##1 } }, % \end{macrocode} % \begin{markdown} % % Furthermore, similar to token renderers and renderer prototypes, the syntax % \meta{key}`^=`\meta{value} is also supported. This syntax prepends % \meta{value} to the current value as the leftmost item in the list. % % \end{markdown} % \begin{macrocode} #3~^ .value_required:n = { true }, #3~^ .code:n = { \@@_prepend_option_value:nn { #2 } { ##1 } }, #3 ^ .value_required:n = { true }, #3 ^ .code:n = { \@@_prepend_option_value:nn { #2 } { ##1 } }, } } } \cs_generate_variant:Nn \clist_set:Nn { NV } \cs_generate_variant:Nn \keys_define:nn { nV } \prg_generate_conditional_variant:Nnn \str_if_eq:nn { en } { p, F } \msg_new:nnn { markdown } { malformed-name-for-clist-option } { Clist~option~name~#1~does~not~end~with~-s. } % \end{macrocode} % \begin{markdown} % % If plain \TeX{} is the top layer, we use the % \mref{@@_define_option_commands_and_keyvals:} macro to define plain \TeX{} % option macros and key--values immediately. Otherwise, we % postpone the definition until the upper layers have been loaded. % % \end{markdown} % \begin{macrocode} \str_if_eq:VVT \c_@@_top_layer_tl \c_@@_option_layer_plain_tex_tl { \@@_define_option_commands_and_keyvals: } \ExplSyntaxOff % \end{macrocode} % \iffalse % %<*manual-options> % \fi % \begin{markdown} %### Themes {#themes} % \iffalse #### Themes {#themes} % \fi User-defined themes for the Markdown package provide a domain-specific interpretation of Markdown tokens. Themes allow the authors to achieve a specific look and other high-level goals without low-level programming. % The key--values `theme`=\meta{theme name} and `import`=\meta{theme name}, % optionally followed by `@`\meta{theme version}, load a \TeX{} document % (further referred to as *a theme*) named `markdowntheme`\meta{munged theme % name}`.tex`, where the *munged theme name* is the *theme name* after the % substitution of all forward slashes (`/`) for an underscore (`_`). % The theme name must be *qualified* and contain no underscores or at signs % (`@`). Themes are inspired by the Beamer \LaTeX{} package, which provides % similar functionality with its `\usetheme` macro [@tantau21, Section 15.1]. % % A theme name is qualified if and only if it contains at least one forward % slash. Theme names must be qualified to minimize naming conflicts between % different themes with a similar purpose. The preferred format of a theme name % is \meta{theme author}`/`\meta{theme purpose}`/`\meta{private naming scheme}, % where the *private naming scheme* may contain additional forward slashes. For % example, a theme by a user `witiko` for the MU theme of the Beamer document % class may have the name `witiko/beamer/MU`. % % Theme names are munged to allow structure inside theme names without % dictating where the themes should be located inside the \TeX{} directory % structure. For example, loading a theme named `witiko/beamer/MU` would % load a \TeX{} document package named `markdownthemewitiko_beamer_MU.tex`. % % If `@`\meta{theme version} is specified after \meta{theme name}, then the % text *theme version* will be available in the macro % \mdef{markdownThemeVersion} when the theme is loaded. If `@`\meta{theme % version} is not specified, the macro \mref{markdownThemeVersion} will % contain the text `latest` [@novotny24]. % % \end{markdown} % \iffalse % %<*tex> % \fi % \begin{macrocode} \ExplSyntaxOn \keys_define:nn { markdown/options } { theme .value_required:n = { true }, theme .code:n = { \@@_set_theme:n { #1 } }, import .value_required:n = { true }, import .code:n = { \tl_set:Nn \l_tmpa_tl { #1 } % \end{macrocode} % \begin{markdown} % % To ensure that keys containing forward slashes get passed correctly, we % replace all forward slashes in the input with backslash tokens with category % code letter and then undo the replacement. This means that if any unbraced % backslash tokens with category code letter exist in the input, they will be % replaced with forward slashes. However, this should be extremely rare. % % \end{markdown} % \begin{macrocode} \tl_replace_all:NnV \l_tmpa_tl { / } \c_backslash_str \keys_set:nV { markdown/options/import } \l_tmpa_tl }, } % \end{macrocode} % \begin{markdown} % % To keep track of the current theme when themes are nested, we will % maintain the stacks \mdef{g_\@\@_theme_names_seq} and % \mdef{g_\@\@_theme_versions_seq} stack of theme names and versions, % respectively. For convenience, the name of the current theme and version is % also available in the macros \mdef{g_@@_current_theme_tl} and % \mref{markdownThemeVersion}, respectively. % % \end{markdown} % \begin{macrocode} \seq_new:N \g_@@_theme_names_seq \seq_new:N \g_@@_theme_versions_seq \tl_new:N \g_@@_current_theme_tl \tl_gset:Nn \g_@@_current_theme_tl { } \seq_gput_right:NV \g_@@_theme_names_seq \g_@@_current_theme_tl \cs_new:Npn \markdownThemeVersion { } \seq_gput_right:NV \g_@@_theme_versions_seq \g_@@_current_theme_tl \cs_new:Nn \@@_set_theme:n { % \end{macrocode} % \begin{markdown} % % First, we validate the theme name. % % \end{markdown} % \begin{macrocode} \str_if_in:nnF { #1 } { / } { \msg_error:nnn { markdown } { unqualified-theme-name } { #1 } } \str_if_in:nnT { #1 } { _ } { \msg_error:nnn { markdown } { underscores-in-theme-name } { #1 } } % \end{macrocode} % \begin{markdown} % % Next, we extract the theme version. % % \end{markdown} % \begin{macrocode} \str_if_in:nnTF { #1 } { @ } { \regex_extract_once:nnN { (.*) @ (.*) } { #1 } \l_tmpa_seq \seq_gpop_left:NN \l_tmpa_seq \l_tmpa_tl \seq_gpop_left:NN \l_tmpa_seq \l_tmpa_tl \tl_gset:NV \g_@@_current_theme_tl \l_tmpa_tl \seq_gpop_left:NN \l_tmpa_seq \l_tmpa_tl \cs_gset:Npe \markdownThemeVersion { \tl_use:N \l_tmpa_tl } } { \tl_gset:Nn \g_@@_current_theme_tl { #1 } \cs_gset:Npn \markdownThemeVersion { latest } } % \end{macrocode} % \begin{markdown} % % Next, we strip a leading slash, if present, for consistency with snippets, % where a leading slash distinguishes absolute snippet names from relative % ones. Theme names, however, are currently always absolute, so stripping the % slash is only a syntactic normalization and has no semantic effect. % % \end{markdown} % \begin{macrocode} \str_if_eq:enT { \tl_head:V \g_@@_current_theme_tl } { / } { \tl_gset:Ne \g_@@_current_theme_tl { \tl_tail:V \g_@@_current_theme_tl } } % \end{macrocode} % \begin{markdown} % % Next, we munge the theme name. % % \end{markdown} % \begin{macrocode} \str_set:NV \l_tmpa_str \g_@@_current_theme_tl \str_replace_all:Nnn \l_tmpa_str { / } { _ } % \end{macrocode} % \begin{markdown} % % Finally, we load the theme. Before loading the theme, we push down the % current name and version of the theme on the stack. % % \end{markdown} % \begin{macrocode} \tl_set:NV \l_tmpa_tl \g_@@_current_theme_tl \tl_put_right:Nn \g_@@_current_theme_tl { / } \seq_gput_right:NV \g_@@_theme_names_seq \g_@@_current_theme_tl \seq_gput_right:NV \g_@@_theme_versions_seq \markdownThemeVersion \@@_load_theme:VeV \l_tmpa_tl { \markdownThemeVersion } \l_tmpa_str % \end{macrocode} % \begin{markdown} % % After the theme has been loaded, we recover the name and version of the % previous theme from the stack. % % \end{markdown} % \begin{macrocode} \seq_gpop_right:NN \g_@@_theme_names_seq \l_tmpa_tl \seq_get_right:NN \g_@@_theme_names_seq \l_tmpa_tl \tl_gset:NV \g_@@_current_theme_tl \l_tmpa_tl \seq_gpop_right:NN \g_@@_theme_versions_seq \l_tmpa_tl \seq_get_right:NN \g_@@_theme_versions_seq \l_tmpa_tl \cs_gset:Npe \markdownThemeVersion { \tl_use:N \l_tmpa_tl } } \msg_new:nnnn { markdown } { unqualified-theme-name } { Won't~load~theme~with~unqualified~name~#1 } { Theme~names~must~contain~at~least~one~forward~slash } \msg_new:nnnn { markdown } { underscores-in-theme-name } { Won't~load~theme~with~an~underscore~in~its~name~#1 } { Theme~names~must~not~contain~underscores~in~their~names } \cs_generate_variant:Nn \tl_replace_all:Nnn { NnV } \cs_generate_variant:Nn \cs_gset:Npn { Npe } \prg_generate_conditional_variant:Nnn \str_if_eq:nn { en } { T } % \end{macrocode} % \begin{markdown} % % We also define the prop \mdef{g_@@_plain_tex_built_in_themes_prop} that % contains the code of built-in themes. This is a packaging optimization, % so that built-in themes does not need to be distributed in many small files. % % \end{markdown} % \begin{macrocode} \prop_new:N \g_@@_plain_tex_built_in_themes_prop % \end{macrocode} % \iffalse % %<*manual-options> % \fi % \markdownBegin Built-in plain \TeX{} themes provided with the Markdown package include: \pkg{witiko/diagrams} : A theme that typesets fenced code blocks with the infostrings `dot`, `mermaid`, and `plantuml` as figures with diagrams produced with the command `dot` from Graphviz tools, the command `mmdc` from the npm package `@mermaid-js/mermaid-cli`, and the command `plantuml` from the package PlantUML, respectively. The key-value attribute `caption` can be used to specify the caption of the figure and for the infostrings `dot` and `plantuml`, the key-value attribute `format` can be used to specify the output image format. The remaining attributes are treated as image attributes. % ```` tex % \documentclass{article} % \usepackage[relativeReferences, texComments]{markdown} % \markdownSetup{import=witiko/diagrams@v2} % \begin{document} % \begin{markdown} % ``` dot {caption="An example directed graph" \% format=svg width=12cm #dot} % digraph tree { % margin = 0; % rankdir = "LR"; % % latex -> pmml; % latex -> cmml; % pmml -> slt; % cmml -> opt; % cmml -> prefix; % cmml -> infix; % pmml -> mterms [style=dashed]; % cmml -> mterms; % % latex [label = "LaTeX"]; % pmml [label = "Presentation MathML"]; % cmml [label = "Content MathML"]; % slt [label = "Symbol Layout Tree"]; % opt [label = "Operator Tree"]; % prefix [label = "Prefix"]; % infix [label = "Infix"]; % mterms [label = "M-Terms"]; % } % ``` % % ``` mermaid {caption="An example mindmap" \% width=9cm #mermaid} % mindmap % root )base-idea( % sub
idea 1 % ((?)) % sub
idea 2 % ((?)) % sub
idea 3 % ((?)) % sub
idea 4 % ((?)) % ``` % % ``` plantuml {caption="An example UML sequence diagram" \% width=7cm #plantuml} % @startuml % ' Define participants (actors) % participant "Client" as C % participant "Server" as S % participant "Database" as DB % % ' Diagram title % title Simple Request-Response Flow % % ' Messages % C -> S: Send Request % note over S: Process request % % alt Request is valid % S -> DB: Query Data % DB -> S: Return Data % S -> C: Respond with Data % else Request is invalid % S -> C: Return Error % end % @enduml % ``` % % See the diagrams in figures <#dot>, <#mermaid>, and <#plantuml>. % \end{markdown} % \end{document} % ```````` % % Typesetting the above document produces the output shown in % figures <#fig:witiko-diagrams-dot>, <#fig:witiko-diagrams-mermaid>, and % <#fig:witiko-diagrams-plantuml>. % % ``` dot {caption="An example directed graph" format=svg #fig:witiko-diagrams-dot} % digraph tree { % margin = 0; % rankdir = "LR"; % % latex -> pmml; % latex -> cmml; % pmml -> slt; % cmml -> opt; % cmml -> prefix; % cmml -> infix; % pmml -> mterms [style=dashed]; % cmml -> mterms; % % latex [label = "LaTeX"]; % pmml [label = "Presentation MathML"]; % cmml [label = "Content MathML"]; % slt [label = "Symbol Layout Tree"]; % opt [label = "Operator Tree"]; % prefix [label = "Prefix"]; % infix [label = "Infix"]; % mterms [label = "M-Terms"]; % } % ``` % % ``` mermaid {caption="An example mindmap" #fig:witiko-diagrams-mermaid} % mindmap % root )base-idea( % sub
idea 1 % ((?)) % sub
idea 2 % ((?)) % sub
idea 3 % ((?)) % sub
idea 4 % ((?)) % ``` % % ``` plantuml {caption="An example UML sequence diagram" #fig:witiko-diagrams-plantuml} % @startuml % ' Define participants (actors) % participant "Client" as C % participant "Server" as S % participant "Database" as DB % % ' Diagram title % title Simple Request-Response Flow % % ' Messages % C -> S: Send Request % note over S: Process request % % alt Request is valid % S -> DB: Query Data % DB -> S: Return Data % S -> C: Respond with Data % else Request is invalid % S -> C: Return Error % end % @enduml % ``` The theme requires a Unix-like operating system with GNU Diffutils, Graphviz, the npm package `@mermaid-js/mermaid-cli`, and PlantUML installed. All these packages are already included in the Docker image `witiko/markdown`; consult `Dockerfile` to see how they are installed. The theme also requires shell access unless the \Opt{frozenCache} plain \TeX{} option is enabled. % \markdownEnd % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage[import=witiko/diagrams@v2, relativeReferences]{markdown} \begin{document} \begin{markdown} ``` dot {caption="An example directed graph" width=12cm #dot} digraph tree { margin = 0; rankdir = "LR"; latex -> pmml; latex -> cmml; pmml -> slt; cmml -> opt; cmml -> prefix; cmml -> infix; pmml -> mterms [style=dashed]; cmml -> mterms; latex [label = "LaTeX"]; pmml [label = "Presentation MathML"]; cmml [label = "Content MathML"]; slt [label = "Symbol Layout Tree"]; opt [label = "Operator Tree"]; prefix [label = "Prefix"]; infix [label = "Infix"]; mterms [label = "M-Terms"]; } ``` ``` mermaid {caption="An example mindmap" width=9cm #mermaid} mindmap root )base-idea( sub
idea 1 ((?)) sub
idea 2 ((?)) sub
idea 3 ((?)) sub
idea 4 ((?)) ``` ``` plantuml {caption="An example UML sequence diagram" width=7cm #plantuml} @startuml ' Define participants (actors) participant "Client" as C participant "Server" as S participant "Database" as DB ' Diagram title title Simple Request-Response Flow ' Messages C -> S: Send Request note over S: Process request alt Request is valid S -> DB: Query Data DB -> S: Return Data S -> C: Respond with Data else Request is invalid S -> C: Return Error end @enduml ``` See the diagrams in figures <#dot>, <#mermaid>, and <#plantuml>. \end{markdown} \end{document} ```````` Next, invoke LuaTeX from the terminal: ``` sh lualatex --shell-escape document.tex `````` A PDF document named `document.pdf` should be produced and contain three diagrams. % \fi % \begin{markdown} \pkg{witiko/glossaries} : A theme that defines snippets with integrations for the \LaTeX{} package % \pkg{glossaries}. See Section <#sec:latexsnippets> for more details. % \iffalse \pkg{glossaries}. % \fi % \end{markdown} % \markdownBegin \pkg{witiko/graphicx/http} : A theme that adds support for downloading images whose URL has the HTTP or HTTPS protocol. % ``` tex % \documentclass{article} % \usepackage[import=witiko/graphicx/http]{markdown} % \begin{document} % \begin{markdown} % ![img](https://github.com/witiko/markdown/raw/main/markdown.png % "The banner of the Markdown package") % \end{markdown} % \end{document} % ``````` % Typesetting the above document produces the output shown in % Figure <#fig:witiko-graphicx-http>. % ![img](https://github.com/witiko/markdown/raw/main/markdown.png % "The banner of the Markdown package"){#fig:witiko-graphicx-http} The theme requires the \pkg{catchfile} \LaTeX{} package and a Unix-like operating system with GNU Coreutils `md5sum` and either GNU Wget or cURL installed. The theme also requires shell access unless the \Opt{frozenCache} plain \TeX{} option is enabled. % \markdownEnd % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[import=witiko/graphicx/http, link_attributes]{markdown} \begin{document} \begin{markdown} ![img](https://github.com/witiko/markdown/raw/main/markdown.png "The banner of the Markdown package"){width=5in} \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex --shell-escape document.tex `````` A PDF document named `document.pdf` should be produced and contain the following image: > ![Figure 1: The banner of the Markdown package](https://github.com/witiko/markdown/raw/main/markdown.png) % \fi % \begin{markdown} \pkg{witiko/tilde} : A theme that makes tilde (`~`) always typeset the non-breaking space even when the \Opt{hybrid} Lua option is disabled. % ``` tex % \input markdown % \markdownSetup{import=witiko/tilde} % \markdownBegin % Bartel~Leendert van~der~Waerden % \markdownEnd % \bye % ``````` % Typesetting the above document produces the following text: % “Bartel~Leendert van~der~Waerden”. % % \end{markdown} % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \markdownSetup{import=witiko/tilde} \markdownBegin Bartel~Leendert van~der~Waerden \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text, where the middot (`·`) denotes a non-breaking space: > Bartel·Leendert van·der·Waerden % \fi % \begin{markdown} \pkg{witiko/markdown/defaults} : A plain \TeX{} theme with the default definitions of token renderer prototypes for plain \TeX{}. This theme is loaded automatically together with the package and explicitly loading it has no effect. % See Section <#sec:themes-implementation> for implementation details of the % built-in plain \TeX{} themes. % %### Snippets {#snippets} % \iffalse #### Snippets {#snippets} % \fi % \end{markdown} % \iffalse User-defined themes provide global control over high-level goals. However, it is often desirable to change only some local aspects of a document. Snippets provide syntactic sugar for defining and invoking various options locally. % %<*tex> % \fi % \begin{markdown} % % We may set up options as *snippets* using the % \mdef{markdownSetupSnippet} macro and invoke them later. The % \mref{markdownSetupSnippet} macro receives two arguments: the name % of the snippet and the options to store. % % \end{markdown} % \begin{macrocode} \prop_new:N \g_@@_snippets_prop \cs_new:Nn \@@_setup_snippet:nn { \tl_if_empty:nT { #1 } { \msg_error:nnn { markdown } { empty-snippet-name } { #1 } } \@@_resolve_snippet_name:nN { #1 } \l_tmpa_tl \@@_if_snippet_exists:nT { #1 } { \msg_warning:nnV { markdown } { redefined-snippet } \l_tmpa_tl } \keys_precompile:nnN { markdown/options } { #2 } \l_tmpb_tl \prop_gput:NVV \g_@@_snippets_prop \l_tmpa_tl \l_tmpb_tl } \cs_gset_eq:NN \markdownSetupSnippet \@@_setup_snippet:nn \msg_new:nnnn { markdown } { empty-snippet-name } { Empty~snippet~name~#1 } { Pick~a~non-empty~name~for~your~snippet } \msg_new:nnn { markdown } { redefined-snippet } { Redefined~snippet~#1 } % \end{macrocode} % \begin{markdown} % % To decide whether a snippet exists, we can use the % \mdef{markdownIfSnippetExists} macro. % % \end{markdown} % \begin{macrocode} \tl_new:N \l_@@_current_snippet_tl \prg_new_conditional:Nnn \@@_if_snippet_exists:n { TF, T } { \@@_resolve_snippet_name:nN { #1 } \l_@@_current_snippet_tl \prop_if_in:NVTF \g_@@_snippets_prop \l_@@_current_snippet_tl { \prg_return_true: } { \prg_return_false: } } \cs_gset_eq:NN \markdownIfSnippetExists \@@_if_snippet_exists:nTF \cs_new:Nn \@@_resolve_snippet_name:nN { % \end{macrocode} % \begin{markdown} % % If the provided snippet name starts with a slash (`/`), consider it as % *absolute* and take the rest of the name as the full name of the defined % snippet, regardless of the currently processed theme. % % \end{markdown} % \begin{macrocode} \str_if_eq:enTF { \tl_head:n { #1 } } { / } { \tl_set:Ne #2 { \tl_tail:n { #1 } } } { % \end{macrocode} % \begin{markdown} % % Otherwise, consider the provided snippet name as *relative* and % prepend the name of the currently processed theme to it, if any. % The result is then the full name of the defined snippet. % % \end{markdown} % \begin{macrocode} \tl_set:NV #2 \g_@@_current_theme_tl \tl_put_right:Nn #2 { #1 } } } \prg_generate_conditional_variant:Nnn \str_if_eq:nn { en } { TF } % \end{macrocode} % \begin{markdown} % % The option with key `snippet` invokes a snippet named \meta{value}. % % \end{markdown} % \begin{macrocode} \keys_define:nn { markdown/options } { snippet .value_required:n = { true }, snippet .code:n = { \@@_resolve_snippet_name:nN { #1 } \l_tmpa_tl \@@_if_snippet_exists:nTF { #1 } { \prop_get:NVN \g_@@_snippets_prop \l_tmpa_tl \l_tmpb_tl \tl_use:N \l_tmpb_tl } { \msg_error:nnV { markdown } { undefined-snippet } \l_tmpa_tl } }, } \msg_new:nnn { markdown } { undefined-snippet } { Can't~invoke~undefined~snippet~#1 } \ExplSyntaxOff % \end{macrocode} % \iffalse % %<*manual-options> % \fi % \markdownBegin Here is how we can use snippets to store options and invoke them later in \LaTeX{}: ``` tex \markdownSetupSnippet{romanNumerals}{ renderers = { olItemWithNumber = {% \item[\romannumeral#1\relax.]% }, }, } \begin{markdown} The following ordered list will be preceded by arabic numerals: 1. wahid 2. aithnayn \end{markdown} \begin{markdown}[snippet=romanNumerals] The following ordered list will be preceded by roman numerals: 3. tres 4. quattuor \end{markdown} ``````` If the `romanNumerals` snippet were defined in the `jdoe/lists` theme, we could import the `jdoe/lists` theme and use the qualified name `jdoe/lists/romanNumerals` to invoke the snippet: ``` tex \markdownSetup{import=jdoe/lists} \begin{markdown}[snippet=jdoe/lists/romanNumerals] The following ordered list will be preceded by roman numerals: 3. tres 4. quattuor \end{markdown} ``````` Alternatively, we can use the extended variant of the `import` \LaTeX{} option that allows us to import the `romanNumerals` snippet to the current namespace for easier access: ``` tex \markdownSetup{ import = { jdoe/lists = romanNumerals, }, } \begin{markdown}[snippet=romanNumerals] The following ordered list will be preceded by roman numerals: 3. tres 4. quattuor \end{markdown} ``````` Furthermore, we can also specify the name of the snippet in the current namespace, which can be different from the name of the snippet in the `jdoe/lists` theme. For example, we can make the snippet `jdoe/lists/romanNumerals` available under the name `roman`. ``` tex \markdownSetup{ import = { jdoe/lists = romanNumerals as roman, }, } \begin{markdown}[snippet=roman] The following ordered list will be preceded by roman numerals: 3. tres 4. quattuor \end{markdown} ``````` Several themes and/or snippets can be loaded at once using the extended variant of the `import` \LaTeX{} option: ``` tex \markdownSetup{ import = { jdoe/longpackagename/lists = { arabic as arabic1, roman, alphabetic, }, jdoe/anotherlongpackagename/lists = { arabic as arabic2, }, jdoe/yetanotherlongpackagename, }, } ``````` % \markdownEnd % \iffalse % %<*tex> % \fi % \begin{macrocode} \ExplSyntaxOn \tl_new:N \l_@@_import_current_theme_tl \keys_define:nn { markdown/options/import } { % \end{macrocode} % \begin{markdown} % % If a theme name is given without a list of snippets to import, % we assume that an empty list was given. % % \end{markdown} % \begin{macrocode} unknown .value_required:n = { false }, unknown .default:n = {}, unknown .code:n = { % \end{macrocode} % \begin{markdown} % % To ensure that keys containing forward slashes get passed correctly, we % replace all forward slashes in the input with backslash tokens with category % code letter and then undo the replacement. This means that if any unbraced % backslash tokens with category code letter exist in the input, they will be % replaced with forward slashes. However, this should be extremely rare. % % \end{markdown} % \begin{macrocode} \tl_set_eq:NN \l_@@_import_current_theme_tl \l_keys_key_str \tl_replace_all:NVn \l_@@_import_current_theme_tl \c_backslash_str { / } % \end{macrocode} % \begin{markdown} % % Here, we import the snippets. % % \end{markdown} % \begin{macrocode} \clist_map_inline:nn { #1 } { \regex_extract_once:nnNTF { ^(.*?)\s+as\s+(.*?)$ } { ##1 } \l_tmpa_seq { \seq_pop:NN \l_tmpa_seq \l_tmpa_tl \seq_pop:NN \l_tmpa_seq \l_tmpa_tl \seq_pop:NN \l_tmpa_seq \l_tmpb_tl } { \tl_set:Nn \l_tmpa_tl { ##1 } \tl_set:Nn \l_tmpb_tl { ##1 } } \tl_put_left:Nn \l_tmpa_tl { / } \tl_put_left:NV \l_tmpa_tl \l_@@_import_current_theme_tl \@@_setup_snippet:Vx \l_tmpb_tl { snippet = { \l_tmpa_tl } } } % \end{macrocode} % \begin{markdown} % % Here, we load the theme. % % \end{markdown} % \begin{macrocode} \@@_set_theme:V \l_@@_import_current_theme_tl }, } \cs_generate_variant:Nn \tl_replace_all:Nnn { NVn } \cs_generate_variant:Nn \@@_set_theme:n { V } \cs_generate_variant:Nn \@@_setup_snippet:nn { Vx } % \end{macrocode} % \iffalse % %<*manual-tokens> ## Markdown Tokens A key feature of the Markdown package is the support for manipulating markdown tokens, such as headings, emphasized text, links, and lists, in \TeX{}. Instead of reducing \TeX{} to a PDF document producer, the Markdown package allows the user to specify how every markdown token should be processed and rendered. % \fi % \begin{markdown} ### Token Renderers {#texrenderersuser} % \end{markdown} % \iffalse Token renderers are user-defined \TeX{} macros, which render markdown tokens. In this section, I will describe the individual token renderers. % \fi % \begin{markdown} % % The following \TeX{} macros may occur inside the output of the % converter functions exposed by the Lua interface (see Section % <#sec:lua-conversion>) and represent the parsed markdown tokens. These % macros are intended to be redefined by the user who is typesetting a % document. By default, they point to the corresponding prototypes (see Section % <#sec:texrendererprototypes>). % % \end{markdown} % % \iffalse % %<*tex> % \fi % \begin{markdown} % % To enable the enumeration of token renderers, we will maintain the % \mdef{g_\@\@_renderers_seq} sequence. % % \end{markdown} % \begin{macrocode} \seq_new:N \g_@@_renderers_seq % \end{macrocode} % \begin{markdown} % % To enable the reflection of token renderers and their parameters, we will % maintain the \mdef{g_\@\@_renderer_arities_prop} property list. % % \end{markdown} % \begin{macrocode} \prop_new:N \g_@@_renderer_arities_prop \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### Acronym Renderers The following macro is only produced when the option \Opt{acronyms} is non-empty. \mdef{markdownRendererAcronym} represents an acronym, initialism, or another all-caps sequence. The macro receives a single attribute that corresponds to the sequence. % \end{markdown} % % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ```` tex \documentclass{article} \usepackage{markdown} \markdownSetup { % Format the following words as acronyms. acronyms = {HTML, YAML}, renderers = { % Format acronyms as small caps. acronym = \textsc{\MakeLowercase{#1}}, }, } \begin{document} \begin{markdown} HTML and YAML are two staples of modern tooling that often get mentioned in the same breath, even though they live in very different layers of the stack. \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex --shell-escape document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > HTML and YAML are two staples of modern tooling > that often get mentioned in the same breath, even though they live in very > different layers of the stack. % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererAcronym { \markdownRendererAcronymPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { acronym } \prop_gput:Nnn \g_@@_renderer_arities_prop { acronym } { 1 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### Attribute Renderers The following macros are only produced, when at least one of the following options for markdown attributes on different elements is enabled: - \Opt{autoIdentifiers} - \Opt{fencedCodeAttributes} - \Opt{gfmAutoIdentifiers} - \Opt{headerAttributes} - \Opt{inlineCodeAttributes} - \Opt{linkAttributes} \mdef{markdownRendererAttributeIdentifier} represents the \meta{identifier} of a markdown element (`id="`\meta{identifier}`"` in HTML and `#`\meta{identifier} in markdown attributes). The macro receives a single attribute that corresponds to the \meta{identifier}. \mdef{markdownRendererAttributeClassName} represents the \meta{class name} of a markdown element (`class="`\meta{class name} ...`"` in HTML and `.`\meta{class name} in markdown attributes). The macro receives a single attribute that corresponds to the \meta{class name}. \mdef{markdownRendererAttributeKeyValue} represents an HTML attribute in the form \meta{key}`=`\meta{value} that is neither an identifier nor a class name. The macro receives two attributes that correspond to the \meta{key} and the \meta{value}, respectively. % \end{markdown} % % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[headerAttributes, underscores=false]{markdown} \markdownSetup{ renderers = { attributeIdentifier = {% \par \emph{(Identifier: #1)} \par }, attributeClassName = {% \par \emph{(Class name: #1)} \par }, attributeKeyValue = {% \par \emph{(Key: #1, Value: #2)} \par }, }, } \begin{document} \begin{markdown} # First top-level heading {jane=doe} ## A subheading {#identifier} # Second top-level heading {.class_name} \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > # First top-level heading > > *(Key: Jane, Value: Doe)* > > ## A subheading > > *(Identifier: identifier)* > > # Second top-level heading > > *(Class name: class\_name)* % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererAttributeIdentifier { \markdownRendererAttributeIdentifierPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { attributeIdentifier } \prop_gput:Nnn \g_@@_renderer_arities_prop { attributeIdentifier } { 1 } \cs_gset_protected:Npn \markdownRendererAttributeClassName { \markdownRendererAttributeClassNamePrototype } \seq_gput_right:Nn \g_@@_renderers_seq { attributeClassName } \prop_gput:Nnn \g_@@_renderer_arities_prop { attributeClassName } { 1 } \cs_gset_protected:Npn \markdownRendererAttributeKeyValue { \markdownRendererAttributeKeyValuePrototype } \seq_gput_right:Nn \g_@@_renderers_seq { attributeKeyValue } \prop_gput:Nnn \g_@@_renderer_arities_prop { attributeKeyValue } { 2 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### Basic HTML Renderers {#basic-html-renderers} The \mdef{markdownRendererInlineHtmlComment} macro represents the contents of an inline HTML comment. The macro receives a single argument that corresponds to the contents of the HTML comment. The \mdef{markdownRendererInlineHtmlTag} macro represents an opening, closing, or empty inline HTML tag. The macro receives a single argument that corresponds to the contents of the HTML tag. The \mdef{markdownRendererInputBlockHtmlElement} macro represents a block HTML element. This macro will only be produced, when the \Opt{html} option is enabled. The macro receives a single argument that filename of a file containing the contents of the HTML element. These macros will only be produced when the \Opt{html} option is enabled and the \Opt{htmlOutput} option is set to `basic`. % \end{markdown} % % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \usepackage[blankBeforeHtmlBlock]{marginnote} \usepackage{verbatim} \markdownSetup{ renderers = { inlineHtmlComment = \marginnote{#1}, inlineHtmlTag = \textbf{#1}, inputBlockHtmlElement = \verbatiminput{#1}, }, } \begin{document} \begin{markdown} A useful use of inline HTML comments are side notes. _Hello,_ world!
_Hello,_ world!
\end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following body text: > A useful use of HTML comments are side notes. > > **<b>**Hello, world!**</b><br/>** > >
_Hello,_ world!
The horizontal margins should contain the following text: > Side notes are displayed in the horizontal margins next to the relevant > passages, which makes them *easier for the reader to find* than notes. % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererInlineHtmlComment { \markdownRendererInlineHtmlCommentPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { inlineHtmlComment } \prop_gput:Nnn \g_@@_renderer_arities_prop { inlineHtmlComment } { 1 } \cs_gset_protected:Npn \markdownRendererInlineHtmlTag { \markdownRendererInlineHtmlTagPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { inlineHtmlTag } \prop_gput:Nnn \g_@@_renderer_arities_prop { inlineHtmlTag } { 1 } \cs_gset_protected:Npn \markdownRendererInputBlockHtmlElement { \markdownRendererInputBlockHtmlElementPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { inputBlockHtmlElement } \prop_gput:Nnn \g_@@_renderer_arities_prop { inputBlockHtmlElement } { 1 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### Block Quote Renderers The \mdef{markdownRendererBlockQuoteBegin} macro represents the beginning of a block quote. The macro receives no arguments. % \end{markdown} % % \iffalse % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererBlockQuoteBegin { \markdownRendererBlockQuoteBeginPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { blockQuoteBegin } \prop_gput:Nnn \g_@@_renderer_arities_prop { blockQuoteBegin } { 0 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} The \mdef{markdownRendererBlockQuoteEnd} macro represents the end of a block quote. The macro receives no arguments. % \end{markdown} % % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownRendererBlockQuoteBegin{% \begingroup \vskip\parindent \leftskip=2\parindent \parindent=0pt } \def\markdownRendererBlockQuoteEnd{% \par \vskip\parindent \endgroup } \markdownBegin A quote from William Shakespeare's King Lear: > This is the excellent foppery of the world that when we are > sick in fortune---often the surfeit of our own behavior---we > make guilty of our disasters the sun, the moon, and the > stars [...] \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A quote from William Shakespeare's King Lear: > > > This is the excellent foppery of the world that when we are > > sick in fortune—often the surfeit of our own behavior—we > > make guilty of our disasters the sun, the moon, and the > > stars [...] ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{markdown} \markdownSetup{ renderers = { blockQuoteBegin = {\begin{quote}}, blockQuoteEnd = {\end{quote}}, }, } \begin{document} \begin{markdown} A quote from William Shakespeare's King Lear: > This is the excellent foppery of the world that when we are > sick in fortune---often the surfeit of our own behavior---we > make guilty of our disasters the sun, the moon, and the > stars [...] \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A quote from William Shakespeare's King Lear: > > > This is the excellent foppery of the world that when we are > > sick in fortune—often the surfeit of our own behavior—we > > make guilty of our disasters the sun, the moon, and the > > stars [...] ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \def\markdownRendererBlockQuoteBegin{\startquotation} \def\markdownRendererBlockQuoteEnd{\stopquotation} \starttext \startmarkdown A quote from William Shakespeare's King Lear: > This is the excellent foppery of the world that when we are > sick in fortune---often the surfeit of our own behavior---we > make guilty of our disasters the sun, the moon, and the > stars [...] \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > A quote from William Shakespeare's King Lear: > > > This is the excellent foppery of the world that when we are > > sick in fortune—often the surfeit of our own behavior—we > > make guilty of our disasters the sun, the moon, and the > > stars [...] % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererBlockQuoteEnd { \markdownRendererBlockQuoteEndPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { blockQuoteEnd } \prop_gput:Nnn \g_@@_renderer_arities_prop { blockQuoteEnd } { 0 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### Bracketed Spans The following macros are only produced, when the \Opt{bracketedSpans} option is enabled. The \mdef{markdownRendererBracketedSpan} macro represents an inline bracketed span. It receives a single argument that corresponds to the inline bracketed span. % \end{markdown} % % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[bracketedSpans]{markdown} \markdownSetup{ renderers = { bracketedSpan = {(#1)}, }, } \begin{document} \begin{markdown} [foo [bar]{#identifier}]{key=value} [baz]{.class_name} \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > (foo (bar)) (baz) % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererBracketedSpan { \markdownRendererBracketedSpanPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { bracketedSpan } \prop_gput:Nnn \g_@@_renderer_arities_prop { bracketedSpan } { 1 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### Bracketed Span Attribute Context Renderers The following macros are only produced, when the \Opt{bracketedSpans} option is enabled. The \mdef{markdownRendererBracketedSpanAttributeContextBegin} and \mdef{markdownRendererBracketedSpanAttributeContextEnd} macros represent the beginning and the end of a context in which the attributes of an inline bracketed span apply. The macros receive no arguments. % \end{markdown} % % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[bracketedSpans]{markdown} \markdownSetup{ renderers = { bracketedSpanAttributeContextBegin = {(}, bracketedSpanAttributeContextEnd = {)}, }, } \begin{document} \begin{markdown} [foo [bar]{#identifier}]{key=value} [baz]{.class_name} \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > (foo (bar)) (baz) % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererBracketedSpanAttributeContextBegin { \markdownRendererBracketedSpanAttributeContextBeginPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { bracketedSpanAttributeContextBegin } \prop_gput:Nnn \g_@@_renderer_arities_prop { bracketedSpanAttributeContextBegin } { 0 } \cs_gset_protected:Npn \markdownRendererBracketedSpanAttributeContextEnd { \markdownRendererBracketedSpanAttributeContextEndPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { bracketedSpanAttributeContextEnd } \prop_gput:Nnn \g_@@_renderer_arities_prop { bracketedSpanAttributeContextEnd } { 0 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### Bullet List Renderers The \mdef{markdownRendererUlBegin} macro represents the beginning of a bulleted list that contains an item with several paragraphs of text (the list is not tight). The macro receives no arguments. % \end{markdown} % % \iffalse % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererUlBegin { \markdownRendererUlBeginPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { ulBegin } \prop_gput:Nnn \g_@@_renderer_arities_prop { ulBegin } { 0 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} The \mdef{markdownRendererUlBeginTight} macro represents the beginning of a bulleted list that contains no item with several paragraphs of text (the list is tight). This macro will only be produced, when the \Opt{tightLists} option is disabled. The macro receives no arguments. % \end{markdown} % % \iffalse % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererUlBeginTight { \markdownRendererUlBeginTightPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { ulBeginTight } \prop_gput:Nnn \g_@@_renderer_arities_prop { ulBeginTight } { 0 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} The \mdef{markdownRendererUlItem} macro represents an item in a bulleted list. The macro receives no arguments. % \end{markdown} % % \iffalse % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererUlItem { \markdownRendererUlItemPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { ulItem } \prop_gput:Nnn \g_@@_renderer_arities_prop { ulItem } { 0 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} The \mdef{markdownRendererUlItemEnd} macro represents the end of an item in a bulleted list. The macro receives no arguments. % \end{markdown} % % \iffalse % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererUlItemEnd { \markdownRendererUlItemEndPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { ulItemEnd } \prop_gput:Nnn \g_@@_renderer_arities_prop { ulItemEnd } { 0 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} The \mdef{markdownRendererUlEnd} macro represents the end of a bulleted list that contains an item with several paragraphs of text (the list is not tight). The macro receives no arguments. % \end{markdown} % % \iffalse % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererUlEnd { \markdownRendererUlEndPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { ulEnd } \prop_gput:Nnn \g_@@_renderer_arities_prop { ulEnd } { 0 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} The \mdef{markdownRendererUlEndTight} macro represents the end of a bulleted list that contains no item with several paragraphs of text (the list is tight). This macro will only be produced, when the \Opt{tightLists} option is disabled. The macro receives no arguments. % \end{markdown} % % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \def\markdownOptionTightLists{true} \def\markdownRendererInterblockSeparator{} \def\markdownRendererUlBeginTight{ (} \def\markdownRendererUlItem{% \def\markdownRendererUlItem{% , \def\markdownRendererUlItem{, and }% }% } \def\markdownRendererUlItemEnd{} \def\markdownRendererUlEndTight{).} \markdownBegin This is a tight list - the first item - the second item - the third item \markdownEnd \def\markdownRendererInterblockSeparator{% :\par \def\markdownRendererInterblockSeparator{\par}% } \def\markdownRendererUlBegin{} \def\markdownRendererUlItem{--\kern 0.5em} \def\markdownRendererUlItemEnd{.\par} \def\markdownRendererUlEnd{} \markdownBegin This is a loose list - This is the first item - This is the second item - This is the third item \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is a tight list (the first item, the second item, and the third item). > > This is a loose list: > > - This is the first item. > > - This is the second item. > > - This is the third item. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[tightLists]{markdown} \begin{document} \begin{markdown}[ renderers = { interblockSeparator = {}, ulBeginTight = { (}, ulItem = {% \def\markdownRendererUlItem{% , \def\markdownRendererUlItem{, and }% }% }, ulItemEnd = {}, ulEndTight = {).}, }, ] This is a tight list - the first item - the second item - the third item \end{markdown} \begin{markdown}[ renderers = { interblockSeparator = {% :\par \def\markdownRendererInterblockSeparator{\par}% }, ulBeginTight = {\begin{itemize}}, ulItem = {\item}, ulItemEnd = {.}, ulEnd = {\end{itemize}}, }, ] This is a loose list - This is the first item - This is the second item - This is the third item \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is a tight list (the first item, the second item, and the third item). > > This is a loose list: > > - This is the first item. > > - This is the second item. > > - This is the third item. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \setupmarkdown[tightLists = yes] \starttext \def\markdownRendererInterblockSeparator{} \def\markdownRendererUlBeginTight{ (} \def\markdownRendererUlItem{% \def\markdownRendererUlItem{% , \def\markdownRendererUlItem{, and }% }% } \def\markdownRendererUlItemEnd{} \def\markdownRendererUlEndTight{).} \startmarkdown This is a tight list - the first item - the second item - the third item \stopmarkdown \def\markdownRendererInterblockSeparator{% :\par \def\markdownRendererInterblockSeparator{\par}% } \def\markdownRendererUlBegin{\startitemize} \def\markdownRendererUlItem{\item} \def\markdownRendererUlItemEnd{.} \def\markdownRendererUlEnd{\stopitemize} \startmarkdown This is a loose list - This is the first item - This is the second item - This is the third item \stopmarkdown \stoptext ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is a tight list (the first item, the second item, and the third item). > > This is a loose list: > > - This is the first item. > > - This is the second item. > > - This is the third item. % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererUlEndTight { \markdownRendererUlEndTightPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { ulEndTight } \prop_gput:Nnn \g_@@_renderer_arities_prop { ulEndTight } { 0 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### Citation Renderers The \mdef{markdownRendererCite} macro represents a string of one or more parenthetical citations. This macro will only be produced, when the \Opt{citations} option is enabled. The macro receives the parameter `{`\meta{number of citations}`}` followed by \meta{suppress author} `{`\meta{prenote}`}{`\meta{postnote}`}{`\meta{name}`}` repeated \meta{number of citations} times. The \meta{suppress author} parameter is either the token `-`, when the author's name is to be suppressed, or `+` otherwise. % \end{markdown} % % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[citations]{markdown} \newcount\citationsCounter \newcount\citationsTotal \makeatletter \def\citations#1#2#3#4{% a parenthesized citation \emph{#4} \advance\citationsCounter by 1\relax \ifx\relax#2\relax \ifx\relax#3\relax\else with a postfix \emph{#3}% \fi \else with a prefix \emph{#2}% \ifx\relax#3\relax\else \ and a postfix \emph{#3}% \fi \fi \ifnum\citationsCounter>\citationsTotal\relax .% \expandafter\@gobble \else , and \fi\citations} \makeatother \markdownSetup{ renderers = { cite = {% \citationsCounter=1% \citationsTotal=#1% This is \expandafter\citations }, }, } \begin{document} \begin{markdown} [see @abrahams90, pp. 12; @eijkhout91, pp. 34] \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is a parenthesized citation *abrahams90* with a prefix see > and a postfix *pp. 12*, and a citation *eijkhout91* with a > postfix *pp. 34*. % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererCite { \markdownRendererCitePrototype } \seq_gput_right:Nn \g_@@_renderers_seq { cite } \prop_gput:Nnn \g_@@_renderer_arities_prop { cite } { 1 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} The \mdef{markdownRendererTextCite} macro represents a string of one or more text citations. This macro will only be produced, when the \Opt{citations} option is enabled. The macro receives parameters in the same format as the \mref{markdownRendererCite} macro. % \end{markdown} % % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[citations]{markdown} \newcount\citationsCounter \newcount\citationsTotal \makeatletter \def\citations#1#2#3#4{% a text citation \emph{#4} \advance\citationsCounter by 1\relax \ifx\relax#2\relax \ifx\relax#3\relax\else with a postfix \emph{#3}% \fi \else with a prefix \emph{#2}% \ifx\relax#3\relax\else \ and a postfix \emph{#3}% \fi \fi \ifnum\citationsCounter>\citationsTotal\relax .% \expandafter\@gobble \else , and \fi\citations} \makeatother \markdownSetup{ renderers = { textCite = {% \citationsCounter=1% \citationsTotal=#1% This is \expandafter\citations }, }, } \begin{document} \begin{markdown} @abrahams90 [pp. 12; also @eijkhout91] \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > This is a text citation *abrahams90* with a postfix *pp. 12*, > and a citation *eijkhout91* with a prefix *also*. % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererTextCite { \markdownRendererTextCitePrototype } \seq_gput_right:Nn \g_@@_renderers_seq { textCite } \prop_gput:Nnn \g_@@_renderer_arities_prop { textCite } { 1 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### Code Block Renderers The \mdef{markdownRendererInputVerbatim} macro represents a code block. The macro receives a single argument that corresponds to the filename of a file containing the code block contents. % \end{markdown} % % \iffalse % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererInputVerbatim { \markdownRendererInputVerbatimPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { inputVerbatim } \prop_gput:Nnn \g_@@_renderer_arities_prop { inputVerbatim } { 1 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} The \mdef{markdownRendererInputFencedCode} macro represents a fenced code block. This macro will only be produced, when the \Opt{fencedCode} option is enabled. The macro receives three arguments that correspond to the filename of a file containing the code block contents, the fully escaped code fence infostring that can be directly typeset, and the raw code fence infostring that can be used outside typesetting. % \end{markdown} % % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage{verbatim} \usepackage[hyphens]{url} \usepackage[fencedCode]{markdown} \markdownSetup{ renderers = { interblockSeparator = { \def\markdownRendererInterblockSeparator{% \par \def\markdownRendererInterblockSeparator{% \def\markdownRendererInterblockSeparator{% \par }% }% }% }, inputVerbatim = { is contained in file \url{#1}:% \verbatiminput{#1}% }, inputFencedCode = { in #2 \markdownRendererInputVerbatim{#1}% }, }, } \begin{document} \begin{markdown} The following code def foo(bar): if len(bar) <= 1: return bar[0] elif len(bar) == 2: return sorted(bar) else: baz = len(bar) // 2 return foo(bar[baz:], bar[:baz]) The following code ~~~ Python >>> foo([4, 2, 1, 3]) [1, 2, 3, 4] ~~~~~~~~~~ \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text except for the filename, which may differ: > The following code is contained in file > `./_markdown_document/882453149edcf288976647f6fe147ada.verbatim`: > ``` py > def foo(bar): > if len(bar) <= 1: > return bar[:1] > elif len(bar) == 2: > return sorted(bar) > else: > baz = bar[len(bar) // 2] > return ( > foo([qux for qux in bar if qux < baz]) + [baz] + > foo([qux for qux in bar if qux > baz]) > ) > `````` > The following code in Python contained in file > `./_markdown_document/cf2a96e2120cef5b1fae5fea36fcc27b.verbatim`: > ``` py > >>> foo([4, 2, 1, 3]) > [1, 2, 3, 4] > `````` % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererInputFencedCode { \markdownRendererInputFencedCodePrototype } \seq_gput_right:Nn \g_@@_renderers_seq { inputFencedCode } \prop_gput:Nnn \g_@@_renderer_arities_prop { inputFencedCode } { 3 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % \begin{markdown} #### Code Span Renderer The \mdef{markdownRendererCodeSpan} macro represents inline code span in the input text. It receives a single argument that corresponds to the inline code span. % \end{markdown} % % \iffalse ##### Plain \TeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \input markdown \input lmfonts \def\markdownRendererCodeSpan#1{#1} \markdownBegin `$\sqrt{-1}$ *equals* $i$` $\sqrt{-1}$ *equals* $i$ \markdownEnd \def\markdownOptionHybrid{true} \markdownBegin $\sqrt{-1}$ *equals* $i$ \markdownEnd \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt{-1}\$ \*equals\* \$i\$. > > \$\\sqrt{-1}\$ *equals* \$i\$. > > 1 > *equals* > i. ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[smartEllipses]{markdown} \markdownSetup{ renderers = { codeSpan = {#1}, }, } \begin{document} \begin{markdown} `$\sqrt{-1}$ *equals* $i$` $\sqrt{-1}$ *equals* $i$ \end{markdown} \begin{markdown}[hybrid] $\sqrt{-1}$ *equals* $i$ \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt{-1}\$ \*equals\* \$i\$. > > \$\\sqrt{-1}\$ *equals* \$i\$. > > 1 > *equals* > i. ##### \Hologo{ConTeXt} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \usemodule[t][markdown] \def\markdownRendererCodeSpan#1{#1} \starttext \startmarkdown `$\sqrt{-1}$ *equals* $i$` $\sqrt{-1}$ *equals* $i$ \stopmarkdown \setupmarkdown[hybrid = yes] \startmarkdown $\sqrt{-1}$ *equals* $i$ \stopmarkdown \bye ``````` Next, invoke LuaTeX from the terminal: ``` sh context --luatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > \$\\sqrt{-1}\$ \*equals\* \$i\$. > > \$\\sqrt{-1}\$ *equals* \$i\$. > > 1 > *equals* > i. % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererCodeSpan { \markdownRendererCodeSpanPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { codeSpan } \prop_gput:Nnn \g_@@_renderer_arities_prop { codeSpan } { 1 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### Code Span Attribute Context Renderers The following macros are only produced, when the \Opt{inlineCodeAttributes} option is enabled. The \mdef{markdownRendererCodeSpanAttributeContextBegin} and \mdef{markdownRendererCodeSpanAttributeContextEnd} macros represent the beginning and the end of a context in which the attributes of an inline code span apply. The macros receive no arguments. % \end{markdown} % % \iffalse ##### \LaTeX{} Example {.unnumbered} Using a text editor, create a text document named `document.tex` with the following content: ``` tex \documentclass{article} \usepackage[inlineCodeAttributes]{markdown} \markdownSetup{ renderers = { codeSpanAttributeContextBegin = {(}, codeSpan = {#1}, codeSpanAttributeContextEnd = {)}, }, } \begin{document} \begin{markdown} foo `bar`{key=value} baz \end{markdown} \end{document} ``````` Next, invoke LuaTeX from the terminal: ``` sh lualatex document.tex `````` A PDF document named `document.pdf` should be produced and contain the following text: > foo (bar) baz % %<*tex> % \fi % % \begin{macrocode} \ExplSyntaxOn \cs_gset_protected:Npn \markdownRendererCodeSpanAttributeContextBegin { \markdownRendererCodeSpanAttributeContextBeginPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { codeSpanAttributeContextBegin } \prop_gput:Nnn \g_@@_renderer_arities_prop { codeSpanAttributeContextBegin } { 0 } \cs_gset_protected:Npn \markdownRendererCodeSpanAttributeContextEnd { \markdownRendererCodeSpanAttributeContextEndPrototype } \seq_gput_right:Nn \g_@@_renderers_seq { codeSpanAttributeContextEnd } \prop_gput:Nnn \g_@@_renderer_arities_prop { codeSpanAttributeContextEnd } { 0 } \ExplSyntaxOff % \end{macrocode} % % \iffalse % %<*manual-tokens> % \fi % % \begin{markdown} #### CommonMark Block HTML Renderers {#commonmark-block-html-renderers} When the \Opt{html} option is enabled and \Opt{htmlOutput} is set to \opt{commonmark}, the following fine-grained renderers are produced instead of \mref{markdownRendererInputBlockHtmlElement} to distinguish between different top-level non-terminal elements of CommonMark's grammar for [raw HTML][html-blocks]: 1. \mdef{markdownRendererInputBlockHtmlCdataElement} -- A CDATA block-level HTML element such as `