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:
parent
92064134d6
commit
0831d2b0f8
|
@ -1,12 +1,13 @@
|
||||||
## HEAD
|
## HEAD
|
||||||
|
|
||||||
### Major Enhancements
|
### Major Enhancements
|
||||||
* Rename the `pygments` option to `highlighter`
|
|
||||||
* Add gem-based plugin whitelist to safe mode (#1657)
|
* Add gem-based plugin whitelist to safe mode (#1657)
|
||||||
* Replace the commander command line parser with a more robust
|
* Replace the commander command line parser with a more robust
|
||||||
solution for our needs called `mercenary` (#1706)
|
solution for our needs called `mercenary` (#1706)
|
||||||
* Remove support for Ruby 1.8.x (#1780)
|
* Remove support for Ruby 1.8.x (#1780)
|
||||||
* Move to jekyll/jekyll from mojombo/jekyll (#1817)
|
* 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
|
### Minor Enhancements
|
||||||
* Move the EntryFilter class into the Jekyll module to avoid polluting the
|
* Move the EntryFilter class into the Jekyll module to avoid polluting the
|
||||||
|
@ -25,7 +26,7 @@
|
||||||
### Development Fixes
|
### Development Fixes
|
||||||
* Add a link to the site in the README.md file (#1795)
|
* Add a link to the site in the README.md file (#1795)
|
||||||
* Add in History and site changes from `v1-stable` branch (#1836)
|
* Add in History and site changes from `v1-stable` branch (#1836)
|
||||||
* Fix the `highlight` tag feature
|
* Fix the `highlight` tag feature (#1859)
|
||||||
|
|
||||||
### Site Enhancements
|
### Site Enhancements
|
||||||
* Document Kramdown's GFM parser option (#1791)
|
* Document Kramdown's GFM parser option (#1791)
|
||||||
|
|
|
@ -98,6 +98,14 @@ Feature: Site configuration
|
||||||
And I should see "Hello world!" in "_site/index.html"
|
And I should see "Hello world!" in "_site/index.html"
|
||||||
And I should see "class=\"highlight\"" 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
|
Scenario: Set time and no future dated posts
|
||||||
Given I have a _layouts directory
|
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" }}"
|
And I have a page layout that contains "Page Layout: {{ site.posts.size }} on {{ site.time | date: "%Y-%m-%d" }}"
|
||||||
|
|
|
@ -52,6 +52,7 @@ Gem::Specification.new do |s|
|
||||||
s.add_development_dependency('activesupport', '~> 3.2.13')
|
s.add_development_dependency('activesupport', '~> 3.2.13')
|
||||||
s.add_development_dependency('jekyll_test_plugin')
|
s.add_development_dependency('jekyll_test_plugin')
|
||||||
s.add_development_dependency('jekyll_test_plugin_malicious')
|
s.add_development_dependency('jekyll_test_plugin_malicious')
|
||||||
|
s.add_development_dependency('rouge', '~> 1.0')
|
||||||
|
|
||||||
# = MANIFEST =
|
# = MANIFEST =
|
||||||
s.files = %w[
|
s.files = %w[
|
||||||
|
|
|
@ -5,7 +5,7 @@ module Jekyll
|
||||||
|
|
||||||
module CommonMethods
|
module CommonMethods
|
||||||
def add_code_tags(code, lang)
|
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>")
|
code = code.sub(/<\/pre>/,"</code></pre>")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -22,7 +22,7 @@ module Jekyll
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module WithoutPygments
|
module WithoutHighlighting
|
||||||
require 'cgi'
|
require 'cgi'
|
||||||
|
|
||||||
include CommonMethods
|
include CommonMethods
|
||||||
|
@ -37,6 +37,22 @@ module Jekyll
|
||||||
end
|
end
|
||||||
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)
|
def initialize(config)
|
||||||
require 'redcarpet'
|
require 'redcarpet'
|
||||||
@config = config
|
@config = config
|
||||||
|
@ -48,9 +64,13 @@ module Jekyll
|
||||||
Class.new(Redcarpet::Render::HTML) do
|
Class.new(Redcarpet::Render::HTML) do
|
||||||
include WithPygments
|
include WithPygments
|
||||||
end
|
end
|
||||||
|
when 'rouge'
|
||||||
|
Class.new(Redcarpet::Render::HTML) do
|
||||||
|
include WithRouge
|
||||||
|
end
|
||||||
else
|
else
|
||||||
Class.new(Redcarpet::Render::HTML) do
|
Class.new(Redcarpet::Render::HTML) do
|
||||||
include WithoutPygments
|
include WithoutHighlighting
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
|
|
|
@ -44,6 +44,8 @@ eos
|
||||||
case context.registers[:site].highlighter
|
case context.registers[:site].highlighter
|
||||||
when 'pygments'
|
when 'pygments'
|
||||||
render_pygments(context, super)
|
render_pygments(context, super)
|
||||||
|
when 'rouge'
|
||||||
|
render_rouge(context, super)
|
||||||
else
|
else
|
||||||
render_codehighlighter(context, super)
|
render_codehighlighter(context, super)
|
||||||
end
|
end
|
||||||
|
@ -65,6 +67,22 @@ eos
|
||||||
return output
|
return output
|
||||||
end
|
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)
|
def render_codehighlighter(context, code)
|
||||||
#The div is required because RDiscount blows ass
|
#The div is required because RDiscount blows ass
|
||||||
<<-HTML
|
<<-HTML
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
pygments: true
|
highlight: pygments
|
||||||
relative_permalinks: false
|
relative_permalinks: false
|
||||||
gauges_id: 503c5af6613f5d0f19000027
|
gauges_id: 503c5af6613f5d0f19000027
|
||||||
permalink: /news/:year/:month/:day/:title/
|
permalink: /news/:year/:month/:day/:title/
|
||||||
|
|
|
@ -288,7 +288,7 @@ encoding: nil
|
||||||
future: true
|
future: true
|
||||||
show_drafts: nil
|
show_drafts: nil
|
||||||
limit_posts: 0
|
limit_posts: 0
|
||||||
pygments: true
|
highlighter: pygments
|
||||||
|
|
||||||
relative_permalinks: true
|
relative_permalinks: true
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ Jekyll handles two special Redcarpet extensions:
|
||||||
# ...ruby code
|
# ...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.
|
- `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:
|
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:
|
||||||
|
|
|
@ -66,9 +66,9 @@ Check out [the extras page](../extras/) for more information.
|
||||||
<h5>ProTip™: Enable Syntax Highlighting</h5>
|
<h5>ProTip™: Enable Syntax Highlighting</h5>
|
||||||
<p>
|
<p>
|
||||||
If you’re the kind of person who is using Jekyll, then chances are you’ll
|
If you’re the kind of person who is using Jekyll, then chances are you’ll
|
||||||
want to enable syntax highlighting using Pygments. You should really
|
want to enable syntax highlighting using Pygments or Rouge. You should
|
||||||
<a href="../templates/#code_snippet_highlighting">check out how to do
|
really <a href="../templates/#code_snippet_highlighting">check out how to
|
||||||
that</a> before you go any further.
|
do that</a> before you go any further.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -139,8 +139,8 @@ your `excerpt_separator` to `""`.
|
||||||
## Highlighting code snippets
|
## Highlighting code snippets
|
||||||
|
|
||||||
Jekyll also has built-in support for syntax highlighting of code snippets using
|
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
|
either Pygments or [Rouge](https://github.com/jayferd/rouge), and including a
|
||||||
dedicated Liquid tag as follows:
|
code snippet in any post is easy. Just use the dedicated Liquid tag as follows:
|
||||||
|
|
||||||
{% highlight text %}
|
{% highlight text %}
|
||||||
{% raw %}{% highlight ruby %}{% endraw %}
|
{% raw %}{% highlight ruby %}{% endraw %}
|
||||||
|
|
|
@ -232,8 +232,14 @@ These parameters are available via Liquid in the include:
|
||||||
|
|
||||||
Jekyll has built in support for syntax highlighting of [over 100
|
Jekyll has built in support for syntax highlighting of [over 100
|
||||||
languages](http://pygments.org/languages/) thanks to
|
languages](http://pygments.org/languages/) thanks to
|
||||||
[Pygments](http://pygments.org/). To use Pygments, you must have Python installed on your
|
[Pygments](http://pygments.org/). To use Pygments, you must have Python installed
|
||||||
system and set `pygments` to `true` in your site's configuration file.
|
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:
|
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
|
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
|
language identifier. To find the appropriate identifier to use for the language
|
||||||
you want to highlight, look for the “short name” on the [Lexers
|
you want to highlight, look for the “short name” on the [Pygments' Lexers
|
||||||
page](http://pygments.org/docs/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
|
#### Line numbers
|
||||||
|
|
||||||
|
|
|
@ -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
|
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
|
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
|
RedCloth that does not have the notextile tag, you may notice that
|
||||||
syntax highlighted blocks from Pygments are not formatted correctly,
|
syntax highlighted blocks from Pygments or Rouge are not formatted
|
||||||
among other things. If you’re seeing this just install 4.1.0.
|
correctly, among other things. If you’re seeing this just install 4.1.0.
|
||||||
|
|
||||||
### Liquid
|
### Liquid
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,22 @@ puts "Hello world"
|
||||||
end
|
end
|
||||||
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
|
context "without any highlighter" do
|
||||||
setup do
|
setup do
|
||||||
@markdown = Converters::Markdown.new @config.merge({ 'highlighter' => nil })
|
@markdown = Converters::Markdown.new @config.merge({ 'highlighter' => nil })
|
||||||
|
|
Loading…
Reference in New Issue