4 minutes
Pandoc: colors, styles and tricks
Pandoc is a very handy tool to create PDF documents from MarkDown files.
Its workflow is very similar to LaTeX (and indeed, by default, it uses it to convert to PDF), but less verbose and a bit easier to write.
However, soon you will face the limits of MarkDown, such as the lack of colors, and you’ll start to introduce bad LaTeX code for this or that feature.
Let’s see a better way to solve the problem.
LUA filters
Pandoc supports LUA filters as preprocessor for the documents: with them you can create custom elements that will change various aspects of the document.
You just need to put the .lua
script in your document’s folder, and pass the --lua-filter=filter.lua
option to the Pandoc command line.
A complete guide to write LUA filters for Pandoc can be found here.
Colors!
MarkDown doesn’t support colors. Our LUA filter would parse for a particular keyword (e.g. color
), and insert the LaTeX command.
The script below also converts colors for HTML documents.
Span = function(el)
color = el.attributes['color']
-- if no color attribute, return unchanged
if color == nil then return el end
-- transform to <span style="color: red;"></span>
if FORMAT:match 'html' then
-- remove color attributes
el.attributes['color'] = nil
-- use style attribute instead
el.attributes['style'] = 'color: ' .. color .. ';'
-- return full span element
return el
elseif FORMAT:match 'latex' then
-- remove color attributes
el.attributes['color'] = nil
-- encapsulate in latex code
table.insert(
el.content, 1,
pandoc.RawInline('latex', '\\textcolor{'..color..'}{')
)
table.insert(
el.content,
pandoc.RawInline('latex', '}')
)
return el.content
else
-- for other format return unchanged
return el
end
end
You also have to include the directive \usepackage{xcolor}
in your document.
To do this, either create a style.tex
file with the above instruction, included with -H style.tex
option, or by adding the following in your frontmatter:
header-includes: |
\usepackage{xcolor}
Then, colore your text with [your text here]{color="red"]
.
Quotes and colored blocks
Sometimes you want to highlight some part of your text (e.g. warnings or solutions blocks).
In LaTeX you would use tcolorbox
. And you may use it also in Pandoc, but it will break any other non-LaTeX output.
Let’s create another LUA filter for this purpose.
function Div(el)
if el.classes[1] == "warning"
or el.classes[1] == "suggestion"
-- ADD HERE MORE CLASSES
then
-- insert element in front
table.insert(
el.content, 1,
pandoc.RawBlock("latex", "\\begin{quote_" .. el.classes[1] .. "}"))
-- insert element at the back
table.insert(
el.content,
pandoc.RawBlock("latex", "\\end{quote_" .. el.classes[1] .. "}"))
end
return el
end
Then declare each class in your style.tex
:
\usepackage{tcolorbox}
% New tcolorbox
\newtcolorbox{warning}{colback=red!5!white, colframe=red!50!white, title={Warning},fonttitle=\bfseries}
\newtcolorbox{suggestion}{colback=green!5!white, colframe=green!50!black, title={Suggestion},fonttitle=\bfseries,}
% Declare the environments
\newenvironment{quote_warning}{\begin{warning}}{\end{warning}}
\newenvironment{quote_suggestion}{\begin{suggestion}}{\end{suggestion}}
Then use it as:
::: warning
Your very important text.
With **any** Markdown __style__.
:::
More intelligent titles
Wondering how to reduce the space above title on the first page and make things a bit more compact?
Paste this in your style.tex
file:
\usepackage{titling}
\pretitle{\begin{center}\vspace{-3cm}\LARGE\bfseries}
\posttitle{\end{center}\vspace{-0cm}}
To change the geometry, add this:
\usepackage[margin=2cm,top=2.5cm, bottom=2.5cm]{geometry}
You can also add the same directives to the frontmatter, but having a separate .tex
style file allows for multiples styles just by changing the command line.
If the weight of section titles isn’t enough:
\usepackage{titlesec}
\titleformat*{\section}{\sffamily\Large\bfseries}
Section numbering
Add --number-sections
to have numbered sections (e.g. each section will be preceded by its number.
Listing
Use --listings
to set Pandoc to use the listings
package to generate code listings.
You can then set any additional settings as normal LaTeX documents in style.tex
.
Page format
Is Pandoc producing a Letter document? Use -V papersize:a4
to set to the european standard format A4, or to any other you want.
Make
Wouldn’t it be great to not remember the super-long command line? Make to the rescue!
PANDOC=$(shell which pandoc)
OPTS=--lua-filter=quote_filter.lua --number-sections --listings -V papersize:a4
HEADERS=style.tex
DEPS=style.tex Makefile
DEPS+=$(wildcard *.lua)
%.pdf: %.md $(DEPS)
$(PANDOC) $< -o $@ -H $(HEADERS) $(OPTS)
Now just type make
to have your PDF compiled.
Continuous compilation
Are you fixing a document and continuing to switch between your markdown, terminal and viewer?
Through make
your document is recompiled only when the source files change.
So you can run watch -n 1 make
, which will automatically re-compile the document when needed.