As I’m setting up my new site with Hakyll, I’m looking to add a few features to
what it offers out of the box, and the first one is syntax highlighting. Syntax
highlighting is enabled by default with recent (>= 1.9) Pandocs, as per the
Hakyll
FAQ,
but only in the sense that the generated HTML of fenced code blocks is decorated
with class
attributes that describe what kind of tokens they are (keywords,
variable names, literal values, etc.)—you still need to “bring your own CSS”. So
the question is: which CSS?
The most straightforward thing to do is to grab the colors from one of Pandoc’s
built-in themes.1 You can list the available colorschemes with
pandoc --list-highlight-styles
, and get the info for a specific one of them
with e.g. pandoc --print-highlight-style=espresso
, but the info gets printed
as JSON, not CSS, so it’ll need a little more massaging to get it web-ready.
There’s a great StackOverflow answer about how to generate the syntax highlighting CSS for a given Pandoc colorscheme—here are the steps in short:
Make a helper template file
highlighting-css.template
which contains the text$highlighting-css$
.Make a helper input file
sample.md
which contains a highlightable code block (in whatever programming language you like, but it does have to be tagged with some language, so that Pandoc knows to highlight it), for example:``` haskell main = putStrLn "Hello world!" ```
Run Pandoc on that input file with the helper template, specifying the colorscheme to use for highlighting: for example, if you wanted the CSS for the
espresso
colorscheme, you would runpandoc --template=highlighting-css.template --highlight-style=espresso sample.md -o highlighting.css
.Now the file
highlighting.css
has your generated CSS.
You can stick the CSS file wherever you want; I have mine at css/syntax.css
(along with css/default.css
, where the main CSS for my site lives), and this
rule in my site.hs
:
"css/*" $ do
match
route idRoute compile compressCssCompiler
But Pandoc only comes with a few themes, and only some of those are for light
mode: the light mode ones are pygments
, tango
, kate
, monochrome
(which,
as the name implies, doesn’t apply any colors), and haddock
(which,
fascinatingly, looks nothing like the highlighting I’m used to seeing in Haddock
documentation). That JSON output we got from --print-highlight-style
is
somewhat standardized, though: the format is shared with KDE’s colorscheme
specification, which means that we can also use any of the themes from the Kate
Editor.
To do this, download one of KDE’s syntax highlighting theme
files, and
use the theme file as the argument to --highlight-style
when running Pandoc to
generate your highlighting.css
. Unfortunately, not all of them work out of
the box; I’m guessing it wouldn’t be too hard to figure out why and fix it, but
after some experimentation with the ones that did “just work” without any extra
finagling, I decided I liked the Breeze Light theme enough to go with that one,
at least as a starting point. Here’s the shell command I ended up with:
pandoc --template=highlighting-css.template \
--highlight-style=breeze-light.theme \
sample.md -o css/syntax.css
Finally, if you’re interested in making your own theme from scratch, or just reading more, there’s a GitHub repo with a boilerplate theme file and more details about how Pandoc uses KDE’s theme format.
Actually, the most straightforward thing to do is probably to just find another Hakyll site online that already has syntax highlighting with colors you like, and grab their CSS, but I’m guessing that if you wanted to do that, you would have done it already and you wouldn’t be reading a blog post about how to DIY it.↩︎