I have worked intensively on the Oden User Guide lately, primarly on improving content, but also on providing high-quality PDF and HTML output formats with detailed control over typesetting.

For some code listings and syntax examples I want the typesetting to convey the meaning of text in the listing -- user input, command output, placeholders, etc. The User Guide build uses Pandoc to transform Markdown documents to PDF (through LaTeX) and to HTML. I could not find a good way to express the custom formatting in a way that worked with both LaTeX and HTML using standard Pandoc functionality. Therefore, I created a filter to handle my input format, called IncludeCode.hs. Using this filter, I can write code listings in separate files, using a small subset of HTML. Here's an example of a shell command listing source file from the User Guide:

$ <strong>GOPATH=PWD/target/go:$GOPATH go build -o hello hello/main</strong>
$ <strong>./hello</strong>
Hello, world!

The strong tags in the listing are part of the HTML subset I use. To include listings in the Pandoc Markdown source I use regular code block syntax and add the custom include and formatted attributes:

```{include=src/listings/hello-world-go-build-and-run.html formatted=true}

The output, both in HTML and PDF, looks like this:

$ GOPATH=PWD/target/go:$GOPATH go build -o hello hello/main
$ ./hello
Hello, world!

For listings explaining the syntax of the Oden language I want placeholders to be typeset in italic text. Where the language supports a sequence of forms I want to express that using placeholder expressions with subscripts. The following listing source file explains the let binding syntax of Oden.

let <em>identifier<sub>1</sub></em> = <em>expression<sub>1</sub></em>
    <em>identifier<sub>2</sub></em> = <em>expression<sub>2</sub></em>
    <em>identifier<sub>n</sub></em> = <em>expression<sub>n</sub></em>
in <em>body-expression</em>

When included in the document, just like in the example before, the output looks like this:

let identifier1 = expression1
    identifier2 = expression2
    identifiern = expressionn
in body-expression

The filter is very simplistic in that it only supports em, strong, and sub elements, but it suits the needs of the Oden User Guide. I find extending Pandoc with filters very powerful, and I hope you find this technique and the blog post useful. If you are interested in the complete solution, including the Makefile compiling the filter and running Pandoc, please see doc/user-guide in the Oden repository. Also, you might want to have a look at the PDF version of the User Guide to see the result after LaTeX typesetting.

Long live Pandoc!