GitHub-style syntax highlighting with Pygments
Update 2016: This tutorial is out-of-date. See the repository for alexpeattie.com and the associated README to see how I do it now.
A few people have asked me how I do the Github-style syntax highlighting on this site. Here’s an example Ruby script with highlighting:
class A < B; def self.create(object = User) object end end
class Zebra; def inspect; "X#{2 + self.object_id}" end end
module ABC::DEF
include Comparable
# @param test
# @return [String] nothing
def foo(test)
Thread.new do |blockvar|
ABC::DEF.reverse(:a_symbol, :'a symbol', :<=>, 'test' + test)
end.join
end
def [](index) self[index] end
def ==(other) other == self end
end
anIdentifier = an_identifier
Constant = 1
render action: :new
This how-to explains my setup on Middleman (which this site is built on), but it should be applicable to any site using Pygments for syntax highlighting.
To enable basic syntax highlighting, we need to add the middleman-syntax gem to our Gemfile
:
gem "middleman-syntax"
and activate it in our config.rb
:
activate :syntax
We’ll also turn on the lineanchors
option, which we’ll need for line numbering (see below).
activate :syntax, lineanchors: 'line'
Fenced code blocks
The first feature we’ll add is fenced code blocks, a feature of Github Flavored Markdown. This allows us to conveniently specify the language (and thus, the Pygments lexer) of our code:
~~~ruby
puts "Hello world from ruby"
~~~
We’ll need to change our Markdown pre-processor to Redcarpet which supports fenced code blocks. We need to add:
gem "redcarpet"
to our Gemfile
and put the following into our config.rb
:
set :markdown_engine, :redcarpet
set :markdown, fenced_code_blocks: true
Github highlighting color scheme
Next we’ll add some CSS to match Github’s color scheme: https://github.com/richleland/pygments-css/blob/146708f9003299106baf05987abf393eae4424fc/github.css
We have to make one small change, .hll
needs to be replaced with .highlight
.hll {
background-color: #ffffcc;
} /* WRONG */
.highlight {
background-color: #ffffcc;
} /* RIGHT */
Line numbers
The last thing we’re missing are line-numbers. We’ll implement this in pure CSS, using CSS counters:
pre {
counter-reset: line-numbering;
border: solid 1px #d9d9d9;
border-radius: 0;
background: #fff;
padding: 0;
line-height: 23px;
margin-bottom: 30px;
white-space: pre;
overflow-x: auto;
word-break: inherit;
word-wrap: inherit;
}
pre a::before {
content: counter(line-numbering);
counter-increment: line-numbering;
padding-right: 1em; /* space after numbers */
width: 25px;
text-align: right;
opacity: 0.7;
display: inline-block;
color: #aaa;
background: #eee;
margin-right: 16px;
padding: 2px 10px;
font-size: 13px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
pre a:first-of-type::before {
padding-top: 10px;
}
pre a:last-of-type::before {
padding-bottom: 10px;
}
pre a:only-of-type::before {
padding: 10px;
}
Notice the user-select: none;
- this ensures that when the code is selected, the line numbers won’t be selected too, which makes copying and pasting a lot more convenient.
CSS counters will work fine for ~95% of users - and older browsers will degrade gracefully (they just won’t show any line numbers).
Hi Alex.
Thanx for sharing...
but how can i use this in my blogger blog... ?
For some reason, line numbering isn't working for me. What else do I need to do apart from copying the CSS above for line numbering?
Thanks man! Was really struggling on finding the right Github css and the line numbers were an extra bonus! Cheers.
Thanks a lot for the line number solution. BTW, It seems I have to add "activate :syntax, lineanchors: 'line' " to config.rb to make it work.
Could you post the whole config please? I've tried this but it's not outputting the anchor tags
activate :syntax, :lineanchors => "line"
Please see my whole config below and if I remove lineanchors: 'line' there is no line no...
activate :blog do |blog|
blog.prefix = "blogs"
blog.permalink = ":year/:month/:day/:title.html"
blog.sources = ":year-:month-:day-:title.html"
blog.taglink = "/tags/:tag.html"
blog.layout = "article_layout"
blog.tag_template = "tag.html"
blog.calendar_template = "calendar.html"
blog.paginate = true
blog.per_page = 10
end
page "/feed.xml", :layout => false
helpers Gravatarify::Helper
set :css_dir, 'stylesheets'
set :js_dir, 'javascripts'
set :images_dir, 'images'
set :markdown_engine, :redcarpet
set :markdown, fenced_code_blocks: true, smartypants: true
activate :syntax, lineanchors: 'line'
end
Cool thanks A lot !
Hi Alex.
Does this page http://fontawesome.io/examp... use Pygments syntax highlighter?
I want to use it for my WordPress blog. Please help me to do it.
Thank you.