One thing I needed recently was an unobtrusive way to highlight lines of code, while keeping it readable (and of course, inside Markdown). The main use case I wanted it for is to highlight changed lines of code inside a tutorial. I think this is a fairly common case, and if your code blocks contain more than 3 lines of code, it’s really helpful for the reader.

I didn’t find any flavor of Markdown that let me do this, so I figured I would build on what I think is the best variant - GitHub Flavored Markdown. Code fences are already a non-standard (but super common) feature that GitHub uses, and they’ve also added in syntax highlighting using Pygments. Pygments already has the ability to highlight lines, so all we need is a way to pass that through.

I came up with this syntax: {1,3,8-12}. It’s simple and let’s you express individual lines and ranges with ease. It shouldn’t conflict with any lexer name you might need to pass to Pygments (or highlighter of choice). Here’s what it looks like in more context:

```javascript{1,3,8-12}

And a full working example:

// This is nonsense sample code
var sample = document.getElementById('sample');
sample.addEventListener('click', function(event) {  console.log('This is a silly place.');});

I would love to see this (or a similar) syntax make it’s way into GFM, and maybe get support in some of the Markdown parsers as another extension. I might start hacking on that soon, but in the mean time, if you want to add support for this to your Jekyll + Redcarpet + Pygments site (and are generating your own HTML because GitHub won’t run your code), here’s a file you can drop into _plugins and go (only tested with Jekyll 1.0+):

# Replace Jekyll's handling of the Redcarpet code_block (which already adds
# support for highlighting, but needs support for the very non-standard
# "code fences with line highlights" extension).
# Since this is currently depending on Redcarpet to cooperate, we are going to
# be naive, and only allow line highlighting when a language is specified. If
# you don't want any syntax highlighting but want to highlight lines, then you
# need to specify text as your language (or it will break), like:
# ```text{4}
module Jekyll
module Converters
class Markdown
class RedcarpetParser
module WithPygments
def block_code(code, lang)
require 'pygments'
lang_parts = lang && lang.split('{')
lang = lang_parts && !lang_parts[0].empty? && lang_parts[0] || 'text'
hl_lines = ''
if lang_parts && lang_parts.size >= 2
hl_lines = lang_parts[1].gsub(/[{}]/, '').split(',').map do |ln|
if matches = /(\d+)-(\d+)/.match(ln)
ln = Range.new(matches[1], matches[2]).to_a.join(' ')
end
ln
end.join(' ')
end
output = add_code_tags(
Pygments.highlight(code, :lexer => lang,
:options => { :encoding => 'utf-8', :hl_lines => hl_lines }),
lang
)
end
end
end
end
end
end