commonmarker 0.21.2 → 0.23.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of commonmarker might be problematic. Click here for more details.

@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'commonmarker/node/inspect'
4
+
5
+ module CommonMarker
6
+ class RenderError < StandardError
7
+ PREAMBLE = 'There was an error rendering'
8
+ def initialize(error)
9
+ super("#{PREAMBLE}: #{error.class} #{error.message}")
10
+ end
11
+ end
12
+ end
@@ -27,11 +27,9 @@ module CommonMarker
27
27
  list_tight
28
28
  fence_info
29
29
  ].map do |name|
30
- begin
31
- [name, __send__(name)]
32
- rescue NodeError
33
- nil
34
- end
30
+ [name, __send__(name)]
31
+ rescue NodeError
32
+ nil
35
33
  end.compact
36
34
 
37
35
  printer.seplist(attrs) do |name, value|
@@ -30,6 +30,16 @@ module CommonMarker
30
30
  _render_html(opts, extensions).force_encoding('utf-8')
31
31
  end
32
32
 
33
+ # Public: Convert the node to an XML string.
34
+ #
35
+ # options - A {Symbol} or {Array of Symbol}s indicating the render options
36
+ #
37
+ # Returns a {String}.
38
+ def to_xml(options = :DEFAULT)
39
+ opts = Config.process_options(options, :render)
40
+ _render_xml(opts).force_encoding('utf-8')
41
+ end
42
+
33
43
  # Public: Convert the node to a CommonMark string.
34
44
  #
35
45
  # options - A {Symbol} or {Array of Symbol}s indicating the render options
@@ -129,7 +129,7 @@ module CommonMarker
129
129
  end
130
130
 
131
131
  def option_enabled?(opt)
132
- (@opts & CommonMarker::Config::Render.value(opt)) != 0
132
+ (@opts & CommonMarker::Config::OPTS.dig(:render, opt)) != 0
133
133
  end
134
134
  end
135
135
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CommonMarker
4
- VERSION = '0.21.2'
4
+ VERSION = '0.23.2'
5
5
  end
data/test/test_basics.rb CHANGED
@@ -15,4 +15,21 @@ class TestBasics < Minitest::Test
15
15
  html = CommonMarker.render_html('Hi *there*')
16
16
  assert_equal "<p>Hi <em>there</em></p>\n", html
17
17
  end
18
+
19
+ # basic test that just checks if every option is accepted & no errors are thrown
20
+ def test_accept_every_option
21
+ text = "Hello **world** -- how are _you_ today? I'm ~~fine~~, ~yourself~?"
22
+ parse_opt = %i[SOURCEPOS UNSAFE VALIDATE_UTF8 SMART LIBERAL_HTML_TAG FOOTNOTES STRIKETHROUGH_DOUBLE_TILDE]
23
+ render_opt = parse_opt + %i[HARDBREAKS NOBREAKS GITHUB_PRE_LANG TABLE_PREFER_STYLE_ATTRIBUTES FULL_INFO_STRING]
24
+
25
+ extensions = %i[table tasklist strikethrough autolink tagfilter]
26
+
27
+ assert_equal "<p>Hello <strong>world</strong> – how are <em>you</em> today? I’m <del>fine</del>, ~yourself~?</p>\n", CommonMarker.render_doc(text, parse_opt, extensions).to_html
28
+
29
+ # NOTE: how tho the doc returned has sourcepos info, by default the renderer
30
+ # won't emit it. for that we need to pass in the render opt
31
+ assert_equal "<p data-sourcepos=\"1:1-1:65\">Hello <strong>world</strong> – how are <em>you</em> today? I’m <del>fine</del>, ~yourself~?</p>\n", CommonMarker.render_doc(text, parse_opt, extensions).to_html(render_opt, extensions)
32
+
33
+ assert_equal "<p data-sourcepos=\"1:1-1:65\">Hello <strong>world</strong> – how are <em>you</em> today? I’m <del>fine</del>, ~yourself~?</p>\n", CommonMarker.render_html(text, parse_opt, extensions)
34
+ end
18
35
  end
