md2latex


md2latex


MD2LATEX ("MarkDown to LaTeX") is a command that transforms a RexxPub article or book (a Markdown file written for the article or the book document class) into LaTeX, after expanding all Rexx fenced code blocks. Conferences and journals usually want LaTeX, and often their own document class: md2latex writes articles for article (the default), Springer's llncs, IEEEtran and ACM's acmart (see ACM). A book (docclass: book in the YAML front matter) becomes a LaTeX book, ready for print: see Books.

The LaTeX it writes is for LuaLaTeX, the only engine that handles Unicode and OpenType fonts properly (pdfTeX does not do Unicode, and XeTeX no longer receives new features from the LaTeX team). With --pdf, md2latex runs LuaLaTeX too.

Usage

[rexx] md2latex [options] filename

md2latex writes filename.tex next to filename.md (or the file given with -o). With --pdf, it also writes the PDF.

When called without arguments, md2latex displays help information and exits.

Options


--check-deps Check that Pandoc, LuaLaTeX and the fonts are there
--class NAME The LaTeX document class: article (default),
llncs, IEEEtran, acmart or book
--filter FILE One more Lua filter for Pandoc, after md2latex's
--header FILE More LaTeX for the preamble, after md2latex's
--csl NAME|PATH Set the Citation Style Language style
--default "options" Default options for all code blocks
-exp, --experimental Enable Experimental features for all code blocks
-h, --help Display help and exit
-it, --itrace Print internal traceback on error
--keep Keep the intermediate files (Markdown, header)
--listings Code that is not Rexx with listings
-o, --output FILE The LaTeX file to write
--pandoc-highlighting-style NAME Pandoc's style for code that is not Rexx
(default: pygments)
--pdf Run LuaLaTeX too
--style NAME Set the visual theme for Rexx code blocks
(default: light)
-u, --tutor, --unicode Enable TUTOR-flavoured Unicode for all code blocks
-xtr, --executor Enable Executor support for all code blocks


What is translated

md2latex reads the same Markdown as md2pdf, with the same RexxPub conventions:

  • The title page (::::: title-page, with its author, affiliation, address, city, country, email, phone and date divs, and an optional subtitle in <small>) becomes the title block of the document class. Each author div starts a new author, and the divs that follow it are that author's. city and country are more lines of the address, except for acmart, which wants them on their own. With llncs, authors who share an institution share its \institute entry; with IEEEtran (in conference mode), each author is an \IEEEauthorblockN/\IEEEauthorblockA pair; with acmart, see ACM. A title given in the YAML front matter (title:, author:, date:) works too.
  • ::: abstract (its own heading, if it has one, is left out: the class writes its own) and ::: keywords (the keywords, separated by commas) become the abstract and the keywords, as each class writes them. abstract: and keywords: in the YAML front matter work too.
  • Epigraphs (::::: epigraph with ::: cite and ::: attribution), ::: quote, ::: quotation, ::: noindent and {.newpage} keep their meaning.
  • <small> around an acronym (a single word with no lowercase letters, as in <small>HTML</small>) becomes small capitals; around anything else (a sentence, perhaps with links and footnotes) it is small print. <sup>, <sub>, <br>, <em>, <strong>, <kbd>, <s> and a few more are translated. Any other HTML tag is left out, and md2latex says so.
  • A <pre> block (a terminal session, say) is set in the box of the code, as plain text, with its entities decoded and its tags left out.
  • Citations go through Pandoc's citeproc, with the CSL style given.
  • section-numbers:, size: (10, 11 or 12), language: and style: in the rexxpub: block of the YAML front matter are honoured. Size, paper (A4) and margins (3cm) apply only to article: a publisher's class decides its own page, and its paragraphs are indented, as the publishers want them (Pandoc's parskip is not used).
  • latex: class-options: in the rexxpub: block (class-options: review, anonymous, say) are passed to the document class, whichever it is.

ACM

With --class acmart, md2latex writes for ACM's acmart class, in the sigconf format (ACM's conference proceedings) unless latex: class-options: names another (acmsmall, sigplan, manuscript...). review (line numbers) and anonymous (no authors, for double-blind review) are class options too:

---
rexxpub:
  latex:
    class-options: sigconf, review, anonymous
    header: acm.tex
---

ACM's class does not work with Pandoc's own LaTeX template (which loads packages that clash with it), so md2latex uses a template of its own, md2latex/acmart.latex. The fonts are acmart's (Linux Libertine and Biolinum, and its mathematics), with md2latex's fallback chains; the code is DejaVu Sans Mono, as in the other classes.

  • Authors. Each author is \author, \affiliation and \email. The affiliation is the affiliation div (\institution), the city div (or, without it, the address) and the country div. acmart stops with an error when an affiliation has no country, and md2latex says so beforehand. The phone and the date are not printed by ACM, and md2latex says that they are left out.

  • Abstract and keywords go before \maketitle, as acmart wants them; the keywords are \keywords.

  • What only ACM knows --- the rights (\setcopyright), the conference (\acmConference), the DOI, the ISBN, the CCS concepts (\ccsdesc) --- go in a LaTeX file of the article's own, latex: header::

    \setcopyright{acmlicensed}
    \acmConference[ICSE '27]{The 49th International Conference on
      Software Engineering}{April 2027}{Rio de Janeiro, Brazil}
    \ccsdesc[500]{Software and its engineering~Development frameworks
      and environments}

    Without them, acmart prints its placeholders, which is what a submission for review usually has.

  • References. --csl acm uses the ACM reference format, through Pandoc's citeproc. (ACM's final production system, TAPS, wants BibTeX and its own .bst instead: that is for the camera-ready version.)

  • In the two-column formats (sigconf, sigplan, siggraph, acmtog), tables are floats, as with IEEEtran.

