Customizing org-mode LaTeX output
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.
(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”.
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.)