diff --git a/History.markdown b/History.markdown index 27c262d8..6707a19e 100644 --- a/History.markdown +++ b/History.markdown @@ -7,6 +7,7 @@ * Remove support for Ruby 1.8.x (#1780) * Move to jekyll/jekyll from mojombo/jekyll (#1817) * Allow custom markdown processors (#1872) + * Provide support for the Rouge syntax highlighter (#1859) ### Minor Enhancements * Move the EntryFilter class into the Jekyll module to avoid polluting the @@ -37,6 +38,7 @@ * Add in History and site changes from `v1-stable` branch (#1836) * Testing additions on the Excerpt class (#1893) * Update Kramdown to `~> 1.3` (#1894) + * Fix the `highlight` tag feature (#1859) ### Site Enhancements * Document Kramdown's GFM parser option (#1791) diff --git a/features/site_configuration.feature b/features/site_configuration.feature index 0a08f753..a7c59b00 100644 --- a/features/site_configuration.feature +++ b/features/site_configuration.feature @@ -91,11 +91,19 @@ Feature: Site configuration And I should see "Google" in "_site/index.html" Scenario: Highlight code with pygments - Given I have an "index.html" file that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}" - And I have a configuration file with "pygments" set to "true" + Given I have an "index.html" page that contains "{% highlight ruby %} puts 'Hello world!' {% endhighlight %}" When I run jekyll Then the _site directory should exist - And I should see "puts '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" + + 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 diff --git a/jekyll.gemspec b/jekyll.gemspec index 564c264d..06dc2e56 100644 --- a/jekyll.gemspec +++ b/jekyll.gemspec @@ -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.3') # = MANIFEST = s.files = %w[ diff --git a/lib/jekyll/configuration.rb b/lib/jekyll/configuration.rb index 340847c3..f5e10fe0 100644 --- a/lib/jekyll/configuration.rb +++ b/lib/jekyll/configuration.rb @@ -24,12 +24,12 @@ module Jekyll 'limit_posts' => 0, 'lsi' => false, 'future' => true, # remove and make true just default - 'pygments' => true, 'relative_permalinks' => true, # backwards-compatibility with < 1.0 # will be set to false once 2.0 hits 'markdown' => 'maruku', + 'highlighter' => 'pygments', 'permalink' => 'date', 'baseurl' => '/', 'include' => ['.htaccess'], @@ -210,6 +210,16 @@ module Jekyll config.delete('server_port') end + if config.has_key? 'pygments' + Jekyll.logger.warn "Deprecation:", "The 'pygments' configuration option" + + " has been renamed to 'highlighter'. Please update your" + + " config file accordingly. The allowed values are 'rouge', " + + "'pygments' or null." + + config['highlighter'] = 'pygments' if config['pygments'] + config.delete('pygments') + end + %w[include exclude].each do |option| if config.fetch(option, []).is_a?(String) Jekyll.logger.warn "Deprecation:", "The '#{option}' configuration option" + diff --git a/lib/jekyll/converter.rb b/lib/jekyll/converter.rb index e2dc2796..c30f4944 100644 --- a/lib/jekyll/converter.rb +++ b/lib/jekyll/converter.rb @@ -1,27 +1,27 @@ module Jekyll class Converter < Plugin - # Public: Get or set the pygments prefix. When an argument is specified, + # Public: Get or set the highlighter prefix. When an argument is specified, # the prefix will be set. If no argument is specified, the current prefix # will be returned. # - # pygments_prefix - The String prefix (default: nil). + # highlighter_prefix - The String prefix (default: nil). # # Returns the String prefix. - def self.pygments_prefix(pygments_prefix = nil) - @pygments_prefix = pygments_prefix if pygments_prefix - @pygments_prefix + def self.highlighter_prefix(highlighter_prefix = nil) + @highlighter_prefix = highlighter_prefix if highlighter_prefix + @highlighter_prefix end - # Public: Get or set the pygments suffix. When an argument is specified, + # Public: Get or set the highlighter suffix. When an argument is specified, # the suffix will be set. If no argument is specified, the current suffix # will be returned. # - # pygments_suffix - The String suffix (default: nil). + # highlighter_suffix - The String suffix (default: nil). # # Returns the String suffix. - def self.pygments_suffix(pygments_suffix = nil) - @pygments_suffix = pygments_suffix if pygments_suffix - @pygments_suffix + def self.highlighter_suffix(highlighter_suffix = nil) + @highlighter_suffix = highlighter_suffix if highlighter_suffix + @highlighter_suffix end # Initialize the converter. @@ -31,18 +31,18 @@ module Jekyll @config = config end - # Get the pygments prefix. + # Get the highlighter prefix. # # Returns the String prefix. - def pygments_prefix - self.class.pygments_prefix + def highlighter_prefix + self.class.highlighter_prefix end - # Get the pygments suffix. + # Get the highlighter suffix. # # Returns the String suffix. - def pygments_suffix - self.class.pygments_suffix + def highlighter_suffix + self.class.highlighter_suffix end end end diff --git a/lib/jekyll/converters/markdown.rb b/lib/jekyll/converters/markdown.rb index 178eaaa8..f68af673 100644 --- a/lib/jekyll/converters/markdown.rb +++ b/lib/jekyll/converters/markdown.rb @@ -3,8 +3,8 @@ module Jekyll class Markdown < Converter safe true - pygments_prefix "\n" - pygments_suffix "\n" + highlighter_prefix "\n" + highlighter_suffix "\n" def setup return if @setup diff --git a/lib/jekyll/converters/markdown/redcarpet_parser.rb b/lib/jekyll/converters/markdown/redcarpet_parser.rb index 9af80571..7a805fe9 100644 --- a/lib/jekyll/converters/markdown/redcarpet_parser.rb +++ b/lib/jekyll/converters/markdown/redcarpet_parser.rb @@ -22,7 +22,7 @@ module Jekyll end end - module WithoutPygments + module WithoutHighlighting require 'cgi' include CommonMethods @@ -37,19 +37,50 @@ module Jekyll end end + module WithRouge + require 'rouge' + require 'rouge/plugins/redcarpet' + + if Rouge.version < '1.3.0' + abort "Please install Rouge 1.3.0 or greater and try running Jekyll again." + end + + include Rouge::Plugins::Redcarpet + include CommonMethods + + def block_code(code, lang) + code = "
#{super}" + + output = "
#{formatter.format(lexer.lex(code))}" + + output = context["highlighter_prefix"] || "" + output << "
` 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 `` 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:
diff --git a/site/docs/installation.md b/site/docs/installation.md
index 8fb82a0a..7e4bd570 100644
--- a/site/docs/installation.md
+++ b/site/docs/installation.md
@@ -66,9 +66,10 @@ Check out [the extras page](../extras/) for more information.
ProTip™: Enable Syntax Highlighting
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
- check out how to do
- that before you go any further.
+ want to enable syntax highlighting using Pygments
+ or Rouge. You should really
+ check out how to
+ do that before you go any farther.
diff --git a/site/docs/posts.md b/site/docs/posts.md
index 88036bdb..e944885e 100644
--- a/site/docs/posts.md
+++ b/site/docs/posts.md
@@ -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, and including a code snippet in any post is easy. Just
+use the dedicated Liquid tag as follows:
{% highlight text %}
{% raw %}{% highlight ruby %}{% endraw %}
diff --git a/site/docs/templates.md b/site/docs/templates.md
index 67b30123..6c34993b 100644
--- a/site/docs/templates.md
+++ b/site/docs/templates.md
@@ -230,8 +230,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:
@@ -247,8 +253,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
@@ -288,7 +295,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 %}
diff --git a/site/docs/troubleshooting.md b/site/docs/troubleshooting.md
index e481af6b..c27c1665 100644
--- a/site/docs/troubleshooting.md
+++ b/site/docs/troubleshooting.md
@@ -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 you’re seeing this just install 4.1.0.
+syntax highlighted blocks from Pygments or Rouge are not formatted
+correctly, among other things. If you’re seeing this just install 4.1.0.
### Liquid
diff --git a/test/test_configuration.rb b/test/test_configuration.rb
index d911b779..36e6cb1d 100644
--- a/test/test_configuration.rb
+++ b/test/test_configuration.rb
@@ -51,11 +51,12 @@ class TestConfiguration < Test::Unit::TestCase
context "#backwards_compatibilize" do
setup do
@config = Configuration[{
- "auto" => true,
- "watch" => true,
- "server" => true,
- "exclude" => "READ-ME.md, Gemfile,CONTRIBUTING.hello.markdown",
- "include" => "STOP_THE_PRESSES.txt,.heloses, .git"
+ "auto" => true,
+ "watch" => true,
+ "server" => true,
+ "exclude" => "READ-ME.md, Gemfile,CONTRIBUTING.hello.markdown",
+ "include" => "STOP_THE_PRESSES.txt,.heloses, .git",
+ "pygments" => true,
}]
end
should "unset 'auto' and 'watch'" do
@@ -78,6 +79,11 @@ class TestConfiguration < Test::Unit::TestCase
assert @config.backwards_compatibilize.has_key?("include")
assert_equal @config.backwards_compatibilize["include"], %w[STOP_THE_PRESSES.txt .heloses .git]
end
+ should "set highlighter to pygments" do
+ assert @config.has_key?("pygments")
+ assert !@config.backwards_compatibilize.has_key?("pygments")
+ assert_equal @config.backwards_compatibilize["highlighter"], "pygments"
+ end
end
context "#fix_common_issues" do
setup do
diff --git a/test/test_redcarpet.rb b/test/test_redcarpet.rb
index c6e8b922..dabcd62c 100644
--- a/test/test_redcarpet.rb
+++ b/test/test_redcarpet.rb
@@ -28,7 +28,7 @@ class TestRedcarpet < Test::Unit::TestCase
context "with pygments enabled" do
setup do
- @markdown = Converters::Markdown.new @config.merge({ 'pygments' => true })
+ @markdown = Converters::Markdown.new @config.merge({ 'highlighter' => 'pygments' })
end
should "render fenced code blocks with syntax highlighting" do
@@ -42,9 +42,25 @@ puts "Hello world"
end
end
- context "with pygments disabled" do
+ context "with rouge enabled" do
setup do
- @markdown = Converters::Markdown.new @config.merge({ 'pygments' => false })
+ @markdown = Converters::Markdown.new @config.merge({ 'highlighter' => 'rouge' })
+ end
+
+ should "render fenced code blocks with syntax highlighting" do
+ assert_equal "puts \"Hello world\"\n
", @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 })
end
should "render fenced code blocks without syntax highlighting" do
diff --git a/test/test_tags.rb b/test/test_tags.rb
index 3d9abd1b..8ecaf19b 100644
--- a/test/test_tags.rb
+++ b/test/test_tags.rb
@@ -6,7 +6,7 @@ class TestTags < Test::Unit::TestCase
def create_post(content, override = {}, converter_class = Jekyll::Converters::Markdown)
stub(Jekyll).configuration do
- Jekyll::Configuration::DEFAULTS.deep_merge({'pygments' => true}).deep_merge(override)
+ Jekyll::Configuration::DEFAULTS.deep_merge({'highlighter' => 'pygments'}).deep_merge(override)
end
site = Site.new(Jekyll.configuration)
@@ -16,8 +16,8 @@ class TestTags < Test::Unit::TestCase
info = { :filters => [Jekyll::Filters], :registers => { :site => site } }
@converter = site.converters.find { |c| c.class == converter_class }
- payload = { "pygments_prefix" => @converter.pygments_prefix,
- "pygments_suffix" => @converter.pygments_suffix }
+ payload = { "highlighter_prefix" => @converter.highlighter_prefix,
+ "highlighter_suffix" => @converter.highlighter_suffix }
@result = Liquid::Template.parse(content).render!(payload, info)
@result = @converter.convert(@result)