Books

With docclass: book in the rexxpub: block of the YAML front matter (or --class book), md2latex writes a LaTeX book: chapters at the top, facing pages, a wider inner margin, running heads, and the size of the YAML (10, 11 or 12pt). The Markdown is the one of RexxPub's book class, with a few conventions more:

  • Parts and chapters. # Title {.part} is a part; any other level-1 heading, a chapter. The unnumbered chapters ({.unnumbered}) before the first part or numbered chapter are the front matter (roman page numbers); a heading with .back starts the back matter.
  • The title page. ::::: title-page with {.book-title} and {.book-subtitle} headings, ::: author, any number of ::: title-line (or date) divs below the author, and ::: title-verso divs, which go to the back of the title page (edition, copyright, address).
  • The lists. An empty div says where each list goes, and the heading in it is the list's title: ::: {#toc} (the table of contents), #list-of-figures, #list-of-tables, #list-of-listings and #index-body (the index; its title is the heading {#index .back} before the div). With latex: toc-depth: N, the table of contents goes down to LaTeX level N (0 is the chapter).
  • Captioned things are divs whose last paragraph is the caption: ::: {#id .listing} (code), ::: {#id .figure} (a picture, or a program's output, which stays where it is) and ::: {#id .table}. Listings are numbered as listings: label: says ("Listing" by default), through the book or, with listings: numbering: section (or chapter), within each section: "Code 1.1-1".
  • Code that is not Rexx (a fence with another class, or with source= to read it from a file) is set in a box like Rexx's, without highlighting; ``` {.output} is a program's output; `x`{.out}, a piece of output in running text.
  • Cross-references are links whose class says what to write: [Code 1.1-1](#id){.ref} (the label and the number), .ref-num and .ref-chapter (the number; for an anchor []{#id} in running text, the number of its section), .ref-page (the page), .ref-dir ("above" or "below", by where the target is) and .ref-text (a heading's title). The text of the link is what an HTML reader sees.
  • The index. []{ix="Level 1!Level 2!Level 3"} is an entry, and {.main} makes its page number bold. makeindex sorts it; md2latex quotes what makeindex and hyperref would misread.

A book can bring its own LaTeX and its own conventions: latex: header: and latex: filter: in the YAML (or --header and --filter) name a LaTeX file read after md2latex's preamble, and a Lua filter run after md2latex's.

---
rexxpub:
  docclass: book
  listings:
    label: Code
    numbering: section
  latex:
    header: latex/book.tex
    filter: latex/book.lua
    toc-depth: 3
    paper: a4
---

A book needs up to five LuaLaTeX runs: the lists, the index and the references move the page numbers until they settle.

Rexx code

Rexx code is highlighted exactly as for HTML, and every token is then written as a LaTeX macro whose look (colour, bold, italic, underline) is generated from the same CSS that styles the HTML: a listing looks the same in both. A listing is a box with the background of its style, in one piece (no stripes between lines), that can break across pages. A listing too wide for the box is set smaller, down to 60% of the size, so that its longest line fits; only a line still too long goes on, indented, on the next. Captions (caption=) and line numbers (.numberLines, startFrom=) are kept. Inline mentions (`...`{.rexx}) work anywhere, headings and footnotes included. A Rexx block that does not parse does not stop md2latex: md2latex says so, with the error, and the block is shown as the error, as in HTML. The macros are those of the LaTeX highlighter: the LaTeX that highlight --latex writes and that of md2latex are the same.

The default style is light, because the result is meant for paper.

Code that is not Rexx

Code in other languages (~~~python, ~~~java...) is highlighted by Pandoc, as md2html and md2pdf do, with the style that highlight-style: names at the top of the YAML front matter (pygments by default; also kate, tango, espresso, zenburn, monochrome, breezeDark and haddock), or --pandoc-highlighting-style. A fence with no language is set as it is, in the code font. In both, a line too long for the page goes on, indented, in the next one.

Some publishers, or co-authors, want listings instead:

rexxpub:
  latex:
    code: listings

(or --listings) sets that code with listings, which breaks long lines too. Rexx code is not affected: it is always the Rexx Highlighter's.

Unicode

Every font has a chain of fallback fonts (Noto, mostly), so that text in any script, symbols, mathematical characters, CJK and emoji are found. Only the fonts the machine has are in a chain: one that is not installed is left out, and only the characters that it alone would have had are missing. Right-to-left scripts (Arabic, Hebrew) are recognised by their characters and set in their direction, whatever the language of the document. Scripts that need shaping (Devanagari, Bengali, Tamil...) are shaped by HarfBuzz, in the text and in the code alike.

A character that no font has is an error, not a blank: with --pdf, md2latex lists each one with its code point, and fails. Nothing is lost in silence.

Inside a listing, every character is one column wide only if the code font has it: a character taken from a fallback font may be wider or narrower, and the columns after it on that line move.

Requirements

Pandoc (tested with 3.1, 3.9 and 3.11), LuaLaTeX (with luaotfload), and the fonts: TeX Gyre Termes and TeX Gyre Termes Math (or Latin Modern, for llncs; Linux Libertine, for acmart), DejaVu Sans Mono, and the Noto families of the fallback chains. acmart needs, besides, texlive-fonts-extra (Libertine, newtx, Inconsolata) and texlive-plain-generic. On Debian or Ubuntu:

apt-get install pandoc texlive-luatex texlive-latex-extra \
  texlive-publishers tex-gyre fonts-noto-core fonts-noto-cjk \
  fonts-noto-color-emoji fonts-dejavu

--check-deps checks them.