Skip to content

Commit

Permalink
lint
Browse files Browse the repository at this point in the history
  • Loading branch information
gjtorikian committed Nov 14, 2022
1 parent 5b807a1 commit bbf631b
Show file tree
Hide file tree
Showing 18 changed files with 89 additions and 40 deletions.
52 changes: 27 additions & 25 deletions lib/commonmarker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,34 @@
require "awesome_print"
rescue LoadError; end # rubocop:disable Lint/SuppressedException
module CommonMarker
# Public: Parses a Markdown string into an HTML string.
#
# text - A {String} of text
# option - Either a {Symbol} or {Array of Symbol}s indicating the render options
# extensions - An {Array of Symbol}s indicating the extensions to use
#
# Returns a {String} of converted HTML.
def self.render_html(text, options = :DEFAULT, extensions = [])
raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
class << self
# Public: Parses a Markdown string into an HTML string.
#
# text - A {String} of text
# option - Either a {Symbol} or {Array of Symbol}s indicating the render options
# extensions - An {Array of Symbol}s indicating the extensions to use
#
# Returns a {String} of converted HTML.
def render_html(text, options = :DEFAULT, extensions = [])
raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)

opts = Config.process_options(options, :render)
Node.markdown_to_html(text.encode("UTF-8"), opts, extensions)
end
opts = Config.process_options(options, :render)
Node.markdown_to_html(text.encode("UTF-8"), opts, extensions)
end

# Public: Parses a Markdown string into a `document` node.
#
# string - {String} to be parsed
# option - A {Symbol} or {Array of Symbol}s indicating the parse options
# extensions - An {Array of Symbol}s indicating the extensions to use
#
# Returns the `document` node.
def self.render_doc(text, options = :DEFAULT, extensions = [])
raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)
# Public: Parses a Markdown string into a `document` node.
#
# string - {String} to be parsed
# option - A {Symbol} or {Array of Symbol}s indicating the parse options
# extensions - An {Array of Symbol}s indicating the extensions to use
#
# Returns the `document` node.
def render_doc(text, options = :DEFAULT, extensions = [])
raise TypeError, "text must be a String; got a #{text.class}!" unless text.is_a?(String)

opts = Config.process_options(options, :parse)
text = text.encode("UTF-8")
Node.parse_document(text, text.bytesize, opts, extensions)
end
opts = Config.process_options(options, :parse)
text = text.encode("UTF-8")
Node.parse_document(text, text.bytesize, opts, extensions)
end
end
end
28 changes: 15 additions & 13 deletions lib/commonmarker/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,22 @@ module Config
format: [:html, :xml, :commonmark, :plaintext].freeze,
}.freeze

def self.process_options(option, type)
case option
when Symbol
OPTS.fetch(type).fetch(option)
when Array
raise TypeError if option.none?
class << self
def process_options(option, type)
case option
when Symbol
OPTS.fetch(type).fetch(option)
when Array
raise TypeError if option.none?

# neckbearding around. the map will both check the opts and then bitwise-OR it
OPTS.fetch(type).fetch_values(*option).inject(0, :|)
else
raise TypeError, "option type must be a valid symbol or array of symbols within the #{name}::OPTS[:#{type}] context"
# neckbearding around. the map will both check the opts and then bitwise-OR it
OPTS.fetch(type).fetch_values(*option).inject(0, :|)
else
raise TypeError, "option type must be a valid symbol or array of symbols within the #{name}::OPTS[:#{type}] context"
end
rescue KeyError => e
raise TypeError, "option ':#{e.key}' does not exist for #{name}::OPTS[:#{type}]"
end
rescue KeyError => e
raise TypeError, "option ':#{e.key}' does not exist for #{name}::OPTS[:#{type}]"
end
end
end
end
2 changes: 1 addition & 1 deletion lib/commonmarker/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def tagfilter(str)
)
(?=\s|>|/>)
}xi,
'&lt;\1'
'&lt;\1',
)
else
str
Expand Down
1 change: 1 addition & 0 deletions test/test_basics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def test_to_html

def test_markdown_to_html
html = CommonMarker.render_html("Hi *there*")

assert_equal("<p>Hi <em>there</em></p>\n", html)
end

Expand Down
8 changes: 8 additions & 0 deletions test/test_commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,58 @@
class TestCommands < Minitest::Test
def test_basic
out = make_bin("strong.md")

assert_equal("<p>I am <strong>strong</strong></p>", out)
end

