# Using ConTeXt to convert markdown to PDF

I am using markdown to write the course notes for a lecture that I am teaching this semester. The notes have no math—just text and images—and markdown is the ideal input format. At the same time, I am easily convert a markdown file to a nicely typeset pdf using pandoc—with the ConTeXt filter module providing the plumbing.

However, it took me a while to come up with a work flow that I like. Normally, to use the filter module I have to create a `tex` file that that converts and inputs the appropriate markdown file; something like:

``````% file: 01-intro.tex
% Boilerplate code to typeset a markdown file

\environment ECSE321
% ECSE321.tex is the environment file that
% sets up the layout, fonts, and style. It
% also loads the filter module and sets up
% a |markdown| external filter environment.

\starttext
\processmarkdownfile{01-intro.txt}
% This command converts 01-intro.txt into a
% tex file and inputs the result
\stoptext
``````

However, such a setup gets frustrating very quickly. For each lecture, I need to create two files: a markdown file (like `01-intro.txt`) and a tex file with boilerplate code (like `01-intro.tex` above). I might be able to get rid of the boilerplate tex file by writing a script that creates the file—adding needless complexity to a simple task. Wouldn’t it be nice if I could just say

``````context <magic options> 01-intro.txt
``````

That is, compile the markdown file directly. After thinking about it for a while, I realized that this task was simple. I just needed to load the environment file and ask it to run `\processmarkdownfile` on the current input file. ConTeXt provides a switch `--enironment=filename` to specify an environment file; the macro `\inputfilename` contains the name of the input file (`\jobname` contains the name without extension. `\inputfilename` contains the name with extension). So, I just needed to add

``````\processmarkdownfile{\inputfilename}
``````

at the appropriate place in the environment file. So, I modified the environment file as follows:

``````% file ECSE321.tex
\startenvironment ECSE321

% Setups for fonts, layout, and styles

\usemodule[filter]

\defineexternalfilter
[markdown]
[filtercommand={pandoc -f \externalfilterparameter{format} -t context
-i \externalfilterinputfile\space
-o \externalfilteroutputfile},
format=markdown,
directory=output]

\stopenvironment

\doifnotmode{standalone}{\endinput}
\starttext
\processmarkdownfile{\inputfilename}
\stoptext
``````

If the `standalone` mode is not set, ConTeXt stops reading the environment file after `\stopenvironment`. If the mode is set, it processes the input file as a markdown file. So, I can invoke ConTeXt using

``````context --environment=ECSE321 --mode=standalone 01-intro.txt
``````

to directly compile a markdown file to pdf. To simplify this process, I added

``````alias lec='context --environment=ECSE321 --mode=standalone'
``````

in my `.zshrc` file and now I am happily compiling my lecture notes using

``````lec 01-intro.txt
``````

## 6 thoughts on “Using ConTeXt to convert markdown to PDF”

1. Great. Does pandoc provide a syntax for literal ConTeXt snippets for, e.g. lua or TikZ?

• Pandoc passes everything inside a context environment `\start<whatever>``\stop<whatever>` unchanged. So, the contents of `\startluacode ... \stopluacode` and `\starttikzcode .. \stoptikzcode` are not touched. If you want more control, you can write stuff inside `\startCONTEXT ... \stopCONTEXT ` environment, and add `\let\startCONTEXT\donothing` and `\let\stopCONTEXT\donothing` in your style file.

2. While this looks extremely cool, I cannot get it to work with the latest context. Context seems to insist on processing the markdown file.

I *can* get it to work in the original, “quickly frustrating” way, but as you point out, you end up with a lot of files that do very little.

(My application is monthly progress reports for a project, and I’m using markdown so that I have both the PDF sent in to the client, and an easy way to render a web page or even a .doc file down the road)

• Now ConTeXt stops reading the current file when it encounters a `\stopenvironment`. So, you need to use

``````
\doifnotmode{standalone}{\stopenvironment}
``````

``````