From 903cce27451db147ba04377f25d0fb11865c75f8 Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Sun, 22 Dec 2013 12:29:19 +0100 Subject: [PATCH 1/9] Fix the highlight tag feature Previously, the assertion made wasn't enough to check whether the code block was correctly parsed through Pygments (and it was not the case). This commit simply ensure there is a div with the "highlight" class and fix the test to correctly invoke the Liquid tag rendering. --- History.markdown | 1 + features/site_configuration.feature | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/History.markdown b/History.markdown index aef437dc..1e6423c6 100644 --- a/History.markdown +++ b/History.markdown @@ -24,6 +24,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 ### Site Enhancements * Document Kramdown's GFM parser option (#1791) diff --git a/features/site_configuration.feature b/features/site_configuration.feature index 0a08f753..50d0fff1 100644 --- a/features/site_configuration.feature +++ b/features/site_configuration.feature @@ -91,11 +91,12 @@ 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 %}" + And I have a configuration file with "highlighter" set to "pygments" 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: Set time and no future dated posts Given I have a _layouts directory From 92064134d67eb17392a45e4fc82d83423a4b8ff4 Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Sun, 22 Dec 2013 12:45:15 +0100 Subject: [PATCH 2/9] Rename the pygments option to highlighter Rename the pygments configuration option to highlighter to allow different highlighters in the future. For now, the allowed values are `pygments` and `null`. It's now more straightforward to plug another syntax highlighter. --- History.markdown | 1 + lib/jekyll/configuration.rb | 9 +++++- lib/jekyll/converter.rb | 32 +++++++++---------- lib/jekyll/converters/markdown.rb | 4 +-- .../converters/markdown/redcarpet_parser.rb | 3 +- lib/jekyll/converters/textile.rb | 4 +-- lib/jekyll/convertible.rb | 4 +-- lib/jekyll/deprecator.rb | 3 +- lib/jekyll/site.rb | 4 +-- lib/jekyll/tags/highlight.rb | 10 +++--- lib/site_template/_config.yml | 2 +- test/test_redcarpet.rb | 6 ++-- test/test_tags.rb | 6 ++-- 13 files changed, 49 insertions(+), 39 deletions(-) diff --git a/History.markdown b/History.markdown index 1e6423c6..3b633a7c 100644 --- a/History.markdown +++ b/History.markdown @@ -1,6 +1,7 @@ ## 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) diff --git a/lib/jekyll/configuration.rb b/lib/jekyll/configuration.rb index a72e51d8..46c3365c 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'], @@ -209,6 +209,13 @@ 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" + 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 485cac82..697f4e7e 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..9e96c35e 100644 --- a/lib/jekyll/converters/markdown/redcarpet_parser.rb +++ b/lib/jekyll/converters/markdown/redcarpet_parser.rb @@ -43,7 +43,8 @@ module Jekyll @redcarpet_extensions = {} @config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true } - @renderer ||= if @config['pygments'] + @renderer ||= case @config['highlighter'] + when 'pygments' Class.new(Redcarpet::Render::HTML) do include WithPygments end diff --git a/lib/jekyll/converters/textile.rb b/lib/jekyll/converters/textile.rb index 54e93749..d05b2169 100644 --- a/lib/jekyll/converters/textile.rb +++ b/lib/jekyll/converters/textile.rb @@ -3,8 +3,8 @@ module Jekyll class Textile < Converter safe true - pygments_prefix '' - pygments_suffix '' + highlighter_prefix '' + highlighter_suffix '' def setup return if @setup diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb index 815c36b0..b0b1b090 100644 --- a/lib/jekyll/convertible.rb +++ b/lib/jekyll/convertible.rb @@ -144,8 +144,8 @@ module Jekyll info = { :filters => [Jekyll::Filters], :registers => { :site => self.site, :page => payload['page'] } } # render and transform content (this becomes the final content of the object) - payload["pygments_prefix"] = converter.pygments_prefix - payload["pygments_suffix"] = converter.pygments_suffix + payload["highlighter_prefix"] = converter.highlighter_prefix + payload["highlighter_suffix"] = converter.highlighter_suffix self.content = self.render_liquid(self.content, payload, diff --git a/lib/jekyll/deprecator.rb b/lib/jekyll/deprecator.rb index 23af739d..0fdb7a7b 100644 --- a/lib/jekyll/deprecator.rb +++ b/lib/jekyll/deprecator.rb @@ -9,8 +9,7 @@ module Jekyll arg_is_present? args, "--auto", "The switch '--auto' has been replaced with '--watch'." arg_is_present? args, "--no-auto", "To disable auto-replication, simply leave off \ the '--watch' switch." - arg_is_present? args, "--pygments", "The 'pygments' setting can only be set in \ - your config files." + arg_is_present? args, "--pygments", "The 'pygments' setting has been removed" arg_is_present? args, "--paginate", "The 'paginate' setting can only be set in your \ config files." arg_is_present? args, "--url", "The 'url' setting can only be set in your config files." diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb index 8fee59cf..95bb46f9 100644 --- a/lib/jekyll/site.rb +++ b/lib/jekyll/site.rb @@ -1,7 +1,7 @@ module Jekyll class Site attr_accessor :config, :layouts, :posts, :pages, :static_files, - :categories, :exclude, :include, :source, :dest, :lsi, :pygments, + :categories, :exclude, :include, :source, :dest, :lsi, :highlighter, :permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts, :show_drafts, :keep_files, :baseurl, :data, :file_read_opts, :gems @@ -13,7 +13,7 @@ module Jekyll def initialize(config) self.config = config.clone - %w[safe lsi pygments baseurl exclude include future show_drafts limit_posts keep_files gems].each do |opt| + %w[safe lsi highlighter baseurl exclude include future show_drafts limit_posts keep_files gems].each do |opt| self.send("#{opt}=", config[opt]) end diff --git a/lib/jekyll/tags/highlight.rb b/lib/jekyll/tags/highlight.rb index 2ea144df..a20e90c0 100644 --- a/lib/jekyll/tags/highlight.rb +++ b/lib/jekyll/tags/highlight.rb @@ -41,7 +41,8 @@ eos end def render(context) - if context.registers[:site].pygments + case context.registers[:site].highlighter + when 'pygments' render_pygments(context, super) else render_codehighlighter(context, super) @@ -58,9 +59,10 @@ eos @lang ) - output = context["pygments_prefix"] + output if context["pygments_prefix"] - output = output + context["pygments_suffix"] if context["pygments_suffix"] - output + output = context["highlighter_prefix"] + output if context["highlighter_prefix"] + output << context["highlighter_suffix"] if context["highlighter_suffix"] + + return output end def render_codehighlighter(context, code) diff --git a/lib/site_template/_config.yml b/lib/site_template/_config.yml index 85daa771..627c7898 100644 --- a/lib/site_template/_config.yml +++ b/lib/site_template/_config.yml @@ -1,3 +1,3 @@ name: Your New Jekyll Site markdown: redcarpet -pygments: true +highlighter: pygments diff --git a/test/test_redcarpet.rb b/test/test_redcarpet.rb index c6e8b922..c8354c4b 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,9 @@ puts "Hello world" end end - context "with pygments disabled" do + context "without any highlighter" do setup do - @markdown = Converters::Markdown.new @config.merge({ 'pygments' => false }) + @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 b21f4931..4819ed93 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) From 0831d2b0f839f8dfc2dcd39387597b4f89a5ac0a Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Sun, 22 Dec 2013 13:53:53 +0100 Subject: [PATCH 3/9] 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. --- History.markdown | 5 ++-- features/site_configuration.feature | 8 ++++++ jekyll.gemspec | 1 + .../converters/markdown/redcarpet_parser.rb | 26 ++++++++++++++++--- lib/jekyll/tags/highlight.rb | 18 +++++++++++++ site/_config.yml | 2 +- site/docs/configuration.md | 6 ++--- site/docs/installation.md | 6 ++--- site/docs/posts.md | 4 +-- site/docs/templates.md | 17 ++++++++---- site/docs/troubleshooting.md | 4 +-- test/test_redcarpet.rb | 16 ++++++++++++ 12 files changed, 92 insertions(+), 21 deletions(-) diff --git a/History.markdown b/History.markdown index 3b633a7c..6988a787 100644 --- a/History.markdown +++ b/History.markdown @@ -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) diff --git a/features/site_configuration.feature b/features/site_configuration.feature index 50d0fff1..6d3ea647 100644 --- a/features/site_configuration.feature +++ b/features/site_configuration.feature @@ -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" }}" diff --git a/jekyll.gemspec b/jekyll.gemspec index 1b1f4ef2..e62e5380 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.0') # = MANIFEST = s.files = %w[ diff --git a/lib/jekyll/converters/markdown/redcarpet_parser.rb b/lib/jekyll/converters/markdown/redcarpet_parser.rb index 9e96c35e..7ad33dd2 100644 --- a/lib/jekyll/converters/markdown/redcarpet_parser.rb +++ b/lib/jekyll/converters/markdown/redcarpet_parser.rb @@ -5,7 +5,7 @@ module Jekyll module CommonMethods def add_code_tags(code, lang) - code = code.sub(/
/, "
")
+            code = code.sub(//, "
")
             code = code.sub(/<\/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 = "
" + output << add_code_tags(formatter.render(lexer.lex(code)), lang) + output << "
" + 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 diff --git a/lib/jekyll/tags/highlight.rb b/lib/jekyll/tags/highlight.rb index a20e90c0..eb6bf5a3 100644 --- a/lib/jekyll/tags/highlight.rb +++ b/lib/jekyll/tags/highlight.rb @@ -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 << "
" + output << add_code_tags(formatter.render(lexer.lex(code)), @lang) + output << "
" + 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 diff --git a/site/_config.yml b/site/_config.yml index f14c4e05..fc1fd46d 100644 --- a/site/_config.yml +++ b/site/_config.yml @@ -1,4 +1,4 @@ -pygments: true +highlight: pygments relative_permalinks: false gauges_id: 503c5af6613f5d0f19000027 permalink: /news/:year/:month/:day/:title/ diff --git a/site/docs/configuration.md b/site/docs/configuration.md index df93d9c6..8740d987 100644 --- a/site/docs/configuration.md +++ b/site/docs/configuration.md @@ -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 `` 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: @@ -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 \ No newline at end of file + input: GFM diff --git a/site/docs/installation.md b/site/docs/installation.md index 8fb82a0a..977e9d9c 100644 --- a/site/docs/installation.md +++ b/site/docs/installation.md @@ -66,9 +66,9 @@ 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 further.

diff --git a/site/docs/posts.md b/site/docs/posts.md index 88036bdb..73899a3b 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](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 %} diff --git a/site/docs/templates.md b/site/docs/templates.md index 7cf2a865..236aaaea 100644 --- a/site/docs/templates.md +++ b/site/docs/templates.md @@ -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 %} 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_redcarpet.rb b/test/test_redcarpet.rb index c8354c4b..dabcd62c 100644 --- a/test/test_redcarpet.rb +++ b/test/test_redcarpet.rb @@ -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 "
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 }) From 4bf716c2ad36d955a27250e12509ae9e4eb8b940 Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Sun, 22 Dec 2013 16:50:13 +0100 Subject: [PATCH 4/9] Set highlighter to pygments when upgrading In case you are upgrading from 1.4.2 to 2.0 and the pygments option is set to true, then the highlighter option will be set to pygments automatically. --- lib/jekyll/configuration.rb | 5 ++++- test/test_configuration.rb | 16 +++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/jekyll/configuration.rb b/lib/jekyll/configuration.rb index 46c3365c..53e0bf4f 100644 --- a/lib/jekyll/configuration.rb +++ b/lib/jekyll/configuration.rb @@ -212,8 +212,11 @@ module Jekyll 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"+ + " 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| 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 From bd442680ea6809a9ed9811fd0a51577c5865c852 Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Sun, 22 Dec 2013 17:09:12 +0100 Subject: [PATCH 5/9] Rely on the Redcarpet plugin instead of hard-coding To avoid code duplication and have to keep tracking of the API change of Rouge, let's rely on the Redcarpet plugin and customize the output on our needs. --- lib/jekyll/converters/markdown/redcarpet_parser.rb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/jekyll/converters/markdown/redcarpet_parser.rb b/lib/jekyll/converters/markdown/redcarpet_parser.rb index 7ad33dd2..082c8889 100644 --- a/lib/jekyll/converters/markdown/redcarpet_parser.rb +++ b/lib/jekyll/converters/markdown/redcarpet_parser.rb @@ -38,16 +38,15 @@ module Jekyll end module WithRouge + require 'rouge' + require 'rouge/plugins/redcarpet' + + include Rouge::Plugins::Redcarpet 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 = "
" - output << add_code_tags(formatter.render(lexer.lex(code)), lang) + output << add_code_tags(super, lang) output << "
" end end From cab9047de10dbfec0dd322acfb191cf0dfdf38e3 Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Sun, 22 Dec 2013 17:24:33 +0100 Subject: [PATCH 6/9] Set the wrap option to false when using Rouge Since Rouge yields the pre tag with a class attribute but we don't want it, we should set the wrap parameter to false when instantiating a new formatter object. Also use Rouge::Formatter#format instead of #render which is deprecated and will be removed in the near future. --- lib/jekyll/tags/highlight.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/jekyll/tags/highlight.rb b/lib/jekyll/tags/highlight.rb index eb6bf5a3..8719511f 100644 --- a/lib/jekyll/tags/highlight.rb +++ b/lib/jekyll/tags/highlight.rb @@ -72,11 +72,13 @@ eos linenos = @options.keys.include?('linenos') lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText - formatter = Rouge::Formatters::HTML.new(line_numbers: linenos) + formatter = Rouge::Formatters::HTML.new(line_numbers: linenos, wrap: false) + + pre = "
#{formatter.format(lexer.lex(code))}
" output = context["highlighter_prefix"] || "" output << "
" - output << add_code_tags(formatter.render(lexer.lex(code)), @lang) + output << add_code_tags(pre, @lang) output << "
" output << context["highlighter_suffix"] if context["highlighter_suffix"] From 3ca2cb0119608a2f31c5561917c9de4c4ab4d663 Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Mon, 23 Dec 2013 12:42:38 +0100 Subject: [PATCH 7/9] Fix various typos and improve the doc --- lib/jekyll/configuration.rb | 2 +- lib/jekyll/deprecator.rb | 3 ++- site/docs/installation.md | 7 ++++--- site/docs/posts.md | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/jekyll/configuration.rb b/lib/jekyll/configuration.rb index 53e0bf4f..27058f54 100644 --- a/lib/jekyll/configuration.rb +++ b/lib/jekyll/configuration.rb @@ -213,7 +213,7 @@ module Jekyll 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" + "'pygments' or null." config['highlighter'] = 'pygments' if config['pygments'] config.delete('pygments') diff --git a/lib/jekyll/deprecator.rb b/lib/jekyll/deprecator.rb index 0fdb7a7b..7600cd29 100644 --- a/lib/jekyll/deprecator.rb +++ b/lib/jekyll/deprecator.rb @@ -9,7 +9,8 @@ module Jekyll arg_is_present? args, "--auto", "The switch '--auto' has been replaced with '--watch'." arg_is_present? args, "--no-auto", "To disable auto-replication, simply leave off \ the '--watch' switch." - arg_is_present? args, "--pygments", "The 'pygments' setting has been removed" + arg_is_present? args, "--pygments", "The 'pygments'settings has been removed in \ + favour of 'highlighter'." arg_is_present? args, "--paginate", "The 'paginate' setting can only be set in your \ config files." arg_is_present? args, "--url", "The 'url' setting can only be set in your config files." diff --git a/site/docs/installation.md b/site/docs/installation.md index 977e9d9c..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 or Rouge. 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 73899a3b..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 -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: +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 %} From 5647a902de7d58e98e3be6b1417fcda1b5ec46ca Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Mon, 23 Dec 2013 12:43:25 +0100 Subject: [PATCH 8/9] Remove a useless given step Since the highlighter configuration option should default to pygments, we don't have to explicitly set it in the step testing the output with pygments. --- features/site_configuration.feature | 1 - 1 file changed, 1 deletion(-) diff --git a/features/site_configuration.feature b/features/site_configuration.feature index 6d3ea647..a7c59b00 100644 --- a/features/site_configuration.feature +++ b/features/site_configuration.feature @@ -92,7 +92,6 @@ Feature: Site configuration Scenario: Highlight code with pygments 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 "pygments" When I run jekyll Then the _site directory should exist And I should see "Hello world!" in "_site/index.html" From 036cbda2f620942a84b475a858d5f3a88b71a322 Mon Sep 17 00:00:00 2001 From: Robin Dupret Date: Wed, 25 Dec 2013 18:06:29 +0100 Subject: [PATCH 9/9] Require at least 1.3.0 for Rouge Rouge 1.3.0 introduced a `rouge_formatter` helper which is handy to overwrite the formatter default when using the Redcarpet plugin so let's require this version at the very least. An abort statement will be thrown when the installed version is not correct. --- jekyll.gemspec | 2 +- .../converters/markdown/redcarpet_parser.rb | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/jekyll.gemspec b/jekyll.gemspec index e62e5380..fcfef499 100644 --- a/jekyll.gemspec +++ b/jekyll.gemspec @@ -52,7 +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') + s.add_development_dependency('rouge', '~> 1.3') # = MANIFEST = s.files = %w[ diff --git a/lib/jekyll/converters/markdown/redcarpet_parser.rb b/lib/jekyll/converters/markdown/redcarpet_parser.rb index 082c8889..7a805fe9 100644 --- a/lib/jekyll/converters/markdown/redcarpet_parser.rb +++ b/lib/jekyll/converters/markdown/redcarpet_parser.rb @@ -5,7 +5,7 @@ module Jekyll module CommonMethods def add_code_tags(code, lang) - code = code.sub(//, "
")
+            code = code.sub(/
/, "
")
             code = code.sub(/<\/pre>/,"
") end end @@ -41,14 +41,25 @@ module Jekyll 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 = "
" - output << add_code_tags(super, lang) + output << add_code_tags(code, lang) output << "
" end + + protected + def rouge_formatter(opts = {}) + Rouge::Formatters::HTML.new(opts.merge(wrap: false)) + end end