so

Customizing org-mode LaTeX output

Volume 4, Issue 2; 05 Jan 2020

A summary of some Emacs customizations to make org-mode PDF output a little nicer.

[ Note: This posting was updated following a thread of useful comments on Twitter. ]

Writing in Org-mode strikes a nice balance (for me) between the simplicity of plain text and the richness possible with XML (and it integrates into Emacs so nicely!). I can convert to XML if I need to, but lots of times, nearly-plain-text is good enough.

If you’re asking colleagues to review specifications, however, you might get a little pushback on Org mode files. Nice as they are, if you aren’t used to the Org-mode conventions, they can be distracting. You’re not doing yourself, or your reviewers, any favors by distracting them from your content with the presentation.

Publishing Org documents on the web is easy enough: export them as HTML, update the styles if you wish, and you’re done. Publishing them in a more paginated form is also easy enough: export to PDF by way of LaTeX. I’ve actually come to prefer PDF, sad to say as “a web guy”, for review because I have good tools for reading and annotating them on my tablet and because everyone is happy to review them.

Out-of-the-box, what you get from Org-to-PDF export is a default LaTeX article. In an academic context, where I last encountered it, that was fine. In a non-academic context, I don’t think it works as well.

[Image]
Default output

(Actually, with the table of contents turned off, that doesn’t look too bad.)

I wrote a book on TeX in the last millenium, but I haven’t thought about it much in twenty years or so. I reached out to Peter Flynn for some advice and in short order had a LaTeX document that I liked much better than the default. It’s all in the preamble.

This is the preamble Peter proposed:

\RequirePackage{fix-cm}
\PassOptionsToPackage{svgnames}{xcolor}
\documentclass[11pt]{article}
\usepackage{fontspec}
\setmainfont{Linux Libertine O}
\setsansfont[Scale=MatchLowercase]{Raleway}
\setmonofont[Scale=MatchLowercase]{Luxi Mono}
\usepackage{sectsty}
\allsectionsfont{\sffamily}
\usepackage{enumitem}
\setlist[description]{style=unboxed,font=\sffamily\bfseries}
\usepackage{listings}
\lstloadlanguages{XML,XSLT}
\lstset{defaultdialect=XSLT,frame=single,
	framesep=.5em,backgroundcolor=\color{AliceBlue},
	rulecolor=\color{LightSteelBlue},framerule=1pt}