@@ -28,4 +28,45 @@ class TestCommands < Minitest::Test
28
28
  assert_includes out, '<p><del>hi</del>'
29
29
  %w[<table> <tr> <th> a </th> <td> c </td>].each { |html| assert_includes out, html }
30
30
  end
31
+
32
+ def test_understands_html_format_with_renderer_and_extensions
33
+ out = make_bin('table.md', '--to=html --extension=table,strikethrough --html-renderer')
34
+ refute_includes out, '| a'
35
+ assert_includes out, '<p><del>hi</del>'
36
+ %w[<table> <tr> <th> a </th> <td> c </td>].each { |html| assert_includes out, html }
37
+ end
38
+
39
+ def test_understands_xml_format
40
+ out = make_bin('strong.md', '--to=xml')
41
+ assert_includes out, '<?xml version="1.0" encoding="UTF-8"?>'
42
+ assert_includes out, '<text xml:space="preserve">strong</text>'
43
+ end
44
+
45
+ def test_understands_commonmark_format
46
+ out = make_bin('strong.md', '--to=commonmark')
47
+ assert_equal('I am **strong**', out)
48
+ end
49
+
50
+ def test_understands_plaintext_format
51
+ out = make_bin('strong.md', '--to=plaintext')
52
+ assert_equal('I am strong', out)
53
+ end
54
+
55
+ def test_aborts_invalid_format
56
+ _out, err = capture_subprocess_io do
57
+ make_bin('strong.md', '--to=unknown')
58
+ end
59
+
60
+ assert_match "format 'unknown' not found", err
61
+ end
62
+
63
+ def test_aborts_format_and_html_renderer_combinations
64
+ (CommonMarker::Config::OPTS[:format] - [:html]).each do |format|
65
+ _out, err = capture_subprocess_io do
66
+ make_bin('strong.md', "--to=#{format} --html-renderer")
67
+ end
68
+
69
+ assert_match "format '#{format}' does not support using the HtmlRenderer renderer", err
70
+ end
71
+ end
31
72
  end
@@ -9,6 +9,9 @@ class TestEncoding < Minitest::Test
9
9
  doc = CommonMarker.render_doc(contents, :SMART)
10
10
  render = doc.to_html
11
11
  assert_equal('<p>This curly quote “makes commonmarker throw an exception”.</p>', render.rstrip)
12
+
13
+ render = doc.to_xml
14
+ assert_includes(render, '<text xml:space="preserve">This curly quote “makes commonmarker throw an exception”.</text>')
12
15
  end
13
16
 
14
17
  def test_string_content_is_utf8
@@ -29,6 +29,9 @@ class TestExtensions < Minitest::Test
29
29
  doc = CommonMarker.render_doc('~a~ ~~b~~ ~~~c~~~', :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])
30
30
  assert_equal("<p>~a~ <del>b</del> ~~~c~~~</p>\n", doc.to_html)
31
31
 
32
+ html = CommonMarker.render_html('~a~ ~~b~~ ~~~c~~~', :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])
33
+ assert_equal("<p>~a~ <del>b</del> ~~~c~~~</p>\n", html)
34
+
32
35
  CommonMarker.render_html(@markdown, :DEFAULT, %i[table strikethrough]).tap do |out|
33
36
  refute_includes out, '| a'
34
37
  refute_includes out, '| <strong>x</strong>'
@@ -5,7 +5,25 @@ require 'test_helper'
5
5
  class TestFootnotes < Minitest::Test
6
6
  def setup
7
7
  @doc = CommonMarker.render_doc("Hello[^hi].\n\n[^hi]: Hey!\n", :FOOTNOTES)
8
- @expected = <<~HTML
8
+ end
9
+
10
+ def test_to_html
11
+ expected = <<~HTML
12
+ <p>Hello<sup class="footnote-ref"><a href="#fn-hi" id="fnref-hi" data-footnote-ref>1</a></sup>.</p>
13
+ <section class="footnotes" data-footnotes>
14
+ <ol>
15
+ <li id="fn-hi">
16
+ <p>Hey! <a href="#fnref-hi" class="footnote-backref" data-footnote-backref aria-label="Back to content">↩</a></p>
17
+ </li>
18
+ </ol>
19
+ </section>
20
+ HTML
21
+
22
+ assert_equal expected, @doc.to_html
23
+ end
24
+
25
+ def test_html_renderer
26
+ expected = <<~HTML
9
27
  <p>Hello<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup>.</p>
