title: How I create fancy PDF-documents in Markdown
url: https://hund.tty1.se/2021/07/14/how-i-create-fancy-pdf-documents-in-markdown.html
hash_url: 0c60682eeb1edfaf2c6c13cd30cce60d

<p class="date">Wednesday, July 14, 2021</p>

<p>I haven’t had the need to create any ‘fancy’ document in ages, but the other day I had to create a PDF-document with fancy formatting for a work related thing.</p>

<p>After some testing of various solutions and tools, I ended up with a setup using <a href="https://pandoc.org">Pandoc</a>, <a href="https://weasyprint.org/">WeasyPrint</a> and <a href="https://en.wikipedia.org/wiki/Markdown">Markdown</a>. I consider Markdown to be the best markup language and I use it for everything!</p>

<div class="grid-container">
    <div class="grid-item single">
        <a href="https://hund.tty1.se/img/pandoc-pdf.png">
            <img src="https://hund.tty1.se/img/t/pandoc-pdf.png" alt="">
        </a>
        <figcaption>My example document</figcaption>
    </div>
</div>

<p>The source for this PDF-document looks like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># H1 Header

I really like using Markdown.

1. First item
2. Second item
3. Third item
4. Fourth item

&gt; This is some quoted text.

```sh
#!/bin/sh
echo "This is a code block."
```
</code></pre></div></div>

<p>And this is the CSS I used:</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">:root</span> <span class="p">{</span>
  <span class="py">--blue</span><span class="p">:</span> <span class="m">#3465A4</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">@font-face</span> <span class="p">{</span>
    <span class="nl">font-family</span><span class="p">:</span> <span class="s2">'NotoSans'</span><span class="p">;</span>
    <span class="nl">src</span><span class="p">:</span> <span class="sx">url('NotoSans-Condensed.ttf')</span> <span class="n">format</span><span class="p">(</span><span class="s2">'ttf'</span><span class="p">)</span>
<span class="p">}</span>

<span class="nt">html</span> <span class="p">{</span>
    <span class="nl">font-family</span><span class="p">:</span> <span class="s2">'NotoSans'</span><span class="p">;</span>
    <span class="nl">line-height</span><span class="p">:</span> <span class="m">1.45em</span><span class="p">;</span>
<span class="p">}</span>

<span class="nt">h1</span> <span class="p">{</span>
    <span class="nl">font-size</span><span class="p">:</span> <span class="m">26px</span><span class="p">;</span>
    <span class="nl">color</span><span class="p">:</span> <span class="n">var</span><span class="p">(</span><span class="n">--blue</span><span class="p">);</span>
    <span class="nl">padding-bottom</span><span class="p">:</span> <span class="m">0.15em</span><span class="p">;</span>
    <span class="nl">border-bottom</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="m">#CCC</span><span class="p">;</span>
<span class="p">}</span>

<span class="nt">pre</span> <span class="p">{</span>
    <span class="nl">background-color</span><span class="p">:</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.05</span><span class="p">);</span>
    <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.1</span><span class="p">);</span>
    <span class="nl">padding</span><span class="p">:</span> <span class="m">1em</span><span class="p">;</span>
    <span class="nl">font-size</span><span class="p">:</span> <span class="m">12px</span><span class="p">;</span>
  <span class="p">}</span>

<span class="nt">blockquote</span> <span class="p">{</span>
    <span class="nl">background-color</span><span class="p">:</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.05</span><span class="p">);</span>
    <span class="nl">border-left</span><span class="p">:</span> <span class="m">5px</span> <span class="nb">solid</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.1</span><span class="p">);</span>
    <span class="nl">padding</span><span class="p">:</span> <span class="m">0.1em</span> <span class="m">0.75em</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And this is the command I used to render the document:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ pandoc --pdf-engine weasyprint -c style.css demo.md -s -o demo.pdf 
</code></pre></div></div>

<h2 id="installation">Installation</h2>

<p>To make this work you need to install Pandoc and WeasyPrint. In Gentoo the packages are called <code class="language-plaintext highlighter-rouge">app-text/pandoc</code> and <code class="language-plaintext highlighter-rouge">dev-python/weasyprint</code>.</p>

<p>With that said. I did not install Pandoc from source myself. It simply requires way too many packages for my liking (when compiled from source):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># emerge pandoc
[...]
Total: 133 packages (133 new), Size of downloads: 165,258 KiB
</code></pre></div></div>

<p>I instead used a binary package that’s available from their <a href="https://github.com/jgm/pandoc/releases/">GitHub-page</a>. The archive weights in at about 14 MB and unpacked at about 68 MB. I then just put the folder in <code class="language-plaintext highlighter-rouge">~/.local/bin/</code> and created a symbolic link to the binary file.</p>
