Use Pandoc With Pygments to Highlight Source Code
I am someone who has JavaScript disabled by default in his browser (I use uMatrix in Firefox for that). Only when I trust a site and I need to use functionality that truly depends on JavaScript will I turn it on. This hopefully protects me from most of the known and unknown bad stuff out there on the internet. It also makes me appreciate people who go through the trouble of making their webpages work without JavaScript.
Until recently, I used a JavaScript plugin on this blog to format source code. This bothered me, since using JavaScript just to display some source code seems like overkill and makes people have to turn on JavaScript in their browsers just to see the source code formatted nicely. I wanted to do better than that.
The way I normally write my blog posts is, I start with a Markdown
article and then use pandoc
to convert it to
HTML which I then copy and paste into Wordpress (if there is a better
way to do this, please contact me). I noticed pandoc
provides a switch
--filter
where you can specify a executable that can transform the
pandoc
output. The only problem is, you have to write a filter.
Luckily, I found a GitHub gist
that has already figured out how to write one. Here is some Haskell for
you:
import Text.Pandoc.Definition
import Text.Pandoc.JSON (toJSONFilter)
import Text.Pandoc.Shared
import Data.Char(toLower)
import System.Process (readProcess)
import System.IO.Unsafe
main = toJSONFilter highlight
highlight :: Block -> Block
highlight (CodeBlock (_, options , _ ) code) = RawBlock (Format "html") (pygments code options)
highlight x = x
pygments:: String -> [String] -> String
pygments code options
| (length options) == 1 = unsafePerformIO $ readProcess "pygmentize" ["-l", (map toLower (head options)), "-f", "html"] code
| (length options) == 2 = unsafePerformIO $ readProcess "pygmentize" ["-l", (map toLower (head options)), "-O linenos=inline", "-f", "html"] code
| otherwise = "<div class =\"highlight\"><pre>" ++ code ++ "</pre></div>"
Note that this program invokes another program, pygmentize
to actually
highlight the source code (pygmentize
is part of the
Pygments project). So, install pygmentize
with
your favorite package manager, install Haskell if you have not done so
already, and then compile pygments.hs
with:
$ ghc -dynamic pygments.hs
That’s it! Putting it all together, to create a blog post, I can now do:
$ pandoc -F pygments -f markdown -t html5 -o blogpost.html blogpost.md
I added some CSS that makes use of the Pygments classes and voilà: you can now view this blog without having to worry about a JavaScript cryptocurrency miner hijacking your CPU. You’re welcome.