Skip to content

Commit

Permalink
Corrections to how options are merged
Browse files Browse the repository at this point in the history
  • Loading branch information
gjtorikian committed Oct 9, 2024
1 parent 4f37ae6 commit 206ebc0
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 46 deletions.
38 changes: 13 additions & 25 deletions lib/commonmarker/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ module Config
underline: false,
spoiler: false,
greentext: false,
},
format: [:html].freeze,
}.freeze,
}.freeze

PLUGINS = {
Expand All @@ -59,10 +58,6 @@ module Config
class << self
include Commonmarker::Utils

def merged_with_defaults(options)
Commonmarker::Config::OPTIONS.merge(process_options(options))
end

def process_options(options)
{
parse: process_parse_options(options[:parse]),
Expand All @@ -79,37 +74,30 @@ def process_plugins(plugins)
end

[:parse, :render, :extension].each do |type|
define_singleton_method :"process_#{type}_options" do |option|
define_singleton_method :"process_#{type}_options" do |options|
Commonmarker::Config::OPTIONS[type].each_with_object({}) do |(key, value), hash|
if option.nil? # option not provided, go for the default
if options.nil? || !options.key?(key) # option not provided, use the default
hash[key] = value
next
end

# option explicitly not included, remove it
next if option[key].nil?
if options[key].nil? # # option explicitly not included, remove it
options.delete(key)
next
end

hash[key] = fetch_kv(option, key, value, type)
hash[key] = fetch_kv(options, key, value, type)
end
end
end

[:syntax_highlighter].each do |type|
define_singleton_method :"process_#{type}_plugin" do |plugin|
return if plugin.nil? # plugin explicitly nil, remove it
define_singleton_method :process_syntax_highlighter_plugin do |options|
return if options.nil? # plugin explicitly nil, remove it

Commonmarker::Config::PLUGINS[type].each_with_object({}) do |(key, value), hash|
if plugin.nil? # option not provided, go for the default
hash[key] = value
next
end
raise TypeError, "Expected a Hash for syntax_highlighter plugin, got #{options.class}" unless options.is_a?(Hash)
raise TypeError, "Expected a Hash for syntax_highlighter plugin, got nothing" if options.empty?

# option explicitly not included, remove it
next if plugin[key].nil?

hash[key] = fetch_kv(plugin, key, value, type)
end
end
Commonmarker::Config::PLUGINS[:syntax_highlighter].merge(options)
end
end
end
12 changes: 6 additions & 6 deletions lib/commonmarker/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ module Commonmarker
module Utils
include Commonmarker::Constants

def fetch_kv(option, key, value, type)
def fetch_kv(options, key, value, type)
value_klass = value.class

if Constants::BOOLS.include?(value) && BOOLS.include?(option[key])
option[key]
elsif option[key].is_a?(value_klass)
option[key]
if Constants::BOOLS.include?(value) && BOOLS.include?(options[key])
options[key]
elsif options[key].is_a?(value_klass)
options[key]
else
expected_type = Constants::BOOLS.include?(value) ? "Boolean" : value_klass.to_s
raise TypeError, "#{type} option `:#{key}` must be #{expected_type}; got #{option[key].class}"
raise TypeError, "#{type} option `:#{key}` must be #{expected_type}; got #{options[key].class}"
end
end
end
Expand Down
6 changes: 3 additions & 3 deletions test/extensions_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ def setup
end

def test_uses_specified_extensions
Commonmarker.to_html(@markdown, options: { extension: {} }).tap do |out|
Commonmarker.to_html(@markdown, options: { extension: { table: false, strikethrough: false } }).tap do |out|
assert_includes(out, "| a")
assert_includes(out, "| <strong>x</strong>")
assert_includes(out, "~~hi~~")
end

Commonmarker.to_html(@markdown, options: { extension: { table: true } }).tap do |out|
Commonmarker.to_html(@markdown, options: { extension: { table: true, strikethrough: false } }).tap do |out|
refute_includes(out, "| a")
["<table>", "<tr>", "<th>", "a", "</th>", "<td>", "c", "</td>", "<strong>x</strong>"].each { |html| assert_includes(out, html) }

assert_includes(out, "~~hi~~")
end

Commonmarker.to_html(@markdown, options: { extension: { strikethrough: true } }).tap do |out|
Commonmarker.to_html(@markdown, options: { extension: { table: false, strikethrough: true } }).tap do |out|
assert_includes(out, "| a")
refute_includes(out, "~~hi~~")
assert_includes(out, "<del>hi</del>")
Expand Down
2 changes: 1 addition & 1 deletion test/footnotes_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ def test_to_html
</section>
HTML

assert_equal(expected, Commonmarker.to_html(md, options: { extension: { footnotes: true } }))
assert_equal(expected, Commonmarker.to_html(md, options: { extension: { header_ids: nil, footnotes: true } }))
end
end
2 changes: 1 addition & 1 deletion test/frontmatter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ def test_frontmatter_custom_delimiter
<h1>Title 1</h1>
HTML

assert_equal(expected, Commonmarker.to_html(md, options: { extension: { front_matter_delimiter: "---" } }))
assert_equal(expected, Commonmarker.to_html(md, options: { extension: { header_ids: nil, front_matter_delimiter: "---" } }))
end
end
1 change: 1 addition & 0 deletions test/smartpunct_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class SmartPunctTest < Minitest::Test
},
render: {
hardbreaks: false,
escaped_char_spans: false,
},
}

Expand Down
32 changes: 22 additions & 10 deletions test/spec_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,30 @@ class SpecTest < Minitest::Test

spec.each do |testcase|
define_method(:"test_to_html_example_#{testcase[:example]}") do
opts = {
render: {
unsafe: true,
gfm_quirks: true,
},
extension: testcase[:extensions].each_with_object({}) do |ext, hash|
hash[ext] = true
end,
render_options = Commonmarker::Config::OPTIONS[:render].each_with_object({}) do |(key, _value), hsh|
hsh[key] = nil
end
render_options[:unsafe] = true
render_options[:gfm_quirks] = true

string_extensions = [:front_matter_delimiter, :header_ids]
extensions_options = Commonmarker::Config::OPTIONS[:extension].each_with_object({}) do |(key, _value), hsh|
hsh[key] = if string_extensions.include?(key)
nil
else
false
end
end

testcase[:extensions].each do |ext, _value|
extensions_options[ext] = true
end

options = {
render: render_options,
extension: extensions_options,
}

options = Commonmarker::Config.merged_with_defaults(opts)
options[:extension].delete(:header_ids) # this interefers with the spec.txt extension-less capability
options[:extension][:tasklist] = true
actual = Commonmarker.to_html(testcase[:markdown], options: options, plugins: nil).rstrip

Expand Down

0 comments on commit 206ebc0

Please sign in to comment.