My Byte of Code Blog. Tips and observations on creating software with Objective-C, C/C++, Python, Cocoa and Boost on Mac.

Saturday, January 16, 2010

Markdown and Pygments to syntax highlight code in Blogger

I wanted to use Markdown for posting on Blogger. As I am planning to post source code examples I wanted to be able to do syntax highlighting of the code.

I've found python-markdown which is Markdown implementation in Python. Furthermore, some searching returned Pygments as an option to generate html syntax highlighting from plain source code snippets and I was considering to use Beautiful Soup to extract relevant code blocks from processed Markdown output and replace them with syntax formatted html. There is a python-markdown extension CodeHilite which adds code syntax highlighting support to Python-Markdown using Pygments.

Install Markdown and Pygments

Using latest Mac OS X (Snow Leopard) with Python 2.6.1, I installed Python-Markdown and Pygments:

easy_install ElementTree
easy_install Markdown
easy_install Pygments

Prepare your blog entry

Asuming you have blog entry written with Markdown syntax which includes some code examples. Make sure the source code snippets are indented with 4 spaces and you specified code language using one of the options. I use the following style to identify language:

:::python

When the language is deduced from shebang like this:

#!/usr/bin/env python

it seems to add line numbering to code which is not what I want (see how to add line numbers below).

Generate blog entry in html

Run the text, in Markdown format, through Python-Markdown to generate html segment:

import markdown
html = markdown.markdown(text,['codehilite'])

If you want the line numbers in code snippet use this line instead:

html = markdown.markdown(text,['codehilite(force_linenos=True)']

This does not generate full html page only a segment that can be pasted to Blogger as html formatted entry. The option codehilite turns on CodeHilite extension which uses Pygments to take care of code syntax highlighting.

For convenience it can be wraped into a scrip that reads a markdown formatted file and generates file with .html extension, let's call this script markdown-pygments.py:

# markdown-pygments.py
#!/usr/bin/env python 
import sys
import os
import markdown

def main(args=None):
    if (args is None or len(args) < 2):
        print "Error, input file missing, usage:"
        print "  markdown-pygments.py <markdown formatted file>"
        return

    markdownInFile = os.path.abspath(args[1])

    (dir, file) = os.path.split(markdownInFile)
    (file, ext) = os.path.splitext(file)
    markdownOutFile = os.path.join(dir, ".".join([file,'html']))

    print "in:  ", markdownInFile
    print "out: ", markdownOutFile

    with open(markdownInFile, 'r') as f: text = f.read()
    html = markdown.markdown(text, ['codehilite'])
    with open(markdownOutFile, 'w') as f: f.write(html)

if __name__ == '__main__':
    main(sys.argv)

You would then generate the html like this:

./markdown-pygments.py post-16-01-2010.txt

It will generate post-16-01-2010.html in the current directory.

Update Blogger CSS to show syntax highlight

You can link to your external CSS which contains the syntax highlight but I prefer to just update Blogger CSS. If you look at the generated html you will see that the highlighted source code is inside:

<div class="codehilite"> ... source code is here ... </div>

We can dump the CSS to use highlight syntax into a file from Pygments. Tell Pygments that our source code is inside div.codehilite tag:

pygmentize -S default -f html -a html -a "div.codehilite" > syntax.css

Now syntax.css contains CSS that can be used with our generated html to add colors to syntax highlight. To update Blogger CSS, log into Blogger and copy CSS styles into template.

Under Customize tab select Edit HTML, find <b:skin><![CDATA[ element and paste CSS within it, I put it at the end just before ]]></b:skin>:

<b:skin><![CDATA[
... your CSS goes here ...
]]></b:skin>

Publish Blog Entry

Publish your blog entry by copying the generated html from file into Blogger. The source code within your post should have syntax highlighted in color.

1 comment:

  1. I take a different approach:
    http://pragmaticlogiclabs.blogspot.com/2009/10/test.html

    But there's a reason why I am landing at this article on your blog. I am still searching for the easiest, most optimal way to blog where embedding and highlighting code is more often than not.

    ReplyDelete