module GitHubParser extend self class HTMLWithPantsRenderer < Redcarpet::Render::HTML include Redcarpet::Render::SmartyPants def block_code(code, language) if language language.sub!(/\Alang(uage)?-/, '') %{
#{html_escape(code)}
}
else
%{#{html_escape(code)}
}
end
end
private
# This is a method copy/pasted from redcarpet/lib/redcarpet.rb
# It's a private instance method on the Render::Safe class which inherits
# from the HTML renderer.
# I'm not sure why our tests expect escaped code while we inherit from the
# HTML renderer and not the Safe renderer though.
def html_escape(string)
string.gsub(/['&\"<>\/]/, {
'&' => '&',
'<' => '<',
'>' => '>',
'"' => '"',
"'" => ''',
"/" => '/',
})
end
end
def self.parse(markdown)
html = github_parser.render(markdown.to_s)
doc = Nokogiri::HTML5::DocumentFragment.parse(html)
special_blocks(doc)
doc
end
private
def self.github_parser
@@github_parser ||= Redcarpet::Markdown.new(HTMLWithPantsRenderer, fenced_code_blocks: true, tables: true, no_intra_emphasis: true)
end
def self.special_blocks(doc)
doc.css('blockquote>p:first').each do |node|
if match = node.inner_html.match(/\A\W*(callout|warning|note)\W/)
node.parent.name = 'div'
node.parent['class'] = match[1]
new_html = node.inner_html.gsub(/\A\W*(callout|warning|note)\W/, '')
# Assigning inner_html directly causes encoding issues in old libxml versions,
# workaround from https://github.com/sparklemotion/nokogiri/issues/458#issuecomment-3136620
node.children = Nokogiri::HTML.fragment(new_html, 'utf-8')
end
end
end
end