def test_does_not_have_extensions
out = make_bin("table.md")

assert_includes(out, "| a")
refute_includes(out, "<p><del>hi</del>")
refute_includes(out, "<table> <tr> <th> a </th> <td> c </td>")
end

def test_understands_extensions
out = make_bin("table.md", "--extension=table")

refute_includes(out, "| a")
refute_includes(out, "<p><del>hi</del>")
["<table>", "<tr>", "<th>", "a", "</th>", "<td>", "c", "</td>"].each { |html| assert_includes(out, html) }
end

def test_understands_multiple_extensions
out = make_bin("table.md", "--extension=table,strikethrough")

refute_includes(out, "| a")
assert_includes(out, "<p><del>hi</del>")
["<table>", "<tr>", "<th>", "a", "</th>", "<td>", "c", "</td>"].each { |html| assert_includes(out, html) }
end

def test_understands_html_format_with_renderer_and_extensions
out = make_bin("table.md", "--to=html --extension=table,strikethrough --html-renderer")

refute_includes(out, "| a")
assert_includes(out, "<p><del>hi</del>")
["<table>", "<tr>", "<th>", "a", "</th>", "<td>", "c", "</td>"].each { |html| assert_includes(out, html) }
end

def test_understands_xml_format
out = make_bin("strong.md", "--to=xml")

assert_includes(out, '<?xml version="1.0" encoding="UTF-8"?>')
assert_includes(out, '<text xml:space="preserve">strong</text>')
end

def test_understands_commonmark_format
out = make_bin("strong.md", "--to=commonmark")

assert_equal("I am **strong**", out)
end

def test_understands_plaintext_format
out = make_bin("strong.md", "--to=plaintext")

assert_equal("I am strong", out)
end

Expand Down
2 changes: 1 addition & 1 deletion test/test_commonmark.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_to_commonmark

assert_equal(\
render_doc(@markdown).to_html.squeeze(" ").gsub(HTML_COMMENT, ""),
render_doc(compare).to_html.squeeze(" ").gsub(HTML_COMMENT, "")
render_doc(compare).to_html.squeeze(" ").gsub(HTML_COMMENT, ""),
)
end
end
4 changes: 4 additions & 0 deletions test/test_doc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,28 @@ def test_get_next

def test_insert_before
paragraph = Node.new(:paragraph)

assert(@first_child.insert_before(paragraph))
assert_match("<p></p>\n<p>Hi <em>there</em>.", @doc.to_html)
end

def test_insert_after
paragraph = Node.new(:paragraph)

assert(@first_child.insert_after(paragraph))
assert_match("<strong>many nodes</strong>!</p>\n<p></p>\n", @doc.to_html)
end

def test_prepend_child
code = Node.new(:code)

assert(@first_child.prepend_child(code))
assert_match("<p><code></code>Hi <em>there</em>.", @doc.to_html)
end

def test_append_child
strong = Node.new(:strong)

assert(@first_child.append_child(strong))
assert_match("!<strong></strong></p>\n", @doc.to_html)
end
Expand Down
3 changes: 3 additions & 0 deletions test/test_encoding.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ def test_encoding
contents = fixtures_file("curly.md")
doc = CommonMarker.render_doc(contents, :SMART)
render = doc.to_html

assert_equal("<p>This curly quote “makes commonmarker throw an exception”.</p>", render.rstrip)

render = doc.to_xml

assert_includes(render, '<text xml:space="preserve">This curly quote “makes commonmarker throw an exception”.</text>')
end

def test_string_content_is_utf8
doc = CommonMarker.render_doc("Hi *there*")
text = doc.first_child.last_child.first_child

assert_equal("there", text.string_content)
assert_equal("UTF-8", text.string_content.encoding.name)
end
Expand Down
6 changes: 6 additions & 0 deletions test/test_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def test_uses_specified_extensions
CommonMarker.render_html(@markdown, :DEFAULT, [:table]).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

Expand All @@ -27,9 +28,11 @@ def test_uses_specified_extensions
end

doc = CommonMarker.render_doc("~a~ ~~b~~ ~~~c~~~", :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])

assert_equal("<p>~a~ <del>b</del> ~~~c~~~</p>\n", doc.to_html)

html = CommonMarker.render_html("~a~ ~~b~~ ~~~c~~~", :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])

assert_equal("<p>~a~ <del>b</del> ~~~c~~~</p>\n", html)

