highlight: fix problem with linenos and rouge.

Found by @EdMcBane in https://github.com/jekyll/jekyll/pull/3435

The strange regexp we were doing to replace the <pre><code></pre></code>
bits in the Pygments output were wreaking havoc on Rouge output
because Rouge uses <pre>'s to wrap line numbers.

To be consistent, the output from render_* should *not* include
the wrapping <div> and <pre> tags. It should just be what was
inside. We can then wrap it in our own custom tags without using
any regular expressions, as God intended. Death to regular
expressions and HTML manipulation!
This commit is contained in:
Parker Moore 2015-02-09 21:42:50 -08:00
parent a0134dea4f
commit bf149a0b97
1 changed files with 8 additions and 10 deletions

View File

@ -77,8 +77,6 @@ eos
def render_pygments(code, is_safe) def render_pygments(code, is_safe)
Jekyll::External.require_with_graceful_fail('pygments') Jekyll::External.require_with_graceful_fail('pygments')
@options[:encoding] = 'utf-8'
highlighted_code = Pygments.highlight( highlighted_code = Pygments.highlight(
code, code,
:lexer => @lang, :lexer => @lang,
@ -96,26 +94,26 @@ eos
raise ArgumentError.new("Pygments.rb returned an unacceptable value when attempting to highlight some code.") raise ArgumentError.new("Pygments.rb returned an unacceptable value when attempting to highlight some code.")
end end
highlighted_code highlighted_code.sub('<div class="highlight"><pre>', '').sub('</pre></div>', '')
end end
def render_rouge(code) def render_rouge(code)
Jekyll::External.require_with_graceful_fail('rouge') Jekyll::External.require_with_graceful_fail('rouge')
formatter = Rouge::Formatters::HTML.new(line_numbers: @options[:linenos], wrap: false) formatter = Rouge::Formatters::HTML.new(line_numbers: @options[:linenos], wrap: false)
lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
code = formatter.format(lexer.lex(code)) formatter.format(lexer.lex(code))
"<div class=\"highlight\"><pre>#{code}</pre></div>"
end end
def render_codehighlighter(code) def render_codehighlighter(code)
"<div class=\"highlight\"><pre>#{h(code).strip}</pre></div>" h(code).strip
end end
def add_code_tag(code) def add_code_tag(code)
# Add nested <code> tags to code blocks code_attributes = [
code = code.sub(/<pre>\n*/,'<pre><code class="language-' + @lang.to_s.gsub("+", "-") + '" data-lang="' + @lang.to_s + '">') "class=\"language-#{@lang.to_s.gsub('+', '-')}\"",
code = code.sub(/\n*<\/pre>/,"</code></pre>") "data-lang=\"#{@lang.to_s}\""
code.strip ].join(" ")
"<div class=\"highlight\"><pre><code #{code_attributes}>#{code.chomp}</code></pre></div>"
end end
end end