Skip to content

Commit

Permalink
Support Commonmarker v1 api
Browse files Browse the repository at this point in the history
The commonmarker gem broke backwards compatibility starting in 1.0 (switching the backend implementation from libcmark (C) to comrak (Rust)).  This keeps support for the pre-1.0 API, and adds support for the 1+ API.
  • Loading branch information
unasuke authored Jan 5, 2024
1 parent 409b338 commit 63a7c27
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 43 deletions.
3 changes: 2 additions & 1 deletion .ci.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ platform :ruby do
gem 'rinku' # dependency for wikicloth for handling links

gem 'RedCloth'
gem 'commonmarker', '< 1'
gem 'commonmarker'

gem 'rdiscount', '>= 2.1.6'
gem 'redcarpet'
gem 'yajl-ruby'
Expand Down
123 changes: 81 additions & 42 deletions lib/tilt/commonmarker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,92 @@
require_relative 'template'
require 'commonmarker'

aliases = {
:smartypants => :SMART
}.freeze
parse_opts = [
:FOOTNOTES,
:LIBERAL_HTML_TAG,
:SMART,
:smartypants,
:STRIKETHROUGH_DOUBLE_TILDE,
:UNSAFE,
:VALIDATE_UTF8,
].freeze
render_opts = [
:FOOTNOTES,
:FULL_INFO_STRING,
:GITHUB_PRE_LANG,
:HARDBREAKS,
:NOBREAKS,
:SAFE, # Removed in v0.18.0 (2018-10-17)
:SOURCEPOS,
:TABLE_PREFER_STYLE_ATTRIBUTES,
:UNSAFE,
].freeze
exts = [
:autolink,
:strikethrough,
:table,
:tagfilter,
:tasklist,
].freeze
if defined?(::Commonmarker)
aliases = {
:smartypants => :smart
}.freeze
parse_opts = [
:smart,
:default_info_string,
].freeze
render_opts = [
:hardbreaks,
:github_pre_lang,
:width,
:unsafe,
:escape,
:sourcepos,
].freeze
exts = [
:strikethrough,
:tagfilter,
:table,
:autolink,
:tasklist,
:superscript,
:header_ids,
:footnotes,
:description_lists,
:front_matter_delimiter,
:shortcodes,
].freeze

Tilt::CommonMarkerTemplate = Tilt::StaticTemplate.subclass do
parse_options = @options.select { |key, _| parse_opts.include?(key.downcase) }.transform_keys(&:downcase)
parse_options.merge!(@options.select { |key, _| aliases.has_key?(key) }.transform_keys { |key| aliases[key] })
render_options = @options.select { |key, _| render_opts.include?(key.downcase) }.transform_keys(&:downcase)
extensions = @options.select { |key, _| exts.include?(key) }.transform_keys(&:downcase)

Tilt::CommonMarkerTemplate = Tilt::StaticTemplate.subclass do
extensions = exts.select do |extension|
@options[extension]
Commonmarker.to_html(@data, options: { parse: parse_options, render: render_options, extension: extensions })
end
else
aliases = {
:smartypants => :SMART
}.freeze
parse_opts = [
:FOOTNOTES,
:LIBERAL_HTML_TAG,
:SMART,
:smartypants,
:STRIKETHROUGH_DOUBLE_TILDE,
:UNSAFE,
:VALIDATE_UTF8,
].freeze
render_opts = [
:FOOTNOTES,
:FULL_INFO_STRING,
:GITHUB_PRE_LANG,
:HARDBREAKS,
:NOBREAKS,
:SAFE, # Removed in v0.18.0 (2018-10-17)
:SOURCEPOS,
:TABLE_PREFER_STYLE_ATTRIBUTES,
:UNSAFE,
].freeze
exts = [
:autolink,
:strikethrough,
:table,
:tagfilter,
:tasklist,
].freeze

parse_options, render_options = [parse_opts, render_opts].map do |opts|
opts = opts.select do |option|
@options[option]
end.map! do |option|
aliases[option] || option
Tilt::CommonMarkerTemplate = Tilt::StaticTemplate.subclass do
extensions = exts.select do |extension|
@options[extension]
end

opts = :DEFAULT unless opts.any?
opts
end
parse_options, render_options = [parse_opts, render_opts].map do |opts|
opts = opts.select do |option|
@options[option]
end.map! do |option|
aliases[option] || option
end

opts = :DEFAULT unless opts.any?
opts
end

CommonMarker.render_doc(@data, parse_options, extensions).to_html(render_options, extensions)
CommonMarker.render_doc(@data, parse_options, extensions).to_html(render_options, extensions)
end
end
42 changes: 42 additions & 0 deletions test/tilt_commonmarkertemplate_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,46 @@
it "sets allows_script metadata set to false" do
assert_equal false, Tilt::CommonMarkerTemplate.new { |t| "# Hello World!" }.metadata[:allows_script]
end

if defined?(::Commonmarker)
it "render unsafe HTML with pre version's option name" do
template = Tilt::CommonMarkerTemplate.new(UNSAFE: true) do |_t|
<<MARKDOWN
<div class="alert alert-info full-width">
<h5 class="card-title">TL;DR</h5>
<p>This is an unsafe HTML block</p>
</div>
And then some **other** Markdown
MARKDOWN
end

expected = <<EXPECTED_HTML
<div class="alert alert-info full-width">
<h5 class="card-title">TL;DR</h5>
<p>This is an unsafe HTML block</p>
</div>
<p>And then some <strong>other</strong> Markdown</p>
EXPECTED_HTML

assert_match(expected, template.render)
end

it "smartypants when :smartypants is set (pre version's option name)" do
template = Tilt::CommonMarkerTemplate.new(:smartypants => true) do |t|
"OKAY -- 'Smarty Pants'"
end
assert_match('<p>OKAY – ‘Smarty Pants’</p>', template.render)
end

it "render markdown with custom prefixed-header id" do
template = Tilt::CommonMarkerTemplate.new(header_ids: "prefix-") do |t|
"# Foo"
end
expected = <<HTML
<h1><a href="#foo" aria-hidden="true" class="anchor" id="prefix-foo"></a>Foo</h1>
HTML
assert_match(expected, template.render)
end
end
end

0 comments on commit 63a7c27

Please sign in to comment.