diff --git a/Gemfile b/Gemfile index a5a58995..cbd97b7b 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ gem "posix-spawn", :platforms => :ruby gem "redcarpet", :platforms => :ruby gem "kramdown", :platforms => :jruby gem "RedCloth" -gem "commonmarker", "~> 0.14.12" +gem "commonmarker", "~> 0.18.1" gem "rdoc", "~>3.6" gem "org-ruby", "= 0.9.9" gem "creole", "~>0.3.6" diff --git a/lib/github/markup.rb b/lib/github/markup.rb index 84c1e45f..5a78d006 100644 --- a/lib/github/markup.rb +++ b/lib/github/markup.rb @@ -20,38 +20,36 @@ module Markups MARKUP_RST = :rst MARKUP_TEXTILE = :textile end - + module Markup extend self - + @@markups = {} def markups @@markups end - + def markup_impls markups.values end def preload! - markup_impls.each do |markup| - markup.load - end + markup_impls.each(&:load) end - def render(filename, content, symlink = false) - if impl = renderer(filename, content, symlink) - impl.render(filename, content) + def render(filename, content, symlink: false, options: {}) + if (impl = renderer(filename, content, symlink: symlink)) + impl.render(filename, content, options: options) else content end end - + def render_s(symbol, content) - if content.nil? - raise ArgumentError, 'Can not render a nil.' - elsif markups.has_key?(symbol) + raise ArgumentError, 'Can not render a nil.' if content.nil? + + if markups.key?(symbol) markups[symbol].render(nil, content) else content @@ -59,11 +57,12 @@ def render_s(symbol, content) end def markup(symbol, gem_name, regexp, languages, opts = {}, &block) - markup_impl(symbol, GemImplementation.new(regexp, languages, gem_name, &block)) + impl = GemImplementation.new(regexp, languages, gem_name, &block) + markup_impl(symbol, impl) end - + def markup_impl(symbol, impl) - if markups.has_key?(symbol) + if markups.key?(symbol) raise ArgumentError, "The '#{symbol}' symbol is already defined." end markups[symbol] = impl @@ -74,25 +73,26 @@ def command(symbol, command, regexp, languages, name, &block) command = file end - markup_impl(symbol, CommandImplementation.new(regexp, languages, command, name, &block)) + impl = CommandImplementation.new(regexp, languages, command, name, &block) + markup_impl(symbol, impl) end - def can_render?(filename, content, symlink = false) - !!renderer(filename, content, symlink) + def can_render?(filename, content, symlink: false) + renderer(filename, content, symlink: symlink) != nil end - def renderer(filename, content, symlink = false) - language = language(filename, content, symlink) - markup_impls.find { |impl| + def renderer(filename, content, symlink: false) + language = language(filename, content, symlink: symlink) + markup_impls.find do |impl| impl.match?(filename, language) - } + end end - def language(filename, content, symlink = false) - if defined?(::Linguist) - blob = Linguist::Blob.new(filename, content, symlink: symlink) - return Linguist.detect(blob, allow_empty: true) - end + def language(filename, content, symlink: false) + return unless defined?(::Linguist) + + blob = Linguist::Blob.new(filename, content, symlink: symlink) + Linguist.detect(blob, allow_empty: true) end # Define markups diff --git a/lib/github/markup/command_implementation.rb b/lib/github/markup/command_implementation.rb index ed67113c..4ecf2ad5 100644 --- a/lib/github/markup/command_implementation.rb +++ b/lib/github/markup/command_implementation.rb @@ -22,7 +22,7 @@ def initialize(regexp, languages, command, name, &block) @name = name end - def render(filename, content) + def render(filename, content, options: {}) rendered = execute(command, content) rendered = rendered.to_s.empty? ? content : rendered call_block(rendered, content) diff --git a/lib/github/markup/gem_implementation.rb b/lib/github/markup/gem_implementation.rb index 29582ce8..843717e6 100644 --- a/lib/github/markup/gem_implementation.rb +++ b/lib/github/markup/gem_implementation.rb @@ -12,14 +12,14 @@ def initialize(regexp, languages, gem_name, &renderer) end def load - return if @loaded + return if defined?(@loaded) && @loaded require gem_name @loaded = true end - def render(filename, content) + def render(filename, content, options: {}) load - renderer.call(filename, content) + renderer.call(filename, content, options: options) end def name diff --git a/lib/github/markup/implementation.rb b/lib/github/markup/implementation.rb index aaa92534..f2854e22 100644 --- a/lib/github/markup/implementation.rb +++ b/lib/github/markup/implementation.rb @@ -16,7 +16,7 @@ def load # no-op by default end - def render(filename, content) + def render(filename, content, options: {}) raise NotImplementedError, "subclasses of GitHub::Markup::Implementation must define #render" end diff --git a/lib/github/markup/markdown.rb b/lib/github/markup/markdown.rb index c51476fd..aa012d48 100644 --- a/lib/github/markup/markdown.rb +++ b/lib/github/markup/markdown.rb @@ -4,25 +4,26 @@ module GitHub module Markup class Markdown < Implementation MARKDOWN_GEMS = { - "commonmarker" => proc { |content| - CommonMarker.render_html(content, :GITHUB_PRE_LANG, [:tagfilter, :autolink, :table, :strikethrough]) + "commonmarker" => proc { |content, options: {}| + commonmarker_opts = [:GITHUB_PRE_LANG].concat(options.fetch(:commonmarker_opts, [])) + CommonMarker.render_html(content, commonmarker_opts, [:tagfilter, :autolink, :table, :strikethrough]) }, - "github/markdown" => proc { |content| + "github/markdown" => proc { |content, options: {}| GitHub::Markdown.render(content) }, - "redcarpet" => proc { |content| + "redcarpet" => proc { |content, options: {}| Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(content) }, - "rdiscount" => proc { |content| + "rdiscount" => proc { |content, options: {}| RDiscount.new(content).to_html }, - "maruku" => proc { |content| + "maruku" => proc { |content, options: {}| Maruku.new(content).to_html }, - "kramdown" => proc { |content| + "kramdown" => proc { |content, options: {}| Kramdown::Document.new(content).to_html }, - "bluecloth" => proc { |content| + "bluecloth" => proc { |content, options: {}| BlueCloth.new(content).to_html }, } @@ -44,9 +45,9 @@ def load raise LoadError, "no suitable markdown gem found" end - def render(filename, content) + def render(filename, content, options: {}) load - @renderer.call(content) + @renderer.call(content, options: options) end def name diff --git a/lib/github/markup/rdoc.rb b/lib/github/markup/rdoc.rb index 749618d9..32cb4194 100644 --- a/lib/github/markup/rdoc.rb +++ b/lib/github/markup/rdoc.rb @@ -9,7 +9,7 @@ def initialize super(/rdoc/, ["RDoc"]) end - def render(filename, content) + def render(filename, content, options: {}) if ::RDoc::VERSION.to_i >= 4 h = ::RDoc::Markup::ToHtml.new(::RDoc::Options.new) else diff --git a/lib/github/markups.rb b/lib/github/markups.rb index 61138e85..440e0dbf 100644 --- a/lib/github/markups.rb +++ b/lib/github/markups.rb @@ -4,30 +4,30 @@ markup_impl(::GitHub::Markups::MARKUP_MARKDOWN, ::GitHub::Markup::Markdown.new) -markup(::GitHub::Markups::MARKUP_TEXTILE, :redcloth, /textile/, ["Textile"]) do |filename, content| +markup(::GitHub::Markups::MARKUP_TEXTILE, :redcloth, /textile/, ["Textile"]) do |filename, content, options: {}| RedCloth.new(content).to_html end markup_impl(::GitHub::Markups::MARKUP_RDOC, GitHub::Markup::RDoc.new) -markup(::GitHub::Markups::MARKUP_ORG, 'org-ruby', /org/, ["Org"]) do |filename, content| +markup(::GitHub::Markups::MARKUP_ORG, 'org-ruby', /org/, ["Org"]) do |filename, content, options: {}| Orgmode::Parser.new(content, { :allow_include_files => false, :skip_syntax_highlight => true }).to_html end -markup(::GitHub::Markups::MARKUP_CREOLE, :creole, /creole/, ["Creole"]) do |filename, content| +markup(::GitHub::Markups::MARKUP_CREOLE, :creole, /creole/, ["Creole"]) do |filename, content, options: {}| Creole.creolize(content) end -markup(::GitHub::Markups::MARKUP_MEDIAWIKI, :wikicloth, /mediawiki|wiki/, ["MediaWiki"]) do |filename, content| +markup(::GitHub::Markups::MARKUP_MEDIAWIKI, :wikicloth, /mediawiki|wiki/, ["MediaWiki"]) do |filename, content, options: {}| wikicloth = WikiCloth::WikiCloth.new(:data => content) WikiCloth::WikiBuffer::HTMLElement::ESCAPED_TAGS << 'tt' unless WikiCloth::WikiBuffer::HTMLElement::ESCAPED_TAGS.include?('tt') wikicloth.to_html(:noedit => true) end -markup(::GitHub::Markups::MARKUP_ASCIIDOC, :asciidoctor, /adoc|asc(iidoc)?/, ["AsciiDoc"]) do |filename, content| +markup(::GitHub::Markups::MARKUP_ASCIIDOC, :asciidoctor, /adoc|asc(iidoc)?/, ["AsciiDoc"]) do |filename, content, options: {}| attributes = { 'showtitle' => '@', 'idprefix' => '', diff --git a/test/markup_test.rb b/test/markup_test.rb index b324c1ab..eedaccdf 100644 --- a/test/markup_test.rb +++ b/test/markup_test.rb @@ -102,7 +102,7 @@ def test_raises_error_if_command_exits_non_zero GitHub::Markup.command(:doesntmatter, 'test/fixtures/fail.sh', /fail/, ['Java'], 'fail') assert GitHub::Markup.can_render?('README.java', 'stop swallowing errors') begin - GitHub::Markup.render('README.java', "stop swallowing errors", false) + GitHub::Markup.render('README.java', "stop swallowing errors", symlink: false) rescue GitHub::Markup::CommandError => e assert_equal "failure message", e.message else @@ -114,4 +114,9 @@ def test_preserve_markup content = "Noël" assert_equal content.encoding.name, GitHub::Markup.render('Foo.rst', content).encoding.name end + + def test_commonmarker_options + assert_equal "

hello world

\n", GitHub::Markup.render("test.md", "hello world") + assert_equal "

hello world

\n", GitHub::Markup.render("test.md", "hello world", options: {commonmarker_opts: [:UNSAFE]}) + end end