Document writing with Markdown and LaTeX
Technical documents, such as academic reports or papers, are frequently written with the powerful and versatile TeX typesetting system, most commonly in the form of the LaTeX document preparation system. If you have a proper template and layout, using this system will produce great looking results.
But most of the time, I don’t need the full power of TeX (equations etc.) and I really cannot be bothered to write verbose constructs, such as \textbf{}
or \texttt{}
– because the source side of LaTeX surely is not so beautiful.
I would much rather just write in plain markdown, like **bold**
, *italic*
or codeblocks with backticks.
For this scenario pandoc is the perfect tool. It is a swiss-army knife for document conversion, but specifically converting markdown documents into LaTeX and further to PDF is a great use-case (an example of how to do this). If you ever need to use more advanced LaTeX features, you can directly embed them in the markdown (e.g. for citations, figures or tables).
Furthermore, pandoc templates can be used to add some styling around these (initially) plain PDF documents. The Eisvogel template is one of my favorites and I have used it several times before for papers, reports etc. which don’t require a specific format.
For my master’s thesis however, I already have a fixed LaTeX template provided by the university (which is great of course, because I don’t have to create it myself!). These LaTeX templates can be quite finicky and brittle, so I was not really looking forward to porting the LaTeX template into a pandoc template.
The following three steps describe what I did to write the document body in markdown, preprocess the markdown with pandoc and generate the PDF with LaTeX.
Important remark: before doing all of this you should make sure the LaTeX template you are modifying actually compiles in its original form! Otherwise you might spend a lot time debugging what you did wrong, when in fact the original document was faulty.
Step 1: Remove the TeX document body
I skipped past the preamble in the provided LaTeX template, removed all the major sections from the main document and instead put them into individual files, so that only the following content remains in the main document (apart from preamble and document declarations):
|
|
Thus, we end up with the following directory structure:
├── include
│ ├── 01-introduction.tex
│ ├── 02-background.tex
│ ├── 03-research.tex
│ ├── 04-evaluation.tex
│ └── 05-conclusion.tex
└── thesis.tex
Step 2: Preprocess markdown to LaTeX
To transform markdown files into TeX files, I’m using the awesome pandoc:
# short form:
pandoc -o out.tex in.md
# long form (equivalent):
pandoc -f markdown -t latex -o out.tex in.md
After running this command for each file, the directory should look like this:
├── include
│ ├── 01-introduction.md
│ ├── 01-introduction.tex
│ ├── 02-background.md
│ ├── 02-background.tex
│ ├── 03-research.md
│ ├── 03-research.tex
│ ├── 04-evaluation.md
│ ├── 04-evaluation.tex
│ ├── 05-conclusion.md
│ └── 05-conclusion.tex
└── thesis.tex
For example, the file 01-introduction.md
:
|
|
will be converted into 01-introduction.tex
:
|
|
Note that pandoc conveniently also generates labels for each section - handy!
Step 3: Automate it with a Makefile
Obviously, I don’t want to run this manually for each file every time I change something, therefore in the next step I will roll it up into a Makefile.
The Makefile takes cares of any preprocessing steps (converting markdown to LaTeX and SVG to PDF), invoking latexmk
to build the final PDF from LaTeX sources, managing all build dependencies and cleaning up, if necessary.
This Makefile is partially based on the Makefiles I have linked to in the references below.
|
|
Now I can just run make
(or make all
or make thesis.pdf
) to generate my beautiful PDF and make will automatically detect which files changed and which parts need to be rebuilt.
Happy writing!
By the way: If you find yourself debugging your Makefile (like I had to do for quite a while), try with make -n
and make --debug=implicit
.
If that is not enough, have a look at the references below.
References
- Generic Makefile using latexmk and/or pandoc: https://gist.github.com/famuvie/dc6ff6c0a0155e0e2d7f281f1a6d4d69
- How to properly make a LaTeX project? https://tex.stackexchange.com/a/40759
- Makefile String Functions: https://www.gnu.org/software/make/manual/html_node/Text-Functions.html
- Debugging Makefiles: https://www.oreilly.com/library/view/managing-projects-with/0596006101/ch12.html