10
28
  <section class="footnotes">
11
29
  <ol>
@@ -15,14 +33,8 @@ class TestFootnotes < Minitest::Test
15
33
  </ol>
16
34
  </section>
17
35
  HTML
18
- end
19
-
20
- def test_to_html
21
- assert_equal @expected, @doc.to_html
22
- end
23
36
 
24
- def test_html_renderer
25
- assert_equal @expected, CommonMarker::HtmlRenderer.new.render(@doc)
37
+ assert_equal expected, CommonMarker::HtmlRenderer.new.render(@doc)
26
38
  end
27
39
 
28
40
  def test_render_html
@@ -34,11 +46,11 @@ class TestFootnotes < Minitest::Test
34
46
  MARKDOWN
35
47
  expected = <<~HTML
36
48
  <h1>footnotes</h1>
37
- <p>Let's render some footnotes<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup></p>
38
- <section class="footnotes">
49
+ <p>Let's render some footnotes<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup></p>
50
+ <section class="footnotes" data-footnotes>
39
51
  <ol>
40
- <li id="fn1">
41
- <p>This is a footnote <a href="#fnref1" class="footnote-backref">↩</a></p>
52
+ <li id="fn-1">
53
+ <p>This is a footnote <a href="#fnref-1" class="footnote-backref" data-footnote-backref aria-label="Back to content">↩</a></p>
42
54
  </li>
43
55
  </ol>
44
56
  </section>
@@ -67,11 +67,6 @@ module CommonMarker
67
67
  CommonMarker.render_html(nil)
68
68
  end
69
69
 
70
- err = assert_raises TypeError do
71
- CommonMarker.render_html("foo \n baz", [:SMART])
72
- end
73
- assert_equal('option \':SMART\' does not exist for CommonMarker::Config::Render', err.message)
74
-
75
70
  assert_raises TypeError do
76
71
  CommonMarker.render_doc("foo \n baz", 123)
77
72
  end
@@ -79,7 +74,7 @@ module CommonMarker
79
74
  err = assert_raises TypeError do
80
75
  CommonMarker.render_doc("foo \n baz", :safe)
81
76
  end
82
- assert_equal('option \':safe\' does not exist for CommonMarker::Config::Parse', err.message)
77
+ assert_equal('option \':safe\' does not exist for CommonMarker::Config::OPTS[:parse]', err.message)
83
78
 
84
79
  assert_raises TypeError do
85
80
  CommonMarker.render_doc("foo \n baz", :totes_fake)
@@ -27,4 +27,21 @@ class TestRenderer < Minitest::Test
27
27
  results = CommonMarker::HtmlRenderer.new.render(doc)
28
28
  assert_equal 2, results.scan(/<tbody>/).size
29
29
  end
30
+
31
+ def test_escape_html_encoding
32
+ my_renderer = Class.new(HtmlRenderer) do
33
+ attr_reader :input_encoding, :output_encoding
34
+
35
+ def text(node)
36
+ @input_encoding = node.string_content.encoding
37
+ escape_html(node.string_content).tap do |escaped|
38
+ @output_encoding = escaped.encoding
39
+ end
40
+ end
41
+ end
42
+
43
+ renderer = my_renderer.new
44
+ assert_equal Encoding::UTF_8, renderer.render(@doc).encoding
45
+ assert_equal renderer.input_encoding, renderer.output_encoding
46
+ end
30
47
  end
@@ -7,11 +7,14 @@ class SmartPunctTest < Minitest::Test
7
7
 
8
8
  smart_punct.each do |testcase|
9
9
  doc = CommonMarker.render_doc(testcase[:markdown], :SMART)
10
+ html = CommonMarker.render_html(testcase[:markdown], :SMART)
10
11
 
