Add support for the Rouge syntax highlighter

By setting the `highlighter` setting to `rouge` you can now easily
highlight your code with it instead of relying on Pygments. However,
Jekyll doesn't depend on Rouge explicitly, you will need to install it
or add it to your Gemfile.

The documentation has been updated accordingly.
This commit is contained in:
Robin Dupret 2013-12-22 13:53:53 +01:00
parent 92064134d6
commit 0831d2b0f8
12 changed files with 92 additions and 21 deletions

View File

@ -1,12 +1,13 @@
## HEAD
### Major Enhancements
* Rename the `pygments` option to `highlighter`
* Add gem-based plugin whitelist to safe mode (#1657)
* Replace the commander command line parser with a more robust
solution for our needs called `mercenary` (#1706)
* Remove support for Ruby 1.8.x (#1780)
* Move to jekyll/jekyll from mojombo/jekyll (#1817)
* Rename the `pygments` option to `highlighter` (#1859)
* Provide support for the Rouge syntax highlighter (#1859)
### Minor Enhancements
* Move the EntryFilter class into the Jekyll module to avoid polluting the
@ -25,7 +26,7 @@
### Development Fixes
* Add a link to the site in the README.md file (#1795)
* Add in History and site changes from `v1-stable` branch (#1836)
* Fix the `highlight` tag feature
* Fix the `highlight` tag feature (#1859)
### Site Enhancements
* Document Kramdown's GFM parser option (#1791)

View File

@ -98,6 +98,14 @@ Feature: Site configuration
And I should see "Hello world!" in "_site/index.html"
And I should see "class=\"highlight\"" in "_site/index.html"
Scenario: Highlight code with rouge
Given I have an "index.html" page that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}"
And I have a configuration file with "highlighter" set to "rouge"
When I run jekyll
Then the _site directory should exist
And I should see "Hello world!" in "_site/index.html"
And I should see "class=\"highlight\"" in "_site/index.html"
Scenario: Set time and no future dated posts
Given I have a _layouts directory
And I have a page layout that contains "Page Layout: {{ site.posts.size }} on {{ site.time | date: "%Y-%m-%d" }}"

View File

@ -52,6 +52,7 @@ Gem::Specification.new do |s|
s.add_development_dependency('activesupport', '~> 3.2.13')
s.add_development_dependency('jekyll_test_plugin')
s.add_development_dependency('jekyll_test_plugin_malicious')
s.add_development_dependency('rouge', '~> 1.0')
# = MANIFEST =
s.files = %w[

View File

@ -5,7 +5,7 @@ module Jekyll
module CommonMethods
def add_code_tags(code, lang)
code = code.sub(/<pre>/, "<pre><code class=\"#{lang} language-#{lang}\" data-lang=\"#{lang}\">")
code = code.sub(/<pre(.*?)>/, "<pre><code class=\"#{lang} language-#{lang}\" data-lang=\"#{lang}\">")
code = code.sub(/<\/pre>/,"</code></pre>")
end
end
@ -22,7 +22,7 @@ module Jekyll
end
end
module WithoutPygments
module WithoutHighlighting
require 'cgi'
include CommonMethods
@ -37,6 +37,22 @@ module Jekyll
end
end
module WithRouge
include CommonMethods
def block_code(code, lang)
require 'rouge'
lexer = Rouge::Lexer.find_fancy(lang, code) || Rouge::Lexers::PlainText
formatter = Rouge::Formatters::HTML.new
output = "<div class=\"highlight\">"
output << add_code_tags(formatter.render(lexer.lex(code)), lang)
output << "</div>"
end
end
def initialize(config)
require 'redcarpet'
@config = config
@ -48,9 +64,13 @@ module Jekyll
Class.new(Redcarpet::Render::HTML) do
include WithPygments
end
when 'rouge'
Class.new(Redcarpet::Render::HTML) do
include WithRouge
end
else
Class.new(Redcarpet::Render::HTML) do
include WithoutPygments
include WithoutHighlighting
end
end
rescue LoadError

View File

@ -44,6 +44,8 @@ eos
case context.registers[:site].highlighter
when 'pygments'
render_pygments(context, super)
when 'rouge'
render_rouge(context, super)
else
render_codehighlighter(context, super)
end
@ -65,6 +67,22 @@ eos
return output
end
def render_rouge(context, code)
require 'rouge'
linenos = @options.keys.include?('linenos')
lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
formatter = Rouge::Formatters::HTML.new(line_numbers: linenos)
output = context["highlighter_prefix"] || ""
output << "<div class=\"highlight\">"
output << add_code_tags(formatter.render(lexer.lex(code)), @lang)
output << "</div>"
output << context["highlighter_suffix"] if context["highlighter_suffix"]
return output
end
def render_codehighlighter(context, code)
#The div is required because RDiscount blows ass
<<-HTML

View File

@ -1,4 +1,4 @@
pygments: true
highlight: pygments
relative_permalinks: false
gauges_id: 503c5af6613f5d0f19000027
permalink: /news/:year/:month/:day/:title/

View File

@ -288,7 +288,7 @@ encoding: nil
future: true
show_drafts: nil
limit_posts: 0
pygments: true
highlighter: pygments
relative_permalinks: true
@ -362,7 +362,7 @@ Jekyll handles two special Redcarpet extensions:
# ...ruby code
```
With both fenced code blocks and pygments enabled, this will statically highlight the code; without pygments, it will add a `class="LANGUAGE"` attribute to the `<code>` element, which can be used as a hint by various JavaScript code highlighting libraries.
With both fenced code blocks and highlighter enabled, this will statically highlight the code; without any syntax highlighter, it will add a `class="LANGUAGE"` attribute to the `<code>` element, which can be used as a hint by various JavaScript code highlighting libraries.
- `smart` --- This pseudo-extension turns on SmartyPants, which converts straight quotes to curly quotes and runs of hyphens to em (`---`) and en (`--`) dashes.
All other extensions retain their usual names from Redcarpet, and no renderer options aside from `smart` can be specified in Jekyll. [A list of available extensions can be found in the Redcarpet README file.][redcarpet_extensions] Make sure you're looking at the README for the right version of Redcarpet: Jekyll currently uses v2.2.x, and extensions like `footnotes` and `highlight` weren't added until after version 3.0.0. The most commonly used extensions are:
@ -380,4 +380,4 @@ In addition to the defaults mentioned above, you can also turn on recognition of
For example, in your `_config.yml`:
kramdown:
input: GFM
input: GFM

View File

@ -66,9 +66,9 @@ Check out [the extras page](../extras/) for more information.
<h5>ProTip™: Enable Syntax Highlighting</h5>
<p>
If youre the kind of person who is using Jekyll, then chances are youll
want to enable syntax highlighting using Pygments. You should really
<a href="../templates/#code_snippet_highlighting">check out how to do
that</a> before you go any further.
want to enable syntax highlighting using Pygments or Rouge. You should
really <a href="../templates/#code_snippet_highlighting">check out how to
do that</a> before you go any further.
</p>
</div>

View File

@ -139,8 +139,8 @@ your `excerpt_separator` to `""`.
## Highlighting code snippets
Jekyll also has built-in support for syntax highlighting of code snippets using
Pygments, and including a code snippet in any post is easy. Just use the
dedicated Liquid tag as follows:
either Pygments or [Rouge](https://github.com/jayferd/rouge), and including a
code snippet in any post is easy. Just use the dedicated Liquid tag as follows:
{% highlight text %}
{% raw %}{% highlight ruby %}{% endraw %}

View File

@ -232,8 +232,14 @@ These parameters are available via Liquid in the include:
Jekyll has built in support for syntax highlighting of [over 100
languages](http://pygments.org/languages/) thanks to
[Pygments](http://pygments.org/). To use Pygments, you must have Python installed on your
system and set `pygments` to `true` in your site's configuration file.
[Pygments](http://pygments.org/). To use Pygments, you must have Python installed
on your system and set `highlighter` to `pygments` in your site's configuration
file.
Alternatively, you can use [Rouge](https://github.com/jayferd/rouge) to highlight
your code snippets. It doesn't support as many languages as Pygments does but
it should fit in most cases and it's written in pure Ruby ; you don't need Python
on your system!
To render a code block with syntax highlighting, surround your code as follows:
@ -249,8 +255,9 @@ end
The argument to the `highlight` tag (`ruby` in the example above) is the
language identifier. To find the appropriate identifier to use for the language
you want to highlight, look for the “short name” on the [Lexers
page](http://pygments.org/docs/lexers/).
you want to highlight, look for the “short name” on the [Pygments' Lexers
page](http://pygments.org/docs/lexers/) or the [Rouge
wiki](https://github.com/jayferd/rouge/wiki/List-of-supported-languages-and-lexers).
#### Line numbers
@ -290,7 +297,7 @@ will generate the correct permalink URL for the post you specify.
{% endraw %}
{% endhighlight %}
If you organize your posts in subdirectories, you need to include subdirectory
If you organize your posts in subdirectories, you need to include subdirectory
path to the post:
{% highlight text %}

View File

@ -123,8 +123,8 @@ bug](http://aaronqian.com/articles/2009/04/07/redcloth-ate-my-notextile.html)
and will hopefully be fixed for 4.2. You can still use 4.1.9, but the
test suite requires that 4.1.0 be installed. If you use a version of
RedCloth that does not have the notextile tag, you may notice that
syntax highlighted blocks from Pygments are not formatted correctly,
among other things. If youre seeing this just install 4.1.0.
syntax highlighted blocks from Pygments or Rouge are not formatted
correctly, among other things. If youre seeing this just install 4.1.0.
### Liquid

View File

@ -42,6 +42,22 @@ puts "Hello world"
end
end
context "with rouge enabled" do
setup do
@markdown = Converters::Markdown.new @config.merge({ 'highlighter' => 'rouge' })
end
should "render fenced code blocks with syntax highlighting" do
assert_equal "<div class=\"highlight\"><pre><code class=\"ruby language-ruby\" data-lang=\"ruby\"><span class=\"nb\">puts</span> <span class=\"s2\">\"Hello world\"</span>\n</code></pre></div>", @markdown.convert(
<<-EOS
```ruby
puts "Hello world"
```
EOS
).strip
end
end
context "without any highlighter" do
setup do
@markdown = Converters::Markdown.new @config.merge({ 'highlighter' => nil })