Multidoc

In technical terms multidoc-rules is a Haskell library for writing Shake rules to be used in a Shake build system generating multiple outputs of a mathematical document written in Pandoc’s Markdown.

As an example I use this library in a basic build-script as I am working my notes.

Runtime dependencies include xmlto, latexmk which ships with TeXLive, and both multidoc-data and customized pandoc-templates in the current working directory1.

Quick Start

For this quick start we will need Mercurial, cabal-install, and stack. We start by cloning the multidoc repository.

$ hg clone https://bfluhr.tucana.uberspace.de/hg/multidoc build-my-document

Then we create a cabal package which will contain our Shake build system.

$ cd build-my-document
$ mkdir build-script
$ cd build-script
$ cabal init

Here we use the default options except when we are asked to choose a license, there2 we choose GPL-2, and when asked whether to build a library or an executable we choose to build an executable. Next we create a text file Main.hs inside the directory build-script with the following content

import Data.Default
import Development.Shake

import qualified Text.MultidocRules as MR

main = shakeArgs shakeOptions { shakeFiles = "_build" } $ fst $
	   MR.makeRules def "my-document" "_build"

Also we alter the file build-script.cabal by changing the part that reads something like

  build-depends:       base >=4.8 && <4.9

to something like

  build-depends:       base >=4.8 && <4.9
                     , data-default
                     , shake
                     , multidoc-rules

Further we edit the file stack.yaml inside build-my-document and change the following

packages:
  - multidoc-rules/
  - https://bfluhr.tucana.uberspace.de/hg/pandoc_docbook-mathjax/archive/docbook-mathjax.tar.gz

to

packages:
  - build-script/
  - multidoc-rules/
  - https://bfluhr.tucana.uberspace.de/hg/pandoc_docbook-mathjax/archive/docbook-mathjax.tar.gz

Now we can finally build the build-script by changing to the directory build-my-document and running

$ stack build

This may take a while. After this command has finished we create the directory my-document inside build-my-document and populate it with Markdown files using .md as an extension containing the content of our document. Our build-script will sort these files alphanumerically and then concatenate them. We can build our document by running

$ stack exec build-script

inside build-my-document. The output files are then inside _build. To use two cores while building you can run for example

$ stack exec build-script -- -j2

For bibliography files if needed we can create the directory bib inside my-document and fill it with bibliography files in any Pandoc compatible format.

For theorems, proofs, examples etc. we may use bullet lists or example lists. That is a list item becomes respectively an unnumbered or numbered theorem or a proof or an example etc. Further XyPic can be used inside mathematical equations.

If the above command for building the document doesn’t terminate there is a good chance that latexmk cannot build the document because of some syntax error. On such occasion try building _build/my-document.tex3 by conventional methods and resolve the issue by editing the original Markdown files.

For slightly more sophisticated use cases the module exports some options.

Technical Details

A Shake build system using multidoc-rules converts Markdown to Docbook and LaTeX using Pandoc. The Docbook output is further processed by xmlto and chunked into several HTML documents. The resulting HTML content is extracted using xml-conduit and HTML templates written in BlazeHtml are used to render the final HTML pages. The LaTeX files are compiled by latexmk.

Mathematical notation and XyPic diagrams are rendered using MathJax and XyJax both loaded through the MathJax CDN. When used in conjunction with the default template, normalize.css is loaded to provide consistency across different browsers.

Similar Tools


  1. The API has options to change this.

  2. since we are using Pandoc

  3. or _build/tmp/my-document/a4/my-document.tex if the other file does not exist