Markdown and Pandoc for Conceptual Documents

24 May 2017 - Documentation, Markdown, VSCode

Introduction

At time cockpit, we use Markdown in more and more scenarios. In our latest newsletter (We Fell in Love With Markdown), we have written about it. I have been using it for conceptual documents, too. Writing it in Visual Studio Code and converting it to PDF using Pandoc with Bash on Ubuntu on Windows works like a charm. In this blog post, I share the setup and scripts I use in such scenarios.

Toolchain

As mentioned above, I like using Visual Studio Code for writing Markdown. I use one of the various spell checkers plugins (example) to get pointed to typing mistakes.

I switched the integrated console in VSCode to bash on Ubuntu on Windows 10 (description in VSCode docs).

Finally, I use Evince as my PDF viewer because…

  • …it does not lock the PDF file, so I can overwrite it although it is open.
  • …it auto-reloads the PDF file when it changes.

When I am in my office, I have VSCode on one monitor and Evince on the other. Here is a screenshot that shows what I mean:

Of course, many documents contain diagrams. I use Inkscape to create SVG files.

Markdown to PDF Conversion

I use two tools for converting my Markdown conceptual documents to PDF:

I have written a short helper script build-pdf.sh doing the conversion. Note that it assumes that SVG diagrams are in a subfolder that has the same name as the Markdown file (without the .md extension). Please excuse possible mistakes in the script. I mainly use languages like C#, TypeScript, etc. and I am by far no bash expert.

#!/bin/sh

# Author: Rainer Stropek
# Tested on Ubuntu 16.04 LTS on Windows 10 Pro

# On Ubuntu 16.04 LTS, you need to install (apt-get install) the following packages in order to run this script:
# * LaTeX (e.g. texlive texlive-lang-german texlive-latex-extra)
# * pandoc
# * librsvg2-bin

# Verify that argument has been given
if [ -z "$1" ]; then {
    echo "Error: Missing argument\n"
    echo "USAGE: $0 name-of-markdown-file"
    echo "Converts specified markdown file to pdf"
    exit 1
}
fi

# Check that file extension is .md
EXT=$1
EXT="${EXT##*.}"
if [ "$EXT" != "md" ]; then {
    echo "Error: Specified file name does not have the extension .md"
    exit 1
} fi

# Verify that file exists
if [ ! -f $1 ]; then {
    echo "Error: Specified file not found"
    exit 1
} fi

BASENAME=$(basename "$1" .md)

# Look for all SVG files in subdirectory having the same name
# as the markdown file to convert.
for f in ./$BASENAME/*.svg
do
    # Skip if not a file
    test -f "$f" || continue
    
    # Convert SVG file into PDF
    rsvg-convert $f -f pdf -o ./$BASENAME/$(basename "$f" .svg).pdf
done

## Convert markdown file into PDF
pandoc $1 -f markdown -t latex -o $BASENAME.pdf

In addition to that script, I use another helper script rerun.sh that executes the script above whenever a file changes. The original script is on GitHub. I only made minor modifications.

#!/usr/bin/env bash

# Events that occur within this time from an initial one are ignored
IGNORE_SECS=0.25

function execute() {
    echo "$@"
    "$@"
}

execute "$@"
ignore_until=$(date +%s.%N)

inotifywait --quiet --recursive --monitor --format "%e %w%f" \
    --event modify --event move --event create --event delete \
    *.md | while read changed
do

    echo "$changed"

    if [ $(echo " $(date +%s.%N) > $ignore_until" | bc) -eq 1 ] ; then
        ignore_until=$(echo "$(date +%s.%N) + $IGNORE_SECS" | bc)
        ( sleep $IGNORE_SECS ; execute "$@" ) &
    fi

done

I hope this is useful for you.