texlive[41376] Master: markdown (6jun16)

commits+karl at tug.org commits+karl at tug.org
Sun Jun 12 01:15:05 CEST 2016


Revision: 41376
          http://tug.org/svn/texlive?view=revision&revision=41376
Author:   karl
Date:     2016-06-12 01:15:05 +0200 (Sun, 12 Jun 2016)
Log Message:
-----------
markdown (6jun16)

Modified Paths:
--------------
    trunk/Master/tlpkg/bin/tlpkg-ctan-check
    trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/generic/markdown/
    trunk/Master/texmf-dist/doc/generic/markdown/markdown.pdf
    trunk/Master/texmf-dist/source/generic/markdown/
    trunk/Master/texmf-dist/source/generic/markdown/docstrip.cfg
    trunk/Master/texmf-dist/source/generic/markdown/markdown.dtx
    trunk/Master/texmf-dist/source/generic/markdown/markdown.ins
    trunk/Master/texmf-dist/tex/context/third/markdown/
    trunk/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex
    trunk/Master/texmf-dist/tex/generic/markdown/
    trunk/Master/texmf-dist/tex/generic/markdown/markdown.tex
    trunk/Master/texmf-dist/tex/latex/markdown/
    trunk/Master/texmf-dist/tex/latex/markdown/markdown.sty
    trunk/Master/texmf-dist/tex/luatex/markdown/
    trunk/Master/texmf-dist/tex/luatex/markdown/markdown.lua
    trunk/Master/tlpkg/tlpsrc/markdown.tlpsrc

Added: trunk/Master/texmf-dist/doc/generic/markdown/markdown.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/generic/markdown/markdown.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/generic/markdown/markdown.pdf	2016-06-11 23:11:37 UTC (rev 41375)
+++ trunk/Master/texmf-dist/doc/generic/markdown/markdown.pdf	2016-06-11 23:15:05 UTC (rev 41376)