11
12
  define_method("test_smart_punct_example_#{testcase[:example]}") do
12
- actual = doc.to_html.strip
13
+ doc_rendered = doc.to_html.strip
14
+ html_rendered = html.strip
13
15
 
14
- assert_equal testcase[:html], actual, testcase[:markdown]
16
+ assert_equal testcase[:html], doc_rendered, testcase[:markdown]
17
+ assert_equal testcase[:html], html_rendered, testcase[:markdown]
15
18
  end
16
19
  end
17
20
 
data/test/test_xml.rb ADDED
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class TestXml < Minitest::Test
6
+ def setup
7
+ @markdown = <<~MD
8
+ Hi *there*!
9
+
10
+ 1. I am a numeric list.
11
+ 2. I continue the list.
12
+ * Suddenly, an unordered list!
13
+ * What fun!
14
+
15
+ Okay, _enough_.
16
+
17
+ | a | b |
18
+ | --- | --- |
19
+ | c | d |
20
+ MD
21
+ end
22
+
23
+ def render_doc(doc)
24
+ CommonMarker.render_doc(doc, :DEFAULT, [:table])
25
+ end
26
+
27
+ def test_to_xml
28
+ compare = render_doc(@markdown).to_xml(:SOURCEPOS)
29
+
30
+ assert_equal <<~XML, compare
31
+ <?xml version="1.0" encoding="UTF-8"?>
32
+ <!DOCTYPE document SYSTEM "CommonMark.dtd">
33
+ <document sourcepos="1:1-12:13" xmlns="http://commonmark.org/xml/1.0">
34
+ <paragraph sourcepos="1:1-1:11">
35
+ <text sourcepos="1:1-1:3" xml:space="preserve">Hi </text>
36
+ <emph sourcepos="1:4-1:10">
37
+ <text sourcepos="1:5-1:9" xml:space="preserve">there</text>
38
+ </emph>
39
+ <text sourcepos="1:11-1:11" xml:space="preserve">!</text>
40
+ </paragraph>
41
+ <list sourcepos="3:1-4:23" type="ordered" start="1" delim="period" tight="true">
42
+ <item sourcepos="3:1-3:23">
43
+ <paragraph sourcepos="3:4-3:23">
44
+ <text sourcepos="3:4-3:23" xml:space="preserve">I am a numeric list.</text>
45
+ </paragraph>
46
+ </item>
47
+ <item sourcepos="4:1-4:23">
48
+ <paragraph sourcepos="4:4-4:23">
49
+ <text sourcepos="4:4-4:23" xml:space="preserve">I continue the list.</text>
50
+ </paragraph>
51
+ </item>
52
+ </list>
53
+ <list sourcepos="5:1-7:0" type="bullet" tight="true">
54
+ <item sourcepos="5:1-5:30">
55
+ <paragraph sourcepos="5:3-5:30">
56
+ <text sourcepos="5:3-5:30" xml:space="preserve">Suddenly, an unordered list!</text>
57
+ </paragraph>
58
+ </item>
59
+ <item sourcepos="6:1-7:0">
60
+ <paragraph sourcepos="6:3-6:11">
61
+ <text sourcepos="6:3-6:11" xml:space="preserve">What fun!</text>
62
+ </paragraph>
63
+ </item>
64
+ </list>
65
+ <paragraph sourcepos="8:1-8:15">
66
+ <text sourcepos="8:1-8:6" xml:space="preserve">Okay, </text>
67
+ <emph sourcepos="8:7-8:14">
68
+ <text sourcepos="8:8-8:13" xml:space="preserve">enough</text>
69
+ </emph>
70
+ <text sourcepos="8:15-8:15" xml:space="preserve">.</text>
71
+ </paragraph>
72
+ <table sourcepos="10:1-12:13">
73
+ <table_header sourcepos="10:1-10:13">
74
+ <table_cell sourcepos="10:2-10:6">
75
+ <text sourcepos="10:3-10:3" xml:space="preserve">a</text>
76
+ </table_cell>
77
+ <table_cell sourcepos="10:8-10:12">
78
+ <text sourcepos="10:9-10:9" xml:space="preserve">b</text>
79
+ </table_cell>
80
+ </table_header>
81
+ <table_row sourcepos="12:1-12:13">
82
+ <table_cell sourcepos="12:2-12:6">
83
+ <text sourcepos="12:3-12:3" xml:space="preserve">c</text>
84
+ </table_cell>
85
+ <table_cell sourcepos="12:8-12:12">
86
+ <text sourcepos="12:9-12:9" xml:space="preserve">d</text>
87
+ </table_cell>
88
+ </table_row>
89
+ </table>
90
+ </document>
91
+ XML
92
+ end
93
+
94
+ def test_to_xml_with_quotes
95
+ compare = render_doc('"quotes" should be escaped').to_xml(:DEFAULT)
96
+
97
+ assert_equal <<~XML, compare
98
+ <?xml version="1.0" encoding="UTF-8"?>
99
+ <!DOCTYPE document SYSTEM "CommonMark.dtd">
100
+ <document xmlns="http://commonmark.org/xml/1.0">
101
+ <paragraph>
102
+ <text xml:space="preserve">&quot;quotes&quot; should be escaped</text>
103
+ </paragraph>
104
+ </document>
105
+ XML
106
+ end
107
+ end
metadata CHANGED
@@ -1,30 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: commonmarker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.2
4
+ version: 0.23.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garen Torikian
8
8
  - Ashe Connor
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-02-11 00:00:00.000000000 Z
12
+ date: 2021-09-17 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: ruby-enum
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '0.5'
21
- type: :runtime
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - "~>"
26
- - !ruby/object:Gem::Version
27
- version: '0.5'
28
14
  - !ruby/object:Gem::Dependency