CommonMarker.render_html(@markdown, :DEFAULT, [:table, :strikethrough]).tap do |out|
Expand All @@ -45,16 +48,19 @@ def test_extensions_with_renderers
doc.to_html.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

HtmlRenderer.new.render(doc).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

doc = CommonMarker.render_doc("~a~ ~~b~~ ~~~c~~~", :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])

assert_equal("<p>~a~ <del>b</del> ~~~c~~~</p>\n", HtmlRenderer.new.render(doc))
end

Expand Down
1 change: 1 addition & 0 deletions test/test_gc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def test_drop_child_reference
GC.start
# Test that the cached child object is still valid.
text = doc.first_child.last_child.first_child

assert_equal("there", text.string_content)
end

Expand Down
2 changes: 2 additions & 0 deletions test/test_linebreaks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
class TestLinebreaks < Minitest::Test
def test_hardbreak_no_spaces
doc = CommonMarker.render_doc("foo\nbaz")

assert_equal("<p>foo<br />\nbaz</p>\n", doc.to_html(:HARDBREAKS))
end

def test_hardbreak_with_spaces
doc = CommonMarker.render_doc("foo \nbaz")

assert_equal("<p>foo<br />\nbaz</p>\n", doc.to_html(:HARDBREAKS))
end
end
1 change: 1 addition & 0 deletions test/test_maliciousness.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def test_rendering_with_bad_type
err = assert_raises(TypeError) do
CommonMarker.render_doc("foo \n baz", :safe)
end

assert_equal("option ':safe' does not exist for CommonMarker::Config::OPTS[:parse]", err.message)

assert_raises(TypeError) do
Expand Down
8 changes: 8 additions & 0 deletions test/test_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def test_walk
@doc.walk do |node|
nodes << node.type
end

assert_equal([:document, :paragraph, :text, :emph, :text, :text], nodes)
end

Expand All @@ -20,6 +21,7 @@ def test_each
@doc.first_child.each do |node|
nodes << node.type
end

assert_equal([:text, :emph, :text], nodes)
end

Expand All @@ -30,18 +32,21 @@ def test_deprecated_each_child
nodes << node.type
end
end

assert_equal([:text, :emph, :text], nodes)
assert_match(/`each_child` is deprecated/, err)
end

def test_select
nodes = @doc.first_child.select { |node| node.type == :text }

assert_equal(CommonMarker::Node, nodes.first.class)
assert_equal([:text, :text], nodes.map(&:type))
end

def test_map
nodes = @doc.first_child.map(&:type)

assert_equal([:text, :emph, :text], nodes)
end

Expand All @@ -58,6 +63,7 @@ def test_to_html
def test_html_renderer
renderer = HtmlRenderer.new
result = renderer.render(@doc)

assert_equal("<p>Hi <em>there</em>, I am mostly text!</p>\n", result)
end

Expand All @@ -66,6 +72,7 @@ def test_walk_and_set_string_content
node.string_content = "world" if node.type == :text && node.string_content == "there"
end
result = HtmlRenderer.new.render(@doc)

assert_equal("<p>Hi <em>world</em>, I am mostly text!</p>\n", result)
end

Expand All @@ -76,6 +83,7 @@ def test_walk_and_delete_node
node.delete
end
end

assert_equal("<p>Hi there, I am mostly text!</p>\n", @doc.to_html)
end

Expand Down
1 change: 1 addition & 0 deletions test/test_pathological_inputs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def markdown(str)
pathological.each_pair do |name, description|
define_method("test_#{name}") do
input, = description

assert markdown(input)
end
end
Expand Down
3 changes: 3 additions & 0 deletions test/test_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def setup
def test_html_renderer
renderer = HtmlRenderer.new
result = renderer.render(@doc)

assert_equal("<p>Hi <em>there</em></p>\n", result)
end

Expand All @@ -25,6 +26,7 @@ def test_multiple_tables
DOC
doc = CommonMarker.render_doc(content, :DEFAULT, [:autolink, :table, :tagfilter])
results = CommonMarker::HtmlRenderer.new.render(doc)

assert_equal(2, results.scan(/<tbody>/).size)
end

Expand All @@ -41,6 +43,7 @@ def text(node)
end

renderer = my_renderer.new

assert_equal(Encoding::UTF_8, renderer.render(@doc).encoding)
assert_equal(renderer.input_encoding, renderer.output_encoding)
end
Expand Down
Loading

0 comments on commit bbf631b

Please sign in to comment.