Property changes on: trunk/Master/texmf-dist/doc/generic/markdown/markdown.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/generic/markdown/docstrip.cfg
===================================================================
--- trunk/Master/texmf-dist/source/generic/markdown/docstrip.cfg	                        (rev 0)
+++ trunk/Master/texmf-dist/source/generic/markdown/docstrip.cfg	2016-06-11 23:15:05 UTC (rev 41376)
@@ -0,0 +1,105 @@
+\askforoverwritefalse
+\def\luapreamble{%
+-- ^^J%
+-- Copyright (C) 2009-2016 John MacFarlane, Hans Hagen^^J%
+-- ^^J%
+-- Permission is hereby granted, free of charge, to any person obtaining^^J%
+-- a copy of this software and associated documentation files (the^^J%
+-- "Software"), to deal in the Software without restriction, including^^J%
+-- without limitation the rights to use, copy, modify, merge, publish,^^J%
+-- distribute, sublicense, and/or sell copies of the Software, and to^^J%
+-- permit persons to whom the Software is furnished to do so, subject to^^J%
+-- the following conditions:^^J%
+-- ^^J%
+-- The above copyright notice and this permission notice shall be included^^J%
+-- in all copies or substantial portions of the Software.^^J%
+-- ^^J%
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,^^J%
+-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF^^J%
+-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.^^J%
+-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY^^J%
+-- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,^^J%
+-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE^^J%
+-- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.^^J%
+-- ^^J%
+-- Copyright (C) 2016 Vít Novotný^^J%
+-- ^^J%
+-- This work may be distributed and/or modified under the^^J%
+-- conditions of the LaTeX Project Public License, either version 1.3^^J%
+-- of this license or (at your option) any later version.^^J%
+-- The latest version of this license is in^^J%
+-- ^^J%
+-- \space\space\space\space http://www.latex-project.org/lppl.txt^^J%
+-- ^^J%
+-- and version 1.3 or later is part of all distributions of LaTeX^^J%
+-- version 2005/12/01 or later.^^J%
+-- ^^J%
+-- This work has the LPPL maintenance status `maintained'.^^J%
+-- The Current Maintainer of this work is Vít Novotný.^^J%
+-- ^^J%
+-- Send bug reports, requests for additions and questions^^J%
+-- either to the GitHub issue tracker at^^J%
+-- ^^J%
+-- \space\space\space\space https://github.com/witiko/markdown/issues^^J%
+-- ^^J%
+-- or to the e-mail address <witiko at mail.muni.cz>.^^J%
+-- ^^J%
+-- MODIFICATION ADVICE:^^J%
+-- ^^J%
+-- If you want to customize this file, it is best to make a copy of^^J%
+-- the source file(s) from which it was produced.  Use a different^^J%
+-- name for your copy(ies) and modify the copy(ies); this will ensure^^J%
+-- that your modifications do not get overwritten when you install a^^J%
+-- new release of the standard system.  You should also ensure that^^J%
+-- your modified source file does not generate any modified file with^^J%
+-- the same name as a standard file.^^J%
+-- ^^J%
+-- You will also need to produce your own, suitably named, .ins file to^^J%
+-- control the generation of files from your source file; this file^^J%
+-- should contain your own preambles for the files it generates, not^^J%
+-- those in the standard .ins files.^^J%
+-- }
+\let\luapostamble\empty
+\declarepreamble\texpreamble
+
+Copyright (C) 2016 Vít Novotný
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+of this license or (at your option) any later version.
+The latest version of this license is in
+
+   http://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+This work has the LPPL maintenance status `maintained'.
+The Current Maintainer of this work is Vít Novotný.
+
+Send bug reports, requests for additions and questions
+either to the GitHub issue tracker at
+
+  https://github.com/Witiko/markdown/issues
+
+or to the e-mail address <witiko at mail.muni.cz>.
+
+MODIFICATION ADVICE:
+
+If you want to customize this file, it is best to make a copy of
+the source file(s) from which it was produced.  Use a different
+name for your copy(ies) and modify the copy(ies); this will ensure
+that your modifications do not get overwritten when you install a
+new release of the standard system.  You should also ensure that
+your modified source file does not generate any modified file with
+the same name as a standard file.
+
+You will also need to produce your own, suitably named, .ins file to
+control the generation of files from your source file; this file
+should contain your own preambles for the files it generates, not
+those in the standard .ins files.
+
+The names of the source files used are shown above.
+
+\endpreamble
+\let\texpostamble\defaultpostamble


Property changes on: trunk/Master/texmf-dist/source/generic/markdown/docstrip.cfg
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/generic/markdown/markdown.dtx
===================================================================
--- trunk/Master/texmf-dist/source/generic/markdown/markdown.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/generic/markdown/markdown.dtx	2016-06-11 23:15:05 UTC (rev 41376)
@@ -0,0 +1,3590 @@
+% \iffalse
+%<*driver>
+\documentclass{ltxdockit}
+\usepackage{btxdockit}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage[american]{babel}
+\usepackage{microtype}
+\usepackage{amsmath}
+\usepackage{fancyvrb}
+\usepackage{hologo}
+\usepackage{xcolor}
+\usepackage{doc}
+
+% Set up the style.
+\emergencystretch=1em
+\RecustomVerbatimEnvironment
+  {Verbatim}{Verbatim}
+  {gobble=2,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}{\oldCodelineNo}}
+
+% Define some markup.
+\let\pkg\relax % A package name
+\newcommand\mdef[1]{% A TeX macro definition
+  \phantomsection\label{macro:#1}\textcolor{spot}{\cs{#1}}}
+\newcommand\m[1]{% A TeX macro reference
+  \hyperref[macro:#1]{\textcolor{spot}{\cs{#1}}}}
+\newcommand\envmdef[1]{% A TeX macro definition
+  \phantomsection\label{environment:#1}\textcolor{spot}{\t`#1`}}
+\newcommand\envm[1]{% A LaTeX environment reference
+  \hyperref[environment:#1]{\textcolor{spot}{\t`#1`}}}
+\newcommand\luamdef[1]{% A Lua object / method definition
+  \phantomsection\label{lua:#1}\textcolor{spot}{\t`#1`}}
+\newcommand\luam[1]{% A Lua object / method reference
+  \hyperref[lua:#1]{\t`#1`}}
+\def\t`#1`{% Inline code
+  \textcolor{spot}{\text{\texttt{#1}}}}
+\newcommand\Optitem[2][]{% An option item definition
+  \phantomsection\label{opt:#2}\optitem[#1]{#2}}
+\newcommand\Valitem[2][]{% A value item definition
+  \phantomsection\label{opt:#2}\valitem[#1]{#2}}
+\newcommand\Opt[1]{% An option / value item reference
+  \hyperref[opt:#1]{\t`#1`}}
+\newcommand\acro[1]{% An acronym
+  \textsc{#1}}
+
+% Set up the catcodes.
+\catcode`\_=12 % We won't be typesetting math and Lua contains lots of `_`.
+
+% Set up the title page.
+\titlepage{%
+  title={A Markdown Interpreter for \TeX{}},
+  subtitle={},
+  url={https://github.com/witiko/markdown},
+  author={Vít Novotný (based on the work of John MacFarlane and Hans Hagen)},
+  email={witiko at mail.muni.cz},
+  revision={\input VERSION},
+  date={\today}}
+\CodelineIndex
+
+% Set up the bibliography.
+\usepackage{filecontents}
+\begin{filecontents}{markdown.bib}
+  @book{luatex16,
+    author    = {{Lua\TeX{} development team}},
+    title     = {Lua\TeX{} reference manual (0.95.0)},
+    url       = {http://www.luatex.org/svn/trunk/manual/luatex.pdf},
+    urldate   = {2016-05-12}}
+  @book{latex16,
+    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      = {2016-03-31},
+    url       = {http://mirrors.ctan.org/macros/latex/base/source2e.pdf},
+    urldate   = {2016-06-02}}
+  @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{knuth86,
+    author    = {Knuth, Donald Ervin},
+    year      = {1986},
+    title     = {The \TeX{}book},
+    edition   = {3},
+    isbn      = {0-201-13447-0},
+    pagetotal = {ix, 479},
+    publisher = {Addison-Westley}}
+\end{filecontents}
+\usepackage[
+  backend=biber,
+  style=iso-numeric,
+  sorting=none,
+  autolang=other,
+  sortlocale=auto]{biblatex}
+\addbibresource{markdown.bib}
+
+\begin{document}
+  \printtitlepage
+  \tableofcontents
+  \DocInput{markdown.dtx}
+  \printbibliography
+\end{document}
+%</driver>
+% \fi
+%
+% \section{Introduction}
+% This document is a reference manual for the \pkg{Markdown} package. It is
+% split into three sections. This section explains the purpose and the
+% background of the package and outlines its prerequisites. Section
+% \ref{sec:interfaces} describes the interfaces exposed by the package along
+% with usage notes and examples. It is aimed at the user of the package.
+% Section \ref{sec:implementation} describes the implementation of the package.
+% It is aimed at the developer of the package and the curious user.
+%
+% \subsection{About \pkg{Markdown}}
+% The \pkg{Markdown} package provides facilities for the conversion of markdown
+% markup to plain \TeX{}. These are provided both in the form of a Lua module
+% and in the form of plain \TeX{}, \LaTeX{}, and \Hologo{ConTeXt} macro
+% packages that enable the direct inclusion of markdown documents inside \TeX{}
+% documents.
+%
+% Architecturally, the package consists of the \pkg{Lunamark} Lua module by
+% John MacFarlane, which was slimmed down and rewritten for the needs of the
+% package. On top of \pkg{Lunamark} sits code for the plain \TeX{}, \LaTeX{},
+% and \Hologo{ConTeXt} formats by Vít Novotný.
+%
+% \iffalse
+%<*lua>
+% \fi
+%  \begin{macrocode}
+if not modules then modules = { } end modules ['markdown'] = {
+    version   = "1.0.1",
+    comment   = "A module for the conversion from markdown to plain TeX",
+    author    = "John MacFarlane, Hans Hagen, Vít Novotný",
+    copyright = "2009-2016 John MacFarlane, Hans Hagen; 2016 Vít Novotný",
+    license   = "LPPL 1.3"
+}
+%    \end{macrocode}
+%
+% \subsection{Feedback}
+% Please use the \pkg{markdown} project page on
+% GitHub\footnote{\url{https://github.com/witiko/markdown/issues}} to report
+% bugs and submit feature requests. Before making a feature request, please
+% ensure that you have thoroughly studied this manual. 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 on the \TeX-\LaTeX{} Stack
+% Exchange\footnote{\url{https://tex.stackexchange.com}}.
+%
+% \subsection{Acknowledgements}
+% I would like to thank the Faculty of Informatics at the Masaryk University in
+% Brno for providing me with the opportunity to work on this package alongside
+% my studies. I would also like to thank the creator of the Lunamark Lua
+% module, John Macfarlane, for releasing Lunamark under a permissive license
+% that enabled its inclusion into the package.
+%
+% The \TeX{} part 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.
+%
+% \subsection{Prerequisites}
+% This section gives an overview of all resources required by the package.
+%
+% \subsubsection{Lua Prerequisites}\label{sec:luaprerequisites}
+% The Lua part of the package requires the following Lua modules:
+% \begin{description}
+%   \item[\pkg{LPeg}] A pattern-matching library for the writing of recursive
+%     descent parsers via the Parsing Expression Grammars (\acro{peg}s). It is
+%     used by the \pkg{Lunamark} library to parse the markdown input.
+%  \begin{macrocode}
+local lpeg = require("lpeg")
+%    \end{macrocode}
+%   \item[\pkg{Selene Unicode}] A library that provides support for the
+%     processing of wide strings. It is used by the \pkg{Lunamark} library to
+%     cast image, link, and footnote tags to the lower case.
+%  \begin{macrocode}
+local unicode = require("unicode")
+%    \end{macrocode}
+%   \item[\pkg{MD5}] A library that provides \acro{md5} crypto functions. It is
+%     used by the \pkg{Lunamark} library to compute the digest of the input for
+%     caching purposes. 
+%  \begin{macrocode}
+local md5 = require("md5")
+%    \end{macrocode}
+% \end{description}
+% All the abovelisted modules are statically linked into the Lua\TeX{} engine
+% (see \cite[Section~3.3]{luatex16}).
+%
+% \iffalse
+%</lua>
+%<*tex>
+% \fi
+% \subsubsection{Plain \TeX{} Prerequisites}\label{sec:texprerequisites}
+% The plain \TeX{} part of the package requires the following Lua module:
+% \begin{description}
+%   \item[\pkg{Lua File System}] A library that provides access to the
+%     filesystem via \acro{os}-specific syscalls. It is used by the plain
+%     \TeX{} code to create the cache directory specified by the
+%     \m{markdownOptionCacheDir} macro before interfacing with the
+%     \pkg{Lunamark} library.
+%
+%     The plain \TeX{} code makes use of the \luam{isDir} method that was added
+%     to the module by the Lua\TeX{} engine developers (see
+%     \cite[Section~3.2]{luatex16}). This method is not present in the base
+%     library.
+% \end{description}
+% The \pkg{Lua File System} module is statically linked into the Lua\TeX{}
+% engine (see \cite[Section~3.3]{luatex16}).
+%
+% The plain \TeX{} part of the package also requires that the plain \TeX{}
+% format (or its superset) is loaded and that either the Lua\TeX{}
+% \m{directlua} primitive or the shell access file stream 18 is available.
+%
+% \iffalse
+%</tex>
+%<*latex>
+% \fi
+% \subsubsection{\LaTeX{} Prerequisites}\label{sec:latexprerequisites}
+% The \LaTeX{} part of the package requires that the \Hologo{LaTeX2e} format is
+% loaded and also, since it uses the plain \TeX{} implementation, all the plain
+% \TeX{} prerequisites (see Section \ref{sec:texprerequisites}).
+%  \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}%
+%    \end{macrocode}
+%
+% The following \Hologo{LaTeX2e} packages are also required:
+% \begin{description}
+%   \item[\pkg{keyval}] A package that enables the creation of parameter sets.
+%     This package is used to provide the \m{markdownSetup} macro, the package
+%     options processing, as well as the parameters of the \envm{markdown*}
+%     \LaTeX{} environment.
+%   \item[\pkg{url}] A package that provides the \m{url} macro for the
+%     typesetting of \acro{url}s. It is used to provide the default token renderer
+%     prototype (see Section \ref{sec:texrendererprototypes}) for links.
+%   \item[\pkg{graphicx}] A package that provides the \m{includegraphics} macro for
+%     the typesetting of images. It is used to provide the corresponding
+%     default token renderer prototype (see Section
+%     \ref{sec:texrendererprototypes}).
+%   \item[\pkg{paralist}] A package that provides the \envm{compactitem},
+%     \envm{compactenum}, and \envm{compactdesc} macros for the
+%     typesetting of tight bulleted lists, ordered lists, and definition lists.
+%     It is used to provide the corresponding default token renderer prototypes
+%     (see Section \ref{sec:texrendererprototypes}).
+%   \item[\pkg{ifthen}] A package that provides a concise syntax for the
+%     inspection of macro values. It is used to determine whether or not the
+%     \pkg{paralist} package should be loaded based on the user options.
+%   \item[\pkg{fancyvrb}] A package that provides the \m{VerbatimInput} macros
+%     for the verbatim inclusion of files containing code.  It is used to
+%     provide the corresponding default token renderer prototype (see Section
+%     \ref{sec:texrendererprototypes}).
+% \end{description}
+%
+% \iffalse
+%</latex>
+%<*context>
+% \fi
+% \subsubsection{\Hologo{ConTeXt} prerequisites}
+% The \Hologo{ConTeXt} part of the package requires that either the Mark II or
+% the Mark IV format is loaded and also, since it uses the plain \TeX{}
+% implementation, all the plain \TeX{} prerequisites (see Section
+% \ref{sec:texprerequisites}).
+%
+% \section{User Guide}\label{sec:interfaces}
+% This part of the manual 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 purely abstract. It serves as
+% a means of structuring this manual and as a promise to the user that if they
+% only access the package through the interfaces, the future versions of the
+% package should remain backwards compatible.
+%
+% \iffalse
+%</context>
+%<*lua>
+% \fi
+% \subsection{Lua Interface}\label{sec:luainterface}
+% The Lua interface provides the conversion from markdown to plain \TeX{}.
+% This interface is used by the plain \TeX{} implementation (see Section
+% \ref{sec:teximplementation}) and will be of interest to the developers of
+% other packages and Lua modules.
+%
+% The Lua interface is implemented by the \t`markdown` Lua module.
+%
+%  \begin{macrocode}
+local M = {}
+%    \end{macrocode}
+%
+% \subsubsection{Conversion from Markdown to Plain \TeX{}}
+% \label{sec:luaconversion}
+% The Lua interface exposes the \luamdef{new}\t`(options)` method.  This
+% method creates converter functions that perform the conversion from markdown
+% to plain \TeX{} according to the table \t`options` that contains options
+% recognized by the Lua interface.  (see Section \ref{sec:luaoptions}). The
+% \t`options` parameter is optional; when unspecified, the behaviour will be
+% the same as if \t`options` were an empty table.
+%  \begin{macrocode}
+M.new = {}
+%    \end{macrocode}
+%
+% The following example Lua code converts the markdown string \t`_Hello
+% world!_` to a \TeX{} output using the default options and prints the \TeX{}
+% output:
+% \begin{Verbatim}
+% local md = require("markdown")
+% local convert = md.new()
+% print(convert("_Hello world!_"))
+% \end{Verbatim}
+%
+% \subsubsection{Options}\label{sec:luaoptions}
+% The Lua interface recognizes the following options. When unspecified, the
+% value of a key is taken from the \luamdef{defaultOptions} table.
+%  \begin{macrocode}
+local defaultOptions = {}
+%    \end{macrocode}
+% \begin{optionlist}
+%   \Optitem[false]{blankBeforeBlockquote}{\opt{true}, \opt{false}}
+%     \begin{valuelist}
+%       \item[true] Require a blank line between a paragraph and the following
+%         blockquote.
+%       \item[false] Do not require a blank line between a paragraph and the
+%         following blockquote.
+%     \end{valuelist}
+%  \begin{macrocode}
+defaultOptions.blankBeforeBlockquote = false
+%    \end{macrocode}
+%
+%   \Optitem[false]{blankBeforeHeading}{\opt{true}, \opt{false}}
+%     \begin{valuelist}
+%       \item[true] Require a blank line between a paragraph and the following
+%         header.
+%       \item[false] Do not require a blank line between a paragraph and the
+%         following header.
+%     \end{valuelist}
+%  \begin{macrocode}
+defaultOptions.blankBeforeHeading = false
+%    \end{macrocode}
+%
+%   \Valitem[.]{cacheDir}{directory}
+%     The path to the directory containing auxiliary cache files.
+% 
+%     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 \t`/tmp` on \acro{un*x} systems), which gets periodically
+%     emptied.
+%  \begin{macrocode}
+defaultOptions.cacheDir = "."
+%    \end{macrocode}
+%
+%   \Optitem[false]{definitionLists}{\opt{true}, \opt{false}}
+%     \begin{valuelist}
+%       \item[true] Enable the pandoc definition list syntax extension:
+%         \begin{Verbatim}
+% Term 1
+% 
+% :   Definition 1
+% 
+% Term 2 with *inline markup*
+% 
+% :   Definition 2
+% 
+%         { some code, part of Definition 2 }
+% 
+%     Third paragraph of definition 2.
+%         \end{Verbatim}
+%       \item[false] Disable the pandoc definition list syntax extension.
+%     \end{valuelist}
+%  \begin{macrocode}
+defaultOptions.definitionLists = false
+%    \end{macrocode}
+% 
+%   \Optitem[false]{hashEnumerators}{\opt{true}, \opt{false}}
+%     \begin{valuelist}
+%       \item[true] Enable the use of hash symbols (\t`\#`) as ordered item
+%         list markers.
+%       \item[false] Disable the use of hash symbols (\t`\#`) as ordered item
+%         list markers.
+%     \end{valuelist}
+%  \begin{macrocode}
+defaultOptions.hashEnumerators = false
+%    \end{macrocode}
+%
+%   \Optitem[false]{hybrid}{\opt{true}, \opt{false}}
+%     \begin{valuelist}
+%       \item[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.
+%
+%       \item[false] Enable the escaping of special plain \TeX{} characters
+%         outside verbatim environments, so that they are not interpretted by
+%         \TeX{}. This is encouraged when typesetting automatically generated
+%         content or markdown documents that were not prepared with this
+%         package in mind.
+%     \end{valuelist}
+%  \begin{macrocode}
+defaultOptions.hybrid = false
+%    \end{macrocode}
+%
+%   \Optitem[false]{footnotes}{\opt{true}, \opt{false}}
+%     \begin{valuelist}
+%       \item[true] Enable the pandoc footnote syntax extension:
+%         \begin{Verbatim}
+% Here is a footnote reference,[^1] and another.[^longnote]
+% 
+% [^1]: Here is the footnote.
+% 
+% [^longnote]: Here's one with multiple blocks.
+% 
+%     Subsequent paragraphs are indented to show that they
+% belong to the previous footnote.
+% 
+%         { some.code }
+% 
+%     The whole paragraph can be indented, or just the
+%     first line.  In this way, multi-paragraph footnotes
+%     work like multi-paragraph list items.
+% 
+% This paragraph won't be part of the note, because it
+% isn't indented.
+%         \end{Verbatim}
+%       \item[false] Disable the pandoc footnote syntax extension.
+%     \end{valuelist}
+%  \begin{macrocode}
+defaultOptions.footnotes = false
+%    \end{macrocode}
+%
+%   \Optitem[false]{preserveTabs}{\opt{true}, \opt{false}}
+%     \begin{valuelist}
+%       \item[true] Preserve all tabs in the input.
+%       \item[false] Convert any tabs in the input to spaces.
+%     \end{valuelist}
+%  \begin{macrocode}
+defaultOptions.preserveTabs = false
+%    \end{macrocode}
+%
+%   \Optitem[false]{smartEllipses}{\opt{true}, \opt{false}}
+%     \begin{valuelist}
+%       \item[true] Convert any ellipses in the input to the
+%         \m{markdownRendererEllipsis} \TeX{} macro.
+%       \item[false] Preserve all ellipses in the input.
+%     \end{valuelist}
+%  \begin{macrocode}
+defaultOptions.smartEllipses = false
+%    \end{macrocode}
+%
+%   \Optitem[true]{startNumber}{\opt{true}, \opt{false}}
+%     \begin{valuelist}
+%       \item[true] Make the number in the first item in ordered lists
+%         significant. The item numbers will be passed to the
+%         \m{markdownRendererOlItemWithNumber} \TeX{} macro.
+%       \item[false] Ignore the number in the items of ordered lists. Each
+%         item will only produce a \m{markdownRendererOlItem} \TeX{} macro.
+%     \end{valuelist}
+%  \begin{macrocode}
+defaultOptions.startNumber = true
+%    \end{macrocode}
+%
+%   \Optitem[true]{tightLists}{\opt{true}, \opt{false}}
+%     \begin{valuelist}
+%       \item[true] Lists whose bullets do not consist of multiple paragraphs
+%         will be detected and passed to the 
+%         \m{markdownRendererOlBeginTight}, \m{markdownRendererOlEndTight},
+%         \m{markdownRendererUlBeginTight}, \m{markdownRendererUlEndTight},
+%         \m{markdownRendererDlBeginTight}, and \m{markdownRendererDlEndTight}
+%         macros.
+%       \item[false] Lists whose bullets do not consist of multiple paragraphs
+%         will be treated the same way as lists that do.
+%     \end{valuelist}
+%  \begin{macrocode}
+defaultOptions.tightLists = true
+%    \end{macrocode}
+% \end{optionlist}
+% 
+% \iffalse
+%</lua>
+%<*tex>
+% \fi\subsection{Plain \TeX{} Interface}\label{sec:texinterface}
+% The plain \TeX{} interface provides macros for the typesetting of markdown input
+% from within plain \TeX{}, for setting the Lua interface options (see Section
+% \ref{sec:luaoptions}) used during the conversion from markdown to plain
+% \TeX{}, and for changing the way markdown the tokens are rendered.
+%  \begin{macrocode}
+\def\markdownVersion{2016/06/03}%
+%    \end{macrocode}
+%
+% The plain \TeX{} interface is implemented by the \t`markdown.tex` file that
+% can be loaded as follows:
+% \begin{Verbatim}
+% \input markdown
+% \end{Verbatim}
+% It is expected that the special plain \TeX{} characters have the expected
+% category codes, when \m{input}ting the file.
+%
+% \subsubsection{Typesetting Markdown}\label{sec:textypesetting}
+% The interface exposes the \mdef{markdownBegin}, \mdef{markdownEnd}, and
+% \mdef{markdownInput} macros.
+%
+% The \m{markdownBegin} macro marks the beginning of a markdown document
+% fragment and the \m{markdownEnd} macro marks its end.
+%  \begin{macrocode}
+\let\markdownBegin\relax
+\let\markdownEnd\relax
+%    \end{macrocode}
+% You may prepend your own code to the \m{markdownBegin} macro and redefine the
+% \m{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 \m{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 otherwise. As a corrolary, the \m{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{} (see
+% \cite[p.~46]{knuth86}). As a corrolary, the \m{markdownBegin} macro also
+% ignores them.
+%
+% The \m{markdownBegin} and \m{markdownEnd} macros will also consume the rest
+% of the lines at which they appear.  In the following example plain \TeX{}
+% code, the characters \t`c`, \t`e`, and \t`f` will not appear in the output.
+% \begin{Verbatim}
+% \input markdown
+% a
+% b \markdownBegin c 
+% d 
+% e \markdownEnd   f
+% g 
+% \bye
+% \end{Verbatim}
+%
+% Note that you may also not nest the \m{markdownBegin} and \m{markdownEnd}
+% macros.
+%
+% The following example plain \TeX{} code showcases the usage of the
+% \m{markdownBegin} and \m{markdownEnd} macros:
+% \begin{Verbatim}
+% \input markdown
+% \markdownBegin
+% _Hello_ **world** ...
+% \markdownEnd
+% \bye
+% \end{Verbatim}
+%
+% The \m{markdownInput} macro accepts a single parameter containing the
+% filename of a markdown document and expands to the result of the conversion
+% of the input markdown document to plain \TeX{}.
+%  \begin{macrocode}
+\let\markdownInput\relax
+%    \end{macrocode}
+% This macro is not subject to the abovelisted limitations of the
+% \m{markdownBegin} and \m{markdownEnd} macros.
+%
+% The following example plain \TeX{} code showcases the usage of the
+% \m{markdownInput} macro:
+% \begin{Verbatim}
+% \input markdown
+% \markdownInput{hello.md}
+% \bye
+% \end{Verbatim}
+%
+% \subsubsection{Options}\label{sec:texoptions}
+% The plain \TeX{} options are represented by \TeX{} macros. Some of them map
+% directly to the options recognized by the Lua interface (see Section
+% \ref{sec:luaoptions}), while some of them are specific to the plain \TeX{}
+% interface.
+%
+% \paragraph{File and directory names}
+% The \mdef{markdownOptionHelperScriptFileName} macro sets the filename of the
+% helper Lua script file that is created during the conversion from markdown to
+% plain \TeX{} in \TeX{} engines without the \m{directlua} primitive. It
+% defaults to \m{jobname}\t`.markdown.lua`, where \m{jobname} is the base name
+% of the document being typeset.
+%
+% The expansion of this macro must not contain quotation marks (\t`"`) or
+% backslash symbols (\t`\textbackslash`). Mind that \TeX{} engines tend to
+% put quotation marks around \m{jobname}, when it contains spaces.
+%  \begin{macrocode}
+\def\markdownOptionHelperScriptFileName{\jobname.markdown.lua}%
+%    \end{macrocode}
+%
+% The \mdef{markdownOptionInputTempFileName} macro sets the filename of the
+% temporary input file that is created during the conversion from markdown to
+% plain \TeX{} in \TeX{} engines without the \m{directlua} primitive. It
+% defaults to \m{jobname}\t`.markdown.out`. The same limitations as in
+% the case of the \m{markdownOptionHelperScriptFileName} macro apply here.
+%  \begin{macrocode}
+\def\markdownOptionInputTempFileName{\jobname.markdown.in}%
+%    \end{macrocode}
+%
+% The \mdef{markdownOptionOutputTempFileName} macro sets the filename of the
+% temporary output file that is created during the conversion from markdown to
+% plain \TeX{} in \TeX{} engines without the \m{directlua} primitive. It
+% defaults to \m{jobname}\t`.markdown.out`. The same limitations apply here as
+% in the case of the \m{markdownOptionHelperScriptFileName} macro.
+%  \begin{macrocode}
+\def\markdownOptionOutputTempFileName{\jobname.markdown.out}%
+%    \end{macrocode}
+%
+% The \mdef{markdownOptionCacheDir} macro corresponds to the Lua interface
+% \Opt{cacheDir} option that sets the name of the directory that will contain
+% the produced cache files. The option defaults to \t`_markdown-`\m{jobname},
+% which is a similar naming scheme to the one used by the \pkg{minted} \LaTeX{}
+% package. The same limitations apply here as in the case of the
+% \m{markdownOptionHelperScriptFileName} macro.
+%  \begin{macrocode}
+\def\markdownOptionCacheDir{_markdown-\jobname}%
+%    \end{macrocode}
+%
+% \paragraph{Lua Interface Options}
+% The following macros map directly to the options recognized by the Lua
+% interface (see Section \ref{sec:luaoptions}) and are not processed by the
+% plain \TeX{} implementation, only passed along to Lua. They are undefined, which
+% makes them fall back to the default values provided by the Lua interface.
+%  \begin{macrocode}
+\let\markdownOptionBlankBeforeBlockquote\undefined
+\let\markdownOptionBlankBeforeHeading\undefined
+\let\markdownOptionDefinitionLists\undefined
+\let\markdownOptionHashEnumerator\undefined
+\let\markdownOptionHybrid\undefined
+\let\markdownOptionFootnotes\undefined
+\let\markdownOptionPreserveTabs\undefined
+\let\markdownOptionSmartEllipses\undefined
+\let\markdownOptionStartNumber\undefined
+\let\markdownOptionTightLists\undefined
+%    \end{macrocode}
+%
+% \subsubsection{Token Renderers}\label{sec:texrenderersuser}
+% The following \TeX{} macros may occur inside the output of the
+% converter functions exposed by the Lua interface (see Section
+% \ref{sec:luaconversion}) 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
+% \ref{sec:texrendererprototypes}).
+%
+% \paragraph{Line Break Renderer}
+% The \mdef{markdownRendererLineBreak} macro represents a forced line break.
+% The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererLineBreak{%
+  \markdownRendererLineBreakPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Ellipsis Renderer}
+% The \mdef{markdownRendererEllipsis} macro replaces any occurance of ASCII
+% ellipses in the input text. This macro will only be produced, when the
+% \Opt{smartEllipses} option is \t`true`.  The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererEllipsis{%
+  \markdownRendererEllipsisPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Code Span Renderer}
+% The \mdef{markdownRendererCodeSpan} macro represents inlined code span in the
+% input text. It receives a single argument that corresponds to the inlined
+% code span.
+%  \begin{macrocode}
+\def\markdownRendererCodeSpan{%
+  \markdownRendererCodeSpanPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Link Renderer}
+% The \mdef{markdownRendererLink} macro represents a hyperlink. It receives
+% three arguments: the label, the \acro{uri}, and the title of the link.
+%  \begin{macrocode}
+\def\markdownRendererLink{%
+  \markdownRendererLinkPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Image Renderer}
+% The \mdef{markdownRendererImage} macro represents an image. It receives three
+% arguments: the label, the \acro{url}, and the title of the image.
+%  \begin{macrocode}
+\def\markdownRendererImage{%
+  \markdownRendererImagePrototype}%
+%    \end{macrocode}
+%
+% \paragraph{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.
+%  \begin{macrocode}
+\def\markdownRendererUlBegin{%
+  \markdownRendererUlBeginPrototype}%
+%    \end{macrocode}
+%
+% 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 \t`false`. The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererUlBeginTight{%
+  \markdownRendererUlBeginTightPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererUlItem} macro represents an item in a bulleted
+% list.
+% The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererUlItem{%
+  \markdownRendererUlItemPrototype}%
+%    \end{macrocode}
+%
+% 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.
+%  \begin{macrocode}
+\def\markdownRendererUlEnd{%
+  \markdownRendererUlEndPrototype}%
+%    \end{macrocode}
+%
+% 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
+% \t`false`. The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererUlEndTight{%
+  \markdownRendererUlEndTightPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Ordered List Renderers}
+% The \mdef{markdownRendererOlBegin} macro represents the beginning of an
+% ordered list that contains an item with several paragraphs of text (the
+% list is not tight). The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererOlBegin{%
+  \markdownRendererOlBeginPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererOlBeginTight} macro represents the beginning of an
+% ordered 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 \t`false`. The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererOlBeginTight{%
+  \markdownRendererOlBeginTightPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererOlItem} macro represents an item in an ordered list.
+% This macro will only be produced, when the \Opt{startNumber} option is
+% \t`false`.  The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererOlItem{%
+  \markdownRendererOlItemPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererOlItemWithNumber} macro represents an item in an
+% ordered list.  This macro will only be produced, when the \Opt{startNumber}
+% option is \t`true`.  The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererOlItemWithNumber{%
+  \markdownRendererOlItemWithNumberPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererOlEnd} macro represents the end of an ordered list
+% that contains an item with several paragraphs of text (the list is not
+% tight). The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererOlEnd{%
+  \markdownRendererOlEndPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererOlEndTight} macro represents the end of an ordered
+% 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
+% \t`false`. The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererOlEndTight{%
+  \markdownRendererOlEndTightPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Definition List Renderers}
+% The following macros are only produces, when the \Opt{definitionLists} option
+% is \t`true`.
+%
+% The \mdef{markdownRendererDlBegin} macro represents the beginning of a
+% definition list that contains an item with several paragraphs of text (the
+% list is not tight). The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererDlBegin{%
+  \markdownRendererDlBeginPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererDlBeginTight} macro represents the beginning of a
+% definition list that contains an item with several paragraphs of text (the
+% list is not tight). This macro will only be produced, when the
+% \Opt{tightLists} option is \t`false`. The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererDlBeginTight{%
+  \markdownRendererDlBeginTightPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererDlItem} macro represents an item in a definition
+% list. The macro receives a single argument that corresponds to the term being
+% defined.
+%  \begin{macrocode}
+\def\markdownRendererDlItem{%
+  \markdownRendererDlItemPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererDlEnd} macro represents the end of a definition
+% list that contains an item with several paragraphs of text (the list is not
+% tight). The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererDlEnd{%
+  \markdownRendererDlEndPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererDlEndTight} macro represents the end of a
+% definition 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 \t`false`. The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererDlEndTight{%
+  \markdownRendererDlEndTightPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Emphasis Renderers}
+% The \mdef{markdownRendererEmphasis} macro represents an emphasized span of
+% text. The macro receives a single argument that corresponds to the emphasized
+% span of text.
+%  \begin{macrocode}
+\def\markdownRendererEmphasis{%
+  \markdownRendererEmphasisPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererStrongEmphasis} macro represents a strongly
+% emphasized span of text. The macro receives a single argument that
+% corresponds to the emphasized span of text.
+%  \begin{macrocode}
+\def\markdownRendererStrongEmphasis{%
+  \markdownRendererStrongEmphasisPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Block Quote Renderers}
+% The \mdef{markdownRendererBlockQuoteBegin} macro represents the beginning of
+% a block quote. The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererBlockQuoteBegin{%
+  \markdownRendererBlockQuoteBeginPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererBlockQuoteEnd} macro represents the end of a block
+% quote. The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererBlockQuoteEnd{%
+  \markdownRendererBlockQuoteEndPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Code Block Renderer}
+% The \mdef{markdownRendererInputVerbatim} macro represents a code
+% block. The macro receives a single argument that corresponds to the
+% filename of a file contaning the code block to input.
+%  \begin{macrocode}
+\def\markdownRendererInputVerbatim{%
+  \markdownRendererInputVerbatimPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Heading Renderers}
+% The \mdef{markdownRendererHeadingOne} macro represents a first level heading.
+% The macro receives a single argument that corresponds to the heading text.
+%  \begin{macrocode}
+\def\markdownRendererHeadingOne{%
+  \markdownRendererHeadingOnePrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererHeadingTwo} macro represents a second level
+% heading. The macro receives a single argument that corresponds to the heading
+% text.
+%  \begin{macrocode}
+\def\markdownRendererHeadingTwo{%
+  \markdownRendererHeadingTwoPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererHeadingThree} macro represents a third level
+% heading. The macro receives a single argument that corresponds to the heading
+% text.
+%  \begin{macrocode}
+\def\markdownRendererHeadingThree{%
+  \markdownRendererHeadingThreePrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererHeadingFour} macro represents a fourth level
+% heading. The macro receives a single argument that corresponds to the heading
+% text.
+%  \begin{macrocode}
+\def\markdownRendererHeadingFour{%
+  \markdownRendererHeadingFourPrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererHeadingFive} macro represents a fifth level
+% heading. The macro receives a single argument that corresponds to the heading
+% text.
+%  \begin{macrocode}
+\def\markdownRendererHeadingFive{%
+  \markdownRendererHeadingFivePrototype}%
+%    \end{macrocode}
+%
+% The \mdef{markdownRendererHeadingSix} macro represents a sixth level
+% heading. The macro receives a single argument that corresponds to the heading
+% text.
+%  \begin{macrocode}
+\def\markdownRendererHeadingSix{%
+  \markdownRendererHeadingSixPrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Horizontal Rule Renderer}
+% The \mdef{markdownRendererHorizontalRule} macro represents a horizontal rule.
+% The macro receives no arguments.
+%  \begin{macrocode}
+\def\markdownRendererHorizontalRule{%
+  \markdownRendererHorizontalRulePrototype}%
+%    \end{macrocode}
+%
+% \paragraph{Footnote Renderer}
+% The \mdef{markdownRendererFootnote} macro represents a footnote. This macro
+% will only be produced, when the \Opt{footnotes} option is \t`true`.  The
+% macro receives a single argument that corresponds to the footnote text.
+%  \begin{macrocode}
+\def\markdownRendererFootnote{%
+  \markdownRendererFootnotePrototype}%
+%    \end{macrocode}
+%
+% \subsubsection{Token Renderer Prototypes}\label{sec:texrendererprototypes}
+% The following \TeX{} macros provide definitions for the token renderers (see
+% Section \ref{sec:texrenderersuser}) that have not been redefined by the
+% user. These macros are intended to be redefined by macro package authors
+% who wish to provide sensible default token renderers. They are also redefined
+% by the \LaTeX{} and \Hologo{ConTeXt} implementations (see sections
+% \ref{sec:lateximplementation} and \ref{sec:contextimplementation}).
+%  \begin{macrocode}
+\def\markdownRendererLineBreakPrototype{}%
+\def\markdownRendererEllipsisPrototype{}%
+\long\def\markdownRendererCodeSpanPrototype#1{}%
+\long\def\markdownRendererLinkPrototype#1#2#3{}%
+\long\def\markdownRendererImagePrototype#1#2#3{}%
+\def\markdownRendererUlBeginPrototype{}%
+\def\markdownRendererUlBeginTightPrototype{}%
+\def\markdownRendererUlItemPrototype{}%
+\def\markdownRendererUlEndPrototype{}%
+\def\markdownRendererUlEndTightPrototype{}%
+\def\markdownRendererOlBeginPrototype{}%
+\def\markdownRendererOlBeginTightPrototype{}%
+\def\markdownRendererOlItemPrototype{}%
+\long\def\markdownRendererOlItemWithNumberPrototype#1{}%
+\def\markdownRendererOlEndPrototype{}%
+\def\markdownRendererOlEndTightPrototype{}%
+\def\markdownRendererDlBeginPrototype{}%
+\def\markdownRendererDlBeginTightPrototype{}%
+\long\def\markdownRendererDlItemPrototype#1{}%
+\def\markdownRendererDlEndPrototype{}%
+\def\markdownRendererDlEndTightPrototype{}%
+\long\def\markdownRendererEmphasisPrototype#1{}%
+\long\def\markdownRendererStrongEmphasisPrototype#1{}%
+\def\markdownRendererBlockQuoteBeginPrototype{}%
+\def\markdownRendererBlockQuoteEndPrototype{}%
+\long\def\markdownRendererInputVerbatimPrototype#1{}%
+\long\def\markdownRendererHeadingOnePrototype#1{}%
+\long\def\markdownRendererHeadingTwoPrototype#1{}%
+\long\def\markdownRendererHeadingThreePrototype#1{}%
+\long\def\markdownRendererHeadingFourPrototype#1{}%
+\long\def\markdownRendererHeadingFivePrototype#1{}%
+\long\def\markdownRendererHeadingSixPrototype#1{}%
+\def\markdownRendererHorizontalRulePrototype{}%
+\long\def\markdownRendererFootnotePrototype#1{}%
+%    \end{macrocode}
+%
+% \subsubsection{Logging Facilities}
+% The \mdef{markdownInfo}, \mdef{markdownWarning}, and
+% \mdef{markdownError} macros provide access to logging to the rest of
+% the macros. Their first argument specifies the text of the info, warning, or
+% error message.
+%  \begin{macrocode}
+\def\markdownInfo#1{}%
+\def\markdownWarning#1{}%
+%    \end{macrocode}
+% The \m{markdownError} macro receives a second argument that provides a help
+% text suggesting a remedy to the error.
+%  \begin{macrocode}
+\def\markdownError#1{}%
+%    \end{macrocode}
+% You may redefine these macros to redirect and process the info, warning, and
+% error messages.
+%
+% \subsubsection{Miscellanea}
+% The \mdef{markdownLuaRegisterIBCallback} and
+% \mdef{markdownLuaUnregisterIBCallback} macros specify the Lua code for
+% registering and unregistering a callback for changing the contents of the
+% line input buffer before a \TeX{} engine that supports direct Lua access via
+% the \m{directlua} macro starts looking at it. The first argument of the
+% \m{markdownLuaRegisterIBCallback} macro corresponds to the callback function
+% being registered.
+%
+% Local members defined within \m{markdownLuaRegisterIBCallback} are guaranteed
+% to be visible from \m{markdownLuaUnregisterIBCallback} and the execution of
+% the two macros alternates, so it is not necessary to consider the case, when
+% one of the macros is called twice in a row.
+%  \begin{macrocode}
+\def\markdownLuaRegisterIBCallback#1{%
+  local old_callback = callback.find("process_input_buffer")
+  callback.register("process_input_buffer", #1)}%
+\def\markdownLuaUnregisterIBCallback{%
+  callback.register("process_input_buffer", old_callback)}%
+%    \end{macrocode}
+%
+% The \mdef{markdownMakeOther} macro is used by the package, when a \TeX{}
+% engine that does not support direct Lua access is starting to buffer a text.
+% The plain \TeX{} implementation changes the category code of plain \TeX{}
+% special characters to other, but there may be other active characters that
+% may break the output. This macro should temporarily change the category of
+% these to \emph{other}.
+%  \begin{macrocode}
+\let\markdownMakeOther\relax
+%    \end{macrocode}
+%
+% The \mdef{markdownReadAndConvert} macro implements the \m{markdownBegin}
+% macro. The first argument specifies the token sequence that will terminate
+% the markdown input (\m{markdownEnd} in the instance of the \m{markdownBegin}
+% macro) when the plain \TeX{} special characters have had their category
+% changed to \emph{other}. The second argument specifies the token sequence
+% that will actually be inserted into the document, when the ending token
+% sequence has been found.
+%  \begin{macrocode}
+\let\markdownReadAndConvert\relax
+\begingroup
+%    \end{macrocode}
+% Locally swap the category code of the backslash symbol (\t`\textbackslash`)
+% with the pipe symbol (\t`|`). This is required in order that all the special
+% symbols in the first argument of the \t`markdownReadAndConvert` macro have
+% the category code \emph{other}.
+%  \begin{macrocode}
+  \catcode`\|=0\catcode`\\=12%
+  |gdef|markdownBegin{%
+    |markdownReadAndConvert{\markdownEnd}%
+                           {|markdownEnd}}%
+|endgroup
+%    \end{macrocode}
+% The macro is exposed in the interface, so that the user can create their own
+% markdown environments. Due to the way the arguments are passed to Lua (see
+% Section \ref{sec:directlua}), the first argument may not contain the
+% string \t`]]` (regardless of the category code of the bracket symbol (\t`]`)).
+%
+% \iffalse
+%</tex>
+%<*latex>
+% \fi\subsection{\LaTeX{} Interface}\label{sec:latexinterface}
+% The \LaTeX{} interface provides \LaTeX{} environments for the typesetting of
+% markdown input from within \LaTeX{}, facilities for setting Lua interface
+% options (see Section \ref{sec:luaoptions}) used during the conversion from
+% markdown to plain \TeX{}, and facilities for changing the way markdown tokens
+% are rendered. The rest of the interface is inherited from the plain \TeX{}
+% interface (see Section \ref{sec:texinterface}).
+%
+% The \LaTeX{} interface is implemented by the \t`markdown.sty` file, which
+% can be loaded from the \LaTeX{} document preamble as follows:
+% \begin{Verbatim}[commandchars=\\\{\}]
+% \textbackslash{}usepackage[\textrm{\meta{options}}]\{markdown\}
+% \end{Verbatim}
+% where \meta{options} are the \LaTeX{} interface options (see Section
+% \ref{sec:latexoptions}).
+%
+% \subsubsection{Typesetting Markdown}
+% The interface exposes the \envmdef{markdown} and \envmdef{markdown*}
+% \LaTeX{} environments, and redefines the \m{markdownInput} command.
+%
+% The \envm{markdown} and \envm{markdown*} \LaTeX{} environments are used to
+% typeset markdown document fragments. The starred version of the
+% \envm{markdown} environment accepts \LaTeX{} interface options (see
+% Section \ref{sec:latexoptions}) as its only argument. These options will
+% only influnce this markdown document fragment.
+%  \begin{macrocode}
+\newenvironment{markdown}\relax\relax
+\newenvironment{markdown*}[1]\relax\relax
+%    \end{macrocode}
+% You may prepend your own code to the \m{markdown} macro and append your own
+% code to the \m{endmarkdown} macro to produce special effects before and after
+% the \envm{markdown} \LaTeX{} environment (and likewise for the starred
+% version).
+%
+% Note that the \envm{markdown} and \envm{markdown*} \LaTeX{} environments are
+% subject to the same limitations as the \m{markdownBegin} and \m{markdownEnd}
+% macros exposed by the plain \TeX{} interface.
+%
+% The following example \LaTeX{} code showcases the usage of the
+% \envm{markdown} and \envm{markdown*} environments:
+% \begin{Verbatim}
+% \documentclass{article}            \documentclass{article}
+% \usepackage{markdown}              \usepackage{markdown}
+% \begin{document}                   \begin{document}
+% % ...                              % ...
+% \begin{markdown}                   \begin{markdown*}{smartEllipses}
+% _Hello_ **world** ...              _Hello_ **world** ...
+% \end{markdown}                     \end{markdown*}
+% % ...                              % ...
+% \end{document}                     \end{document}
+% \end{Verbatim}
+%
+% The \m{markdownInput} macro accepts a single mandatory parameter containing
+% the filename of a markdown document and expands to the result of the
+% conversion of the input markdown document to plain \TeX{}.  Unlike the
+% \m{markdownInput} macro provided by the plain \TeX{} interface, this macro
+% also accepts \LaTeX{} interface options (see Section \ref{sec:latexoptions})
+% as its optional argument. These options will only influnce this markdown
+% document.
+%
+% The following example \LaTeX{} code showcases the usage of the
+% \m{markdownInput} macro:
+% \begin{Verbatim}
+% \documentclass{article}
+% \usepackage{markdown}
+% \begin{document}
+% % ...
+% \markdownInput[smartEllipses]{hello.md}
+% % ...
+% \end{document}
+% \end{Verbatim}
+%
+% \subsubsection{Options}\label{sec:latexoptions}
+% The \LaTeX{} options are represented by a comma-delimited list of
+% \meta{\meta{key}=\meta{value}} pairs. For boolean options, the
+% \meta{=\meta{value}} part is optional, and \meta{\meta{key}} will be
+% interpreted as \meta{\meta{key}=true}.
+%
+% The \LaTeX{} options map directly to the options recognized by the plain
+% \TeX{} interface (see Section \ref{sec:texoptions}) and to the markdown token
+% renderers and their prototypes recognized by the plain \TeX{} interface (see
+% Sections \ref{sec:texrenderersuser} and \ref{sec:texrendererprototypes}).
+%
+% The \LaTeX{} options may be specified when loading the \LaTeX{} package (see
+% Section \ref{sec:latexinterface}), when using the \envm{markdown*} \LaTeX{}
+% environment, or via the \mdef{markdownSetup} macro.  The \m{markdownSetup}
+% macro receives the options to set up as its only argument.
+%  \begin{macrocode}
+\newcommand\markdownSetup[1]{%
+  \setkeys{markdownOptions}{#1}}%
+%    \end{macrocode}
+%
+% \paragraph{Plain \TeX{} Interface Options}
+% The following options map directly to the option macros exposed by the plain
+% \TeX{} interface (see Section \ref{sec:texoptions}).
+%  \begin{macrocode}
+\RequirePackage{keyval}
+\define at key{markdownOptions}{helperScriptFileName}{%
+  \def\markdownOptionHelperScriptFileName{#1}}%
+\define at key{markdownOptions}{inputTempFileName}{%
+  \def\markdownOptionInputTempFileName{#1}}%
+\define at key{markdownOptions}{outputTempFileName}{%
+  \def\markdownOptionOutputTempFileName{#1}}%
+\define at key{markdownOptions}{blankBeforeBlockquote}[true]{%
+  \def\markdownOptionBlankBeforeBlockquote{#1}}%
+\define at key{markdownOptions}{blankBeforeHeading}[true]{%
+  \def\markdownOptionBlankBeforeHeading{#1}}%
+\define at key{markdownOptions}{cacheDir}{%
+  \def\markdownOptionCacheDir{#1}}%
+\define at key{markdownOptions}{definitionLists}[true]{%
+  \def\markdownOptionDefinitionLists{#1}}%
+\define at key{markdownOptions}{hashEnumerators}[true]{%
+  \def\markdownOptionHashEnumerators{#1}}%
+\define at key{markdownOptions}{hybrid}[true]{%
+  \def\markdownOptionHybrid{#1}}%
+\define at key{markdownOptions}{footnotes}[true]{%
+  \def\markdownOptionFootnotes{#1}}%
+\define at key{markdownOptions}{preserveTabs}[true]{%
+  \def\markdownOptionPreserveTabs{#1}}%
+\define at key{markdownOptions}{smartEllipses}[true]{%
+  \def\markdownOptionSmartEllipses{#1}}%
+\define at key{markdownOptions}{startNumber}[true]{%
+  \def\markdownOptionStartNumber{#1}}%
+%    \end{macrocode}
+% If the \t`tightLists=false` option is specified, when loading the package,
+% then the \pkg{paralist} package for typesetting tight lists will not be
+% automatically loaded. This precaution is meant to minimize the footprint of
+% this package, since some documentclasses (\pkg{beamer}) do not play nice
+% with the \pkg{paralist} package.
+%  \begin{macrocode}
+\define at key{markdownOptions}{tightLists}[true]{%
+  \def\markdownOptionTightLists{#1}}%
+%    \end{macrocode}
+%
+% The following example \LaTeX{} code showcases a possible configuration of
+% plain \TeX{} interface options \m{markdownOptionHybrid},
+% \m{markdownOptionSmartEllipses}, and \m{markdownOptionCacheDir}.
+% \begin{Verbatim}
+% \markdownSetup{
+%   hybrid,
+%   smartEllipses,
+%   cacheDir = /tmp,
+% }
+% \end{Verbatim}
+%
+% \paragraph{Plain \TeX{} Markdown Token Renderers}
+% The \LaTeX{} interface recognizes an option with the \t`renderers` key,
+% whose value must be a list of options that map directly to the markdown token
+% renderer macros exposed by the plain \TeX{} interface (see Section
+% \ref{sec:texrenderersuser}).
+%  \begin{macrocode}
+\define at key{markdownOptions}{renderers}{%
+  \setkeys{markdownRenderers}{#1}}%
+\define at key{markdownRenderers}{lineBreak}{%
+  \renewcommand\markdownRendererLineBreak{#1}}%
+\define at key{markdownRenderers}{ellipsis}{%
+  \renewcommand\markdownRendererEllipsis{#1}}%
+\define at key{markdownRenderers}{codeSpan}{%
+  \renewcommand\markdownRendererCodeSpan[1]{#1}}%
+\define at key{markdownRenderers}{link}{%
+  \renewcommand\markdownRendererLink[3]{#1}}%
+\define at key{markdownRenderers}{image}{%
+  \renewcommand\markdownRendererImage[3]{#1}}%
+\define at key{markdownRenderers}{ulBegin}{%
+  \renewcommand\markdownRendererUlBegin{#1}}%
+\define at key{markdownRenderers}{ulBeginTight}{%
+  \renewcommand\markdownRendererUlBeginTight{#1}}%
+\define at key{markdownRenderers}{ulItem}{%
+  \renewcommand\markdownRendererUlItem{#1}}%
+\define at key{markdownRenderers}{ulEnd}{%
+  \renewcommand\markdownRendererUlEnd{#1}}%
+\define at key{markdownRenderers}{ulEndTight}{%
+  \renewcommand\markdownRendererUlEndTight{#1}}%
+\define at key{markdownRenderers}{olBegin}{%
+  \renewcommand\markdownRendererOlBegin{#1}}%
+\define at key{markdownRenderers}{olBeginTight}{%
+  \renewcommand\markdownRendererOlBeginTight{#1}}%
+\define at key{markdownRenderers}{olItem}{%
+  \renewcommand\markdownRendererOlItem{#1}}%
+\define at key{markdownRenderers}{olItemWithNumber}{%
+  \renewcommand\markdownRendererOlItemWithNumber[1]{#1}}%
+\define at key{markdownRenderers}{olEnd}{%
+  \renewcommand\markdownRendererOlEnd{#1}}%
+\define at key{markdownRenderers}{olEndTight}{%
+  \renewcommand\markdownRendererOlEndTight{#1}}%
+\define at key{markdownRenderers}{dlBegin}{%
+  \renewcommand\markdownRendererDlBegin{#1}}%
+\define at key{markdownRenderers}{dlBeginTight}{%
+  \renewcommand\markdownRendererDlBeginTight{#1}}%
+\define at key{markdownRenderers}{dlItem}{%
+  \renewcommand\markdownRendererDlItem[1]{#1}}%
+\define at key{markdownRenderers}{dlEnd}{%
+  \renewcommand\markdownRendererDlEnd{#1}}%
+\define at key{markdownRenderers}{dlEndTight}{%
+  \renewcommand\markdownRendererDlEndTight{#1}}%
+\define at key{markdownRenderers}{emphasis}{%
+  \renewcommand\markdownRendererEmphasis[1]{#1}}%
+\define at key{markdownRenderers}{strongEmphasis}{%
+  \renewcommand\markdownRendererStrongEmphasis[1]{#1}}%
+\define at key{markdownRenderers}{blockQuoteBegin}{%
+  \renewcommand\markdownRendererBlockQuoteBegin{#1}}%
+\define at key{markdownRenderers}{blockQuoteEnd}{%
+  \renewcommand\markdownRendererBlockQuoteEnd{#1}}%
+\define at key{markdownRenderers}{inputVerbatim}{%
+  \renewcommand\markdownRendererInputVerbatim[1]{#1}}%
+\define at key{markdownRenderers}{headingOne}{%
+  \renewcommand\markdownRendererHeadingOne[1]{#1}}%
+\define at key{markdownRenderers}{headingTwo}{%
+  \renewcommand\markdownRendererHeadingTwo[1]{#1}}%
+\define at key{markdownRenderers}{headingThree}{%
+  \renewcommand\markdownRendererHeadingThree[1]{#1}}%
+\define at key{markdownRenderers}{headingFour}{%
+  \renewcommand\markdownRendererHeadingFour[1]{#1}}%
+\define at key{markdownRenderers}{headingFive}{%
+  \renewcommand\markdownRendererHeadingFive[1]{#1}}%
+\define at key{markdownRenderers}{headingSix}{%
+  \renewcommand\markdownRendererHeadingSix[1]{#1}}%
+\define at key{markdownRenderers}{horizontalRule}{%
+  \renewcommand\markdownRendererHorizontalRule{#1}}%
+\define at key{markdownRenderers}{footnote}{%
+  \renewcommand\markdownRendererFootnote[1]{#1}}%
+%    \end{macrocode}
+%
+% The following example \LaTeX{} code showcases a possible configuration of the
+% \m{markdownRendererLink} and \m{markdownRendererEmphasis} markdown token
+% renderers.
+% \begin{Verbatim}
+% \markdownSetup{
+%   renderers = {
+%     link = {#3},                   % Render links as the link title.
+%     emphasis = {\emph{#1}},    % Render emphasized text via `\emph`.
+%   }
+% }
+% \end{Verbatim}
+%
+% \paragraph{Plain \TeX{} Markdown Token Renderer Prototypes}
+% The \LaTeX{} interface recognizes an option with the \t`rendererPrototypes`
+% key, whose value must be a list of options that map directly to the markdown
+% token renderer prototype macros exposed by the plain \TeX{} interface (see
+% Section \ref{sec:texrendererprototypes}).
+%  \begin{macrocode}
+\define at key{markdownOptions}{rendererPrototypes}{%
+  \setkeys{markdownRendererPrototypes}{#1}}%
+\define at key{markdownRendererPrototypes}{lineBreak}{%
+  \renewcommand\markdownRendererLineBreakPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{ellipsis}{%
+  \renewcommand\markdownRendererEllipsisPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{codeSpan}{%
+  \renewcommand\markdownRendererCodeSpanPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{link}{%
+  \renewcommand\markdownRendererLink[3]{#1}}%
+\define at key{markdownRendererPrototypes}{image}{%
+  \renewcommand\markdownRendererImage[3]{#1}}%
+\define at key{markdownRendererPrototypes}{ulBegin}{%
+  \renewcommand\markdownRendererUlBeginPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{ulBeginTight}{%
+  \renewcommand\markdownRendererUlBeginTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{ulItem}{%
+  \renewcommand\markdownRendererUlItemPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{ulEnd}{%
+  \renewcommand\markdownRendererUlEndPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{ulEndTight}{%
+  \renewcommand\markdownRendererUlEndTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{olBegin}{%
+  \renewcommand\markdownRendererOlBeginPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{olBeginTight}{%
+  \renewcommand\markdownRendererOlBeginTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{olItem}{%
+  \renewcommand\markdownRendererOlItemPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{olItemWithNumber}{%
+  \renewcommand\markdownRendererOlItemWithNumberPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{olEnd}{%
+  \renewcommand\markdownRendererOlEndPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{olEndTight}{%
+  \renewcommand\markdownRendererOlEndTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{dlBegin}{%
+  \renewcommand\markdownRendererDlBeginPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{dlBeginTight}{%
+  \renewcommand\markdownRendererDlBeginTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{dlItem}{%
+  \renewcommand\markdownRendererDlItemPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{dlEnd}{%
+  \renewcommand\markdownRendererDlEndPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{dlEndTight}{%
+  \renewcommand\markdownRendererDlEndTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{emphasis}{%
+  \renewcommand\markdownRendererEmphasisPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{strongEmphasis}{%
+  \renewcommand\markdownRendererStrongEmphasisPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{blockQuoteBegin}{%
+  \renewcommand\markdownRendererBlockQuoteBeginPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{blockQuoteEnd}{%
+  \renewcommand\markdownRendererBlockQuoteEndPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{inputVerbatim}{%
+  \renewcommand\markdownRendererInputVerbatimPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingOne}{%
+  \renewcommand\markdownRendererHeadingOnePrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingTwo}{%
+  \renewcommand\markdownRendererHeadingTwoPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingThree}{%
+  \renewcommand\markdownRendererHeadingThreePrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingFour}{%
+  \renewcommand\markdownRendererHeadingFourPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingFive}{%
+  \renewcommand\markdownRendererHeadingFivePrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingSix}{%
+  \renewcommand\markdownRendererHeadingSixPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{horizontalRule}{%
+  \renewcommand\markdownRendererHorizontalRulePrototype{#1}}%
+\define at key{markdownRendererPrototypes}{footnote}{%
+  \renewcommand\markdownRendererFootnotePrototype[1]{#1}}%
+%    \end{macrocode}
+%
+% The following example \LaTeX{} code showcases a possible configuration of the
+% \m{markdownRendererImagePrototype} and \m{markdownRendererCodeSpanPrototype}
+% markdown token renderer prototypes.
+% \begin{Verbatim}
+% \markdownSetup{
+%   renderers = {
+%     image = {\includegraphics{#2}},
+%     codeSpan = {\texttt{#1}},    % Render inline code via `\texttt`.
+%   }
+% }
+% \end{Verbatim}
+%
+% \iffalse
+%</latex>
+%<*context>
+% \fi\subsection{\Hologo{ConTeXt} Interface}\label{sec:contextinterface}
+% The \Hologo{ConTeXt} interface provides a start-stop macro pair for the
+% typesetting of markdown input from within \Hologo{ConTeXt}. The rest of the
+% interface is inherited from the plain \TeX{} interface (see Section
+% \ref{sec:texinterface}).
+%  \begin{macrocode}
+\writestatus{loading}{ConTeXt User Module / markdown}%
+\unprotect
+%    \end{macrocode}
+%
+% The \Hologo{ConTeXt} interface is implemented by the
+% \t`t-markdown.tex` \Hologo{ConTeXt} module file that can be loaded as follows:
+% \begin{Verbatim}
+% \usemodule[t][markdown]
+% \end{Verbatim}
+% It is expected that the special plain \TeX{} characters have the expected
+% category codes, when \m{input}ting the file.
+%
+% \subsubsection{Typesetting Markdown}
+% The interface exposes the \mdef{startmarkdown} and \mdef{stopmarkdown} macro
+% pair for the typesetting of a markdown document fragment.
+%  \begin{macrocode}
+\let\startmarkdown\relax
+\let\stopmarkdown\relax
+%    \end{macrocode}
+% You may prepend your own code to the \m{startmarkdown} macro and redefine the
+% \m{stopmarkdown} macro to produce special effects before and after the
+% markdown block.
+%
+% Note that the \m{startmarkdown} and \m{stopmarkdown} macros
+% are subject to the same limitations as the \m{markdownBegin} and
+% \m{markdownEnd} macros exposed by the plain \TeX{} interface.
+%
+% The following example \Hologo{ConTeXt} code showcases the usage of the
+% \m{startmarkdown} and \m{stopmarkdown} macros:
+% \begin{Verbatim}
+% \usemodule[t][markdown]
+% \starttext
+% \startmarkdown
+% _Hello_ **world** ...
+% \stopmarkdown
+% \stoptext
+% \end{Verbatim}
+% 
+% \section{Technical Documentation}\label{sec:implementation}
+% This part of the manual describes the implementation of the interfaces
+% exposed by the package (see Section \ref{sec:interfaces}) and is aimed at the
+% developers of the package, as well as the curious users.
+%
+% \iffalse
+%</context>
+%<*lua>
+% \fi\subsection{Lua Implementation}\label{sec:luaimplementation}
+% The Lua implementation implements \luamdef{writer} and \luamdef{reader}
+% objects that provide the conversion from markdown to plain \TeX{}.
+%
+% The Lunamark Lua module implements writers for the conversion to various
+% other formats, such as DocBook, Groff, or \acro{HTML}. These were stripped
+% from the module and the remaining markdown reader and plain \TeX{} writer
+% were hidden behind the converter functions exposed by the Lua interface (see
+% Section \ref{sec:luainterface}).
+%
+%  \begin{macrocode}
+local upper, gsub, format, length =
+  string.upper, string.gsub, string.format, string.len
+local concat = table.concat
+local P, R, S, V, C, Cg, Cb, Cmt, Cc, Ct, B, Cs, any =
+  lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Cg, lpeg.Cb,
+  lpeg.Cmt, lpeg.Cc, lpeg.Ct, lpeg.B, lpeg.Cs, lpeg.P(1)
+%    \end{macrocode}
+% 
+% \subsubsection{Utility Functions}
+% This section documents the utility functions used by the Lua code. These
+% functions are encapsulated in the \t`util` object. The functions were
+% originally located in the \t`lunamark/util.lua` file in the Lunamark Lua
+% module.
+%  \begin{macrocode}
+local util = {}
+%    \end{macrocode}
+% 
+% The \luamdef{util.err} method prints an error message \t`msg` and exits.
+% If \t`exit_code` is provided, it specifies the exit code.  Otherwise, the
+% exit code will be 1.
+%  \begin{macrocode}
+function util.err(msg, exit_code)
+  io.stderr:write("markdown.lua: " .. msg .. "\n")
+  os.exit(exit_code or 1)
+end
+%    \end{macrocode}
+%
+% The \luamdef{util.cache} method computes the digest of \t`string` and
+% \t`salt`, adds the \t`suffix` and looks into the directory \t`dir`, whether a
+% file with such a name exists. If it does not, it gets created with
+% \t`transform(string)` as its content. The filename is then returned.
+%  \begin{macrocode}
+function util.cache(dir, string, salt, transform, suffix)
+  local digest = md5.sumhexa(string .. (salt or ""))
+  local name = util.pathname(dir, digest .. suffix)
+  local file = io.open(name, "r")
+  if file == nil then -- If no cache entry exists, then create a new one.
+    local file = assert(io.open(name, "w"))
+    local result = string
+    if transform ~= nil then
+      result = transform(result)
+    end
+    assert(file:write(result))
+    assert(file:close())
+  end
+  return name
+end
+%    \end{macrocode}
+%
+% The \luamdef{util.table_copy} method creates a shallow copy of a table \t`t`
+% and its metatable.
+%  \begin{macrocode}
+function util.table_copy(t)
+  local u = { }
+  for k, v in pairs(t) do u[k] = v end
+  return setmetatable(u, getmetatable(t))
+end
+%    \end{macrocode}
+%
+% The \luamdef{util.expand_tabs_in_line} expands tabs in string \t`s`. If
+% \t`tabstop` is specified, it is used as the tab stop width. Otherwise,
+% the tab stop width of 4 characters is used. The method is a copy of the tab
+% expansion algorithm from \cite[Chapter~21]{ierusalimschy13}.
+%  \begin{macrocode}
+function util.expand_tabs_in_line(s, tabstop)
+  local tab = tabstop or 4
+  local corr = 0
+  return (s:gsub("()\t", function(p)
+            local sp = tab - (p - 1 + corr) % tab
+            corr = corr - 1 + sp
+            return string.rep(" ", sp)
+          end))
+end
+%    \end{macrocode}
+%
+% The \luamdef{util.walk} method walks a rope \t`t`, applying a function \t`f`
+% to each leaf element in order. A rope is an array whose elements may be
+% ropes, strings, numbers, or functions.  If a leaf element is a function, call
+% it and get the return value before proceeding.
+%  \begin{macrocode}
+function util.walk(t, f)
+  local typ = type(t)
+  if typ == "string" then
+    f(t)
+  elseif typ == "table" then
+    local i = 1
+    local n
+    n = t[i]
+    while n do
+      util.walk(n, f)
+      i = i + 1
+      n = t[i]
+    end
+  elseif typ == "function" then
+    local ok, val = pcall(t)
+    if ok then
+      util.walk(val,f)
+    end
+  else
+    f(tostring(t))
+  end
+end
+%    \end{macrocode}
+%
+% The \luamdef{util.flatten} method flattens an array \t`ary` that does not
+% contain cycles and returns the result.
+%  \begin{macrocode}
+function util.flatten(ary)
+  local new = {}
+  for _,v in ipairs(ary) do
+    if type(v) == "table" then
+      for _,w in ipairs(util.flatten(v)) do
+        new[#new + 1] = w
+      end
+    else
+      new[#new + 1] = v
+    end
+  end
+  return new
+end
+%    \end{macrocode}
+%
+% The \luamdef{util.rope_to_string} method converts a rope \t`rope` to a
+% string and returns it. For the definition of a rope, see the definition of
+% the \luam{util.walk} method.
+%  \begin{macrocode}
+function util.rope_to_string(rope)
+  local buffer = {}
+  util.walk(rope, function(x) buffer[#buffer + 1] = x end)
+  return table.concat(buffer)
+end
+%    \end{macrocode}
+%
+% The \luamdef{util.rope_last} method retrieves the last item in a rope. For
+% the definition of a rope, see the definition of the \luam{util.walk} method.
+%  \begin{macrocode}
+function util.rope_last(rope)
+  if #rope == 0 then
+    return nil
+  else
+    local l = rope[#rope]
+    if type(l) == "table" then
+      return util.rope_last(l)
+    else
+      return l
+    end
+  end
+end
+%    \end{macrocode}
+%
+% Given an array \t`ary` and a string \t`x`, the \luamdef{util.intersperse}
+% method returns an array \t`new`, such that \t`ary[i] == new[2*(i-1)+1]` and
+% \t`new[2*i] == x` for all $1\leq\t`i`\leq\t`\#ary`$.
+%  \begin{macrocode}
+function util.intersperse(ary, x)
+  local new = {}
+  local l = #ary
+  for i,v in ipairs(ary) do
+    local n = #new
+    new[n + 1] = v
+    if i ~= l then
+      new[n + 2] = x
+    end
+  end
+  return new
+end
+%    \end{macrocode}
+% 
+% Given an array \t`ary` and a function \t`f`, the \luamdef{util.map} method
+% returns an array \t`new`, such that \t`new[i] == f(ary[i])` for all
+% $1\leq\t`i`\leq\t`\#ary`$.
+%  \begin{macrocode}
+function util.map(ary, f)
+  local new = {}
+  for i,v in ipairs(ary) do
+    new[i] = f(v)
+  end
+  return new
+end
+%    \end{macrocode}
+%
+% Given a table \t`char_escapes` mapping escapable characters to escaped
+% strings and optionally a table \t`string_escapes` mapping escapable strings
+% to escaped strings, the \luamdef{util.escaper} method returns an escaper
+% function that escapes all occurances of escapable strings and characters (in
+% this order).
+% 
+% The method uses \pkg{LPeg}, which is faster than the Lua \t`string.gsub`
+% built-in method.
+%  \begin{macrocode}
+function util.escaper(char_escapes, string_escapes)
+%    \end{macrocode}
+% Build a string of escapable characters.
+%  \begin{macrocode}
+  local char_escapes_list = ""
+  for i,_ in pairs(char_escapes) do
+    char_escapes_list = char_escapes_list .. i
+  end
+%    \end{macrocode}
+% Create an \pkg{LPeg} capture \t`escapable` that produces the escaped string
+% corresponding to the matched escapable character.
+%  \begin{macrocode}
+  local escapable = S(char_escapes_list) / char_escapes
+%    \end{macrocode}
+% If \t`string_escapes` is provided, turn \t`escapable` into the
+% {\catcode`\_=8\[
+%   \sum_{(\t`k`,\t`v`)\in\t`string\_escapes`}\t`P(k) / v` + \t`escapable`
+% \]}^^A
+% capture that replaces any occurance of the string \t`k` with the string
+% \t`v` for each $(\t`k`, \t`v`)\in\t`string\_escapes`$. Note that the pattern
+% summation is not commutative and the its operands are inspected in the
+% summation order during the matching. As a corrolary, the strings always
+% take precedence over the characters.
+%  \begin{macrocode}
+  if string_escapes then
+    for k,v in pairs(string_escapes) do
+      escapable = P(k) / v + escapable
+    end
+  end
+%    \end{macrocode}
+% Create an \pkg{LPeg} capture \t`escape_string` that captures anything
+% \t`escapable` does and matches any other unmatched characters.
+%  \begin{macrocode}
+  local escape_string = Cs((escapable + any)^0)
+%    \end{macrocode}
+% Return a function that matches the input string \t`s` against the
+% \t`escape_string` capture.
+%  \begin{macrocode}
+  return function(s)
+    return lpeg.match(escape_string, s)
+  end
+end
+%    \end{macrocode}
+%
+% The \luamdef{util.pathname} method produces a pathname out of a directory
+% name \t`dir` and a filename \t`file` and returns it.
+%  \begin{macrocode}
+function util.pathname(dir, file)
+  if #dir == 0 then
+    return file
+  else
+    return dir .. "/" .. file
+  end
+end
+%    \end{macrocode}
+% \subsubsection{Plain \TeX{} Writer}\label{sec:texwriter}
+% This section documents the \luam{writer} object, which implements the
+% routines for producing the \TeX{} output. The object is an amalgamate of the
+% generic, \TeX{}, \LaTeX{} writer objects that were located in the
+% \t`lunamark/writer/generic.lua`, \t`lunamark/writer/tex.lua`, and
+% \t`lunamark/writer/latex.lua` files in the Lunamark Lua module.
+%
+% Although not specified in the Lua interface (see Section
+% \ref{sec:luainterface}), the \luam{writer} object is exported, so that the
+% curious user could easily tinker with the methods of the objects produced by
+% the \luam{writer.new} method described below. The user should be aware,
+% however, that the implementation may change in a future revision.
+%  \begin{macrocode}
+M.writer = {}
+%    \end{macrocode}
+%
+% The \luamdef{writer.new} method creates and returns a new \TeX{} writer
+% object associated with the Lua interface options (see Section
+% \ref{sec:luaoptions}) \t`options`. When \t`options` are unspecified, it is
+% assumed that an empty table was passed to the method.
+%
+% The objects produced by the \luam{writer.new} method expose instance methods
+% and variables of their own. As a convention, I will refer to these
+% \meta{member}s as \t`writer->`\meta{member}.
+%  \begin{macrocode}
+function M.writer.new(options)
+  local self = {}
+  options = options or {}
+%    \end{macrocode}
+%
+% Make the \t`options` table inherit from the \luam{defaultOptions} table.
+%  \begin{macrocode}
+  setmetatable(options, { __index = function (_, key)
+    return defaultOptions[key] end })
+%    \end{macrocode}
+%
+% Define \luamdef{writer->suffix} as the suffix of the produced cache files.
+%  \begin{macrocode}
+  self.suffix = ".tex"
+%    \end{macrocode}
+%
+% Define \luamdef{writer->space} as the output format of a space character.
+%  \begin{macrocode}
+  self.space = " "
+%    \end{macrocode}
+%
+% Define \luamdef{writer->plain} as a function that will transform an input
+% plain text block \t`s` to the output format.
+%  \begin{macrocode}
+  function self.plain(s)
+    return s
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->paragraph} as a function that will transform an
+% input paragraph \t`s` to the output format.
+%  \begin{macrocode}
+  function self.paragraph(s)
+    return s
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->pack} as a function that will take the filename
+% \t`name` of the output file prepared by the reader and transform it to the
+% output format.
+%  \begin{macrocode}
+  function self.pack(name)
+    return [[\input"]] .. name .. [["\relax]]
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->interblocksep} as the output format of a block
+% element separator.
+%  \begin{macrocode}
+  self.interblocksep = "\n\n"
+%    \end{macrocode}
+%
+% Define \luamdef{writer->containersep} as the output format of a container
+% separator.
+%  \begin{macrocode}
+  self.containersep = "\n\n"
+%    \end{macrocode}
+%
+% Define \luamdef{writer->eof} as the end of file marker in the output format.
+%  \begin{macrocode}
+  self.eof = [[\relax]]
+%    \end{macrocode}
+%
+% Define \luamdef{writer->linebreak} as the output format of a forced line break.
+%  \begin{macrocode}
+  self.linebreak = "\\markdownRendererLineBreak "
+%    \end{macrocode}
+%
+% Define \luamdef{writer->ellipsis} as the output format of an ellipsis.
+%  \begin{macrocode}
+  self.ellipsis = "\\markdownRendererEllipsis{}"
+%    \end{macrocode}
+%
+% Define \luamdef{writer->hrule} as the output format of a horizontal rule.
+%  \begin{macrocode}
+  self.hrule = "\\markdownRendererHorizontalRule "
+%    \end{macrocode}
+%
+% Define a table \luamdef{escaped} containing the mapping from special plain
+% \TeX{} characters to their escaped variants.
+%  \begin{macrocode}
+  local escaped = {
+     ["{"] = "\\{",
+     ["}"] = "\\}",
+     ["$"] = "\\$",
+     ["%"] = "\\%",
+     ["&"] = "\\&",
+     ["_"] = "\\_",
+     ["#"] = "\\#",
+     ["^"] = "\\^{}",
+     ["\\"] = "\\char92{}",
+     ["~"] = "\\char126{}",
+     ["|"] = "\\char124{}", }
+%    \end{macrocode}
+% Use the \luam{escaped} table to create an escaper function \luamdef{escape}.
+%  \begin{macrocode}
+  local escape = util.escaper(escaped)
+%    \end{macrocode}
+%
+% Define \luamdef{writer->string} as a function that will transform an input
+% plain text span \t`s` to the output format. If the \Opt{hybrid} option is
+% \t`true`, use an identity function. Otherwise, use the \luam{escape}
+% function.
+%  \begin{macrocode}
+  if options.hybrid then
+    self.string = function(s) return s end
+  else
+    self.string = escape
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->code} as a function that will transform an input
+% inlined code span \t`s` to the output format.
+%  \begin{macrocode}
+  function self.code(s)
+    return {"\\markdownRendererCodeSpan{",escape(s),"}"}
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->link} as a function that will transform an input
+% hyperlink to the output format, where \t`lab` corresponds to thelabel,
+% \t`src` to \acro{uri}, and \t`tit` to the title of the link.
+%  \begin{macrocode}
+  function self.link(lab,src,tit)
+    return {"\\markdownRendererLink{",lab,"}",
+                          "{",self.string(src),"}",
+                          "{",self.string(tit),"}"}
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->image} as a function that will transform an input
+% image to the output format, where \t`lab` corresponds to the label, \t`src`
+% to the \acro{url}, and \t`tit` to the title of the image.
+%  \begin{macrocode}
+  function self.image(lab,src,tit)
+    return {"\\markdownRendererImage{",lab,"}",
+                           "{",self.string(src),"}",
+                           "{",self.string(tit),"}"}
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->bulletlist} as a function that will transform an input
+% bulleted list to the output format, where \t`items` is an array of the list
+% items and \t`tight` specifies, whether the list is tight or not.
+%  \begin{macrocode}
+  local function ulitem(s)
+    return {"\\markdownRendererUlItem ",s}
+  end
+
+  function self.bulletlist(items,tight)
+    local buffer = {}
+    for _,item in ipairs(items) do
+      buffer[#buffer + 1] = ulitem(item)
+    end
+    local contents = util.intersperse(buffer,"\n")
+    if tight and options.tightLists then
+      return {"\\markdownRendererUlBeginTight\n",contents,
+        "\n\\markdownRendererUlEndTight "}
+    else
+      return {"\\markdownRendererUlBegin\n",contents,
+        "\n\\markdownRendererUlEnd "}
+    end
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->ollist} as a function that will transform an input
+% ordered list to the output format, where \t`items` is an array of the list
+% items and \t`tight` specifies, whether the list is tight or not. If the
+% optional parameter \t`startnum` is present, it should be used as the number
+% of the first list item.
+%  \begin{macrocode}
+  local function olitem(s,num)
+    if num ~= nil then
+      return {"\\markdownRendererOlItemWithNumber{",num,"}",s}
+    else
+      return {"\\markdownRendererOlItem ",s}
+    end
+  end
+
+  function self.orderedlist(items,tight,startnum)
+    local buffer = {}
+    local num = startnum
+    for _,item in ipairs(items) do
+      buffer[#buffer + 1] = olitem(item,num)
+      if num ~= nil then
+        num = num + 1
+      end
+    end
+    local contents = util.intersperse(buffer,"\n")
+    if tight and options.tightLists then
+      return {"\\markdownRendererOlBeginTight\n",contents,
+        "\n\\markdownRendererOlEndTight "}
+    else
+      return {"\\markdownRendererOlBegin\n",contents,
+        "\n\\markdownRendererOlEnd "}
+    end
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->definitionlist} as a function that will transform an
+% input definition list to the output format, where \t`items` is an array of
+% tables, each of the form \t`\{ term = t, definitions = defs \}`, where \t`t`
+% is a term and \t`defs` is an array of definitions. \t`tight` specifies,
+% whether the list is tight or not.
+%  \begin{macrocode}
+  local function dlitem(term,defs)
+      return {"\\markdownRendererDlItem{",term,"}\n",defs}
+  end
+
+  function self.definitionlist(items,tight)
+    local buffer = {}
+    for _,item in ipairs(items) do
+      buffer[#buffer + 1] = dlitem(item.term,
+        util.intersperse(item.definitions, self.interblocksep))
+    end
+    local contents = util.intersperse(buffer, self.containersep)
+    if tight and options.tightLists then
+      return {"\\markdownRendererDlBeginTight\n\n", contents,
+        "\n\n\\markdownRendererDlEndTight\n"}
+    else
+      return {"\\markdownRendererDlBegin\n\n", contents,
+        "\n\n\\markdownRendererDlEnd\n"}
+    end
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->emphasis} as a function that will transform an
+% emphasized span \t`s` of input text to the output format.
+%  \begin{macrocode}
+  function self.emphasis(s)
+    return {"\\markdownRendererEmphasis{",s,"}"}
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->strong} as a function that will transform a strongly
+% emphasized span \t`s` of input text to the output format.
+%  \begin{macrocode}
+  function self.strong(s)
+    return {"\\markdownRendererStrongEmphasis{",s,"}"}
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->blockquote} as a function that will transform an
+% input block quote \t`s` to the output format.
+%  \begin{macrocode}
+  function self.blockquote(s)
+    return {"\\markdownRendererBlockQuoteBegin\n",s,
+      "\n\\markdownRendererBlockQuoteEnd "}
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->verbatim} as a function that will transform an
+% input code block \t`s` to the output format.
+%  \begin{macrocode}
+  function self.verbatim(s)
+    local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim")
+    return {"\\markdownRendererInputVerbatim{",name,"}"}
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->heading} as a function that will transform an
+% input heading \t`s` at level \t`level` to the output format.
+%  \begin{macrocode}
+  function self.heading(s,level)
+    local cmd
+    if level == 1 then
+      cmd = "\\markdownRendererHeadingOne"
+    elseif level == 2 then
+      cmd = "\\markdownRendererHeadingTwo"
+    elseif level == 3 then
+      cmd = "\\markdownRendererHeadingThree"
+    elseif level == 4 then
+      cmd = "\\markdownRendererHeadingFour"
+    elseif level == 5 then
+      cmd = "\\markdownRendererHeadingFive"
+    elseif level == 6 then
+      cmd = "\\markdownRendererHeadingSix"
+    else
+      cmd = ""
+    end
+    return {cmd,"{",s,"}"}
+  end
+%    \end{macrocode}
+%
+% Define \luamdef{writer->footnote} as a function that will transform an
+% input footnote \t`s` to the output format.
+%  \begin{macrocode}
+  function self.note(s)
+    return {"\\markdownRendererFootnote{",s,"}"}
+  end
+
+  return self
+end
+%    \end{macrocode}
+% 
+% \subsubsection{Markdown Reader}\label{sec:markdownreader}
+% This section documents the \luam{reader} object, which implements the
+% routines for parsing the markdown input. The object corresponds to the
+% markdown reader object that was located in the
+% \t`lunamark/reader/markdown.lua` file in the Lunamark Lua module.
+%
+% Although not specified in the Lua interface (see Section
+% \ref{sec:luainterface}), the \luam{reader} object is exported, so that the
+% curious user could easily tinker with the methods of the objects produced by
+% the \luam{reader.new} method described below. The user should be aware,
+% however, that the implementation may change in a future revision.
+%
+% The \luamdef{reader.new} method creates and returns a new \TeX{} reader
+% object associated with the Lua interface options (see Section
+% \ref{sec:luaoptions}) \t`options` and with a writer object \t`writer`. When
+% \t`options` are unspecified, it is assumed that an empty table was passed to
+% the method.
+%
+% The objects produced by the \luam{reader.new} method expose instance methods
+% and variables of their own. As a convention, I will refer to these
+% \meta{member}s as \t`reader->`\meta{member}.
+%  \begin{macrocode}
+M.reader = {}
+function M.reader.new(writer, options)
+  local self = {}
+  options = options or {}
+%    \end{macrocode}
+%
+% Make the \t`options` table inherit from the \luam{defaultOptions} table.
+%  \begin{macrocode}
+  setmetatable(options, { __index = function (_, key)
+    return defaultOptions[key] end })
+%    \end{macrocode}
+%
+% \paragraph{Top Level Helper Functions}
+% Define \luamdef{normalize_tag} as a function that normalizes a markdown
+% reference tag by lowercasing it, and by collapsing any adjacent whitespace
+% characters.
+%  \begin{macrocode}
+  local function normalize_tag(tag)
+    return unicode.utf8.lower(
+      gsub(util.rope_to_string(tag), "[ \n\r\t]+", " "))
+  end
+%    \end{macrocode}
+% 
+% Define \luamdef{expandtabs} either as an identity function, when the
+% \Opt{preserveTabs} Lua inrerface option is \t`true`, or to a function that
+% expands tabs into spaces otherwise.
+%  \begin{macrocode}
+  local expandtabs
+  if options.preserveTabs then
+    expandtabs = function(s) return s end
+  else
+    expandtabs = function(s)
+                   if s:find("\t") then
+                     return s:gsub("[^\n]*", util.expand_tabs_in_line)
+                   else
+                     return s
+                   end
+                 end
+  end
+%    \end{macrocode}
+% \paragraph{Top Level Parsing Functions}
+%  \begin{macrocode}
+  local syntax
+  local blocks
+  local inlines
+
+  local parse_blocks =
+    function(str)
+      local res = lpeg.match(blocks, str)
+      if res == nil then
+        error(format("parse_blocks failed on:\n%s", str:sub(1,20)))
+      else
+        return res
+      end
+    end
+
+  local parse_inlines =
+    function(str)
+      local res = lpeg.match(inlines, str)
+      if res == nil then
+        error(format("parse_inlines failed on:\n%s",
+        str:sub(1,20)))
+      else
+        return res
+      end
+    end
+
+  local parse_inlines_no_link =
+    function(str)
+      local res = lpeg.match(inlines_no_link, str)
+      if res == nil then
+        error(format("parse_inlines_no_link failed on:\n%s",
+        str:sub(1,20)))
+      else
+        return res
+      end
+    end
+%    \end{macrocode}
+% \paragraph{Generic \acro{peg} Patterns}
+%  \begin{macrocode}
+  local percent                = P("%")
+  local asterisk               = P("*")
+  local dash                   = P("-")
+  local plus                   = P("+")
+  local underscore             = P("_")
+  local period                 = P(".")
+  local hash                   = P("#")
+  local ampersand              = P("&")
+  local backtick               = P("`")
+  local less                   = P("<")
+  local more                   = P(">")
+  local space                  = P(" ")
+  local squote                 = P("'")
+  local dquote                 = P('"')
+  local lparent                = P("(")
+  local rparent                = P(")")
+  local lbracket               = P("[")
+  local rbracket               = P("]")
+  local circumflex             = P("^")
+  local slash                  = P("/")
+  local equal                  = P("=")
+  local colon                  = P(":")
+  local semicolon              = P(";")
+  local exclamation            = P("!")
+
+  local digit                  = R("09")
+  local hexdigit               = R("09","af","AF")
+  local letter                 = R("AZ","az")
+  local alphanumeric           = R("AZ","az","09")
+  local keyword                = letter * alphanumeric^0
+
+  local doubleasterisks        = P("**")
+  local doubleunderscores      = P("__")
+  local fourspaces             = P("    ")
+
+  local any                    = P(1)
+  local fail                   = any - 1
+  local always                 = P("")
+
+  local escapable              = S("\\`*_{}[]()+_.!#-~:^")
+  local anyescaped             = P("\\") / "" * escapable
+                               + any
+
+  local tab                    = P("\t")
+  local spacechar              = S("\t ")
+  local spacing                = S(" \n\r\t")
+  local newline                = P("\n")
+  local nonspacechar           = any - spacing
+  local tightblocksep          = P("\001")
+
+  local specialchar
+  if options.smartEllipses then
+    specialchar                = S("*_`&[]!\\.")
+  else
+    specialchar                = S("*_`&[]!\\")
+  end
+
+  local normalchar             = any -
+                                 (specialchar + spacing + tightblocksep)
+  local optionalspace          = spacechar^0
+  local spaces                 = spacechar^1
+  local eof                    = - any
+  local nonindentspace         = space^-3 * - spacechar
+  local indent                 = space^-3 * tab
+                               + fourspaces / ""
+  local linechar               = P(1 - newline)
+
+  local blankline              = optionalspace * newline / "\n"
+  local blanklines             = blankline^0
+  local skipblanklines         = (optionalspace * newline)^0
+  local indentedline           = indent    /"" * C(linechar^1 * newline^-1)
+  local optionallyindentedline = indent^-1 /"" * C(linechar^1 * newline^-1)
+  local sp                     = spacing^0
+  local spnl                   = optionalspace * (newline * optionalspace)^-1
+  local line                   = linechar^0 * newline
+                               + linechar^1 * eof
+  local nonemptyline           = line - blankline
+
+  local chunk = line * (optionallyindentedline - blankline)^0
+
+  -- block followed by 0 or more optionally
+  -- indented blocks with first line indented.
+  local function indented_blocks(bl)
+    return Cs( bl
+             * (blankline^1 * indent * -blankline * bl)^0
+             * blankline^1 )
+  end
+%    \end{macrocode}
+% \paragraph{List \acro{peg} Patterns}
+%  \begin{macrocode}
+  local bulletchar = C(plus + asterisk + dash)
+
+  local bullet     = ( bulletchar * #spacing * (tab + space^-3)
+                     + space * bulletchar * #spacing * (tab + space^-2)
+                     + space * space * bulletchar * #spacing * (tab + space^-1)
+                     + space * space * space * bulletchar * #spacing
+                     ) * -bulletchar
+
+  if options.hashEnumerators then
+    dig = digit + hash
+  else
+    dig = digit
+  end
+
+  local enumerator = C(dig^3 * period) * #spacing
+                   + C(dig^2 * period) * #spacing * (tab + space^1)
+                   + C(dig * period) * #spacing * (tab + space^-2)
+                   + space * C(dig^2 * period) * #spacing
+                   + space * C(dig * period) * #spacing * (tab + space^-1)
+                   + space * space * C(dig^1 * period) * #spacing
+%    \end{macrocode}
+% \paragraph{Code Span \acro{peg} Patterns}
+%  \begin{macrocode}
+  local openticks   = Cg(backtick^1, "ticks")
+
+  local function captures_equal_length(s,i,a,b)
+    return #a == #b and i
+  end
+
+  local closeticks  = space^-1 *
+                      Cmt(C(backtick^1) * Cb("ticks"), captures_equal_length)
+
+  local intickschar = (any - S(" \n\r`"))
+                    + (newline * -blankline)
+                    + (space - closeticks)
+                    + (backtick^1 - closeticks)
+
+  local inticks     = openticks * space^-1 * C(intickschar^1) * closeticks
+%    \end{macrocode}
+% \paragraph{Tag \acro{peg} Patterns}
+%  \begin{macrocode}
+  local leader        = space^-3
+
+  -- in balanced brackets, parentheses, quotes:
+  local bracketed     = P{ lbracket
+                         * ((anyescaped - (lbracket + rbracket
+                             + blankline^2)) + V(1))^0
+                         * rbracket }
+
+  local inparens      = P{ lparent
+                         * ((anyescaped - (lparent + rparent
+                             + blankline^2)) + V(1))^0
+                         * rparent }
+
+  local squoted       = P{ squote * alphanumeric
+                         * ((anyescaped - (squote + blankline^2))
+                             + V(1))^0
+                         * squote }
+
+  local dquoted       = P{ dquote * alphanumeric
+                         * ((anyescaped - (dquote + blankline^2))
+                             + V(1))^0
+                         * dquote }
+
+  -- bracketed 'tag' for markdown links, allowing nested brackets:
+  local tag           = lbracket
+                      * Cs((alphanumeric^1
+                           + bracketed
+                           + inticks
+                           + (anyescaped - (rbracket + blankline^2)))^0)
+                      * rbracket
+
+  -- url for markdown links, allowing balanced parentheses:
+  local url           = less * Cs((anyescaped-more)^0) * more
+                      + Cs((inparens + (anyescaped-spacing-rparent))^1)
+
+  -- quoted text possibly with nested quotes:
+  local title_s       = squote * Cs(((anyescaped-squote) + squoted)^0) *
+                        squote
+
+  local title_d       = dquote * Cs(((anyescaped-dquote) + dquoted)^0) *
+                        dquote
+
+  local title_p       = lparent
+                      * Cs((inparens + (anyescaped-rparent))^0)
+                      * rparent
+
+  local title         = title_d + title_s + title_p
+
+  local optionaltitle = spnl * title * spacechar^0
+                      + Cc("")
+%    \end{macrocode}
+% \paragraph{Footnote \acro{peg} Patterns}
+%  \begin{macrocode}
+  local rawnotes = {}
+
+  local function strip_first_char(s)
+    return s:sub(2)
+  end
+
+  -- like indirect_link
+  local function lookup_note(ref)
+    return function()
+      local found = rawnotes[normalize_tag(ref)]
+      if found then
+        return writer.note(parse_blocks(found))
+      else
+        return {"[^", ref, "]"}
+      end
+    end
+  end
+
+  local function register_note(ref,rawnote)
+    rawnotes[normalize_tag(ref)] = rawnote
+    return ""
+  end
+
+  local RawNoteRef = #(lbracket * circumflex) * tag / strip_first_char
+
+  local NoteRef    = RawNoteRef / lookup_note
+
+  local NoteBlock
+
+  if options.footnotes then
+    NoteBlock = leader * RawNoteRef * colon * spnl *
+                indented_blocks(chunk) / register_note
+  else
+    NoteBlock = fail
+  end
+%    \end{macrocode}
+% \paragraph{Link and Image \acro{peg} Patterns}
+%  \begin{macrocode}
+  -- List of references defined in the document
+  local references
+
+  -- add a reference to the list
+  local function register_link(tag,url,title)
+      references[normalize_tag(tag)] = { url = url, title = title }
+      return ""
+  end
+
+  -- parse a reference definition:  [foo]: /bar "title"
+  local define_reference_parser =
+    leader * tag * colon * spacechar^0 * url * optionaltitle * blankline^1
+
+  -- lookup link reference and return either
+  -- the link or nil and fallback text.
+  local function lookup_reference(label,sps,tag)
+      local tagpart
+      if not tag then
+          tag = label
+          tagpart = ""
+      elseif tag == "" then
+          tag = label
+          tagpart = "[]"
+      else
+          tagpart = {"[", parse_inlines(tag), "]"}
+      end
+      if sps then
+        tagpart = {sps, tagpart}
+      end
+      local r = references[normalize_tag(tag)]
+      if r then
+        return r
+      else
+        return nil, {"[", parse_inlines(label), "]", tagpart}
+      end
+  end
+
+  -- lookup link reference and return a link, if the reference is found,
+  -- or a bracketed label otherwise.
+  local function indirect_link(label,sps,tag)
+    return function()
+      local r,fallback = lookup_reference(label,sps,tag)
+      if r then
+        return writer.link(parse_inlines_no_link(label), r.url, r.title)
+      else
+        return fallback
+      end
+    end
+  end
+
+  -- lookup image reference and return an image, if the reference is found,
+  -- or a bracketed label otherwise.
+  local function indirect_image(label,sps,tag)
+    return function()
+      local r,fallback = lookup_reference(label,sps,tag)
+      if r then
+        return writer.image(writer.string(label), r.url, r.title)
+      else
+        return {"!", fallback}
+      end
+    end
+  end
+%    \end{macrocode}
+% \paragraph{Inline Element \acro{peg} Patterns}
+%  \begin{macrocode}
+  local Inline    = V("Inline")
+
+  local Str       = normalchar^1 / writer.string
+
+  local Ellipsis  = P("...") / writer.ellipsis
+
+  local Smart     = Ellipsis
+
+  local Symbol    = (specialchar - tightblocksep) / writer.string
+
+  local Code      = inticks / writer.code
+
+  local bqstart      = more
+  local headerstart  = hash
+                     + (line * (equal^1 + dash^1) * optionalspace * newline)
+
+  if options.blankBeforeBlockquote then
+    bqstart = fail
+  end
+
+  if options.blankBeforeHeading then
+    headerstart = fail
+  end
+
+  local Endline   = newline * -( -- newline, but not before...
+                        blankline -- paragraph break
+                      + tightblocksep  -- nested list
+                      + eof       -- end of document
+                      + bqstart
+                      + headerstart
+                    ) * spacechar^0 / writer.space
+
+%    \end{macrocode}
+% Make two and more trailing spaces before a newline produce a forced line
+% break, throw away one or more trailing spaces and an optional newline at the
+% end of a file, and reduce one or more spaces and an optional newline into a
+% single space.
+%  \begin{macrocode}
+  local Space     = spacechar^2 * Endline / writer.linebreak
+                  + spacechar^1 * Endline^-1 * eof / ""
+                  + spacechar^1 * Endline^-1 * optionalspace / writer.space
+
+  -- parse many p between starter and ender
+  local function between(p, starter, ender)
+      local ender2 = B(nonspacechar) * ender
+      return (starter * #nonspacechar * Ct(p * (p - ender2)^0) * ender2)
+  end
+
+  local Strong = ( between(Inline, doubleasterisks, doubleasterisks)
+                 + between(Inline, doubleunderscores, doubleunderscores)
+                 ) / writer.strong
+
+  local Emph   = ( between(Inline, asterisk, asterisk)
+                 + between(Inline, underscore, underscore)
+                 ) / writer.emphasis
+
+  local urlchar = anyescaped - newline - more
+
+  local AutoLinkUrl   = less
+                      * C(alphanumeric^1 * P("://") * urlchar^1)
+                      * more
+                      / function(url)
+                        return writer.link(writer.string(url), url)
+                      end
+
+  local AutoLinkEmail = less
+                      * C((alphanumeric + S("-._+"))^1 * P("@") * urlchar^1)
+                      * more
+                      / function(email)
+                        return writer.link(writer.string(email),
+                                           "mailto:"..email)
+                      end
+
+  local DirectLink    = (tag / parse_inlines_no_link)  -- no links inside links
+                      * spnl
+                      * lparent
+                      * (url + Cc(""))  -- link can be empty [foo]()
+                      * optionaltitle
+                      * rparent
+                      / writer.link
+
+  local IndirectLink = tag * (C(spnl) * tag)^-1 / indirect_link
+
+  -- parse a link or image (direct or indirect)
+  local Link          = DirectLink + IndirectLink
+
+  local DirectImage   = exclamation
+                      * (tag / parse_inlines)
+                      * spnl
+                      * lparent
+                      * (url + Cc(""))  -- link can be empty [foo]()
+                      * optionaltitle
+                      * rparent
+                      / writer.image
+
+  local IndirectImage  = exclamation * tag * (C(spnl) * tag)^-1 /
+                         indirect_image
+
+  local Image         = DirectImage + IndirectImage
+
+  -- avoid parsing long strings of * or _ as emph/strong
+  local UlOrStarLine  = asterisk^4 + underscore^4 / writer.string
+
+  local EscapedChar   = S("\\") * C(escapable) / writer.string
+%    \end{macrocode}
+% \paragraph{Block Element \acro{peg} Patterns}
+%  \begin{macrocode}
+  local Block          = V("Block")
+
+  local Verbatim       = Cs( (blanklines
+                           * ((indentedline - blankline))^1)^1
+                           ) / expandtabs / writer.verbatim
+
+  -- strip off leading > and indents, and run through blocks
+  local Blockquote     = Cs((
+            ((leader * more * space^-1)/"" * linechar^0 * newline)^1
+          * (-blankline * linechar^1 * newline)^0
+          * blankline^0
+          )^1) / parse_blocks / writer.blockquote
+
+  local function lineof(c)
+      return (leader * (P(c) * optionalspace)^3 * newline * blankline^1)
+  end
+
+  local HorizontalRule = ( lineof(asterisk)
+                         + lineof(dash)
+                         + lineof(underscore)
+                         ) / writer.hrule
+
+  local Reference      = define_reference_parser / register_link
+
+  local Paragraph      = nonindentspace * Ct(Inline^1) * newline
+                       * ( blankline^1
+                         + #hash
+                         + #(leader * more * space^-1)
+                         )
+                       / writer.paragraph
+
+  local Plain          = nonindentspace * Ct(Inline^1) / writer.plain
+%    \end{macrocode}
+% \paragraph{List \acro{peg} Patterns}
+%  \begin{macrocode}
+  local starter = bullet + enumerator
+
+  -- we use \001 as a separator between a tight list item and a
+  -- nested list under it.
+  local NestedList            = Cs((optionallyindentedline - starter)^1)
+                              / function(a) return "\001"..a end
+
+  local ListBlockLine         = optionallyindentedline
+                                - blankline - (indent^-1 * starter)
+
+  local ListBlock             = line * ListBlockLine^0
+
+  local ListContinuationBlock = blanklines * (indent / "") * ListBlock
+
+  local function TightListItem(starter)
+      return -HorizontalRule
+             * (Cs(starter / "" * ListBlock * NestedList^-1) /
+                parse_blocks)
+             * -(blanklines * indent)
+  end
+
+  local function LooseListItem(starter)
+      return -HorizontalRule
+             * Cs( starter / "" * ListBlock * Cc("\n")
+               * (NestedList + ListContinuationBlock^0)
+               * (blanklines / "\n\n")
+               ) / parse_blocks
+  end
+
+  local BulletList = ( Ct(TightListItem(bullet)^1)
+                       * Cc(true) * skipblanklines * -bullet
+                     + Ct(LooseListItem(bullet)^1)
+                       * Cc(false) * skipblanklines ) /
+                         writer.bulletlist
+
+  local function orderedlist(items,tight,startNumber)
+    if options.startNumber then
+      startNumber = tonumber(startNumber) or 1  -- fallback for '#'
+    else
+      startNumber = nil
+    end
+    return writer.orderedlist(items,tight,startNumber)
+  end
+
+  local OrderedList = Cg(enumerator, "listtype") *
+                      ( Ct(TightListItem(Cb("listtype")) *
+                           TightListItem(enumerator)^0)
+                        * Cc(true) * skipblanklines * -enumerator
+                      + Ct(LooseListItem(Cb("listtype")) *
+                           LooseListItem(enumerator)^0)
+                        * Cc(false) * skipblanklines
+                      ) * Cb("listtype") / orderedlist
+
+  local defstartchar = S("~:")
+  local defstart     = ( defstartchar * #spacing * (tab + space^-3)
+                     + space * defstartchar * #spacing * (tab + space^-2)
+                     + space * space * defstartchar * #spacing *
+                       (tab + space^-1)
+                     + space * space * space * defstartchar * #spacing
+                     )
+
+  local dlchunk = Cs(line * (indentedline - blankline)^0)
+
+  local function definition_list_item(term, defs, tight)
+    return { term = parse_inlines(term), definitions = defs }
+  end
+
+  local DefinitionListItemLoose = C(line) * skipblanklines
+                           * Ct((defstart *
+                                 indented_blocks(dlchunk) /
+                                 parse_blocks)^1)
+                           * Cc(false)
+                           / definition_list_item
+
+  local DefinitionListItemTight = C(line)
+                           * Ct((defstart * dlchunk /
+                                            parse_blocks)^1)
+                           * Cc(true)
+                           / definition_list_item
+
+  local DefinitionList =  ( Ct(DefinitionListItemLoose^1) * Cc(false)
+                          +  Ct(DefinitionListItemTight^1)
+                             * (skipblanklines *
+                                -DefinitionListItemLoose * Cc(true))
+                          ) / writer.definitionlist
+%    \end{macrocode}
+% \paragraph{Blank \acro{peg} Patterns}
+%  \begin{macrocode}
+  local Blank          = blankline / ""
+                       + NoteBlock
+                       + Reference
+                       + (tightblocksep / "\n")
+%    \end{macrocode}
+% \paragraph{Heading \acro{peg} Patterns}
+%  \begin{macrocode}
+  -- parse Atx heading start and return level
+  local HeadingStart = #hash * C(hash^-6) * -hash / length
+
+  -- parse setext header ending and return level
+  local HeadingLevel = equal^1 * Cc(1) + dash^1 * Cc(2)
+
+  local function strip_atx_end(s)
+    return s:gsub("[#%s]*\n$","")
+  end
+
+  -- parse atx header
+  local AtxHeading = Cg(HeadingStart,"level")
+                     * optionalspace
+                     * (C(line) / strip_atx_end / parse_inlines)
+                     * Cb("level")
+                     / writer.heading
+
+  -- parse setext header
+  local SetextHeading = #(line * S("=-"))
+                     * Ct(line / parse_inlines)
+                     * HeadingLevel
+                     * optionalspace * newline
+                     / writer.heading
+%    \end{macrocode}
+% \paragraph{Top Level \acro{peg} Specification}
+%  \begin{macrocode}
+  syntax =
+    { "Blocks",
+
+      Blocks                = Blank^0 *
+                              Block^-1 *
+                              (Blank^0 / function()
+                                return writer.interblocksep
+                               end * Block)^0 *
+                              Blank^0 *
+                              eof,
+
+      Blank                 = Blank,
+
+      Block                 = V("Blockquote")
+                            + V("Verbatim")
+                            + V("HorizontalRule")
+                            + V("BulletList")
+                            + V("OrderedList")
+                            + V("Heading")
+                            + V("DefinitionList")
+                            + V("Paragraph")
+                            + V("Plain"),
+
+      Blockquote            = Blockquote,
+      Verbatim              = Verbatim,
+      HorizontalRule        = HorizontalRule,
+      BulletList            = BulletList,
+      OrderedList           = OrderedList,
+      Heading               = AtxHeading + SetextHeading,
+      DefinitionList        = DefinitionList,
+      DisplayHtml           = DisplayHtml,
+      Paragraph             = Paragraph,
+      Plain                 = Plain,
+
+      Inline                = V("Str")
+                            + V("Space")
+                            + V("Endline")
+                            + V("UlOrStarLine")
+                            + V("Strong")
+                            + V("Emph")
+                            + V("NoteRef")
+                            + V("Link")
+                            + V("Image")
+                            + V("Code")
+                            + V("AutoLinkUrl")
+                            + V("AutoLinkEmail")
+                            + V("EscapedChar")
+                            + V("Smart")
+                            + V("Symbol"),
+
+      Str                   = Str,
+      Space                 = Space,
+      Endline               = Endline,
+      UlOrStarLine          = UlOrStarLine,
+      Strong                = Strong,
+      Emph                  = Emph,
+      NoteRef               = NoteRef,
+      Link                  = Link,
+      Image                 = Image,
+      Code                  = Code,
+      AutoLinkUrl           = AutoLinkUrl,
+      AutoLinkEmail         = AutoLinkEmail,
+      InlineHtml            = InlineHtml,
+      HtmlEntity            = HtmlEntity,
+      EscapedChar           = EscapedChar,
+      Smart                 = Smart,
+      Symbol                = Symbol,
+    }
+
+  if not options.definitionLists then
+    syntax.DefinitionList = fail
+  end
+
+  if not options.footnotes then
+    syntax.NoteRef = fail
+  end
+
+  if not options.smartEllipses then
+    syntax.Smart = fail
+  end
+
+  blocks = Ct(syntax)
+
+  local inlines_t = util.table_copy(syntax)
+  inlines_t[1] = "Inlines"
+  inlines_t.Inlines = Inline^0 * (spacing^0 * eof / "")
+  inlines = Ct(inlines_t)
+
+  inlines_no_link_t = util.table_copy(inlines_t)
+  inlines_no_link_t.Link = fail
+  inlines_no_link = Ct(inlines_no_link_t)
+%    \end{macrocode}
+%
+% \paragraph{Exported Conversion Function}
+% Define \luamdef{reader->convert} as a function that converts markdown string
+% \t`input` into a plain \TeX{} output and returns it. Note that the converter
+% assumes that the input has \acro{unix} line endings.
+%  \begin{macrocode}
+  function self.convert(input)
+    references = {}
+%    \end{macrocode}
+% When determining the name of the cache file, create salt for the hashing
+% function out of the passed options recognized by the Lua interface (see
+% Section \ref{sec:luaoptions}). The \Opt{cacheDir} option is disregarded.
+%  \begin{macrocode}
+    local opt_string = {}
+    for k,_ in pairs(defaultOptions) do
+      local v = options[k]
+      if k ~= "cacheDir" then
+        opt_string[#opt_string+1] = k .. "=" .. tostring(v)
+      end
+    end
+    table.sort(opt_string)
+    local salt = table.concat(opt_string, ",")
+%    \end{macrocode}
+% Produce the cache file, transform its filename via the \luam{writer->pack}
+% method, and return the result.
+%  \begin{macrocode}
+    local name = util.cache(options.cacheDir, input, salt, function(input)
+        return util.rope_to_string(parse_blocks(input)) .. writer.eof
+      end, ".md" .. writer.suffix)
+    return writer.pack(name)
+  end
+  return self
+end
+%    \end{macrocode}
+% \subsubsection{Conversion from Markdown to Plain \TeX{}}
+% The \luam{new} method returns the \luam{reader->convert} function of a reader
+% object associated with the Lua interface options (see Section
+% \ref{sec:luaoptions}) \t`options` and with a writer object associated with
+% \t`options`.
+%  \begin{macrocode}
+function M.new(options)
+  local writer = M.writer.new(options)
+  local reader = M.reader.new(writer, options)
+  return reader.convert
+end
+
+return M
+%    \end{macrocode}
+%
+% \iffalse
+%</lua>
+%<*tex>
+% \fi\subsection{Plain \TeX{} Implementation}\label{sec:teximplementation}
+% The plain \TeX{} implementation provides macros for the interfacing between
+% \TeX{} and Lua and for the buffering of input text. These macros are then
+% used to implement the macros for the conversion from markdown to plain \TeX{}
+% exposed by the plain \TeX{} interface (see Section \ref{sec:texinterface}).
+%
+% \subsubsection{Logging Facilities}\label{sec:texinterfacelogging}
+%  \begin{macrocode}
+\def\markdownInfo#1{%
+  \message{(l.\the\inputlineno) markdown.tex info: #1.}}%
+\def\markdownWarning#1{%
+  \message{(l.\the\inputlineno) markdown.tex warning: #1}}%
+\def\markdownError#1#2{%
+  \errhelp{#2.}%
+  \errmessage{(l.\the\inputlineno) markdown.tex error: #1}}%
+%    \end{macrocode}
+%
+% \subsubsection{Options}
+% The following definitions should be considered placeholder.
+%  \begin{macrocode}
+\def\markdownRendererLineBreakPrototype{\hfil\break}%
+\let\markdownRendererEllipsisPrototype\dots
+\long\def\markdownRendererCodeSpanPrototype#1{{\tt#1}}%
+\long\def\markdownRendererLinkPrototype#1#2#3{#1}%
+\long\def\markdownRendererImagePrototype#1#2#3{#1}%
+\def\markdownRendererUlBeginPrototype{}%
+\def\markdownRendererUlBeginTightPrototype{}%
+\def\markdownRendererUlItemPrototype{}%
+\def\markdownRendererUlEndPrototype{}%
+\def\markdownRendererUlEndTightPrototype{}%
+\def\markdownRendererOlBeginPrototype{}%
+\def\markdownRendererOlBeginTightPrototype{}%
+\def\markdownRendererOlItemPrototype{}%
+\long\def\markdownRendererOlItemWithNumberPrototype#1{}%
+\def\markdownRendererOlEndPrototype{}%
+\def\markdownRendererOlEndTightPrototype{}%
+\def\markdownRendererDlBeginPrototype{}%
+\def\markdownRendererDlBeginTightPrototype{}%
+\long\def\markdownRendererDlItemPrototype#1{#1}%
+\def\markdownRendererDlEndPrototype{}%
+\def\markdownRendererDlEndTightPrototype{}%
+\long\def\markdownRendererEmphasisPrototype#1{{\it#1}}%
+\long\def\markdownRendererStrongEmphasisPrototype#1{{\it#1}}%
+\def\markdownRendererBlockQuoteBeginPrototype{\par\begingroup\it}%
+\def\markdownRendererBlockQuoteEndPrototype{\endgroup\par}%
+\long\def\markdownRendererInputVerbatimPrototype#1{%
+  \par{\tt\input"#1"\relax}\par}%
+\long\def\markdownRendererHeadingOnePrototype#1{#1}%
+\long\def\markdownRendererHeadingTwoPrototype#1{#1}%
+\long\def\markdownRendererHeadingThreePrototype#1{#1}%
+\long\def\markdownRendererHeadingFourPrototype#1{#1}%
+\long\def\markdownRendererHeadingFivePrototype#1{#1}%
+\long\def\markdownRendererHeadingSixPrototype#1{#1}%
+\def\markdownRendererHorizontalRulePrototype{}%
+\long\def\markdownRendererFootnotePrototype#1{#1}%
+%    \end{macrocode}
+%
+% \subsubsection{Lua Snippets}
+% The \mdef{markdownLuaOptions} macro expands to a Lua table that
+% contains the plain \TeX{} options (see Section \ref{sec:texoptions}) in a
+% format recognized by Lua (see Section \ref{sec:luaoptions}). Note that the
+% boolean options are not sanitized and expect the plain \TeX{} option macros
+% to expand to either \t`true` or \t`false`.
+%  \begin{macrocode}
+\def\markdownLuaOptions{{%
+  \ifx\markdownOptionBlankBeforeBlockquote\undefined\else
+    blankBeforeBlockquote = \markdownOptionBlankBeforeBlockquote,
+  \fi
+  \ifx\markdownOptionBlankBeforeHeading\undefined\else
+    blankBeforeHeading = \markdownOptionBlankBeforeHeading,
+  \fi
+  \ifx\markdownOptionCacheDir\undefined\else
+    cacheDir = "\markdownOptionCacheDir",
+  \fi
+  \ifx\markdownOptionDefinitionLists\undefined\else
+    definitionLists = \markdownOptionDefinitionLists,
+  \fi
+  \ifx\markdownOptionHashEnumerators\undefined\else
+    hashEnumerators = \markdownOptionHashEnumerators,
+  \fi
+  \ifx\markdownOptionHybrid\undefined\else
+    hybrid = \markdownOptionHybrid,
+  \fi
+  \ifx\markdownOptionFootnotes\undefined\else
+    footnotes = \markdownOptionFootnotes,
+  \fi
+  \ifx\markdownOptionPreserveTabs\undefined\else
+    preserveTabs = \markdownOptionPreserveTabs,
+  \fi
+  \ifx\markdownOptionSmartEllipses\undefined\else
+    smartEllipses = \markdownOptionSmartEllipses,
+  \fi
+  \ifx\markdownOptionStartNumber\undefined\else
+    startNumber = \markdownOptionStartNumber,
+  \fi
+  \ifx\markdownOptionTightLists\undefined\else
+    tightLists = \markdownOptionTightLists,
+  \fi}
+}%
+%    \end{macrocode}
+%
+% The \mdef{markdownPrepare} macro contains the Lua code that is executed prior
+% to any conversion from markdown to plain \TeX{}. It exposes the
+% \luam{convert} function for the use by any further Lua code.
+%  \begin{macrocode}
+\def\markdownPrepare{%
+%    \end{macrocode}
+% First, ensure that the \m{markdownOptionCacheDir} directory exists.
+%  \begin{macrocode}
+  local lfs = require("lfs")
+  local cacheDir = "\markdownOptionCacheDir"
+  if lfs.isdir(cacheDir) == true then else
+    assert(lfs.mkdir(cacheDir))
+  end
+%    \end{macrocode}
+% Next, load the \t`markdown` module and create a converter function using
+% the plain \TeX{} options, which were serialized to a Lua table via the
+% \m{markdownLuaOptions} macro.
+%  \begin{macrocode}
+  local md = require("markdown")
+  local convert = md.new(\markdownLuaOptions)
+}%
+%    \end{macrocode}
+%
+% \subsubsection{Lua \t`\textbackslash write18` Bridge}\label{sec:luabridge}
+% The following \TeX{} code is intended for \TeX{} engines that do not provide
+% direct access to Lua, but expose the shell of the operating system through
+% the output file stream 18 (\Hologo{XeTeX}, \hologo{pdfLaTeX}).
+% The \m{markdownLuaExecute} and \m{markdownReadAndConvert} macros defined here
+% and in Section \ref{sec:directlua} are meant to be transparent to the
+% remaining code.
+%
+% The package assumes that although the user is not using the Lua\TeX{} engine,
+% their TeX distribution contains it, and uses shell access to produce and
+% execute Lua scripts using the \TeX{}Lua interpreter (see
+% \cite[Section~3.1.1]{luatex16}).
+%  \begin{macrocode}
+\ifx\directlua\undefined
+%    \end{macrocode}
+%
+% The macro \mdef{markdownLuaExecuteFileStream} contains the number of the output
+% file stream that will be used to store the helper Lua script in the file named
+% \m{markdownOptionHelperScriptFileName} during the expansion of the macro
+% \m{markdownLuaExecute}, and to store the markdown input in the file
+% named \m{markdownOptionInputTempFileName} during the expansion of the macro
+% \m{markdownReadAndConvert}.
+%  \begin{macrocode}
+  \csname newwrite\endcsname\markdownLuaExecuteFileStream
+%    \end{macrocode}
+%
+% The \mdef{markdownLuaExecuteShellEscape} macro contains the numeric value of
+% either the \m{pdfshellescape} (Lua\TeX{}, \Hologo{pdfTeX}) or the
+% \m{shellescape} (\Hologo{XeTeX}) commands. This value indicates, whether the
+% shell access is enabled (\t`1`), disabled (\t`0`), or restricted (\t`2`).  If
+% neither of these commands is defined, act as if the shell access were enabled.
+%  \begin{macrocode}
+  \csname newcount\endcsname\markdownLuaExecuteShellEscape
+  \ifx\pdfshellescape\undefined
+    \ifx\shellescape\undefined
+      \markdownLuaExecuteShellEscape=1%
+    \else
+      \markdownLuaExecuteShellEscape=\shellescape
+    \fi
+  \else
+    \markdownLuaExecuteShellEscape=\pdfshellescape
+  \fi
+%    \end{macrocode}
+%
+% The \mdef{markdownLuaExecute} macro executes the Lua code it has received as
+% its first argument. The Lua code may not directly interact with the \TeX{}
+% engine, but it can use the \luam{print} function in the same manner it
+% would use the \luam{tex.print} method.
+%  \begin{macrocode}
+  \def\markdownLuaExecute#1{%
+%    \end{macrocode}
+% If the shell is accessible, create the file
+% \m{markdownOptionHelperScriptFileName} and fill it with the input Lua code
+% prepended with \pkg{kpathsea} initialization, so that Lua modules from the
+% \TeX{} distribution are available.
+%  \begin{macrocode}
+    \ifnum\markdownLuaExecuteShellEscape=1%
+      \immediate\openout\markdownLuaExecuteFileStream=%
+        \markdownOptionHelperScriptFileName
+      \markdownInfo{Writing a helper Lua script to the file
+        "\markdownOptionHelperScriptFileName"}%
+      \immediate\write\markdownLuaExecuteFileStream{%
+        local kpse = require('kpse')
+        kpse.set_program_name('luatex') #1}%
+      \immediate\closeout\markdownLuaExecuteFileStream
+%    \end{macrocode}
+% Execute the generated \m{markdownOptionHelperScriptFileName} Lua script using
+% the \TeX{}Lua binary and store the output in the
+% \m{markdownOptionOutputTempFileName} file.
+%  \begin{macrocode}
+      \markdownInfo{Executing a helper Lua script from the file
+        "\markdownOptionHelperScriptFileName" and storing the result in the
+        file "\markdownOptionOutputTempFileName"}%
+      \immediate\write18{texlua "\markdownOptionHelperScriptFileName" >
+        "\markdownOptionOutputTempFileName"}%
+%    \end{macrocode}
+% \m{input} the generated \m{markdownOptionOutputTempFileName} file.
+%  \begin{macrocode}
+      \input\markdownOptionOutputTempFileName\relax
+    \else
+%    \end{macrocode}
+% If the shell is inaccessible, let the user know and suggest a remedy.
+%  \begin{macrocode}
+      \markdownError{I can not access the shell}{Either run the TeX
+        compiler with the --shell-escape or the --enable-write18 flag,
+        or set shell_escape=t in the texmf.cnf file}%
+    \fi}%
+%    \end{macrocode}
+%
+% The \mdef{markdownReadAndConvertTab} macro contains the tab character literal.
+%  \begin{macrocode}
+  \begingroup
+    \catcode`\^^I=12%
+    \gdef\markdownReadAndConvertTab{^^I}%
+  \endgroup
+%    \end{macrocode}
+%
+% The \m{markdownReadAndConvert} macro is largely a rewrite of the
+% \Hologo{LaTeX2e} \m{filecontents} macro to plain \TeX{}.
+%  \begin{macrocode}
+  \begingroup
+%    \end{macrocode}
+% Make the newline and tab characters active and swap the character codes of the
+% backslash symbol (\t`\textbackslash`) and the pipe symbol (\t`|`), so that
+% we can use the backslash as an ordinary character inside the macro definition.
+%  \begin{macrocode}
+    \catcode`\^^M=13%
+    \catcode`\^^I=13%
+    \catcode`|=0%
+    \catcode`\\=12%
+    |gdef|markdownReadAndConvert#1#2{%
+      |begingroup%
+%    \end{macrocode}
+% Open the \m{markdownOptionInputTempFileName} file for writing.
+%  \begin{macrocode}
+      |immediate|openout|markdownLuaExecuteFileStream%
+        |markdownOptionInputTempFileName%
+      |markdownInfo{Buffering markdown input into the temporary %
+        input file "|markdownOptionInputTempFileName" and scanning %
+        for the closing token sequence "#1"}%
+%    \end{macrocode}
+% Locally change the category of the special plain \TeX{} characters to
+% \emph{other} in order to prevent unwanted interpretation of the input.
+% Change also the category of the space and tab characters, so that we
+% can retrieve them unaltered.
+%  \begin{macrocode}
+      |def|do##1{|catcode`##1=12}|dospecials%
+      |catcode`| =12%
+      |markdownMakeOther%
+%    \end{macrocode}
+% The \mdef{markdownReadAndConvertProcessLine} macro will process the individual
+% lines of output. Note the use of the comments to ensure that the entire macro
+% is at a single line and therefore no (active) newline symbols are produced.
+%  \begin{macrocode}
+      |def|markdownReadAndConvertProcessLine##1#1##2#1##3|relax{%
+%    \end{macrocode}
+% When the ending token sequence does not appear in the line, store the line in
+% the \m{markdownOptionInputTempFileName} file.
+%  \begin{macrocode}
+        |ifx|relax##3|relax%
+          |immediate|write|markdownLuaExecuteFileStream{##1}%
+        |else%
+%    \end{macrocode}
+% When the ending token sequence appears in the line, make the next newline
+% character close the \m{markdownOptionInputTempFileName} file, return the
+% character categories back to the former state, convert the
+% \m{markdownOptionInputTempFileName} file from markdown to plain \TeX{},
+% \m{input} the result of the conversion, and expand the ending control
+% sequence.
+%  \begin{macrocode}
+          |def^^M{%
+            |markdownInfo{The ending token sequence was found}%
+            |immediate|write|markdownLuaExecuteFileStream{}%
+            |immediate|closeout|markdownLuaExecuteFileStream%
+            |endgroup%
+            |markdownInput|markdownOptionInputTempFileName%
+            #2}%
+        |fi%
+%    \end{macrocode}
+% Repeat with the next line.
+%  \begin{macrocode}
+        ^^M}%
+%    \end{macrocode}
+% Make the tab character active at expansion time and make it expand to a
+% literal tab character.
+%  \begin{macrocode}
+      |catcode`|^^I=13%
+      |def^^I{|markdownReadAndConvertTab}%
+%    \end{macrocode}
+% Make the newline character active at expansion time and make it consume the
+% rest of the line on expansion. Throw away the rest of the first line and
+% pass the second line to the \m{markdownReadAndConvertProcessLine} macro.
+%  \begin{macrocode}
+      |catcode`|^^M=13%
+      |def^^M##1^^M{%
+        |def^^M####1^^M{%
+          |markdownReadAndConvertProcessLine####1#1#1|relax}%
+        ^^M}%
+      ^^M}%
+%    \end{macrocode}
+% Reset the character categories back to the former state.
+%  \begin{macrocode}
+  |endgroup
+%    \end{macrocode}
+%
+% \subsubsection{Direct Lua Access}\label{sec:directlua}
+% The following \TeX{} code is intended for \TeX{} engines that provide
+% direct access to Lua (Lua\TeX{}). The \m{markdownLuaExecute} and
+% \m{markdownReadAndConvert} defined here and in Section \ref{sec:luabridge}
+% are meant to be transparent to the remaining code.
+%  \begin{macrocode}
+\else
+%    \end{macrocode}
+% The direct Lua access version of the \m{markdownLuaExecute} macro is defined
+% in terms of the \m{directlua} primitive. The \luam{print} function is set as
+% an alias to the \m{tex.print} method in order to mimic the behaviour of the
+% \m{markdownLuaExecute} definition from Section \ref{sec:luabridge},
+%  \begin{macrocode}
+  \def\markdownLuaExecute#1{\directlua{local print = tex.print #1}}%
+%    \end{macrocode}
+%
+% In the definition of the direct Lua access version of the
+% \m{markdownReadAndConvert} macro, we will be using the hash symbol
+% (\t`\#`), the underscore symbol (\t`_`), the caret symbol (\t`\^`), the
+% dollar sign (\t`\$`), the backslash symbol (\t`\textbackslash`), the percent
+% sign (\t`\%`), and the braces (\t`\{\}`) as a part of the Lua syntax.
+%  \begin{macrocode}
+  \begingroup
+%    \end{macrocode}
+%
+% To this end, we will make the underscore symbol, the dollar sign, and caret
+% symbols ordinary characters,
+%  \begin{macrocode}
+    \catcode`\_=12%
+    \catcode`\$=12%
+    \catcode`\^=12%
+%    \end{macrocode}
+% swap the category code of the hash symbol with the slash symbol (\t`/`).
+%  \begin{macrocode}
+    \catcode`\/=6%
+    \catcode`\#=12%
+%    \end{macrocode}
+% swap the category code of the percent sign with the at symbol (\t`@`).
+%  \begin{macrocode}
+    \catcode`\@=14%
+    \catcode`\%=12%
+%    \end{macrocode}
+% swap the category code of the backslash symbol with the pipe symbol (\t`|`),
+%  \begin{macrocode}
+    \catcode`|=0@
+    \catcode`\\=12@
+%    \end{macrocode}
+% Braces are a part of the plain \TeX{} syntax, but they are not removed during
+% expansion, so we do not need to bother with changing their category codes.
+%  \begin{macrocode}
+    |gdef|markdownReadAndConvert/1/2{@
+%    \end{macrocode}
+% Make the \mdef{markdownReadAndConvertAfter} macro store the token sequence
+% that will be inserted into the document after the ending token sequence has
+% been found.
+%  \begin{macrocode}
+      |def|markdownReadAndConvertAfter{/2}@
+      |markdownInfo{Buffering markdown input and scanning for the
+        closing token sequence "/1"}@
+      |directlua{@
+%    \end{macrocode}
+% Set up an empty Lua table that will serve as our buffer.
+%  \begin{macrocode}
+        |markdownPrepare
+        local buffer = {}
+%    \end{macrocode}
+% Create a regex that will match the ending input sequence. Escape any special
+% regex characters (like a star inside \t`\textbackslash end\{markdown*\}`)
+% inside the input.
+%  \begin{macrocode}
+        local ending_sequence = "^.-" .. ([[/1]]):gsub(
+          "([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1")
+%    \end{macrocode}
+% Register a callback that will notify you about new lines of input.
+%  \begin{macrocode}
+        |markdownLuaRegisterIBCallback{function(line)
+%    \end{macrocode}
+% When the ending token sequence appears on a line, unregister the callback,
+% convert the contents of our buffer from markdown to plain \TeX{}, and insert
+% the result into the input line buffer of \TeX{}.
+%  \begin{macrocode}
+          if line:match(ending_sequence) then
+            |markdownLuaUnregisterIBCallback
+            local input = table.concat(buffer, "\n") .. "\n\n"
+            local output = convert(input)
+            return [[\markdownInfo{The ending token sequence was found}]] ..
+              output .. [[\markdownReadAndConvertAfter]]
+%    \end{macrocode}
+% When the ending token sequence does not appear on a line, store the line in
+% our buffer, and insert either \m{fi}, if this is the first line of input,
+% or an empty token list to the input line buffer of \TeX{}.
+%  \begin{macrocode}
+          else
+            buffer[#buffer+1] = line
+            return [[\]] .. (#buffer == 1 and "fi" or "relax")
+          end
+        end}}@
+%    \end{macrocode}
+% Insert \m{iffalse} after the \m{markdownReadAndConvert} macro in order to
+% consume the rest of the first line of input.
+%  \begin{macrocode}
+      |iffalse}@
+%    \end{macrocode}
+% Reset the character categories back to the former state.
+%  \begin{macrocode}
+  |endgroup
+\fi
+%    \end{macrocode}
+%
+% \subsubsection{Typesetting Markdown}
+% The \m{markdownInput} macro uses an implementation of the
+% \m{markdownLuaExecute} macro to convert the contents of the file whose
+% filename it has received as its single argument from markdown to plain
+% \TeX{}.
+%  \begin{macrocode}
+\begingroup
+%    \end{macrocode}
+% Swap the category code of the backslash symbol and the pipe symbol, so that
+% we may use the backslash symbol freely inside the Lua code.
+%  \begin{macrocode}
+  \catcode`|=0%
+  \catcode`\\=12%
+  |gdef|markdownInput#1{%
+    |markdownInfo{Including markdown document "#1"}%
+    |markdownLuaExecute{%
+      |markdownPrepare
+      local input = assert(io.open("#1","r")):read("*a") .. "\n\n"
+%    \end{macrocode}
+% Since the Lua converter expects \acro{unix} line endings, normalize the
+% input.
+%  \begin{macrocode}
+      print(convert(input:gsub("\r\n?", "\n")))}}%
+|endgroup
+%    \end{macrocode}
+%
+% \iffalse
+%</tex>
+%<*latex>
+% \fi\subsection{\LaTeX{} Implementation}\label{sec:lateximplementation}
+% The \LaTeX{} implemenation makes use of the fact that, apart from some subtle
+% differences, \LaTeX{} implements the majority of the plain \TeX{} format
+% (see \cite[Section~9]{latex16}). As a consequence, we can directly reuse the
+% existing plain \TeX{} implementation.
+%  \begin{macrocode}
+\input markdown
+\ProvidesPackage{markdown}[\markdownVersion]%
+%    \end{macrocode}
+%
+% \subsubsection{Logging Facilities}
+% The \LaTeX{} implementation redefines the plain \TeX{} logging macros (see
+% Section \ref{sec:texinterfacelogging}) to use the \LaTeX{} \m{PackageInfo},
+% \m{PackageWarning}, and \m{PackageError} macros.
+%  \begin{macrocode}
+\renewcommand\markdownInfo[1]{\PackageInfo{markdown}{#1}}%
+\renewcommand\markdownWarning[1]{\PackageWarning{markdown}{#1}}%
+\renewcommand\markdownError[2]{\PackageError{markdown}{#1}{#2.}}%
+%    \end{macrocode}
+%
+% \subsubsection{Typesetting Markdown}
+% The \mdef{markdownInputPlainTeX} macro is used to store the original plain
+% \TeX{} implementation of the \m{markdownInput} macro. The \m{markdownInput}
+% is then redefined to accept an optional argument with options recognized by
+% the \LaTeX{} interface (see Section \ref{sec:latexoptions}).
+%  \begin{macrocode}
+\let\markdownInputPlainTeX\markdownInput
+\renewcommand\markdownInput[2][]{%
+  \begingroup
+    \markdownSetup{#1}%
+    \markdownInputPlainTeX{#2}%
+  \endgroup}%
+%    \end{macrocode}
+%
+% The \env{markdown}, and \env{markdown*} \LaTeX{} environments are implemented
+% using the \m{markdownReadAndConvert} macro.
+%  \begin{macrocode}
+\renewenvironment{markdown}{%
+  \markdownReadAndConvert at markdown{}}\relax
+\renewenvironment{markdown*}[1]{%
+  \markdownSetup{#1}%
+  \markdownReadAndConvert at markdown*}\relax
+\begingroup
+%    \end{macrocode}
+% Locally swap the category code of the backslash symbol with the pipe symbol,
+% and of the left (\t`\{`) and right brace (\t`\}`) with the less-than (\t`<`)
+% and greater-than (\t`>`) signs. This is required in order that all the
+% special symbols that appear in the first argument of the
+% \t`markdownReadAndConvert` macro have the category code \emph{other}.
+%  \begin{macrocode}
+  \catcode`\|=0\catcode`\<=1\catcode`\>=2%
+  \catcode`\\=12|catcode`|{=12|catcode`|}=12%
+  |gdef|markdownReadAndConvert at markdown#1<%
+    |markdownReadAndConvert<\end{markdown#1}>%
+                           <|end<markdown#1>>>%
+|endgroup
+%    \end{macrocode}
+%
+% \subsubsection{Options}
+% The supplied package options are processed using the \m{markdownSetup} macro.
+%  \begin{macrocode}
+\DeclareOption*{%
+  \expandafter\markdownSetup\expandafter{\CurrentOption}}%
+\ProcessOptions\relax
+%    \end{macrocode}
+%
+% The following configuration should be considered placeholder.
+%  \begin{macrocode}
+\RequirePackage{url}
+\RequirePackage{graphicx}
+%    \end{macrocode}
+% If the \m{markdownOptionTightLists} macro expands to \t`false`, do not load
+% the \pkg{paralist} package.
+%  \begin{macrocode}
+\RequirePackage{ifthen}
+\ifx\markdownOptionTightLists\undefined
+  \RequirePackage{paralist}
+\else
+  \ifthenelse{\equal{\markdownOptionTightLists}{false}}{}{
+    \RequirePackage{paralist}}
+\fi
+\RequirePackage{fancyvrb}
+\markdownSetup{rendererPrototypes={
+  lineBreak = {\\},
+  codeSpan = {\texttt{#1}},
+  link = {#1\footnote{\ifx\empty#3\empty\else#3:
+    \fi\texttt<\url{#2}\texttt>}},
+  image = {\begin{figure}
+      \begin{center}%
+        \includegraphics{#2}%
+      \end{center}%
+      \ifx\empty#3\empty\else
+        \caption{#3}%
+      \fi
+      \label{fig:#1}%
+    \end{figure}},
+  ulBegin = {\begin{itemize}},
+  ulBeginTight = {\begin{compactitem}},
+  ulItem = {\item},
+  ulEnd = {\end{itemize}},
+  ulEndTight = {\end{compactitem}},
+  olBegin = {\begin{enumerate}},
+  olBeginTight = {\begin{compactenum}},
+  olItem = {\item},
+  olItemWithNumber = {\item[#1.]},
+  olEnd = {\end{enumerate}},
+  olEndTight = {\end{compactenum}},
+  dlBegin = {\begin{description}},
+  dlBeginTight = {\begin{compactdesc}},
+  dlItem = {\item[#1]},
+  dlEnd = {\end{description}},
+  dlEndTight = {\end{compactdesc}},
+  emphasis = {\emph{#1}},
+  strongEmphasis = {%
+    \ifx\alert\undefined
+      \textbf{\emph{#1}}%
+    \else % Beamer support
+      \alert{\emph{#1}}
+    \fi},
+  blockQuoteBegin = {\begin{quotation}},
+  blockQuoteEnd = {\end{quotation}},
+  inputVerbatim = {\VerbatimInput{#1}},
+  horizontalRule = {\noindent\rule[0.5ex]{\linewidth}{1pt}},
+  footnote = {\footnote{#1}}}}%
+
+\ifx\chapter\undefined
+  \markdownSetup{rendererPrototypes={
+    headingOne = {\section{#1}},
+    headingTwo = {\subsection{#1}},
+    headingThree = {\subsubsection{#1}},
+    headingFour = {\paragraph{#1}},
+    headingFive = {\subparagraph{#1}}}}%
+\else
+  \markdownSetup{rendererPrototypes={
+    headingOne = {\chapter{#1}},
+    headingTwo = {\section{#1}},
+    headingThree = {\subsection{#1}},
+    headingFour = {\subsubsection{#1}},
+    headingFive = {\paragraph{#1}},
+    headingSix = {\subparagraph{#1}}}}%
+\fi
+%    \end{macrocode}
+%
+% \subsubsection{Miscellanea}
+% Unlike base Lua\TeX{}, which only allows for a single registered function per
+% a callback (see \cite[Section~8.1]{luatex16}), the \Hologo{LaTeX2e} format
+% disables the \luam{callback.register} method and exposes the
+% \luam{luatexbase.add_to_callback} and \luam{luatexbase.remove_from_callback}
+% methods that enable the user code to hook several functions on a single
+% callback (see \cite[Section~73.4]{latex16}).
+%
+% To make our code function with the \Hologo{LaTeX2e} format, we need to
+% redefine the \m{markdownLuaRegisterIBCallback} and
+% \m{markdownLuaUnregisterIBCallback} macros accordingly.
+%  \begin{macrocode}
+\renewcommand\markdownLuaRegisterIBCallback[1]{%
+  luatexbase.add_to_callback("process_input_buffer", #1, %
+    "The markdown input processor")}
+\renewcommand\markdownLuaUnregisterIBCallback{%
+  luatexbase.remove_from_callback("process_input_buffer",%
+    "The markdown input processor")}
+%    \end{macrocode}
+%
+% When buffering user input, we should disable the bytes with the high bit set,
+% since these are made active by the \pkg{inputenc} package. We will do this by
+% redefining the \m{markdownMakeOther} macro accordingly. The code is courtesy
+% of Scott Pakin, the creator of the \pkg{filecontents} package.
+%  \begin{macrocode}
+\newcommand\markdownMakeOther{%
+  \count0=128\relax
+  \loop
+    \catcode\count0=11\relax
+    \advance\count0 by 1\relax
+  \ifnum\count0<256\repeat}%
+%    \end{macrocode}
+%
+% \iffalse
+%</latex>
+%<*context>
+% \fi\subsection{\Hologo{ConTeXt} Implementation}
+% \label{sec:contextimplementation}
+% The \Hologo{ConTeXt} implementation makes use of the fact that, apart from
+% some subtle differences, the Mark II and Mark IV \Hologo{ConTeXt} formats
+% \emph{seem} to implement (the documentation is scarce) the majority of the
+% plain \TeX{} format required by the plain \TeX{} implementation.  As a
+% consequence, we can directly reuse the existing plain \TeX{} implementation
+% after supplying the missing plain \TeX{} macros.
+%  \begin{macrocode}
+\def\dospecials{\do\ \do\\\do\{\do\}\do\$\do\&%
+  \do\#\do\^\do\_\do\%\do\~}%
+%    \end{macrocode}
+% When there is no Lua support, then just load the plain \TeX{} implementation.
+%  \begin{macrocode}
+\ifx\directlua\undefined
+  \input markdown
+\else
+%    \end{macrocode}
+% When there is Lua support, check if we can set the \t`process_input_buffer`
+% Lua\TeX{} callback.
+%  \begin{macrocode}
+  \directlua{%
+    local function unescape(str)
+      return (str:gsub("|", string.char(92))) end
+    local old_callback = callback.find("process_input_buffer")
+    callback.register("process_input_buffer", function() end)
+    local new_callback = callback.find("process_input_buffer")
+%    \end{macrocode}
+%
+% If we can not, we are probably using ConTeXt Mark IV. In ConTeXt Mark IV, the
+% \t`process_input_buffer` callback is currently frozen (inaccessible from the
+% user code) and, due to the lack of available documentation, it is unclear to
+% me how to emulate it. Therefore, we will just force the plain \TeX{}
+% implementation to use the \m{write18} bridge (see Section
+% \ref{sec:luabridge}) by locally undefining the \m{directlua} primitive.
+%  \begin{macrocode}
+    if new_callback == false then
+      tex.print(unescape([[|let|markdownDirectLua|directlua
+                           |let|directlua|undefined
+                           |input markdown
+                           |let|directlua|markdownDirectLua
+                           |let|markdownDirectLua|undefined]]))
+%    \end{macrocode}
+%
+% If we can, then just load the plain \TeX{} implementation.
+%  \begin{macrocode}
+    else
+      callback.register("process_input_buffer", old_callback)
+      tex.print(unescape("|input markdown"))
+    end}%
+\fi
+%    \end{macrocode}
+%
+% \subsubsection{Logging Facilities}
+% The \Hologo{ConTeXt} implementation redefines the plain \TeX{} logging macros (see
+% Section \ref{sec:texinterfacelogging}) to use the \Hologo{ConTeXt}
+% \m{writestatus} macro.
+%  \begin{macrocode}
+\def\markdownInfo#1{\writestatus{markdown}{#1.}}%
+\def\markdownWarning#1{\writestatus{markdown\space warn}{#1.}}%
+%    \end{macrocode}
+%
+% \subsubsection{Typesetting Markdown}
+% The \m{startmarkdown} and \m{stopmarkdown} macros are implemented using the
+% \m{markdownReadAndConvert} macro.
+%  \begin{macrocode}
+\begingroup
+%    \end{macrocode}
+% Locally swap the category code of the backslash symbol with the pipe symbol.
+% This is required in order that all the special symbols that appear in the
+% first argument of the \t`markdownReadAndConvert` macro have the category code
+% \emph{other}.
+%  \begin{macrocode}
+  \catcode`\|=0%
+  \catcode`\\=12%
+  |gdef|startmarkdown{%
+    |markdownReadAndConvert{\stopmarkdown}%
+                           {|stopmarkdown}}%
+|endgroup
+%    \end{macrocode}
+%
+% \subsubsection{Options}
+% The following configuration should be considered placeholder.
+%  \begin{macrocode}
+\def\markdownRendererLineBreakPrototype{\blank}%
+\long\def\markdownRendererLinkPrototype#1#2#3{%
+  \useURL[#1][#2][][#3]#1\footnote[#1]{\ifx\empty#3\empty\else#3:
+  \fi\tt<\hyphenatedurl{#2}>}}%
+\long\def\markdownRendererImagePrototype#1#2#3{%
+  \placefigure[][fig:#1]{#3}{\externalfigure[#2]}}%
+\def\markdownRendererUlBeginPrototype{\startitemize}%
+\def\markdownRendererUlBeginTightPrototype{\startitemize[packed]}%
+\def\markdownRendererUlItemPrototype{\item}%
+\def\markdownRendererUlEndPrototype{\stopitemize}%
+\def\markdownRendererUlEndTightPrototype{\stopitemize}%
+\def\markdownRendererOlBeginPrototype{\startitemize[n]}%
+\def\markdownRendererOlBeginTightPrototype{\startitemize[packed,n]}%
+\def\markdownRendererOlItemPrototype{\item}%
+\long\def\markdownRendererOlItemWithNumberPrototype#1{\sym{#1.}}%
+\def\markdownRendererOlEndPrototype{\stopitemize}%
+\def\markdownRendererOlEndTightPrototype{\stopitemize}%
+\definedescription
+  [markdownConTeXtDlItemPrototype]
+  [location=hanging,
+   margin=standard,
+   headstyle=bold]%
+\definestartstop
+  [MarkdownConTeXtDlPrototype]
+  [before=\blank,
+   after=\blank]%
+\definestartstop
+  [MarkdownConTeXtDlTightPrototype]
+  [before=\blank\startpacked,
+   after=\stoppacked\blank]%
+\def\markdownRendererDlBeginPrototype{%
+  \startMarkdownConTeXtDlPrototype}%
+\def\markdownRendererDlBeginTightPrototype{%
+  \startMarkdownConTeXtDlTightPrototype}%
+\long\long\def\markdownRendererDlItemPrototype#1{%
+  \markdownConTeXtDlItemPrototype{#1}}%
+\def\markdownRendererDlEndPrototype{%
+  \stopMarkdownConTeXtDlPrototype}%
+\def\markdownRendererDlEndTightPrototype{%
+  \stopMarkdownConTeXtDlTightPrototype}%
+\long\def\markdownRendererEmphasisPrototype#1{{\em#1}}%
+\long\def\markdownRendererStrongEmphasisPrototype#1{{\bf\em#1}}%
+\def\markdownRendererBlockQuoteBeginPrototype{\startquotation}%
+\def\markdownRendererBlockQuoteEndPrototype{\stopquotation}%
+\long\def\markdownRendererInputVerbatimPrototype#1{\typefile{#1}}%
+\long\def\markdownRendererHeadingOnePrototype#1{\chapter{#1}}%
+\long\def\markdownRendererHeadingTwoPrototype#1{\section{#1}}%
+\long\def\markdownRendererHeadingThreePrototype#1{\subsection{#1}}%
+\long\def\markdownRendererHeadingFourPrototype#1{\subsubsection{#1}}%
+\long\def\markdownRendererHeadingFivePrototype#1{\subsubsubsection{#1}}%
+\long\def\markdownRendererHeadingSixPrototype#1{\subsubsubsubsection{#1}}%
+\def\markdownRendererHorizontalRulePrototype{%
+  \blackrule[height=1pt, width=\hsize]}%
+\long\def\markdownRendererFootnotePrototype#1{\footnote{#1}}%
+\stopmodule\protect
+%    \end{macrocode}
+%
+% \iffalse
+%</context>
+% \fi


Property changes on: trunk/Master/texmf-dist/source/generic/markdown/markdown.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/generic/markdown/markdown.ins
===================================================================
--- trunk/Master/texmf-dist/source/generic/markdown/markdown.ins	                        (rev 0)
+++ trunk/Master/texmf-dist/source/generic/markdown/markdown.ins	2016-06-11 23:15:05 UTC (rev 41376)
@@ -0,0 +1,8 @@
+\input docstrip.tex
+\generate{\usepreamble\luapreamble\usepostamble\luapostamble
+          \file{markdown.lua}{\from{markdown.dtx}{lua}}
+          \usepreamble\texpreamble\usepostamble\texpostamble
+          \file{markdown.tex}{\from{markdown.dtx}{tex}}
+          \file{markdown.sty}{\from{markdown.dtx}{latex}}
+          \file{t-markdown.tex}{\from{markdown.dtx}{context}}}
+\endbatchfile

Added: trunk/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex
===================================================================
--- trunk/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex	2016-06-11 23:15:05 UTC (rev 41376)
@@ -0,0 +1,140 @@
+%%
+%% This is file `t-markdown.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% markdown.dtx  (with options: `context')
+%% 
+%% Copyright (C) 2016 Vít Novotný
+%% 
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% 
+%%    http://www.latex-project.org/lppl.txt
+%% 
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%% 
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Vít Novotný.
+%% 
+%% Send bug reports, requests for additions and questions
+%% either to the GitHub issue tracker at
+%% 
+%%   https://github.com/Witiko/markdown/issues
+%% 
+%% or to the e-mail address <witiko at mail.muni.cz>.
+%% 
+%% MODIFICATION ADVICE:
+%% 
+%% If you want to customize this file, it is best to make a copy of
+%% the source file(s) from which it was produced.  Use a different
+%% name for your copy(ies) and modify the copy(ies); this will ensure
+%% that your modifications do not get overwritten when you install a
+%% new release of the standard system.  You should also ensure that
+%% your modified source file does not generate any modified file with
+%% the same name as a standard file.
+%% 
+%% You will also need to produce your own, suitably named, .ins file to
+%% control the generation of files from your source file; this file
+%% should contain your own preambles for the files it generates, not
+%% those in the standard .ins files.
+%% 
+%% The names of the source files used are shown above.
+%% 
+\writestatus{loading}{ConTeXt User Module / markdown}%
+\unprotect
+\let\startmarkdown\relax
+\let\stopmarkdown\relax
+\def\dospecials{\do\ \do\\\do\{\do\}\do\$\do\&%
+  \do\#\do\^\do\_\do\%\do\~}%
+\ifx\directlua\undefined
+  \input markdown
+\else
+  \directlua{%
+    local function unescape(str)
+      return (str:gsub("|", string.char(92))) end
+    local old_callback = callback.find("process_input_buffer")
+    callback.register("process_input_buffer", function() end)
+    local new_callback = callback.find("process_input_buffer")
+    if new_callback == false then
+      tex.print(unescape([[|let|markdownDirectLua|directlua
+                           |let|directlua|undefined
+                           |input markdown
+                           |let|directlua|markdownDirectLua
+                           |let|markdownDirectLua|undefined]]))
+    else
+      callback.register("process_input_buffer", old_callback)
+      tex.print(unescape("|input markdown"))
+    end}%
+\fi
+\def\markdownInfo#1{\writestatus{markdown}{#1.}}%
+\def\markdownWarning#1{\writestatus{markdown\space warn}{#1.}}%
+\begingroup
+  \catcode`\|=0%
+  \catcode`\\=12%
+  |gdef|startmarkdown{%
+    |markdownReadAndConvert{\stopmarkdown}%
+                           {|stopmarkdown}}%
+|endgroup
+\def\markdownRendererLineBreakPrototype{\blank}%
+\long\def\markdownRendererLinkPrototype#1#2#3{%
+  \useURL[#1][#2][][#3]#1\footnote[#1]{\ifx\empty#3\empty\else#3:
+  \fi\tt<\hyphenatedurl{#2}>}}%
+\long\def\markdownRendererImagePrototype#1#2#3{%
+  \placefigure[][fig:#1]{#3}{\externalfigure[#2]}}%
+\def\markdownRendererUlBeginPrototype{\startitemize}%
+\def\markdownRendererUlBeginTightPrototype{\startitemize[packed]}%
+\def\markdownRendererUlItemPrototype{\item}%
+\def\markdownRendererUlEndPrototype{\stopitemize}%
+\def\markdownRendererUlEndTightPrototype{\stopitemize}%
+\def\markdownRendererOlBeginPrototype{\startitemize[n]}%
+\def\markdownRendererOlBeginTightPrototype{\startitemize[packed,n]}%
+\def\markdownRendererOlItemPrototype{\item}%
+\long\def\markdownRendererOlItemWithNumberPrototype#1{\sym{#1.}}%
+\def\markdownRendererOlEndPrototype{\stopitemize}%
+\def\markdownRendererOlEndTightPrototype{\stopitemize}%
+\definedescription
+  [markdownConTeXtDlItemPrototype]
+  [location=hanging,
+   margin=standard,
+   headstyle=bold]%
+\definestartstop
+  [MarkdownConTeXtDlPrototype]
+  [before=\blank,
+   after=\blank]%
+\definestartstop
+  [MarkdownConTeXtDlTightPrototype]
+  [before=\blank\startpacked,
+   after=\stoppacked\blank]%
+\def\markdownRendererDlBeginPrototype{%
+  \startMarkdownConTeXtDlPrototype}%
+\def\markdownRendererDlBeginTightPrototype{%
+  \startMarkdownConTeXtDlTightPrototype}%
+\long\long\def\markdownRendererDlItemPrototype#1{%
+  \markdownConTeXtDlItemPrototype{#1}}%
+\def\markdownRendererDlEndPrototype{%
+  \stopMarkdownConTeXtDlPrototype}%
+\def\markdownRendererDlEndTightPrototype{%
+  \stopMarkdownConTeXtDlTightPrototype}%
+\long\def\markdownRendererEmphasisPrototype#1{{\em#1}}%
+\long\def\markdownRendererStrongEmphasisPrototype#1{{\bf\em#1}}%
+\def\markdownRendererBlockQuoteBeginPrototype{\startquotation}%
+\def\markdownRendererBlockQuoteEndPrototype{\stopquotation}%
+\long\def\markdownRendererInputVerbatimPrototype#1{\typefile{#1}}%
+\long\def\markdownRendererHeadingOnePrototype#1{\chapter{#1}}%
+\long\def\markdownRendererHeadingTwoPrototype#1{\section{#1}}%
+\long\def\markdownRendererHeadingThreePrototype#1{\subsection{#1}}%
+\long\def\markdownRendererHeadingFourPrototype#1{\subsubsection{#1}}%
+\long\def\markdownRendererHeadingFivePrototype#1{\subsubsubsection{#1}}%
+\long\def\markdownRendererHeadingSixPrototype#1{\subsubsubsubsection{#1}}%
+\def\markdownRendererHorizontalRulePrototype{%
+  \blackrule[height=1pt, width=\hsize]}%
+\long\def\markdownRendererFootnotePrototype#1{\footnote{#1}}%
+\stopmodule\protect
+\endinput
+%%
+%% End of file `t-markdown.tex'.


Property changes on: trunk/Master/texmf-dist/tex/context/third/markdown/t-markdown.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/generic/markdown/markdown.tex
===================================================================
--- trunk/Master/texmf-dist/tex/generic/markdown/markdown.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/generic/markdown/markdown.tex	2016-06-11 23:15:05 UTC (rev 41376)
@@ -0,0 +1,392 @@
+%%
+%% This is file `markdown.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% markdown.dtx  (with options: `tex')
+%% 
+%% Copyright (C) 2016 Vít Novotný
+%% 
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% 
+%%    http://www.latex-project.org/lppl.txt
+%% 
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%% 
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Vít Novotný.
+%% 
+%% Send bug reports, requests for additions and questions
+%% either to the GitHub issue tracker at
+%% 
+%%   https://github.com/Witiko/markdown/issues
+%% 
+%% or to the e-mail address <witiko at mail.muni.cz>.
+%% 
+%% MODIFICATION ADVICE:
+%% 
+%% If you want to customize this file, it is best to make a copy of
+%% the source file(s) from which it was produced.  Use a different
+%% name for your copy(ies) and modify the copy(ies); this will ensure
+%% that your modifications do not get overwritten when you install a
+%% new release of the standard system.  You should also ensure that
+%% your modified source file does not generate any modified file with
+%% the same name as a standard file.
+%% 
+%% You will also need to produce your own, suitably named, .ins file to
+%% control the generation of files from your source file; this file
+%% should contain your own preambles for the files it generates, not
+%% those in the standard .ins files.
+%% 
+%% The names of the source files used are shown above.
+%% 
+\def\markdownVersion{2016/06/03}%
+\let\markdownBegin\relax
+\let\markdownEnd\relax
+\let\markdownInput\relax
+\def\markdownOptionHelperScriptFileName{\jobname.markdown.lua}%
+\def\markdownOptionInputTempFileName{\jobname.markdown.in}%
+\def\markdownOptionOutputTempFileName{\jobname.markdown.out}%
+\def\markdownOptionCacheDir{_markdown-\jobname}%
+\let\markdownOptionBlankBeforeBlockquote\undefined
+\let\markdownOptionBlankBeforeHeading\undefined
+\let\markdownOptionDefinitionLists\undefined
+\let\markdownOptionHashEnumerator\undefined
+\let\markdownOptionHybrid\undefined
+\let\markdownOptionFootnotes\undefined
+\let\markdownOptionPreserveTabs\undefined
+\let\markdownOptionSmartEllipses\undefined
+\let\markdownOptionStartNumber\undefined
+\let\markdownOptionTightLists\undefined
+\def\markdownRendererLineBreak{%
+  \markdownRendererLineBreakPrototype}%
+\def\markdownRendererEllipsis{%
+  \markdownRendererEllipsisPrototype}%
+\def\markdownRendererCodeSpan{%
+  \markdownRendererCodeSpanPrototype}%
+\def\markdownRendererLink{%
+  \markdownRendererLinkPrototype}%
+\def\markdownRendererImage{%
+  \markdownRendererImagePrototype}%
+\def\markdownRendererUlBegin{%
+  \markdownRendererUlBeginPrototype}%
+\def\markdownRendererUlBeginTight{%
+  \markdownRendererUlBeginTightPrototype}%
+\def\markdownRendererUlItem{%
+  \markdownRendererUlItemPrototype}%
+\def\markdownRendererUlEnd{%
+  \markdownRendererUlEndPrototype}%
+\def\markdownRendererUlEndTight{%
+  \markdownRendererUlEndTightPrototype}%
+\def\markdownRendererOlBegin{%
+  \markdownRendererOlBeginPrototype}%
+\def\markdownRendererOlBeginTight{%
+  \markdownRendererOlBeginTightPrototype}%
+\def\markdownRendererOlItem{%
+  \markdownRendererOlItemPrototype}%
+\def\markdownRendererOlItemWithNumber{%
+  \markdownRendererOlItemWithNumberPrototype}%
+\def\markdownRendererOlEnd{%
+  \markdownRendererOlEndPrototype}%
+\def\markdownRendererOlEndTight{%
+  \markdownRendererOlEndTightPrototype}%
+\def\markdownRendererDlBegin{%
+  \markdownRendererDlBeginPrototype}%
+\def\markdownRendererDlBeginTight{%
+  \markdownRendererDlBeginTightPrototype}%
+\def\markdownRendererDlItem{%
+  \markdownRendererDlItemPrototype}%
+\def\markdownRendererDlEnd{%
+  \markdownRendererDlEndPrototype}%
+\def\markdownRendererDlEndTight{%
+  \markdownRendererDlEndTightPrototype}%
+\def\markdownRendererEmphasis{%
+  \markdownRendererEmphasisPrototype}%
+\def\markdownRendererStrongEmphasis{%
+  \markdownRendererStrongEmphasisPrototype}%
+\def\markdownRendererBlockQuoteBegin{%
+  \markdownRendererBlockQuoteBeginPrototype}%
+\def\markdownRendererBlockQuoteEnd{%
+  \markdownRendererBlockQuoteEndPrototype}%
+\def\markdownRendererInputVerbatim{%
+  \markdownRendererInputVerbatimPrototype}%
+\def\markdownRendererHeadingOne{%
+  \markdownRendererHeadingOnePrototype}%
+\def\markdownRendererHeadingTwo{%
+  \markdownRendererHeadingTwoPrototype}%
+\def\markdownRendererHeadingThree{%
+  \markdownRendererHeadingThreePrototype}%
+\def\markdownRendererHeadingFour{%
+  \markdownRendererHeadingFourPrototype}%
+\def\markdownRendererHeadingFive{%
+  \markdownRendererHeadingFivePrototype}%
+\def\markdownRendererHeadingSix{%
+  \markdownRendererHeadingSixPrototype}%
+\def\markdownRendererHorizontalRule{%
+  \markdownRendererHorizontalRulePrototype}%
+\def\markdownRendererFootnote{%
+  \markdownRendererFootnotePrototype}%
+\def\markdownRendererLineBreakPrototype{}%
+\def\markdownRendererEllipsisPrototype{}%
+\long\def\markdownRendererCodeSpanPrototype#1{}%
+\long\def\markdownRendererLinkPrototype#1#2#3{}%
+\long\def\markdownRendererImagePrototype#1#2#3{}%
+\def\markdownRendererUlBeginPrototype{}%
+\def\markdownRendererUlBeginTightPrototype{}%
+\def\markdownRendererUlItemPrototype{}%
+\def\markdownRendererUlEndPrototype{}%
+\def\markdownRendererUlEndTightPrototype{}%
+\def\markdownRendererOlBeginPrototype{}%
+\def\markdownRendererOlBeginTightPrototype{}%
+\def\markdownRendererOlItemPrototype{}%
+\long\def\markdownRendererOlItemWithNumberPrototype#1{}%
+\def\markdownRendererOlEndPrototype{}%
+\def\markdownRendererOlEndTightPrototype{}%
+\def\markdownRendererDlBeginPrototype{}%
+\def\markdownRendererDlBeginTightPrototype{}%
+\long\def\markdownRendererDlItemPrototype#1{}%
+\def\markdownRendererDlEndPrototype{}%
+\def\markdownRendererDlEndTightPrototype{}%
+\long\def\markdownRendererEmphasisPrototype#1{}%
+\long\def\markdownRendererStrongEmphasisPrototype#1{}%
+\def\markdownRendererBlockQuoteBeginPrototype{}%
+\def\markdownRendererBlockQuoteEndPrototype{}%
+\long\def\markdownRendererInputVerbatimPrototype#1{}%
+\long\def\markdownRendererHeadingOnePrototype#1{}%
+\long\def\markdownRendererHeadingTwoPrototype#1{}%
+\long\def\markdownRendererHeadingThreePrototype#1{}%
+\long\def\markdownRendererHeadingFourPrototype#1{}%
+\long\def\markdownRendererHeadingFivePrototype#1{}%
+\long\def\markdownRendererHeadingSixPrototype#1{}%
+\def\markdownRendererHorizontalRulePrototype{}%
+\long\def\markdownRendererFootnotePrototype#1{}%
+\def\markdownInfo#1{}%
+\def\markdownWarning#1{}%
+\def\markdownError#1{}%
+\def\markdownLuaRegisterIBCallback#1{%
+  local old_callback = callback.find("process_input_buffer")
+  callback.register("process_input_buffer", #1)}%
+\def\markdownLuaUnregisterIBCallback{%
+  callback.register("process_input_buffer", old_callback)}%
+\let\markdownMakeOther\relax
+\let\markdownReadAndConvert\relax
+\begingroup
+  \catcode`\|=0\catcode`\\=12%
+  |gdef|markdownBegin{%
+    |markdownReadAndConvert{\markdownEnd}%
+                           {|markdownEnd}}%
+|endgroup
+\def\markdownInfo#1{%
+  \message{(l.\the\inputlineno) markdown.tex info: #1.}}%
+\def\markdownWarning#1{%
+  \message{(l.\the\inputlineno) markdown.tex warning: #1}}%
+\def\markdownError#1#2{%
+  \errhelp{#2.}%
+  \errmessage{(l.\the\inputlineno) markdown.tex error: #1}}%
+\def\markdownRendererLineBreakPrototype{\hfil\break}%
+\let\markdownRendererEllipsisPrototype\dots
+\long\def\markdownRendererCodeSpanPrototype#1{{\tt#1}}%
+\long\def\markdownRendererLinkPrototype#1#2#3{#1}%
+\long\def\markdownRendererImagePrototype#1#2#3{#1}%
+\def\markdownRendererUlBeginPrototype{}%
+\def\markdownRendererUlBeginTightPrototype{}%
+\def\markdownRendererUlItemPrototype{}%
+\def\markdownRendererUlEndPrototype{}%
+\def\markdownRendererUlEndTightPrototype{}%
+\def\markdownRendererOlBeginPrototype{}%
+\def\markdownRendererOlBeginTightPrototype{}%
+\def\markdownRendererOlItemPrototype{}%
+\long\def\markdownRendererOlItemWithNumberPrototype#1{}%
+\def\markdownRendererOlEndPrototype{}%
+\def\markdownRendererOlEndTightPrototype{}%
+\def\markdownRendererDlBeginPrototype{}%
+\def\markdownRendererDlBeginTightPrototype{}%
+\long\def\markdownRendererDlItemPrototype#1{#1}%
+\def\markdownRendererDlEndPrototype{}%
+\def\markdownRendererDlEndTightPrototype{}%
+\long\def\markdownRendererEmphasisPrototype#1{{\it#1}}%
+\long\def\markdownRendererStrongEmphasisPrototype#1{{\it#1}}%
+\def\markdownRendererBlockQuoteBeginPrototype{\par\begingroup\it}%
+\def\markdownRendererBlockQuoteEndPrototype{\endgroup\par}%
+\long\def\markdownRendererInputVerbatimPrototype#1{%
+  \par{\tt\input"#1"\relax}\par}%
+\long\def\markdownRendererHeadingOnePrototype#1{#1}%
+\long\def\markdownRendererHeadingTwoPrototype#1{#1}%
+\long\def\markdownRendererHeadingThreePrototype#1{#1}%
+\long\def\markdownRendererHeadingFourPrototype#1{#1}%
+\long\def\markdownRendererHeadingFivePrototype#1{#1}%
+\long\def\markdownRendererHeadingSixPrototype#1{#1}%
+\def\markdownRendererHorizontalRulePrototype{}%
+\long\def\markdownRendererFootnotePrototype#1{#1}%
+\def\markdownLuaOptions{{%
+  \ifx\markdownOptionBlankBeforeBlockquote\undefined\else
+    blankBeforeBlockquote = \markdownOptionBlankBeforeBlockquote,
+  \fi
+  \ifx\markdownOptionBlankBeforeHeading\undefined\else
+    blankBeforeHeading = \markdownOptionBlankBeforeHeading,
+  \fi
+  \ifx\markdownOptionCacheDir\undefined\else
+    cacheDir = "\markdownOptionCacheDir",
+  \fi
+  \ifx\markdownOptionDefinitionLists\undefined\else
+    definitionLists = \markdownOptionDefinitionLists,
+  \fi
+  \ifx\markdownOptionHashEnumerators\undefined\else
+    hashEnumerators = \markdownOptionHashEnumerators,
+  \fi
+  \ifx\markdownOptionHybrid\undefined\else
+    hybrid = \markdownOptionHybrid,
+  \fi
+  \ifx\markdownOptionFootnotes\undefined\else
+    footnotes = \markdownOptionFootnotes,
+  \fi
+  \ifx\markdownOptionPreserveTabs\undefined\else
+    preserveTabs = \markdownOptionPreserveTabs,
+  \fi
+  \ifx\markdownOptionSmartEllipses\undefined\else
+    smartEllipses = \markdownOptionSmartEllipses,
+  \fi
+  \ifx\markdownOptionStartNumber\undefined\else
+    startNumber = \markdownOptionStartNumber,
+  \fi
+  \ifx\markdownOptionTightLists\undefined\else
+    tightLists = \markdownOptionTightLists,
+  \fi}
+}%
+\def\markdownPrepare{%
+  local lfs = require("lfs")
+  local cacheDir = "\markdownOptionCacheDir"
+  if lfs.isdir(cacheDir) == true then else
+    assert(lfs.mkdir(cacheDir))
+  end
+  local md = require("markdown")
+  local convert = md.new(\markdownLuaOptions)
+}%
+\ifx\directlua\undefined
+  \csname newwrite\endcsname\markdownLuaExecuteFileStream
+  \csname newcount\endcsname\markdownLuaExecuteShellEscape
+  \ifx\pdfshellescape\undefined
+    \ifx\shellescape\undefined
+      \markdownLuaExecuteShellEscape=1%
+    \else
+      \markdownLuaExecuteShellEscape=\shellescape
+    \fi
+  \else
+    \markdownLuaExecuteShellEscape=\pdfshellescape
+  \fi
+  \def\markdownLuaExecute#1{%
+    \ifnum\markdownLuaExecuteShellEscape=1%
+      \immediate\openout\markdownLuaExecuteFileStream=%
+        \markdownOptionHelperScriptFileName
+      \markdownInfo{Writing a helper Lua script to the file
+        "\markdownOptionHelperScriptFileName"}%
+      \immediate\write\markdownLuaExecuteFileStream{%
+        local kpse = require('kpse')
+        kpse.set_program_name('luatex') #1}%
+      \immediate\closeout\markdownLuaExecuteFileStream
+      \markdownInfo{Executing a helper Lua script from the file
+        "\markdownOptionHelperScriptFileName" and storing the result in the
+        file "\markdownOptionOutputTempFileName"}%
+      \immediate\write18{texlua "\markdownOptionHelperScriptFileName" >
+        "\markdownOptionOutputTempFileName"}%
+      \input\markdownOptionOutputTempFileName\relax
+    \else
+      \markdownError{I can not access the shell}{Either run the TeX
+        compiler with the --shell-escape or the --enable-write18 flag,
+        or set shell_escape=t in the texmf.cnf file}%
+    \fi}%
+  \begingroup
+    \catcode`\^^I=12%
+    \gdef\markdownReadAndConvertTab{^^I}%
+  \endgroup
+  \begingroup
+    \catcode`\^^M=13%
+    \catcode`\^^I=13%
+    \catcode`|=0%
+    \catcode`\\=12%
+    |gdef|markdownReadAndConvert#1#2{%
+      |begingroup%
+      |immediate|openout|markdownLuaExecuteFileStream%
+        |markdownOptionInputTempFileName%
+      |markdownInfo{Buffering markdown input into the temporary %
+        input file "|markdownOptionInputTempFileName" and scanning %
+        for the closing token sequence "#1"}%
+      |def|do##1{|catcode`##1=12}|dospecials%
+      |catcode`| =12%
+      |markdownMakeOther%
+      |def|markdownReadAndConvertProcessLine##1#1##2#1##3|relax{%
+        |ifx|relax##3|relax%
+          |immediate|write|markdownLuaExecuteFileStream{##1}%
+        |else%
+          |def^^M{%
+            |markdownInfo{The ending token sequence was found}%
+            |immediate|write|markdownLuaExecuteFileStream{}%
+            |immediate|closeout|markdownLuaExecuteFileStream%
+            |endgroup%
+            |markdownInput|markdownOptionInputTempFileName%
+            #2}%
+        |fi%
+        ^^M}%
+      |catcode`|^^I=13%
+      |def^^I{|markdownReadAndConvertTab}%
+      |catcode`|^^M=13%
+      |def^^M##1^^M{%
+        |def^^M####1^^M{%
+          |markdownReadAndConvertProcessLine####1#1#1|relax}%
+        ^^M}%
+      ^^M}%
+  |endgroup
+\else
+  \def\markdownLuaExecute#1{\directlua{local print = tex.print #1}}%
+  \begingroup
+    \catcode`\_=12%
+    \catcode`\$=12%
+    \catcode`\^=12%
+    \catcode`\/=6%
+    \catcode`\#=12%
+    \catcode`\@=14%
+    \catcode`\%=12%
+    \catcode`|=0@
+    \catcode`\\=12@
+    |gdef|markdownReadAndConvert/1/2{@
+      |def|markdownReadAndConvertAfter{/2}@
+      |markdownInfo{Buffering markdown input and scanning for the
+        closing token sequence "/1"}@
+      |directlua{@
+        |markdownPrepare
+        local buffer = {}
+        local ending_sequence = "^.-" .. ([[/1]]):gsub(
+          "([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1")
+        |markdownLuaRegisterIBCallback{function(line)
+          if line:match(ending_sequence) then
+            |markdownLuaUnregisterIBCallback
+            local input = table.concat(buffer, "\n") .. "\n\n"
+            local output = convert(input)
+            return [[\markdownInfo{The ending token sequence was found}]] ..
+              output .. [[\markdownReadAndConvertAfter]]
+          else
+            buffer[#buffer+1] = line
+            return [[\]] .. (#buffer == 1 and "fi" or "relax")
+          end
+        end}}@
+      |iffalse}@
+  |endgroup
+\fi
+\begingroup
+  \catcode`|=0%
+  \catcode`\\=12%
+  |gdef|markdownInput#1{%
+    |markdownInfo{Including markdown document "#1"}%
+    |markdownLuaExecute{%
+      |markdownPrepare
+      local input = assert(io.open("#1","r")):read("*a") .. "\n\n"
+      print(convert(input:gsub("\r\n?", "\n")))}}%
+|endgroup
+\endinput
+%%
+%% End of file `markdown.tex'.


Property changes on: trunk/Master/texmf-dist/tex/generic/markdown/markdown.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/markdown/markdown.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/markdown/markdown.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/markdown/markdown.sty	2016-06-11 23:15:05 UTC (rev 41376)
@@ -0,0 +1,331 @@
+%%
+%% This is file `markdown.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% markdown.dtx  (with options: `latex')
+%% 
+%% Copyright (C) 2016 Vít Novotný
+%% 
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% 
+%%    http://www.latex-project.org/lppl.txt
+%% 
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%% 
+%% This work has the LPPL maintenance status `maintained'.
+%% The Current Maintainer of this work is Vít Novotný.
+%% 
+%% Send bug reports, requests for additions and questions
+%% either to the GitHub issue tracker at
+%% 
+%%   https://github.com/Witiko/markdown/issues
+%% 
+%% or to the e-mail address <witiko at mail.muni.cz>.
+%% 
+%% MODIFICATION ADVICE:
+%% 
+%% If you want to customize this file, it is best to make a copy of
+%% the source file(s) from which it was produced.  Use a different
+%% name for your copy(ies) and modify the copy(ies); this will ensure
+%% that your modifications do not get overwritten when you install a
+%% new release of the standard system.  You should also ensure that
+%% your modified source file does not generate any modified file with
+%% the same name as a standard file.
+%% 
+%% You will also need to produce your own, suitably named, .ins file to
+%% control the generation of files from your source file; this file
+%% should contain your own preambles for the files it generates, not
+%% those in the standard .ins files.
+%% 
+%% The names of the source files used are shown above.
+%% 
+\NeedsTeXFormat{LaTeX2e}%
+\newenvironment{markdown}\relax\relax
+\newenvironment{markdown*}[1]\relax\relax
+\newcommand\markdownSetup[1]{%
+  \setkeys{markdownOptions}{#1}}%
+\RequirePackage{keyval}
+\define at key{markdownOptions}{helperScriptFileName}{%
+  \def\markdownOptionHelperScriptFileName{#1}}%
+\define at key{markdownOptions}{inputTempFileName}{%
+  \def\markdownOptionInputTempFileName{#1}}%
+\define at key{markdownOptions}{outputTempFileName}{%
+  \def\markdownOptionOutputTempFileName{#1}}%
+\define at key{markdownOptions}{blankBeforeBlockquote}[true]{%
+  \def\markdownOptionBlankBeforeBlockquote{#1}}%
+\define at key{markdownOptions}{blankBeforeHeading}[true]{%
+  \def\markdownOptionBlankBeforeHeading{#1}}%
+\define at key{markdownOptions}{cacheDir}{%
+  \def\markdownOptionCacheDir{#1}}%
+\define at key{markdownOptions}{definitionLists}[true]{%
+  \def\markdownOptionDefinitionLists{#1}}%
+\define at key{markdownOptions}{hashEnumerators}[true]{%
+  \def\markdownOptionHashEnumerators{#1}}%
+\define at key{markdownOptions}{hybrid}[true]{%
+  \def\markdownOptionHybrid{#1}}%
+\define at key{markdownOptions}{footnotes}[true]{%
+  \def\markdownOptionFootnotes{#1}}%
+\define at key{markdownOptions}{preserveTabs}[true]{%
+  \def\markdownOptionPreserveTabs{#1}}%
+\define at key{markdownOptions}{smartEllipses}[true]{%
+  \def\markdownOptionSmartEllipses{#1}}%
+\define at key{markdownOptions}{startNumber}[true]{%
+  \def\markdownOptionStartNumber{#1}}%
+\define at key{markdownOptions}{tightLists}[true]{%
+  \def\markdownOptionTightLists{#1}}%
+\define at key{markdownOptions}{renderers}{%
+  \setkeys{markdownRenderers}{#1}}%
+\define at key{markdownRenderers}{lineBreak}{%
+  \renewcommand\markdownRendererLineBreak{#1}}%
+\define at key{markdownRenderers}{ellipsis}{%
+  \renewcommand\markdownRendererEllipsis{#1}}%
+\define at key{markdownRenderers}{codeSpan}{%
+  \renewcommand\markdownRendererCodeSpan[1]{#1}}%
+\define at key{markdownRenderers}{link}{%
+  \renewcommand\markdownRendererLink[3]{#1}}%
+\define at key{markdownRenderers}{image}{%
+  \renewcommand\markdownRendererImage[3]{#1}}%
+\define at key{markdownRenderers}{ulBegin}{%
+  \renewcommand\markdownRendererUlBegin{#1}}%
+\define at key{markdownRenderers}{ulBeginTight}{%
+  \renewcommand\markdownRendererUlBeginTight{#1}}%
+\define at key{markdownRenderers}{ulItem}{%
+  \renewcommand\markdownRendererUlItem{#1}}%
+\define at key{markdownRenderers}{ulEnd}{%
+  \renewcommand\markdownRendererUlEnd{#1}}%
+\define at key{markdownRenderers}{ulEndTight}{%
+  \renewcommand\markdownRendererUlEndTight{#1}}%
+\define at key{markdownRenderers}{olBegin}{%
+  \renewcommand\markdownRendererOlBegin{#1}}%
+\define at key{markdownRenderers}{olBeginTight}{%
+  \renewcommand\markdownRendererOlBeginTight{#1}}%
+\define at key{markdownRenderers}{olItem}{%
+  \renewcommand\markdownRendererOlItem{#1}}%
+\define at key{markdownRenderers}{olItemWithNumber}{%
+  \renewcommand\markdownRendererOlItemWithNumber[1]{#1}}%
+\define at key{markdownRenderers}{olEnd}{%
+  \renewcommand\markdownRendererOlEnd{#1}}%
+\define at key{markdownRenderers}{olEndTight}{%
+  \renewcommand\markdownRendererOlEndTight{#1}}%
+\define at key{markdownRenderers}{dlBegin}{%
+  \renewcommand\markdownRendererDlBegin{#1}}%
+\define at key{markdownRenderers}{dlBeginTight}{%
+  \renewcommand\markdownRendererDlBeginTight{#1}}%
+\define at key{markdownRenderers}{dlItem}{%
+  \renewcommand\markdownRendererDlItem[1]{#1}}%
+\define at key{markdownRenderers}{dlEnd}{%
+  \renewcommand\markdownRendererDlEnd{#1}}%
+\define at key{markdownRenderers}{dlEndTight}{%
+  \renewcommand\markdownRendererDlEndTight{#1}}%
+\define at key{markdownRenderers}{emphasis}{%
+  \renewcommand\markdownRendererEmphasis[1]{#1}}%
+\define at key{markdownRenderers}{strongEmphasis}{%
+  \renewcommand\markdownRendererStrongEmphasis[1]{#1}}%
+\define at key{markdownRenderers}{blockQuoteBegin}{%
+  \renewcommand\markdownRendererBlockQuoteBegin{#1}}%
+\define at key{markdownRenderers}{blockQuoteEnd}{%
+  \renewcommand\markdownRendererBlockQuoteEnd{#1}}%
+\define at key{markdownRenderers}{inputVerbatim}{%
+  \renewcommand\markdownRendererInputVerbatim[1]{#1}}%
+\define at key{markdownRenderers}{headingOne}{%
+  \renewcommand\markdownRendererHeadingOne[1]{#1}}%
+\define at key{markdownRenderers}{headingTwo}{%
+  \renewcommand\markdownRendererHeadingTwo[1]{#1}}%
+\define at key{markdownRenderers}{headingThree}{%
+  \renewcommand\markdownRendererHeadingThree[1]{#1}}%
+\define at key{markdownRenderers}{headingFour}{%
+  \renewcommand\markdownRendererHeadingFour[1]{#1}}%
+\define at key{markdownRenderers}{headingFive}{%
+  \renewcommand\markdownRendererHeadingFive[1]{#1}}%
+\define at key{markdownRenderers}{headingSix}{%
+  \renewcommand\markdownRendererHeadingSix[1]{#1}}%
+\define at key{markdownRenderers}{horizontalRule}{%
+  \renewcommand\markdownRendererHorizontalRule{#1}}%
+\define at key{markdownRenderers}{footnote}{%
+  \renewcommand\markdownRendererFootnote[1]{#1}}%
+\define at key{markdownOptions}{rendererPrototypes}{%
+  \setkeys{markdownRendererPrototypes}{#1}}%
+\define at key{markdownRendererPrototypes}{lineBreak}{%
+  \renewcommand\markdownRendererLineBreakPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{ellipsis}{%
+  \renewcommand\markdownRendererEllipsisPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{codeSpan}{%
+  \renewcommand\markdownRendererCodeSpanPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{link}{%
+  \renewcommand\markdownRendererLink[3]{#1}}%
+\define at key{markdownRendererPrototypes}{image}{%
+  \renewcommand\markdownRendererImage[3]{#1}}%
+\define at key{markdownRendererPrototypes}{ulBegin}{%
+  \renewcommand\markdownRendererUlBeginPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{ulBeginTight}{%
+  \renewcommand\markdownRendererUlBeginTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{ulItem}{%
+  \renewcommand\markdownRendererUlItemPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{ulEnd}{%
+  \renewcommand\markdownRendererUlEndPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{ulEndTight}{%
+  \renewcommand\markdownRendererUlEndTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{olBegin}{%
+  \renewcommand\markdownRendererOlBeginPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{olBeginTight}{%
+  \renewcommand\markdownRendererOlBeginTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{olItem}{%
+  \renewcommand\markdownRendererOlItemPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{olItemWithNumber}{%
+  \renewcommand\markdownRendererOlItemWithNumberPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{olEnd}{%
+  \renewcommand\markdownRendererOlEndPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{olEndTight}{%
+  \renewcommand\markdownRendererOlEndTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{dlBegin}{%
+  \renewcommand\markdownRendererDlBeginPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{dlBeginTight}{%
+  \renewcommand\markdownRendererDlBeginTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{dlItem}{%
+  \renewcommand\markdownRendererDlItemPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{dlEnd}{%
+  \renewcommand\markdownRendererDlEndPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{dlEndTight}{%
+  \renewcommand\markdownRendererDlEndTightPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{emphasis}{%
+  \renewcommand\markdownRendererEmphasisPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{strongEmphasis}{%
+  \renewcommand\markdownRendererStrongEmphasisPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{blockQuoteBegin}{%
+  \renewcommand\markdownRendererBlockQuoteBeginPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{blockQuoteEnd}{%
+  \renewcommand\markdownRendererBlockQuoteEndPrototype{#1}}%
+\define at key{markdownRendererPrototypes}{inputVerbatim}{%
+  \renewcommand\markdownRendererInputVerbatimPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingOne}{%
+  \renewcommand\markdownRendererHeadingOnePrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingTwo}{%
+  \renewcommand\markdownRendererHeadingTwoPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingThree}{%
+  \renewcommand\markdownRendererHeadingThreePrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingFour}{%
+  \renewcommand\markdownRendererHeadingFourPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingFive}{%
+  \renewcommand\markdownRendererHeadingFivePrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{headingSix}{%
+  \renewcommand\markdownRendererHeadingSixPrototype[1]{#1}}%
+\define at key{markdownRendererPrototypes}{horizontalRule}{%
+  \renewcommand\markdownRendererHorizontalRulePrototype{#1}}%
+\define at key{markdownRendererPrototypes}{footnote}{%
+  \renewcommand\markdownRendererFootnotePrototype[1]{#1}}%
+\input markdown
+\ProvidesPackage{markdown}[\markdownVersion]%
+\renewcommand\markdownInfo[1]{\PackageInfo{markdown}{#1}}%
+\renewcommand\markdownWarning[1]{\PackageWarning{markdown}{#1}}%
+\renewcommand\markdownError[2]{\PackageError{markdown}{#1}{#2.}}%
+\let\markdownInputPlainTeX\markdownInput
+\renewcommand\markdownInput[2][]{%
+  \begingroup
+    \markdownSetup{#1}%
+    \markdownInputPlainTeX{#2}%
+  \endgroup}%
+\renewenvironment{markdown}{%
+  \markdownReadAndConvert at markdown{}}\relax
+\renewenvironment{markdown*}[1]{%
+  \markdownSetup{#1}%
+  \markdownReadAndConvert at markdown*}\relax
+\begingroup
+  \catcode`\|=0\catcode`\<=1\catcode`\>=2%
+  \catcode`\\=12|catcode`|{=12|catcode`|}=12%
+  |gdef|markdownReadAndConvert at markdown#1<%
+    |markdownReadAndConvert<\end{markdown#1}>%
+                           <|end<markdown#1>>>%
+|endgroup
+\DeclareOption*{%
+  \expandafter\markdownSetup\expandafter{\CurrentOption}}%
+\ProcessOptions\relax
+\RequirePackage{url}
+\RequirePackage{graphicx}
+\RequirePackage{ifthen}
+\ifx\markdownOptionTightLists\undefined
+  \RequirePackage{paralist}
+\else
+  \ifthenelse{\equal{\markdownOptionTightLists}{false}}{}{
+    \RequirePackage{paralist}}
+\fi
+\RequirePackage{fancyvrb}
+\markdownSetup{rendererPrototypes={
+  lineBreak = {\\},
+  codeSpan = {\texttt{#1}},
+  link = {#1\footnote{\ifx\empty#3\empty\else#3:
+    \fi\texttt<\url{#2}\texttt>}},
+  image = {\begin{figure}
+      \begin{center}%
+        \includegraphics{#2}%
+      \end{center}%
+      \ifx\empty#3\empty\else
+        \caption{#3}%
+      \fi
+      \label{fig:#1}%
+    \end{figure}},
+  ulBegin = {\begin{itemize}},
+  ulBeginTight = {\begin{compactitem}},
+  ulItem = {\item},
+  ulEnd = {\end{itemize}},
+  ulEndTight = {\end{compactitem}},
+  olBegin = {\begin{enumerate}},
+  olBeginTight = {\begin{compactenum}},
+  olItem = {\item},
+  olItemWithNumber = {\item[#1.]},
+  olEnd = {\end{enumerate}},
+  olEndTight = {\end{compactenum}},
+  dlBegin = {\begin{description}},
+  dlBeginTight = {\begin{compactdesc}},
+  dlItem = {\item[#1]},
+  dlEnd = {\end{description}},
+  dlEndTight = {\end{compactdesc}},
+  emphasis = {\emph{#1}},
+  strongEmphasis = {%
+    \ifx\alert\undefined
+      \textbf{\emph{#1}}%
+    \else % Beamer support
+      \alert{\emph{#1}}
+    \fi},
+  blockQuoteBegin = {\begin{quotation}},
+  blockQuoteEnd = {\end{quotation}},
+  inputVerbatim = {\VerbatimInput{#1}},
+  horizontalRule = {\noindent\rule[0.5ex]{\linewidth}{1pt}},
+  footnote = {\footnote{#1}}}}%
+
+\ifx\chapter\undefined
+  \markdownSetup{rendererPrototypes={
+    headingOne = {\section{#1}},
+    headingTwo = {\subsection{#1}},
+    headingThree = {\subsubsection{#1}},
+    headingFour = {\paragraph{#1}},
+    headingFive = {\subparagraph{#1}}}}%
+\else
+  \markdownSetup{rendererPrototypes={
+    headingOne = {\chapter{#1}},
+    headingTwo = {\section{#1}},
+    headingThree = {\subsection{#1}},
+    headingFour = {\subsubsection{#1}},
+    headingFive = {\paragraph{#1}},
+    headingSix = {\subparagraph{#1}}}}%
+\fi
+\renewcommand\markdownLuaRegisterIBCallback[1]{%
+  luatexbase.add_to_callback("process_input_buffer", #1, %
+    "The markdown input processor")}
+\renewcommand\markdownLuaUnregisterIBCallback{%
+  luatexbase.remove_from_callback("process_input_buffer",%
+    "The markdown input processor")}
+\newcommand\markdownMakeOther{%
+  \count0=128\relax
+  \loop
+    \catcode\count0=11\relax
+    \advance\count0 by 1\relax
+  \ifnum\count0<256\repeat}%
+\endinput
+%%
+%% End of file `markdown.sty'.


Property changes on: trunk/Master/texmf-dist/tex/latex/markdown/markdown.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/luatex/markdown/markdown.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/markdown/markdown.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/luatex/markdown/markdown.lua	2016-06-11 23:15:05 UTC (rev 41376)
@@ -0,0 +1,1057 @@
+-- 
+-- Copyright (C) 2009-2016 John MacFarlane, Hans Hagen
+-- 
+-- Permission is hereby granted, free of charge, to any person obtaining
+-- a copy of this software and associated documentation files (the
+-- "Software"), to deal in the Software without restriction, including
+-- without limitation the rights to use, copy, modify, merge, publish,
+-- distribute, sublicense, and/or sell copies of the Software, and to
+-- permit persons to whom the Software is furnished to do so, subject to
+-- the following conditions:
+-- 
+-- The above copyright notice and this permission notice shall be included
+-- in all copies or substantial portions of the Software.
+-- 
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+-- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+-- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+-- 
+-- Copyright (C) 2016 Vít Novotný
+-- 
+-- This work may be distributed and/or modified under the
+-- conditions of the LaTeX Project Public License, either version 1.3
+-- of this license or (at your option) any later version.
+-- The latest version of this license is in
+-- 
+--     http://www.latex-project.org/lppl.txt
+-- 
+-- and version 1.3 or later is part of all distributions of LaTeX
+-- version 2005/12/01 or later.
+-- 
+-- This work has the LPPL maintenance status `maintained'.
+-- The Current Maintainer of this work is Vít Novotný.
+-- 
+-- Send bug reports, requests for additions and questions
+-- either to the GitHub issue tracker at
+-- 
+--     https://github.com/witiko/markdown/issues
+-- 
+-- or to the e-mail address <witiko at mail.muni.cz>.
+-- 
+-- MODIFICATION ADVICE:
+-- 
+-- If you want to customize this file, it is best to make a copy of
+-- the source file(s) from which it was produced. Use a different
+-- name for your copy(ies) and modify the copy(ies); this will ensure
+-- that your modifications do not get overwritten when you install a
+-- new release of the standard system. You should also ensure that
+-- your modified source file does not generate any modified file with
+-- the same name as a standard file.
+-- 
+-- You will also need to produce your own, suitably named, .ins file to
+-- control the generation of files from your source file; this file
+-- should contain your own preambles for the files it generates, not
+-- those in the standard .ins files.
+-- 
+if not modules then modules = { } end modules ['markdown'] = {
+    version   = "1.0.1",
+    comment   = "A module for the conversion from markdown to plain TeX",
+    author    = "John MacFarlane, Hans Hagen, Vít Novotný",
+    copyright = "2009-2016 John MacFarlane, Hans Hagen; 2016 Vít Novotný",
+    license   = "LPPL 1.3"
+}
+local lpeg = require("lpeg")
+local unicode = require("unicode")
+local md5 = require("md5")
+local M = {}
+M.new = {}
+local defaultOptions = {}
+defaultOptions.blankBeforeBlockquote = false
+defaultOptions.blankBeforeHeading = false
+defaultOptions.cacheDir = "."
+defaultOptions.definitionLists = false
+defaultOptions.hashEnumerators = false
+defaultOptions.hybrid = false
+defaultOptions.footnotes = false
+defaultOptions.preserveTabs = false
+defaultOptions.smartEllipses = false
+defaultOptions.startNumber = true
+defaultOptions.tightLists = true
+local upper, gsub, format, length =
+  string.upper, string.gsub, string.format, string.len
+local concat = table.concat
+local P, R, S, V, C, Cg, Cb, Cmt, Cc, Ct, B, Cs, any =
+  lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.C, lpeg.Cg, lpeg.Cb,
+  lpeg.Cmt, lpeg.Cc, lpeg.Ct, lpeg.B, lpeg.Cs, lpeg.P(1)
+local util = {}
+function util.err(msg, exit_code)
+  io.stderr:write("markdown.lua: " .. msg .. "\n")
+  os.exit(exit_code or 1)
+end
+function util.cache(dir, string, salt, transform, suffix)
+  local digest = md5.sumhexa(string .. (salt or ""))
+  local name = util.pathname(dir, digest .. suffix)
+  local file = io.open(name, "r")
+  if file == nil then -- If no cache entry exists, then create a new one.
+    local file = assert(io.open(name, "w"))
+    local result = string
+    if transform ~= nil then
+      result = transform(result)
+    end
+    assert(file:write(result))
+    assert(file:close())
+  end
+  return name
+end
+function util.table_copy(t)
+  local u = { }
+  for k, v in pairs(t) do u[k] = v end
+  return setmetatable(u, getmetatable(t))
+end
+function util.expand_tabs_in_line(s, tabstop)
+  local tab = tabstop or 4
+  local corr = 0
+  return (s:gsub("()\t", function(p)
+            local sp = tab - (p - 1 + corr) % tab
+            corr = corr - 1 + sp
+            return string.rep(" ", sp)
+          end))
+end
+function util.walk(t, f)
+  local typ = type(t)
+  if typ == "string" then
+    f(t)
+  elseif typ == "table" then
+    local i = 1
+    local n
+    n = t[i]
+    while n do
+      util.walk(n, f)
+      i = i + 1
+      n = t[i]
+    end
+  elseif typ == "function" then
+    local ok, val = pcall(t)
+    if ok then
+      util.walk(val,f)
+    end
+  else
+    f(tostring(t))
+  end
+end
+function util.flatten(ary)
+  local new = {}
+  for _,v in ipairs(ary) do
+    if type(v) == "table" then
+      for _,w in ipairs(util.flatten(v)) do
+        new[#new + 1] = w
+      end
+    else
+      new[#new + 1] = v
+    end
+  end
+  return new
+end
+function util.rope_to_string(rope)
+  local buffer = {}
+  util.walk(rope, function(x) buffer[#buffer + 1] = x end)
+  return table.concat(buffer)
+end
+function util.rope_last(rope)
+  if #rope == 0 then
+    return nil
+  else
+    local l = rope[#rope]
+    if type(l) == "table" then
+      return util.rope_last(l)
+    else
+      return l
+    end
+  end
+end
+function util.intersperse(ary, x)
+  local new = {}
+  local l = #ary
+  for i,v in ipairs(ary) do
+    local n = #new
+    new[n + 1] = v
+    if i ~= l then
+      new[n + 2] = x
+    end
+  end
+  return new
+end
+function util.map(ary, f)
+  local new = {}
+  for i,v in ipairs(ary) do
+    new[i] = f(v)
+  end
+  return new
+end
+function util.escaper(char_escapes, string_escapes)
+  local char_escapes_list = ""
+  for i,_ in pairs(char_escapes) do
+    char_escapes_list = char_escapes_list .. i
+  end
+  local escapable = S(char_escapes_list) / char_escapes
+  if string_escapes then
+    for k,v in pairs(string_escapes) do
+      escapable = P(k) / v + escapable
+    end
+  end
+  local escape_string = Cs((escapable + any)^0)
+  return function(s)
+    return lpeg.match(escape_string, s)
+  end
+end
+function util.pathname(dir, file)
+  if #dir == 0 then
+    return file
+  else
+    return dir .. "/" .. file
+  end
+end
+M.writer = {}
+function M.writer.new(options)
+  local self = {}
+  options = options or {}
+  setmetatable(options, { __index = function (_, key)
+    return defaultOptions[key] end })
+  self.suffix = ".tex"
+  self.space = " "
+  function self.plain(s)
+    return s
+  end
+  function self.paragraph(s)
+    return s
+  end
+  function self.pack(name)
+    return [[\input"]] .. name .. [["\relax]]
+  end
+  self.interblocksep = "\n\n"
+  self.containersep = "\n\n"
+  self.eof = [[\relax]]
+  self.linebreak = "\\markdownRendererLineBreak "
+  self.ellipsis = "\\markdownRendererEllipsis{}"
+  self.hrule = "\\markdownRendererHorizontalRule "
+  local escaped = {
+     ["{"] = "\\{",
+     ["}"] = "\\}",
+     ["$"] = "\\$",
+     ["%"] = "\\%",
+     ["&"] = "\\&",
+     ["_"] = "\\_",
+     ["#"] = "\\#",
+     ["^"] = "\\^{}",
+     ["\\"] = "\\char92{}",
+     ["~"] = "\\char126{}",
+     ["|"] = "\\char124{}", }
+  local escape = util.escaper(escaped)
+  if options.hybrid then
+    self.string = function(s) return s end
+  else
+    self.string = escape
+  end
+  function self.code(s)
+    return {"\\markdownRendererCodeSpan{",escape(s),"}"}
+  end
+  function self.link(lab,src,tit)
+    return {"\\markdownRendererLink{",lab,"}",
+                          "{",self.string(src),"}",
+                          "{",self.string(tit),"}"}
+  end
+  function self.image(lab,src,tit)
+    return {"\\markdownRendererImage{",lab,"}",
+                           "{",self.string(src),"}",
+                           "{",self.string(tit),"}"}
+  end
+  local function ulitem(s)
+    return {"\\markdownRendererUlItem ",s}
+  end
+
+  function self.bulletlist(items,tight)
+    local buffer = {}
+    for _,item in ipairs(items) do
+      buffer[#buffer + 1] = ulitem(item)
+    end
+    local contents = util.intersperse(buffer,"\n")
+    if tight and options.tightLists then
+      return {"\\markdownRendererUlBeginTight\n",contents,
+        "\n\\markdownRendererUlEndTight "}
+    else
+      return {"\\markdownRendererUlBegin\n",contents,
+        "\n\\markdownRendererUlEnd "}
+    end
+  end
+  local function olitem(s,num)
+    if num ~= nil then
+      return {"\\markdownRendererOlItemWithNumber{",num,"}",s}
+    else
+      return {"\\markdownRendererOlItem ",s}
+    end
+  end
+
+  function self.orderedlist(items,tight,startnum)
+    local buffer = {}
+    local num = startnum
+    for _,item in ipairs(items) do
+      buffer[#buffer + 1] = olitem(item,num)
+      if num ~= nil then
+        num = num + 1
+      end
+    end
+    local contents = util.intersperse(buffer,"\n")
+    if tight and options.tightLists then
+      return {"\\markdownRendererOlBeginTight\n",contents,
+        "\n\\markdownRendererOlEndTight "}
+    else
+      return {"\\markdownRendererOlBegin\n",contents,
+        "\n\\markdownRendererOlEnd "}
+    end
+  end
+  local function dlitem(term,defs)
+      return {"\\markdownRendererDlItem{",term,"}\n",defs}
+  end
+
+  function self.definitionlist(items,tight)
+    local buffer = {}
+    for _,item in ipairs(items) do
+      buffer[#buffer + 1] = dlitem(item.term,
+        util.intersperse(item.definitions, self.interblocksep))
+    end
+    local contents = util.intersperse(buffer, self.containersep)
+    if tight and options.tightLists then
+      return {"\\markdownRendererDlBeginTight\n\n", contents,
+        "\n\n\\markdownRendererDlEndTight\n"}
+    else
+      return {"\\markdownRendererDlBegin\n\n", contents,
+        "\n\n\\markdownRendererDlEnd\n"}
+    end
+  end
+  function self.emphasis(s)
+    return {"\\markdownRendererEmphasis{",s,"}"}
+  end
+  function self.strong(s)
+    return {"\\markdownRendererStrongEmphasis{",s,"}"}
+  end
+  function self.blockquote(s)
+    return {"\\markdownRendererBlockQuoteBegin\n",s,
+      "\n\\markdownRendererBlockQuoteEnd "}
+  end
+  function self.verbatim(s)
+    local name = util.cache(options.cacheDir, s, nil, nil, ".verbatim")
+    return {"\\markdownRendererInputVerbatim{",name,"}"}
+  end
+  function self.heading(s,level)
+    local cmd
+    if level == 1 then
+      cmd = "\\markdownRendererHeadingOne"
+    elseif level == 2 then
+      cmd = "\\markdownRendererHeadingTwo"
+    elseif level == 3 then
+      cmd = "\\markdownRendererHeadingThree"
+    elseif level == 4 then
+      cmd = "\\markdownRendererHeadingFour"
+    elseif level == 5 then
+      cmd = "\\markdownRendererHeadingFive"
+    elseif level == 6 then
+      cmd = "\\markdownRendererHeadingSix"
+    else
+      cmd = ""
+    end
+    return {cmd,"{",s,"}"}
+  end
+  function self.note(s)
+    return {"\\markdownRendererFootnote{",s,"}"}
+  end
+
+  return self
+end
+M.reader = {}
+function M.reader.new(writer, options)
+  local self = {}
+  options = options or {}
+  setmetatable(options, { __index = function (_, key)
+    return defaultOptions[key] end })
+  local function normalize_tag(tag)
+    return unicode.utf8.lower(
+      gsub(util.rope_to_string(tag), "[ \n\r\t]+", " "))
+  end
+  local expandtabs
+  if options.preserveTabs then
+    expandtabs = function(s) return s end
+  else
+    expandtabs = function(s)
+                   if s:find("\t") then
+                     return s:gsub("[^\n]*", util.expand_tabs_in_line)
+                   else
+                     return s
+                   end
+                 end
+  end
+  local syntax
+  local blocks
+  local inlines
+
+  local parse_blocks =
+    function(str)
+      local res = lpeg.match(blocks, str)
+      if res == nil then
+        error(format("parse_blocks failed on:\n%s", str:sub(1,20)))
+      else
+        return res
+      end
+    end
+
+  local parse_inlines =
+    function(str)
+      local res = lpeg.match(inlines, str)
+      if res == nil then
+        error(format("parse_inlines failed on:\n%s",
+        str:sub(1,20)))
+      else
+        return res
+      end
+    end
+
+  local parse_inlines_no_link =
+    function(str)
+      local res = lpeg.match(inlines_no_link, str)
+      if res == nil then
+        error(format("parse_inlines_no_link failed on:\n%s",
+        str:sub(1,20)))
+      else
+        return res
+      end
+    end
+  local percent                = P("%")
+  local asterisk               = P("*")
+  local dash                   = P("-")
+  local plus                   = P("+")
+  local underscore             = P("_")
+  local period                 = P(".")
+  local hash                   = P("#")
+  local ampersand              = P("&")
+  local backtick               = P("`")
+  local less                   = P("<")
+  local more                   = P(">")
+  local space                  = P(" ")
+  local squote                 = P("'")
+  local dquote                 = P('"')
+  local lparent                = P("(")
+  local rparent                = P(")")
+  local lbracket               = P("[")
+  local rbracket               = P("]")
+  local circumflex             = P("^")
+  local slash                  = P("/")
+  local equal                  = P("=")
+  local colon                  = P(":")
+  local semicolon              = P(";")
+  local exclamation            = P("!")
+
+  local digit                  = R("09")
+  local hexdigit               = R("09","af","AF")
+  local letter                 = R("AZ","az")
+  local alphanumeric           = R("AZ","az","09")
+  local keyword                = letter * alphanumeric^0
+
+  local doubleasterisks        = P("**")
+  local doubleunderscores      = P("__")
+  local fourspaces             = P("    ")
+
+  local any                    = P(1)
+  local fail                   = any - 1
+  local always                 = P("")
+
+  local escapable              = S("\\`*_{}[]()+_.!#-~:^")
+  local anyescaped             = P("\\") / "" * escapable
+                               + any
+
+  local tab                    = P("\t")
+  local spacechar              = S("\t ")
+  local spacing                = S(" \n\r\t")
+  local newline                = P("\n")
+  local nonspacechar           = any - spacing
+  local tightblocksep          = P("\001")
+
+  local specialchar
+  if options.smartEllipses then
+    specialchar                = S("*_`&[]!\\.")
+  else
+    specialchar                = S("*_`&[]!\\")
+  end
+
+  local normalchar             = any -
+                                 (specialchar + spacing + tightblocksep)
+  local optionalspace          = spacechar^0
+  local spaces                 = spacechar^1
+  local eof                    = - any
+  local nonindentspace         = space^-3 * - spacechar
+  local indent                 = space^-3 * tab
+                               + fourspaces / ""
+  local linechar               = P(1 - newline)
+
+  local blankline              = optionalspace * newline / "\n"
+  local blanklines             = blankline^0
+  local skipblanklines         = (optionalspace * newline)^0
+  local indentedline           = indent    /"" * C(linechar^1 * newline^-1)
+  local optionallyindentedline = indent^-1 /"" * C(linechar^1 * newline^-1)
+  local sp                     = spacing^0
+  local spnl                   = optionalspace * (newline * optionalspace)^-1
+  local line                   = linechar^0 * newline
+                               + linechar^1 * eof
+  local nonemptyline           = line - blankline
+
+  local chunk = line * (optionallyindentedline - blankline)^0
+
+  -- block followed by 0 or more optionally
+  -- indented blocks with first line indented.
+  local function indented_blocks(bl)
+    return Cs( bl
+             * (blankline^1 * indent * -blankline * bl)^0
+             * blankline^1 )
+  end
+  local bulletchar = C(plus + asterisk + dash)
+
+  local bullet     = ( bulletchar * #spacing * (tab + space^-3)
+                     + space * bulletchar * #spacing * (tab + space^-2)
+                     + space * space * bulletchar * #spacing * (tab + space^-1)
+                     + space * space * space * bulletchar * #spacing
+                     ) * -bulletchar
+
+  if options.hashEnumerators then
+    dig = digit + hash
+  else
+    dig = digit
+  end
+
+  local enumerator = C(dig^3 * period) * #spacing
+                   + C(dig^2 * period) * #spacing * (tab + space^1)
+                   + C(dig * period) * #spacing * (tab + space^-2)
+                   + space * C(dig^2 * period) * #spacing
+                   + space * C(dig * period) * #spacing * (tab + space^-1)
+                   + space * space * C(dig^1 * period) * #spacing
+  local openticks   = Cg(backtick^1, "ticks")
+
+  local function captures_equal_length(s,i,a,b)
+    return #a == #b and i
+  end
+
+  local closeticks  = space^-1 *
+                      Cmt(C(backtick^1) * Cb("ticks"), captures_equal_length)
+
+  local intickschar = (any - S(" \n\r`"))
+                    + (newline * -blankline)
+                    + (space - closeticks)
+                    + (backtick^1 - closeticks)
+
+  local inticks     = openticks * space^-1 * C(intickschar^1) * closeticks
+  local leader        = space^-3
+
+  -- in balanced brackets, parentheses, quotes:
+  local bracketed     = P{ lbracket
+                         * ((anyescaped - (lbracket + rbracket
+                             + blankline^2)) + V(1))^0
+                         * rbracket }
+
+  local inparens      = P{ lparent
+                         * ((anyescaped - (lparent + rparent
+                             + blankline^2)) + V(1))^0
+                         * rparent }
+
+  local squoted       = P{ squote * alphanumeric
+                         * ((anyescaped - (squote + blankline^2))
+                             + V(1))^0
+                         * squote }
+
+  local dquoted       = P{ dquote * alphanumeric
+                         * ((anyescaped - (dquote + blankline^2))
+                             + V(1))^0
+                         * dquote }
+
+  -- bracketed 'tag' for markdown links, allowing nested brackets:
+  local tag           = lbracket
+                      * Cs((alphanumeric^1
+                           + bracketed
+                           + inticks
+                           + (anyescaped - (rbracket + blankline^2)))^0)
+                      * rbracket
+
+  -- url for markdown links, allowing balanced parentheses:
+  local url           = less * Cs((anyescaped-more)^0) * more
+                      + Cs((inparens + (anyescaped-spacing-rparent))^1)
+
+  -- quoted text possibly with nested quotes:
+  local title_s       = squote * Cs(((anyescaped-squote) + squoted)^0) *
+                        squote
+
+  local title_d       = dquote * Cs(((anyescaped-dquote) + dquoted)^0) *
+                        dquote
+
+  local title_p       = lparent
+                      * Cs((inparens + (anyescaped-rparent))^0)
+                      * rparent
+
+  local title         = title_d + title_s + title_p
+
+  local optionaltitle = spnl * title * spacechar^0
+                      + Cc("")
+  local rawnotes = {}
+
+  local function strip_first_char(s)
+    return s:sub(2)
+  end
+
+  -- like indirect_link
+  local function lookup_note(ref)
+    return function()
+      local found = rawnotes[normalize_tag(ref)]
+      if found then
+        return writer.note(parse_blocks(found))
+      else
+        return {"[^", ref, "]"}
+      end
+    end
+  end
+
+  local function register_note(ref,rawnote)
+    rawnotes[normalize_tag(ref)] = rawnote
+    return ""
+  end
+
+  local RawNoteRef = #(lbracket * circumflex) * tag / strip_first_char
+
+  local NoteRef    = RawNoteRef / lookup_note
+
+  local NoteBlock
+
+  if options.footnotes then
+    NoteBlock = leader * RawNoteRef * colon * spnl *
+                indented_blocks(chunk) / register_note
+  else
+    NoteBlock = fail
+  end
+  -- List of references defined in the document
+  local references
+
+  -- add a reference to the list
+  local function register_link(tag,url,title)
+      references[normalize_tag(tag)] = { url = url, title = title }
+      return ""
+  end
+
+  -- parse a reference definition:  [foo]: /bar "title"
+  local define_reference_parser =
+    leader * tag * colon * spacechar^0 * url * optionaltitle * blankline^1
+
+  -- lookup link reference and return either
+  -- the link or nil and fallback text.
+  local function lookup_reference(label,sps,tag)
+      local tagpart
+      if not tag then
+          tag = label
+          tagpart = ""
+      elseif tag == "" then
+          tag = label
+          tagpart = "[]"
+      else
+          tagpart = {"[", parse_inlines(tag), "]"}
+      end
+      if sps then
+        tagpart = {sps, tagpart}
+      end
+      local r = references[normalize_tag(tag)]
+      if r then
+        return r
+      else
+        return nil, {"[", parse_inlines(label), "]", tagpart}
+      end
+  end
+
+  -- lookup link reference and return a link, if the reference is found,
+  -- or a bracketed label otherwise.
+  local function indirect_link(label,sps,tag)
+    return function()
+      local r,fallback = lookup_reference(label,sps,tag)
+      if r then
+        return writer.link(parse_inlines_no_link(label), r.url, r.title)
+      else
+        return fallback
+      end
+    end
+  end
+
+  -- lookup image reference and return an image, if the reference is found,
+  -- or a bracketed label otherwise.
+  local function indirect_image(label,sps,tag)
+    return function()
+      local r,fallback = lookup_reference(label,sps,tag)
+      if r then
+        return writer.image(writer.string(label), r.url, r.title)
+      else
+        return {"!", fallback}
+      end
+    end
+  end
+  local Inline    = V("Inline")
+
+  local Str       = normalchar^1 / writer.string
+
+  local Ellipsis  = P("...") / writer.ellipsis
+
+  local Smart     = Ellipsis
+
+  local Symbol    = (specialchar - tightblocksep) / writer.string
+
+  local Code      = inticks / writer.code
+
+  local bqstart      = more
+  local headerstart  = hash
+                     + (line * (equal^1 + dash^1) * optionalspace * newline)
+
+  if options.blankBeforeBlockquote then
+    bqstart = fail
+  end
+
+  if options.blankBeforeHeading then
+    headerstart = fail
+  end
+
+  local Endline   = newline * -( -- newline, but not before...
+                        blankline -- paragraph break
+                      + tightblocksep  -- nested list
+                      + eof       -- end of document
+                      + bqstart
+                      + headerstart
+                    ) * spacechar^0 / writer.space
+
+  local Space     = spacechar^2 * Endline / writer.linebreak
+                  + spacechar^1 * Endline^-1 * eof / ""
+                  + spacechar^1 * Endline^-1 * optionalspace / writer.space
+
+  -- parse many p between starter and ender
+  local function between(p, starter, ender)
+      local ender2 = B(nonspacechar) * ender
+      return (starter * #nonspacechar * Ct(p * (p - ender2)^0) * ender2)
+  end
+
+  local Strong = ( between(Inline, doubleasterisks, doubleasterisks)
+                 + between(Inline, doubleunderscores, doubleunderscores)
+                 ) / writer.strong
+
+  local Emph   = ( between(Inline, asterisk, asterisk)
+                 + between(Inline, underscore, underscore)
+                 ) / writer.emphasis
+
+  local urlchar = anyescaped - newline - more
+
+  local AutoLinkUrl   = less
+                      * C(alphanumeric^1 * P("://") * urlchar^1)
+                      * more
+                      / function(url)
+                        return writer.link(writer.string(url), url)
+                      end
+
+  local AutoLinkEmail = less
+                      * C((alphanumeric + S("-._+"))^1 * P("@") * urlchar^1)
+                      * more
+                      / function(email)
+                        return writer.link(writer.string(email),
+                                           "mailto:"..email)
+                      end
+
+  local DirectLink    = (tag / parse_inlines_no_link)  -- no links inside links
+                      * spnl
+                      * lparent
+                      * (url + Cc(""))  -- link can be empty [foo]()
+                      * optionaltitle
+                      * rparent
+                      / writer.link
+
+  local IndirectLink = tag * (C(spnl) * tag)^-1 / indirect_link
+
+  -- parse a link or image (direct or indirect)
+  local Link          = DirectLink + IndirectLink
+
+  local DirectImage   = exclamation
+                      * (tag / parse_inlines)
+                      * spnl
+                      * lparent
+                      * (url + Cc(""))  -- link can be empty [foo]()
+                      * optionaltitle
+                      * rparent
+                      / writer.image
+
+  local IndirectImage  = exclamation * tag * (C(spnl) * tag)^-1 /
+                         indirect_image
+
+  local Image         = DirectImage + IndirectImage
+
+  -- avoid parsing long strings of * or _ as emph/strong
+  local UlOrStarLine  = asterisk^4 + underscore^4 / writer.string
+
+  local EscapedChar   = S("\\") * C(escapable) / writer.string
+  local Block          = V("Block")
+
+  local Verbatim       = Cs( (blanklines
+                           * ((indentedline - blankline))^1)^1
+                           ) / expandtabs / writer.verbatim
+
+  -- strip off leading > and indents, and run through blocks
+  local Blockquote     = Cs((
+            ((leader * more * space^-1)/"" * linechar^0 * newline)^1
+          * (-blankline * linechar^1 * newline)^0
+          * blankline^0
+          )^1) / parse_blocks / writer.blockquote
+
+  local function lineof(c)
+      return (leader * (P(c) * optionalspace)^3 * newline * blankline^1)
+  end
+
+  local HorizontalRule = ( lineof(asterisk)
+                         + lineof(dash)
+                         + lineof(underscore)
+                         ) / writer.hrule
+
+  local Reference      = define_reference_parser / register_link
+
+  local Paragraph      = nonindentspace * Ct(Inline^1) * newline
+                       * ( blankline^1
+                         + #hash
+                         + #(leader * more * space^-1)
+                         )
+                       / writer.paragraph
+
+  local Plain          = nonindentspace * Ct(Inline^1) / writer.plain
+  local starter = bullet + enumerator
+
+  -- we use \001 as a separator between a tight list item and a
+  -- nested list under it.
+  local NestedList            = Cs((optionallyindentedline - starter)^1)
+                              / function(a) return "\001"..a end
+
+  local ListBlockLine         = optionallyindentedline
+                                - blankline - (indent^-1 * starter)
+
+  local ListBlock             = line * ListBlockLine^0
+
+  local ListContinuationBlock = blanklines * (indent / "") * ListBlock
+
+  local function TightListItem(starter)
+      return -HorizontalRule
+             * (Cs(starter / "" * ListBlock * NestedList^-1) /
+                parse_blocks)
+             * -(blanklines * indent)
+  end
+
+  local function LooseListItem(starter)
+      return -HorizontalRule
+             * Cs( starter / "" * ListBlock * Cc("\n")
+               * (NestedList + ListContinuationBlock^0)
+               * (blanklines / "\n\n")
+               ) / parse_blocks
+  end
+
+  local BulletList = ( Ct(TightListItem(bullet)^1)
+                       * Cc(true) * skipblanklines * -bullet
+                     + Ct(LooseListItem(bullet)^1)
+                       * Cc(false) * skipblanklines ) /
+                         writer.bulletlist
+
+  local function orderedlist(items,tight,startNumber)
+    if options.startNumber then
+      startNumber = tonumber(startNumber) or 1  -- fallback for '#'
+    else
+      startNumber = nil
+    end
+    return writer.orderedlist(items,tight,startNumber)
+  end
+
+  local OrderedList = Cg(enumerator, "listtype") *
+                      ( Ct(TightListItem(Cb("listtype")) *
+                           TightListItem(enumerator)^0)
+                        * Cc(true) * skipblanklines * -enumerator
+                      + Ct(LooseListItem(Cb("listtype")) *
+                           LooseListItem(enumerator)^0)
+                        * Cc(false) * skipblanklines
+                      ) * Cb("listtype") / orderedlist
+
+  local defstartchar = S("~:")
+  local defstart     = ( defstartchar * #spacing * (tab + space^-3)
+                     + space * defstartchar * #spacing * (tab + space^-2)
+                     + space * space * defstartchar * #spacing *
+                       (tab + space^-1)
+                     + space * space * space * defstartchar * #spacing
+                     )
+
+  local dlchunk = Cs(line * (indentedline - blankline)^0)
+
+  local function definition_list_item(term, defs, tight)
+    return { term = parse_inlines(term), definitions = defs }
+  end
+
+  local DefinitionListItemLoose = C(line) * skipblanklines
+                           * Ct((defstart *
+                                 indented_blocks(dlchunk) /
+                                 parse_blocks)^1)
+                           * Cc(false)
+                           / definition_list_item
+
+  local DefinitionListItemTight = C(line)
+                           * Ct((defstart * dlchunk /
+                                            parse_blocks)^1)
+                           * Cc(true)
+                           / definition_list_item
+
+  local DefinitionList =  ( Ct(DefinitionListItemLoose^1) * Cc(false)
+                          +  Ct(DefinitionListItemTight^1)
+                             * (skipblanklines *
+                                -DefinitionListItemLoose * Cc(true))
+                          ) / writer.definitionlist
+  local Blank          = blankline / ""
+                       + NoteBlock
+                       + Reference
+                       + (tightblocksep / "\n")
+  -- parse Atx heading start and return level
+  local HeadingStart = #hash * C(hash^-6) * -hash / length
+
+  -- parse setext header ending and return level
+  local HeadingLevel = equal^1 * Cc(1) + dash^1 * Cc(2)
+
+  local function strip_atx_end(s)
+    return s:gsub("[#%s]*\n$","")
+  end
+
+  -- parse atx header
+  local AtxHeading = Cg(HeadingStart,"level")
+                     * optionalspace
+                     * (C(line) / strip_atx_end / parse_inlines)
+                     * Cb("level")
+                     / writer.heading
+
+  -- parse setext header
+  local SetextHeading = #(line * S("=-"))
+                     * Ct(line / parse_inlines)
+                     * HeadingLevel
+                     * optionalspace * newline
+                     / writer.heading
+  syntax =
+    { "Blocks",
+
+      Blocks                = Blank^0 *
+                              Block^-1 *
+                              (Blank^0 / function()
+                                return writer.interblocksep
+                               end * Block)^0 *
+                              Blank^0 *
+                              eof,
+
+      Blank                 = Blank,
+
+      Block                 = V("Blockquote")
+                            + V("Verbatim")
+                            + V("HorizontalRule")
+                            + V("BulletList")
+                            + V("OrderedList")
+                            + V("Heading")
+                            + V("DefinitionList")
+                            + V("Paragraph")
+                            + V("Plain"),
+
+      Blockquote            = Blockquote,
+      Verbatim              = Verbatim,
+      HorizontalRule        = HorizontalRule,
+      BulletList            = BulletList,
+      OrderedList           = OrderedList,
+      Heading               = AtxHeading + SetextHeading,
+      DefinitionList        = DefinitionList,
+      DisplayHtml           = DisplayHtml,
+      Paragraph             = Paragraph,
+      Plain                 = Plain,
+
+      Inline                = V("Str")
+                            + V("Space")
+                            + V("Endline")
+                            + V("UlOrStarLine")
+                            + V("Strong")
+                            + V("Emph")
+                            + V("NoteRef")
+                            + V("Link")
+                            + V("Image")
+                            + V("Code")
+                            + V("AutoLinkUrl")
+                            + V("AutoLinkEmail")
+                            + V("EscapedChar")
+                            + V("Smart")
+                            + V("Symbol"),
+
+      Str                   = Str,
+      Space                 = Space,
+      Endline               = Endline,
+      UlOrStarLine          = UlOrStarLine,
+      Strong                = Strong,
+      Emph                  = Emph,
+      NoteRef               = NoteRef,
+      Link                  = Link,
+      Image                 = Image,
+      Code                  = Code,
+      AutoLinkUrl           = AutoLinkUrl,
+      AutoLinkEmail         = AutoLinkEmail,
+      InlineHtml            = InlineHtml,
+      HtmlEntity            = HtmlEntity,
+      EscapedChar           = EscapedChar,
+      Smart                 = Smart,
+      Symbol                = Symbol,
+    }
+
+  if not options.definitionLists then
+    syntax.DefinitionList = fail
+  end
+
+  if not options.footnotes then
+    syntax.NoteRef = fail
+  end
+
+  if not options.smartEllipses then
+    syntax.Smart = fail
+  end
+
+  blocks = Ct(syntax)
+
+  local inlines_t = util.table_copy(syntax)
+  inlines_t[1] = "Inlines"
+  inlines_t.Inlines = Inline^0 * (spacing^0 * eof / "")
+  inlines = Ct(inlines_t)
+
+  inlines_no_link_t = util.table_copy(inlines_t)
+  inlines_no_link_t.Link = fail
+  inlines_no_link = Ct(inlines_no_link_t)
+  function self.convert(input)
+    references = {}
+    local opt_string = {}
+    for k,_ in pairs(defaultOptions) do
+      local v = options[k]
+      if k ~= "cacheDir" then
+        opt_string[#opt_string+1] = k .. "=" .. tostring(v)
+      end
+    end
+    table.sort(opt_string)
+    local salt = table.concat(opt_string, ",")
+    local name = util.cache(options.cacheDir, input, salt, function(input)
+        return util.rope_to_string(parse_blocks(input)) .. writer.eof
+      end, ".md" .. writer.suffix)
+    return writer.pack(name)
+  end
+  return self
+end
+function M.new(options)
+  local writer = M.writer.new(options)
+  local reader = M.reader.new(writer, options)
+  return reader.convert
+end
+
+return M


Property changes on: trunk/Master/texmf-dist/tex/luatex/markdown/markdown.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/tlpkg/bin/tlpkg-ctan-check
===================================================================
--- trunk/Master/tlpkg/bin/tlpkg-ctan-check	2016-06-11 23:11:37 UTC (rev 41375)
+++ trunk/Master/tlpkg/bin/tlpkg-ctan-check	2016-06-11 23:15:05 UTC (rev 41376)
@@ -374,7 +374,7 @@
     make4ht makebarcode makebase makebox makecell makecirc makecmds
     makedtx makeglos makeplot
     makeshape mandi manfnt manfnt-font manuscript margbib
-    marginfix marginnote marvosym
+    marginfix marginnote markdown marvosym
     matc3 matc3mem match_parens
     math-e mathabx mathabx-type1 mathalfa mathastext
     mathcomp mathdesign mathdots mathexam mathpartir

Modified: trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2016-06-11 23:11:37 UTC (rev 41375)
+++ trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2016-06-11 23:15:05 UTC (rev 41376)
@@ -607,6 +607,7 @@
 depend manuscript
 depend marginfix
 depend marginnote
+depend markdown
 depend mathalfa
 depend mathastext
 depend mathexam

Added: trunk/Master/tlpkg/tlpsrc/markdown.tlpsrc
===================================================================


More information about the tex-live-commits mailing list