\usepackage{xcolor}
\newcommand\basicdefault[1]{\scriptsize\color{Black}\ttfamily#1}
\lstset{basicstyle=\basicdefault{\spaceskip.5em}}
\lstset{literate=
	    {§}{{\S}}1
	    {©}{{\raisebox{.125ex}{\copyright}\enspace}}1
	    {«}{{\guillemotleft}}1
	    {»}{{\guillemotright}}1
	    {Á}{{\'A}}1
	    {Ä}{{\"A}}1
	    {É}{{\'E}}1
	    {Í}{{\'I}}1
	    {Ó}{{\'O}}1
	    {Ö}{{\"O}}1
	    {Ú}{{\'U}}1
	    {Ü}{{\"U}}1
	    {ß}{{\ss}}2
	    {à}{{\`a}}1
	    {á}{{\'a}}1
	    {ä}{{\"a}}1
	    {é}{{\'e}}1
	    {í}{{\'i}}1
	    {ó}{{\'o}}1
	    {ö}{{\"o}}1
	    {ú}{{\'u}}1
	    {ü}{{\"u}}1
	    {¹}{{\textsuperscript1}}1
            {²}{{\textsuperscript2}}1
            {³}{{\textsuperscript3}}1
	    {ı}{{\i}}1
	    {—}{{---}}1
	    {’}{{'}}1
	    {…}{{\dots}}1
            {⮠}{{$\hookleftarrow$}}1
	    {␣}{{\textvisiblespace}}1,
	    keywordstyle=\color{DarkGreen}\bfseries,
	    identifierstyle=\color{DarkRed},
	    commentstyle=\color{Gray}\upshape,
	    stringstyle=\color{DarkBlue}\upshape,
	    emphstyle=\color{Chocolate}\upshape,
	    showstringspaces=false,
	    columns=fullflexible,
	    keepspaces=true}
\usepackage[letterpaper,margin=1in,left=1.5in]{geometry}
\makeatletter
\renewcommand{\maketitle}{%
  \begingroup\parindent0pt
  \sffamily
  \Huge{\bfseries\@title}\par\bigskip
  \LARGE{\bfseries\@author}\par\medskip
  \normalsize\@date\par\bigskip
  \endgroup}
\makeatother
\usepackage{graphicx}
\usepackage{grffile}
\usepackage{longtable}
\usepackage{wrapfig}
\usepackage{rotating}
\usepackage[normalem]{ulem}
\usepackage{amsmath}
\usepackage{textcomp}
\usepackage{amssymb}
\usepackage{capt-of}
\usepackage{hyperref}
\hypersetup{linkcolor=Blue,urlcolor=DarkBlue,
  citecolor=DarkRed,colorlinks=true}
\AtBeginDocument{\renewcommand{\UrlFont}{\ttfamily}}

And this post is an attempt to write the post I wish I’d found when I was searching for how to update my Org-mode configuration to produce the preamble I wanted!

Here are the customizations that work for me:

First, because I’m using UTF-8, switch the processor and configure the process command:

(setq org-latex-compiler "xelatex")
(setq org-latex-pdf-process
      (list (concat "latexmk -"
                    org-latex-compiler 
                    " -recorder -synctex=1 -bibtex-cond %b")))

Then, configure Org to use lstlisting for source environments:

(setq org-latex-listings t)

Next, update org-latex-default-packages-alist to remove inputenc and fontenc because fontspec in my premable takes care of those things:

(setq org-latex-default-packages-alist
      '(("" "graphicx" t)
        ("" "grffile" t)
        ("" "longtable" nil)
        ("" "wrapfig" nil)
        ("" "rotating" nil)
        ("normalem" "ulem" t)
        ("" "amsmath" t)
        ("" "textcomp" t)
        ("" "amssymb" t)
        ("" "capt-of" nil)
        ("" "hyperref" nil)))

The documentation for org-latex-default-packages-alist suggests that it shouldn't be changed because it's used for more than one backend. How it's used for non-LaTeX backends, I don't know. I may need to revisit this approach if I encounter problems elsewhere; so far, I haven’t.

Finally, update org-latex-classes to include the big wodgeYes, I do have A4 paper. Because it’s better. of preamble that I want:

(setq org-latex-classes
'(("article"
"\\RequirePackage{fix-cm}
\\PassOptionsToPackage{svgnames}{xcolor}
\\documentclass[11pt]{article}
\\usepackage{fontspec}
\\setmainfont{ETBembo RomanOSF}
\\setsansfont[Scale=MatchLowercase]{Raleway}
\\setmonofont[Scale=MatchLowercase]{Operator Mono SSm}
\\usepackage{sectsty}
\\allsectionsfont{\\sffamily}
\\usepackage{enumitem}
\\setlist[description]{style=unboxed,font=\\sffamily\\bfseries}
\\usepackage{listings}
\\lstset{frame=single,aboveskip=1em,
	framesep=.5em,backgroundcolor=\\color{AliceBlue},
	rulecolor=\\color{LightSteelBlue},framerule=1pt}
\\usepackage{xcolor}
\\newcommand\\basicdefault[1]{\\scriptsize\\color{Black}\\ttfamily#1}
\\lstset{basicstyle=\\basicdefault{\\spaceskip1em}}
\\lstset{literate=
	    {§}{{\\S}}1
	    {©}{{\\raisebox{.125ex}{\\copyright}\\enspace}}1
	    {«}{{\\guillemotleft}}1
	    {»}{{\\guillemotright}}1
	    {Á}{{\\'A}}1
	    {Ä}{{\\\"A}}1
	    {É}{{\\'E}}1
	    {Í}{{\\'I}}1
	    {Ó}{{\\'O}}1
	    {Ö}{{\\\"O}}1
	    {Ú}{{\\'U}}1
	    {Ü}{{\\\"U}}1
	    {ß}{{\\ss}}2
	    {à}{{\\`a}}1
	    {á}{{\\'a}}1
	    {ä}{{\\\"a}}1
	    {é}{{\\'e}}1
	    {í}{{\\'i}}1
	    {ó}{{\\'o}}1
	    {ö}{{\\\"o}}1
	    {ú}{{\\'u}}1
	    {ü}{{\\\"u}}1
	    {¹}{{\\textsuperscript1}}1
            {²}{{\\textsuperscript2}}1
            {³}{{\\textsuperscript3}}1
	    {ı}{{\\i}}1
	    {—}{{---}}1
	    {’}{{'}}1
	    {…}{{\\dots}}1
            {⮠}{{$\\hookleftarrow$}}1
	    {␣}{{\\textvisiblespace}}1,
	    keywordstyle=\\color{DarkGreen}\\bfseries,
	    identifierstyle=\\color{DarkRed},
	    commentstyle=\\color{Gray}\\upshape,
	    stringstyle=\\color{DarkBlue}\\upshape,
	    emphstyle=\\color{Chocolate}\\upshape,
	    showstringspaces=false,
	    columns=fullflexible,
	    keepspaces=true}
\\usepackage[a4paper,margin=1in,left=1.5in]{geometry}
\\usepackage{parskip}
\\makeatletter
\\renewcommand{\\maketitle}{%
  \\begingroup\\parindent0pt
  \\sffamily
  \\Huge{\\bfseries\\@title}\\par\\bigskip
  \\LARGE{\\bfseries\\@author}\\par\\medskip
  \\normalsize\\@date\\par\\bigskip
  \\endgroup\\@afterindentfalse\\@afterheading}
\\makeatother
[DEFAULT-PACKAGES]
\\hypersetup{linkcolor=Blue,urlcolor=DarkBlue,
  citecolor=DarkRed,colorlinks=true}
\\AtBeginDocument{\\renewcommand{\\UrlFont}{\\ttfamily}}
[PACKAGES]
[EXTRA]"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))

("report" "\\documentclass[11pt]{report}"
("\\part{%s}" . "\\part*{%s}")
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))

("book" "\\documentclass[11pt]{book}"
("\\part{%s}" . "\\part*{%s}")
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))

The [DEFAULT-PACKAGES], [PACKAGES], and [EXTRA] strings are place holders for additional customizations that can be added on a per-file basis.

I’ve chosen slightly different fonts than Peter, I increased the space above listings, and I added the parskip package because I prefer flush-left paragraphs with spaces between them.

I haven’t actually changed anything about the report or book styles yet because I’m not using them.

The resulting document looks less academic and less “computer modern”.

[Image]
Custom output refined

I have no doubt that I’ll be refining things as I go, but this got me started. Thanks, Peter! And thank you, Michael for the follow-up on Twitter! (And thanks to several folks who replied to my message on the Org mailing list.)