Syntax coloring

I use this to highlight code, it uses an external application to do the actual code highlighting (but that can be changed to anything). The plugin is used as a filter, and turns <code>-blocks into highlighted code.

Usage

Add the codify filter to your meta-file. Then it's as simple as this:

<code lang="ruby" file="example.rb">
def example
    "Hello"
end
</code>

Source

def codify(str, lang)
    lang ||= 'ruby'
    html_coded = ""

    # Use pygmentize, it's very nice
    open("|/usr/bin/pygmentize -f html -l #{lang}", "w+") do |f|
        # Write the code to standard input of pygmentize.
        f.puts(str)

        # Close standard input so that we get some output.
        f.close_write

        # Read the output of pygmentize.
        html_coded = f.read
    end

    if html_coded.empty?
        html_coded = '<pre><code>' + str.strip + '</code></pre>'
    end

    html_coded.strip
end

def copy_text_to_file(str, identifier, dir)
    File.open(File.join(dir, identifier), 'w+') do |f|
        f.write(str)
        puts "*** Wrote plaintext file '#{File.join(dir, identifier)}'"
    end
    File.join(dir, identifier)
end

register_filter 'codify' do |page, pages, config|
    while page.content =~ %r{((<pre>\s*)?(<code lang="(\w+)"( file="(.+?[^"])")?>(.+?[^(</code>)])</code>)(\s*</pre>)?)}m
        orginal, code, lang, filename = $1, $7, $4, $6
        
        # Create a plaintext file version to.
        if filename
            code_path = File.join(config[:output_dir], page.path, 'code')
            url = page.path + 'code/' + filename
            FileUtils.mkdir_p(code_path)
            copy_text_to_file(code, filename, code_path)
            page.content.gsub!(orginal, %{<a class="file" href="#{url}">#{filename}</a>\n} + orginal)
        end

        # Substitute the un-highlighted code with the highlighted code from
        # pygmentize.
        page.content.gsub!(orginal, codify(code, lang))
    end
    page.content
end

I'm not sure I like the use of pygmentize here... I'd much rather use a plugin which uses either CodeRay or Ultraviolet (two Ruby libraries for syntax highlighting). I'm also not happy about the way the HTML-like <code> tag is parsed—it's probably a better idea to use Hpricot for this instead.

Attachments