Refactor highlighting
Extract some of the common logic from the renderers.
This commit is contained in:
parent
494dd97775
commit
d6bd735aff
|
@ -5,30 +5,18 @@ module Jekyll
|
||||||
|
|
||||||
# The regular expression syntax checker. Start with the language specifier.
|
# The regular expression syntax checker. Start with the language specifier.
|
||||||
# Follow that by zero or more space separated options that take one of two
|
# Follow that by zero or more space separated options that take one of two
|
||||||
# forms:
|
# forms: name or name=value
|
||||||
#
|
|
||||||
# 1. name
|
|
||||||
# 2. name=value
|
|
||||||
SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=\w+)?)*)$/
|
SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=\w+)?)*)$/
|
||||||
|
|
||||||
def initialize(tag_name, markup, tokens)
|
def initialize(tag_name, markup, tokens)
|
||||||
super
|
super
|
||||||
if markup.strip =~ SYNTAX
|
if markup.strip =~ SYNTAX
|
||||||
@lang = $1.downcase
|
@lang = $1.downcase
|
||||||
@options = {}
|
@options = Hash[$2.split.map do |opt|
|
||||||
if defined?($2) && $2 != ''
|
key, value = opt.split("=")
|
||||||
$2.split.each do |opt|
|
[key.to_sym, (value || true)]
|
||||||
key, value = opt.split('=')
|
end]
|
||||||
if value.nil?
|
@options[:linenos] = "inline" if @options.key?(:linenos) and @options[:linenos] == true
|
||||||
if key == 'linenos'
|
|
||||||
value = 'inline'
|
|
||||||
else
|
|
||||||
value = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@options[key] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
raise SyntaxError.new <<-eos
|
raise SyntaxError.new <<-eos
|
||||||
Syntax Error in tag 'highlight' while parsing the following markup:
|
Syntax Error in tag 'highlight' while parsing the following markup:
|
||||||
|
@ -41,8 +29,11 @@ eos
|
||||||
end
|
end
|
||||||
|
|
||||||
def render(context)
|
def render(context)
|
||||||
|
prefix = context["highlighter_prefix"] || ""
|
||||||
|
suffix = context["highlighter_suffix"] || ""
|
||||||
code = super.to_s.strip
|
code = super.to_s.strip
|
||||||
case context.registers[:site].highlighter
|
|
||||||
|
output = case context.registers[:site].highlighter
|
||||||
when 'pygments'
|
when 'pygments'
|
||||||
render_pygments(context, code)
|
render_pygments(context, code)
|
||||||
when 'rouge'
|
when 'rouge'
|
||||||
|
@ -50,11 +41,11 @@ eos
|
||||||
else
|
else
|
||||||
render_codehighlighter(context, code)
|
render_codehighlighter(context, code)
|
||||||
end.strip
|
end.strip
|
||||||
|
prefix + add_code_tag(output) + suffix
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_pygments(context, code)
|
def render_pygments(context, code)
|
||||||
require 'pygments'
|
require 'pygments'
|
||||||
|
|
||||||
@options[:encoding] = 'utf-8'
|
@options[:encoding] = 'utf-8'
|
||||||
|
|
||||||
highlighted_code = Pygments.highlight(code, :lexer => @lang, :options => @options)
|
highlighted_code = Pygments.highlight(code, :lexer => @lang, :options => @options)
|
||||||
|
@ -70,45 +61,24 @@ 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
|
||||||
|
|
||||||
output = add_code_tags(highlighted_code, @lang)
|
highlighted_code
|
||||||
|
|
||||||
output = context["highlighter_prefix"] + output if context["highlighter_prefix"]
|
|
||||||
output << context["highlighter_suffix"] if context["highlighter_suffix"]
|
|
||||||
|
|
||||||
return output
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_rouge(context, code)
|
def render_rouge(context, code)
|
||||||
require 'rouge'
|
require 'rouge'
|
||||||
|
formatter = Rouge::Formatters::HTML.new(line_numbers: @options[:linenos], wrap: false)
|
||||||
linenos = @options.keys.include?('linenos')
|
|
||||||
lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
|
lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
|
||||||
formatter = Rouge::Formatters::HTML.new(line_numbers: linenos, wrap: false)
|
code = formatter.format(lexer.lex(code))
|
||||||
|
"<div class=\"highlight\"><pre>#{code}</pre></div>"
|
||||||
pre = "<pre>#{formatter.format(lexer.lex(code))}</pre>"
|
|
||||||
output = ""
|
|
||||||
|
|
||||||
output << context["highlighter_prefix"] if context["highlighter_prefix"]
|
|
||||||
output << "<div class=\"highlight\">"
|
|
||||||
output << add_code_tags(pre, @lang)
|
|
||||||
output << "</div>"
|
|
||||||
output << context["highlighter_suffix"] if context["highlighter_suffix"]
|
|
||||||
|
|
||||||
return output
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_codehighlighter(context, code)
|
def render_codehighlighter(context, code)
|
||||||
#The div is required because RDiscount blows ass
|
"<div class=\"highlight\"><pre>#{h(code).strip}</pre></div>"
|
||||||
<<-HTML
|
|
||||||
<div>
|
|
||||||
<pre><code class='#{@lang.to_s.gsub("+", "-")}'>#{h(code).strip}</code></pre>
|
|
||||||
</div>
|
|
||||||
HTML
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_code_tags(code, lang)
|
def add_code_tag(code)
|
||||||
# Add nested <code> tags to code blocks
|
# Add nested <code> tags to code blocks
|
||||||
code = code.sub(/<pre>\n*/,'<pre><code class="' + lang.to_s.gsub("+", "-") + '">')
|
code = code.sub(/<pre>\n*/,'<pre><code class="' + @lang.to_s.gsub("+", "-") + '">')
|
||||||
code = code.sub(/\n*<\/pre>/,"</code></pre>")
|
code = code.sub(/\n*<\/pre>/,"</code></pre>")
|
||||||
code.strip
|
code.strip
|
||||||
end
|
end
|
||||||
|
|
|
@ -65,16 +65,16 @@ CONTENT
|
||||||
assert_equal({}, tag.instance_variable_get(:@options))
|
assert_equal({}, tag.instance_variable_get(:@options))
|
||||||
|
|
||||||
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos ', ["test", "{% endhighlight %}", "\n"])
|
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos ', ["test", "{% endhighlight %}", "\n"])
|
||||||
assert_equal({ 'linenos' => 'inline' }, tag.instance_variable_get(:@options))
|
assert_equal({ :linenos => 'inline' }, tag.instance_variable_get(:@options))
|
||||||
|
|
||||||
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table ', ["test", "{% endhighlight %}", "\n"])
|
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table ', ["test", "{% endhighlight %}", "\n"])
|
||||||
assert_equal({ 'linenos' => 'table' }, tag.instance_variable_get(:@options))
|
assert_equal({ :linenos => 'table' }, tag.instance_variable_get(:@options))
|
||||||
|
|
||||||
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table nowrap', ["test", "{% endhighlight %}", "\n"])
|
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table nowrap', ["test", "{% endhighlight %}", "\n"])
|
||||||
assert_equal({ 'linenos' => 'table', 'nowrap' => true }, tag.instance_variable_get(:@options))
|
assert_equal({ :linenos => 'table', :nowrap => true }, tag.instance_variable_get(:@options))
|
||||||
|
|
||||||
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table cssclass=hl', ["test", "{% endhighlight %}", "\n"])
|
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'ruby linenos=table cssclass=hl', ["test", "{% endhighlight %}", "\n"])
|
||||||
assert_equal({ 'cssclass' => 'hl', 'linenos' => 'table' }, tag.instance_variable_get(:@options))
|
assert_equal({ :cssclass => 'hl', :linenos => 'table' }, tag.instance_variable_get(:@options))
|
||||||
|
|
||||||
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'Ruby ', ["test", "{% endhighlight %}", "\n"])
|
tag = Jekyll::Tags::HighlightBlock.new('highlight', 'Ruby ', ["test", "{% endhighlight %}", "\n"])
|
||||||
assert_equal "ruby", tag.instance_variable_get(:@lang), "lexers should be case insensitive"
|
assert_equal "ruby", tag.instance_variable_get(:@lang), "lexers should be case insensitive"
|
||||||
|
|
Loading…
Reference in New Issue