Skip to content

Commit

Permalink
Allow for passing Rouge formatter as a String
Browse files Browse the repository at this point in the history
  • Loading branch information
kejadlen authored and gettalong committed Nov 26, 2017
1 parent ae2a208 commit ff0218a
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 17 deletions.
4 changes: 2 additions & 2 deletions doc/syntax_highlighter/rouge.page
Expand Up @@ -25,8 +25,8 @@ formatter
: A custom Rouge formatter class that should be used instead of the following default formatter
(Rogue 1.x: `Rouge::Formatters::HTML` / Rogue 2.x: `Rouge::Formatters::HTMLLegacy`).

Note that setting this key only makes sense using Ruby code because the value needs to be a class
object!
If this setting is a string, it needs to contain the name of a constant under the
`Rouge::Formatters` namespace.

disable
: If set to `true`, highlighting with Rouge will be disabled.
Expand Down
25 changes: 16 additions & 9 deletions lib/kramdown/converter/syntax_highlighter/rouge.rb
Expand Up @@ -17,14 +17,6 @@ module Rouge

# Highlighting via Rouge is available if this constant is +true+.
AVAILABLE = true

begin
# Rouge::Formatters::HTMLLegacy is available on Rouge 2.0 or later
FORMATTER_CLASS = ::Rouge::Formatters::HTMLLegacy
rescue NameError
# Fallbacks to Rouge 1.x formatter if Rouge::Formatters::HTMLLegacy is not available
FORMATTER_CLASS = ::Rouge::Formatters::HTML
end
rescue LoadError, SyntaxError
AVAILABLE = false # :nodoc:
end
Expand All @@ -35,7 +27,7 @@ def self.call(converter, text, lang, type, call_opts)
lexer = ::Rouge::Lexer.find_fancy(lang || opts[:default_lang], text)
return nil if opts[:disable] || !lexer
opts[:css_class] ||= 'highlight' # For backward compatibility when using Rouge 2.0
formatter = (opts.fetch(:formatter, FORMATTER_CLASS)).new(opts)
formatter = formatter_class(opts).new(opts)
formatter.format(lexer.lex(text))
end

Expand All @@ -62,6 +54,21 @@ def self.prepare_options(converter)
cache[:block] = opts.merge(block_opts)
end

def self.formatter_class(opts = {})
case formatter = opts[:formatter]
when Class
formatter
when /\A[[:upper:]][[:alnum:]_]*\z/
::Rouge::Formatters.const_get(formatter)
else
# Available in Rouge 2.0 or later
::Rouge::Formatters::HTMLLegacy
end
rescue NameError
# Fallback to Rouge 1.x
::Rouge::Formatters::HTML
end

end

end
8 changes: 3 additions & 5 deletions test/test_files.rb
Expand Up @@ -15,14 +15,12 @@
begin
require 'kramdown/converter/syntax_highlighter/rouge'

class Kramdown::Converter::SyntaxHighlighter::Rouge::FORMATTER_CLASS
def format(tokens, &b)
super.sub(/<\/code><\/pre>\n?/, "</code></pre>\n")
end
Kramdown::Converter::SyntaxHighlighter::Rouge.formatter_class.send(:define_method, :format) do |tokens, &b|
super(tokens, &b).sub(/<\/code><\/pre>\n?/, "</code></pre>\n")
end

# custom formatter for tests
class RougeHTMLFormatters < Kramdown::Converter::SyntaxHighlighter::Rouge::FORMATTER_CLASS
class RougeHTMLFormatters < Kramdown::Converter::SyntaxHighlighter::Rouge.formatter_class
tag 'rouge_html_formatters'

def stream(tokens, &b)
Expand Down
2 changes: 1 addition & 1 deletion test/testcases/block/06_codeblock/rouge/multiple.options
@@ -1,4 +1,4 @@
:syntax_highlighter: rouge
:syntax_highlighter_opts:
default_lang: ruby
formatter: !ruby/class 'RougeHTMLFormatters'
formatter: RougeHTMLFormatters

0 comments on commit ff0218a

Please sign in to comment.