29
15
  name: awesome_print
30
16
  requirement: !ruby/object:Gem::Requirement
@@ -153,7 +139,7 @@ dependencies:
153
139
  version: '0'
154
140
  description: A fast, safe, extensible parser for CommonMark. This wraps the official
155
141
  libcmark library.
156
- email:
142
+ email:
157
143
  executables:
158
144
  - commonmarker
159
145
  extensions:
@@ -238,6 +224,7 @@ files:
238
224
  - ext/commonmarker/xml.c
239
225
  - lib/commonmarker.rb
240
226
  - lib/commonmarker/config.rb
227
+ - lib/commonmarker/errors.rb
241
228
  - lib/commonmarker/node.rb
242
229
  - lib/commonmarker/node/inspect.rb
243
230
  - lib/commonmarker/renderer.rb
@@ -268,11 +255,12 @@ files:
268
255
  - test/test_smartpunct.rb
269
256
  - test/test_spec.rb
270
257
  - test/test_tasklists.rb
258
+ - test/test_xml.rb
271
259
  homepage: https://github.com/gjtorikian/commonmarker
272
260
  licenses:
273
261
  - MIT
274
262
  metadata: {}
275
- post_install_message:
263
+ post_install_message:
276
264
  rdoc_options:
277
265
  - "-x"
278
266
  - ext/commonmarker/cmark/.*
@@ -283,7 +271,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
283
271
  requirements:
284
272
  - - ">="
285
273
  - !ruby/object:Gem::Version
286
- version: 2.4.10
274
+ version: '2.6'
287
275
  - - "<"
288
276
  - !ruby/object:Gem::Version
289
277
  version: '4.0'
@@ -294,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
294
282
  version: '0'
295
283
  requirements: []
296
284
  rubygems_version: 3.1.4
297
- signing_key:
285
+ signing_key:
298
286
  specification_version: 4
299
287
  summary: CommonMark parser and renderer. Written in C, wrapped in Ruby.
300
288
  test_files:
@@ -320,6 +308,7 @@ test_files:
320
308
  - test/test_helper.rb
321
309
  - test/test_options.rb
322
310
  - test/benchmark.rb
311
+ - test/test_xml.rb
323
312
  - test/test_basics.rb
324
313
  - test/test_renderer.rb
325
314
  - test/test_gc.rb