commonmarker 0.17.13 → 0.23.4
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.
- checksums.yaml +5 -5
- data/README.md +94 -18
- data/Rakefile +24 -5
- data/bin/commonmarker +107 -47
- data/commonmarker.gemspec +18 -15
- data/ext/commonmarker/autolink.c +10 -6
- data/ext/commonmarker/blocks.c +102 -31
- data/ext/commonmarker/buffer.c +0 -1
- data/ext/commonmarker/chunk.h +0 -1
- data/ext/commonmarker/cmark-gfm-core-extensions.h +29 -0
- data/ext/commonmarker/cmark-gfm-extension_api.h +19 -2
- data/ext/commonmarker/cmark-gfm.h +19 -5
- data/ext/commonmarker/cmark-gfm_version.h +2 -2
- data/ext/commonmarker/commonmark.c +33 -12
- data/ext/commonmarker/commonmarker.c +209 -100
- data/ext/commonmarker/core-extensions.c +2 -0
- data/ext/commonmarker/ext_scanners.c +622 -684
- data/ext/commonmarker/ext_scanners.h +2 -0
- data/ext/commonmarker/extconf.rb +3 -1
- data/ext/commonmarker/footnotes.c +23 -0
- data/ext/commonmarker/footnotes.h +2 -0
- data/ext/commonmarker/houdini_href_e.c +1 -1
- data/ext/commonmarker/html.c +46 -25
- data/ext/commonmarker/inlines.c +127 -30
- data/ext/commonmarker/iterator.h +0 -1
- data/ext/commonmarker/map.h +0 -1
- data/ext/commonmarker/node.c +17 -3
- data/ext/commonmarker/node.h +9 -0
- data/ext/commonmarker/parser.h +2 -1
- data/ext/commonmarker/plaintext.c +22 -0
- data/ext/commonmarker/render.c +18 -15
- data/ext/commonmarker/render.h +0 -1
- data/ext/commonmarker/scanners.c +779 -953
- data/ext/commonmarker/scanners.h +0 -2
- data/ext/commonmarker/strikethrough.c +4 -1
- data/ext/commonmarker/syntax_extension.c +10 -0
- data/ext/commonmarker/syntax_extension.h +2 -0
- data/ext/commonmarker/table.c +178 -31
- data/ext/commonmarker/tasklist.c +156 -0
- data/ext/commonmarker/tasklist.h +8 -0
- data/ext/commonmarker/xml.c +9 -2
- data/lib/commonmarker/config.rb +41 -38
- data/lib/commonmarker/errors.rb +12 -0
- data/lib/commonmarker/node/inspect.rb +15 -17
- data/lib/commonmarker/node.rb +14 -2
- data/lib/commonmarker/renderer/html_renderer.rb +45 -36
- data/lib/commonmarker/renderer.rb +16 -10
- data/lib/commonmarker/version.rb +3 -1
- data/lib/commonmarker.rb +8 -7
- data/test/benchmark.rb +26 -21
- data/test/fixtures/strong.md +1 -0
- data/test/fixtures/table.md +10 -0
- data/test/test_attributes.rb +5 -3
- data/test/test_basics.rb +19 -0
- data/test/test_commands.rb +72 -0
- data/test/test_commonmark.rb +15 -13
- data/test/test_doc.rb +31 -29
- data/test/test_encoding.rb +9 -5
- data/test/test_extensions.rb +66 -73
- data/test/test_footnotes.rb +47 -12
- data/test/test_gc.rb +6 -2
- data/test/test_helper.rb +25 -15
- data/test/test_linebreaks.rb +2 -0
- data/test/test_maliciousness.rb +189 -190
- data/test/test_node.rb +12 -12
- data/test/test_options.rb +17 -15
- data/test/test_pathological_inputs.rb +14 -12
- data/test/test_plaintext.rb +23 -21
- data/test/test_renderer.rb +29 -10
- data/test/test_smartpunct.rb +7 -2
- data/test/test_spec.rb +7 -4
- data/test/test_tasklists.rb +43 -0
- data/test/test_xml.rb +107 -0
- metadata +74 -30
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestCommands < Minitest::Test
|
6
|
+
def test_basic
|
7
|
+
out = make_bin('strong.md')
|
8
|
+
assert_equal('<p>I am <strong>strong</strong></p>', out)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_does_not_have_extensions
|
12
|
+
out = make_bin('table.md')
|
13
|
+
assert_includes out, '| a'
|
14
|
+
refute_includes out, '<p><del>hi</del>'
|
15
|
+
refute_includes out, '<table> <tr> <th> a </th> <td> c </td>'
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_understands_extensions
|
19
|
+
out = make_bin('table.md', '--extension=table')
|
20
|
+
refute_includes out, '| a'
|
21
|
+
refute_includes out, '<p><del>hi</del>'
|
22
|
+
%w[<table> <tr> <th> a </th> <td> c </td>].each { |html| assert_includes out, html }
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_understands_multiple_extensions
|
26
|
+
out = make_bin('table.md', '--extension=table,strikethrough')
|
27
|
+
refute_includes out, '| a'
|
28
|
+
assert_includes out, '<p><del>hi</del>'
|
29
|
+
%w[<table> <tr> <th> a </th> <td> c </td>].each { |html| assert_includes out, html }
|
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
|
72
|
+
end
|
data/test/test_commonmark.rb
CHANGED
@@ -1,22 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class TestCommonmark < Minitest::Test
|
4
|
-
HTML_COMMENT =
|
6
|
+
HTML_COMMENT = /<!--.*?-->\s?/.freeze
|
5
7
|
|
6
8
|
def setup
|
7
|
-
@markdown =
|
8
|
-
Hi *there*!
|
9
|
+
@markdown = <<~MD
|
10
|
+
Hi *there*!
|
9
11
|
|
10
|
-
1. I am a numeric list.
|
11
|
-
2. I continue the list.
|
12
|
-
* Suddenly, an unordered list!
|
13
|
-
* What fun!
|
12
|
+
1. I am a numeric list.
|
13
|
+
2. I continue the list.
|
14
|
+
* Suddenly, an unordered list!
|
15
|
+
* What fun!
|
14
16
|
|
15
|
-
Okay, _enough_.
|
17
|
+
Okay, _enough_.
|
16
18
|
|
17
|
-
| a | b |
|
18
|
-
| --- | --- |
|
19
|
-
| c | d |
|
19
|
+
| a | b |
|
20
|
+
| --- | --- |
|
21
|
+
| c | d |
|
20
22
|
MD
|
21
23
|
end
|
22
24
|
|
@@ -28,7 +30,7 @@ Okay, _enough_.
|
|
28
30
|
compare = render_doc(@markdown).to_commonmark
|
29
31
|
|
30
32
|
assert_equal \
|
31
|
-
render_doc(@markdown).to_html.
|
32
|
-
render_doc(compare).to_html.
|
33
|
+
render_doc(@markdown).to_html.squeeze(' ').gsub(HTML_COMMENT, ''),
|
34
|
+
render_doc(compare).to_html.squeeze(' ').gsub(HTML_COMMENT, '')
|
33
35
|
end
|
34
36
|
end
|
data/test/test_doc.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class TestDocNode < Minitest::Test
|
@@ -15,114 +17,114 @@ class TestDocNode < Minitest::Test
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def test_get_type
|
18
|
-
assert_equal @doc.type
|
20
|
+
assert_equal(:document, @doc.type)
|
19
21
|
end
|
20
22
|
|
21
23
|
def test_get_type_string
|
22
|
-
assert_equal @doc.type_string
|
24
|
+
assert_equal('document', @doc.type_string)
|
23
25
|
end
|
24
26
|
|
25
27
|
def test_get_first_child
|
26
|
-
assert_equal @first_child.type
|
28
|
+
assert_equal(:paragraph, @first_child.type)
|
27
29
|
end
|
28
30
|
|
29
31
|
def test_get_next
|
30
|
-
assert_equal @first_child.first_child.next.type
|
32
|
+
assert_equal(:emph, @first_child.first_child.next.type)
|
31
33
|
end
|
32
34
|
|
33
35
|
def test_insert_before
|
34
36
|
paragraph = Node.new(:paragraph)
|
35
|
-
|
37
|
+
assert(@first_child.insert_before(paragraph))
|
36
38
|
assert_match "<p></p>\n<p>Hi <em>there</em>.", @doc.to_html
|
37
39
|
end
|
38
40
|
|
39
41
|
def test_insert_after
|
40
42
|
paragraph = Node.new(:paragraph)
|
41
|
-
|
43
|
+
assert(@first_child.insert_after(paragraph))
|
42
44
|
assert_match "<strong>many nodes</strong>!</p>\n<p></p>\n", @doc.to_html
|
43
45
|
end
|
44
46
|
|
45
47
|
def test_prepend_child
|
46
48
|
code = Node.new(:code)
|
47
|
-
|
49
|
+
assert(@first_child.prepend_child(code))
|
48
50
|
assert_match '<p><code></code>Hi <em>there</em>.', @doc.to_html
|
49
51
|
end
|
50
52
|
|
51
53
|
def test_append_child
|
52
54
|
strong = Node.new(:strong)
|
53
|
-
|
55
|
+
assert(@first_child.append_child(strong))
|
54
56
|
assert_match "!<strong></strong></p>\n", @doc.to_html
|
55
57
|
end
|
56
58
|
|
57
59
|
def test_get_last_child
|
58
|
-
assert_equal @last_child.type
|
60
|
+
assert_equal(:paragraph, @last_child.type)
|
59
61
|
end
|
60
62
|
|
61
63
|
def test_get_parent
|
62
|
-
assert_equal @first_child.first_child.next.parent.type
|
64
|
+
assert_equal(:paragraph, @first_child.first_child.next.parent.type)
|
63
65
|
end
|
64
66
|
|
65
67
|
def test_get_previous
|
66
|
-
assert_equal @first_child.first_child.next.previous.type
|
68
|
+
assert_equal(:text, @first_child.first_child.next.previous.type)
|
67
69
|
end
|
68
70
|
|
69
71
|
def test_get_url
|
70
|
-
assert_equal
|
72
|
+
assert_equal('https://www.github.com', @link.url)
|
71
73
|
end
|
72
74
|
|
73
75
|
def test_set_url
|
74
|
-
assert_equal
|
76
|
+
assert_equal('https://www.mozilla.org', @link.url = 'https://www.mozilla.org')
|
75
77
|
end
|
76
78
|
|
77
79
|
def test_get_title
|
78
|
-
assert_equal @image.title
|
80
|
+
assert_equal('Favicon', @image.title)
|
79
81
|
end
|
80
82
|
|
81
83
|
def test_set_title
|
82
|
-
assert_equal @image.title = 'Octocat'
|
84
|
+
assert_equal('Octocat', @image.title = 'Octocat')
|
83
85
|
end
|
84
86
|
|
85
87
|
def test_get_header_level
|
86
|
-
assert_equal @header.header_level
|
88
|
+
assert_equal(3, @header.header_level)
|
87
89
|
end
|
88
90
|
|
89
91
|
def test_set_header_level
|
90
|
-
assert_equal @header.header_level = 6
|
92
|
+
assert_equal(6, @header.header_level = 6)
|
91
93
|
end
|
92
94
|
|
93
95
|
def test_get_list_type
|
94
|
-
assert_equal @ul_list.list_type
|
95
|
-
assert_equal @ol_list.list_type
|
96
|
+
assert_equal(:bullet_list, @ul_list.list_type)
|
97
|
+
assert_equal(:ordered_list, @ol_list.list_type)
|
96
98
|
end
|
97
99
|
|
98
100
|
def test_set_list_type
|
99
|
-
assert_equal @ul_list.list_type = :ordered_list
|
100
|
-
assert_equal @ol_list.list_type = :bullet_list
|
101
|
+
assert_equal(:ordered_list, @ul_list.list_type = :ordered_list)
|
102
|
+
assert_equal(:bullet_list, @ol_list.list_type = :bullet_list)
|
101
103
|
end
|
102
104
|
|
103
105
|
def test_get_list_start
|
104
|
-
assert_equal @ol_list.list_start
|
106
|
+
assert_equal(1, @ol_list.list_start)
|
105
107
|
end
|
106
108
|
|
107
109
|
def test_set_list_start
|
108
|
-
assert_equal @ol_list.list_start = 8
|
110
|
+
assert_equal(8, @ol_list.list_start = 8)
|
109
111
|
end
|
110
112
|
|
111
113
|
def test_get_list_tight
|
112
|
-
|
113
|
-
|
114
|
+
assert(@ul_list.list_tight)
|
115
|
+
assert(@ol_list.list_tight)
|
114
116
|
end
|
115
117
|
|
116
118
|
def test_set_list_tight
|
117
|
-
|
118
|
-
|
119
|
+
refute(@ul_list.list_tight = false)
|
120
|
+
refute(@ol_list.list_tight = false)
|
119
121
|
end
|
120
122
|
|
121
123
|
def test_get_fence_info
|
122
|
-
assert_equal @fence.fence_info
|
124
|
+
assert_equal('ruby', @fence.fence_info)
|
123
125
|
end
|
124
126
|
|
125
127
|
def test_set_fence_info
|
126
|
-
assert_equal @fence.fence_info = 'javascript'
|
128
|
+
assert_equal('javascript', @fence.fence_info = 'javascript')
|
127
129
|
end
|
128
130
|
end
|
data/test/test_encoding.rb
CHANGED
@@ -1,19 +1,23 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'test_helper'
|
3
4
|
|
4
5
|
class TestEncoding < Minitest::Test
|
5
6
|
# see http://git.io/vq4FR
|
6
7
|
def test_encoding
|
7
|
-
contents =
|
8
|
+
contents = fixtures_file('curly.md')
|
8
9
|
doc = CommonMarker.render_doc(contents, :SMART)
|
9
10
|
render = doc.to_html
|
10
|
-
assert_equal
|
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>')
|
11
15
|
end
|
12
16
|
|
13
17
|
def test_string_content_is_utf8
|
14
18
|
doc = CommonMarker.render_doc('Hi *there*')
|
15
19
|
text = doc.first_child.last_child.first_child
|
16
|
-
assert_equal text.string_content
|
17
|
-
assert_equal text.string_content.encoding.name
|
20
|
+
assert_equal('there', text.string_content)
|
21
|
+
assert_equal('UTF-8', text.string_content.encoding.name)
|
18
22
|
end
|
19
23
|
end
|
data/test/test_extensions.rb
CHANGED
@@ -1,123 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class TestExtensions < Minitest::Test
|
4
6
|
def setup
|
5
|
-
@markdown =
|
6
|
-
One extension:
|
7
|
-
|
8
|
-
| a | b |
|
9
|
-
| --- | --- |
|
10
|
-
| c | d |
|
11
|
-
| **x** | |
|
12
|
-
|
13
|
-
Another extension:
|
14
|
-
|
15
|
-
~~hi~~
|
16
|
-
MD
|
7
|
+
@markdown = fixtures_file('table.md')
|
17
8
|
end
|
18
9
|
|
19
10
|
def test_uses_specified_extensions
|
20
11
|
CommonMarker.render_html(@markdown, :DEFAULT, %i[]).tap do |out|
|
21
|
-
|
22
|
-
|
23
|
-
|
12
|
+
assert_includes out, '| a'
|
13
|
+
assert_includes out, '| <strong>x</strong>'
|
14
|
+
assert_includes out, '~~hi~~'
|
24
15
|
end
|
25
16
|
|
26
17
|
CommonMarker.render_html(@markdown, :DEFAULT, %i[table]).tap do |out|
|
27
|
-
|
28
|
-
%w
|
29
|
-
|
18
|
+
refute_includes out, '| a'
|
19
|
+
%w[<table> <tr> <th> a </th> <td> c </td> <strong>x</strong>].each { |html| assert_includes out, html }
|
20
|
+
assert_includes out, '~~hi~~'
|
30
21
|
end
|
31
22
|
|
32
23
|
CommonMarker.render_html(@markdown, :DEFAULT, %i[strikethrough]).tap do |out|
|
33
|
-
|
34
|
-
|
35
|
-
|
24
|
+
assert_includes out, '| a'
|
25
|
+
refute_includes out, '~~hi~~'
|
26
|
+
assert_includes out, '<del>hi</del>'
|
36
27
|
end
|
37
28
|
|
38
|
-
doc = CommonMarker.render_doc(
|
39
|
-
assert_equal
|
29
|
+
doc = CommonMarker.render_doc('~a~ ~~b~~ ~~~c~~~', :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])
|
30
|
+
assert_equal("<p>~a~ <del>b</del> ~~~c~~~</p>\n", doc.to_html)
|
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)
|
40
34
|
|
41
35
|
CommonMarker.render_html(@markdown, :DEFAULT, %i[table strikethrough]).tap do |out|
|
42
|
-
|
43
|
-
|
44
|
-
|
36
|
+
refute_includes out, '| a'
|
37
|
+
refute_includes out, '| <strong>x</strong>'
|
38
|
+
refute_includes out, '~~hi~~'
|
45
39
|
end
|
46
|
-
|
47
40
|
end
|
48
41
|
|
49
42
|
def test_extensions_with_renderers
|
50
43
|
doc = CommonMarker.render_doc(@markdown, :DEFAULT, %i[table])
|
51
44
|
|
52
45
|
doc.to_html.tap do |out|
|
53
|
-
|
54
|
-
%w
|
55
|
-
|
46
|
+
refute_includes out, '| a'
|
47
|
+
%w[<table> <tr> <th> a </th> <td> c </td> <strong>x</strong>].each { |html| assert_includes out, html }
|
48
|
+
assert_includes out, '~~hi~~'
|
56
49
|
end
|
57
50
|
|
58
51
|
HtmlRenderer.new.render(doc).tap do |out|
|
59
|
-
|
60
|
-
%w
|
61
|
-
|
52
|
+
refute_includes out, '| a'
|
53
|
+
%w[<table> <tr> <th> a </th> <td> c </td> <strong>x</strong>].each { |html| assert_includes out, html }
|
54
|
+
assert_includes out, '~~hi~~'
|
62
55
|
end
|
63
56
|
|
64
|
-
doc = CommonMarker.render_doc(
|
65
|
-
assert_equal
|
57
|
+
doc = CommonMarker.render_doc('~a~ ~~b~~ ~~~c~~~', :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])
|
58
|
+
assert_equal("<p>~a~ <del>b</del> ~~~c~~~</p>\n", HtmlRenderer.new.render(doc))
|
66
59
|
end
|
67
60
|
|
68
61
|
def test_bad_extension_specifications
|
69
|
-
assert_raises(TypeError) { CommonMarker.render_html(@markdown, :DEFAULT,
|
70
|
-
assert_raises(TypeError) { CommonMarker.render_html(@markdown, :DEFAULT, [
|
62
|
+
assert_raises(TypeError) { CommonMarker.render_html(@markdown, :DEFAULT, 'nope') }
|
63
|
+
assert_raises(TypeError) { CommonMarker.render_html(@markdown, :DEFAULT, ['table']) }
|
71
64
|
assert_raises(ArgumentError) { CommonMarker.render_html(@markdown, :DEFAULT, %i[table bad]) }
|
72
65
|
end
|
73
66
|
|
74
67
|
def test_comments_are_kept_as_expected
|
75
68
|
assert_equal "<!--hello--> <blah> <xmp>\n",
|
76
|
-
|
69
|
+
CommonMarker.render_html("<!--hello--> <blah> <xmp>\n", :UNSAFE, %i[tagfilter])
|
77
70
|
end
|
78
71
|
|
79
72
|
def test_table_prefer_style_attributes
|
80
|
-
|
81
|
-
<table>
|
82
|
-
<thead>
|
83
|
-
<tr>
|
84
|
-
<th style="text-align: left">aaa</th>
|
85
|
-
<th>bbb</th>
|
86
|
-
<th style="text-align: center">ccc</th>
|
87
|
-
<th>ddd</th>
|
88
|
-
<th style="text-align: right">eee</th>
|
89
|
-
</tr>
|
90
|
-
</thead>
|
91
|
-
<tbody>
|
92
|
-
<tr>
|
93
|
-
<td style="text-align: left">fff</td>
|
94
|
-
<td>ggg</td>
|
95
|
-
<td style="text-align: center">hhh</td>
|
96
|
-
<td>iii</td>
|
97
|
-
<td style="text-align: right">jjj</td>
|
98
|
-
</tr>
|
99
|
-
</tbody>
|
100
|
-
</table>
|
101
|
-
|
102
|
-
aaa | bbb | ccc | ddd | eee
|
103
|
-
:-- | --- | :-: | --- | --:
|
104
|
-
fff | ggg | hhh | iii | jjj
|
105
|
-
|
73
|
+
assert_equal(<<~HTML, CommonMarker.render_html(<<~MD, :TABLE_PREFER_STYLE_ATTRIBUTES, %i[table]))
|
74
|
+
<table>
|
75
|
+
<thead>
|
76
|
+
<tr>
|
77
|
+
<th style="text-align: left">aaa</th>
|
78
|
+
<th>bbb</th>
|
79
|
+
<th style="text-align: center">ccc</th>
|
80
|
+
<th>ddd</th>
|
81
|
+
<th style="text-align: right">eee</th>
|
82
|
+
</tr>
|
83
|
+
</thead>
|
84
|
+
<tbody>
|
85
|
+
<tr>
|
86
|
+
<td style="text-align: left">fff</td>
|
87
|
+
<td>ggg</td>
|
88
|
+
<td style="text-align: center">hhh</td>
|
89
|
+
<td>iii</td>
|
90
|
+
<td style="text-align: right">jjj</td>
|
91
|
+
</tr>
|
92
|
+
</tbody>
|
93
|
+
</table>
|
94
|
+
HTML
|
95
|
+
aaa | bbb | ccc | ddd | eee
|
96
|
+
:-- | --- | :-: | --- | --:
|
97
|
+
fff | ggg | hhh | iii | jjj
|
98
|
+
MD
|
106
99
|
end
|
107
100
|
|
108
101
|
def test_plaintext
|
109
|
-
assert_equal(
|
110
|
-
Hello ~there~.
|
102
|
+
assert_equal(<<~HTML, CommonMarker.render_doc(<<~MD, :DEFAULT, %i[table strikethrough]).to_plaintext)
|
103
|
+
Hello ~there~.
|
111
104
|
|
112
|
-
| a |
|
113
|
-
| --- |
|
114
|
-
| b |
|
105
|
+
| a |
|
106
|
+
| --- |
|
107
|
+
| b |
|
115
108
|
HTML
|
116
|
-
Hello ~~there~~.
|
109
|
+
Hello ~~there~~.
|
117
110
|
|
118
|
-
| a |
|
119
|
-
| - |
|
120
|
-
| b |
|
111
|
+
| a |
|
112
|
+
| - |
|
113
|
+
| b |
|
121
114
|
MD
|
122
115
|
end
|
123
116
|
end
|
data/test/test_footnotes.rb
CHANGED
@@ -1,25 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'test_helper'
|
2
4
|
|
3
5
|
class TestFootnotes < Minitest::Test
|
4
6
|
def setup
|
5
7
|
@doc = CommonMarker.render_doc("Hello[^hi].\n\n[^hi]: Hey!\n", :FOOTNOTES)
|
6
|
-
@expected = <<-HTML
|
7
|
-
<p>Hello<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup>.</p>
|
8
|
-
<section class="footnotes">
|
9
|
-
<ol>
|
10
|
-
<li id="fn1">
|
11
|
-
<p>Hey! <a href="#fnref1" class="footnote-backref">↩</a></p>
|
12
|
-
</li>
|
13
|
-
</ol>
|
14
|
-
</section>
|
15
|
-
HTML
|
16
8
|
end
|
17
9
|
|
18
10
|
def test_to_html
|
19
|
-
|
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
|
20
23
|
end
|
21
24
|
|
22
25
|
def test_html_renderer
|
23
|
-
|
26
|
+
expected = <<~HTML
|
27
|
+
<p>Hello<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup>.</p>
|
28
|
+
<section class="footnotes">
|
29
|
+
<ol>
|
30
|
+
<li id="fn1">
|
31
|
+
<p>Hey! <a href="#fnref1" class="footnote-backref">↩</a></p>
|
32
|
+
</li>
|
33
|
+
</ol>
|
34
|
+
</section>
|
35
|
+
HTML
|
36
|
+
|
37
|
+
assert_equal expected, CommonMarker::HtmlRenderer.new.render(@doc)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_render_html
|
41
|
+
md = <<~MARKDOWN
|
42
|
+
# footnotes
|
43
|
+
Let's render some footnotes[^1]
|
44
|
+
|
45
|
+
[^1]: This is a footnote
|
46
|
+
MARKDOWN
|
47
|
+
expected = <<~HTML
|
48
|
+
<h1>footnotes</h1>
|
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>
|
51
|
+
<ol>
|
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>
|
54
|
+
</li>
|
55
|
+
</ol>
|
56
|
+
</section>
|
57
|
+
HTML
|
58
|
+
assert_equal expected, CommonMarker.render_html(md, :FOOTNOTES)
|
24
59
|
end
|
25
60
|
end
|
data/test/test_gc.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Lint/UselessAssignment
|
1
4
|
require 'test_helper'
|
2
5
|
|
3
6
|
class TestNode < Minitest::Test
|
@@ -11,7 +14,7 @@ class TestNode < Minitest::Test
|
|
11
14
|
doc = nil
|
12
15
|
GC.start
|
13
16
|
# Test that doc has not been freed.
|
14
|
-
assert_equal
|
17
|
+
assert_equal 'there', text.string_content
|
15
18
|
end
|
16
19
|
|
17
20
|
def test_drop_child_reference
|
@@ -21,7 +24,7 @@ class TestNode < Minitest::Test
|
|
21
24
|
GC.start
|
22
25
|
# Test that the cached child object is still valid.
|
23
26
|
text = doc.first_child.last_child.first_child
|
24
|
-
assert_equal
|
27
|
+
assert_equal 'there', text.string_content
|
25
28
|
end
|
26
29
|
|
27
30
|
def test_remove_parent
|
@@ -41,3 +44,4 @@ class TestNode < Minitest::Test
|
|
41
44
|
# free.
|
42
45
|
end
|
43
46
|
end
|
47
|
+
# rubocop:enable Lint/UselessAssignment
|
data/test/test_helper.rb
CHANGED
@@ -1,12 +1,22 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'commonmarker'
|
3
4
|
require 'minitest/autorun'
|
4
5
|
require 'minitest/pride'
|
6
|
+
require 'minitest/focus'
|
5
7
|
|
6
|
-
include CommonMarker
|
8
|
+
include CommonMarker # rubocop:disable Style/MixinUsage
|
7
9
|
|
8
10
|
FIXTURES_DIR = File.join(File.dirname(__FILE__), 'fixtures')
|
9
11
|
|
12
|
+
def fixtures_file(file)
|
13
|
+
File.read(File.join(FIXTURES_DIR, file), encoding: 'utf-8')
|
14
|
+
end
|
15
|
+
|
16
|
+
def make_bin(file, args = '')
|
17
|
+
`ruby bin/commonmarker #{File.join(FIXTURES_DIR, file)} #{args}`.chomp
|
18
|
+
end
|
19
|
+
|
10
20
|
def open_spec_file(filename)
|
11
21
|
line_number = 0
|
12
22
|
start_line = 0
|
@@ -22,25 +32,25 @@ def open_spec_file(filename)
|
|
22
32
|
header_re = Regexp.new('#+ ')
|
23
33
|
filepath = File.join('ext', 'commonmarker', 'cmark-upstream', 'test', filename)
|
24
34
|
|
25
|
-
File.readlines(filepath, encoding:
|
35
|
+
File.readlines(filepath, encoding: 'utf-8').each do |line|
|
26
36
|
line_number += 1
|
27
37
|
|
28
38
|
l = line.strip
|
29
39
|
if l =~ /^`{32} example(.*)$/
|
30
40
|
state = 1
|
31
|
-
extensions =
|
41
|
+
extensions = Regexp.last_match(1).split
|
32
42
|
elsif l == '`' * 32
|
33
43
|
state = 0
|
34
44
|
example_number += 1
|
35
45
|
end_line = line_number
|
36
46
|
tests << {
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
47
|
+
markdown: markdown_lines.join.tr('→', "\t"),
|
48
|
+
html: html_lines.join.tr('→', "\t").rstrip,
|
49
|
+
example: example_number,
|
50
|
+
start_line: start_line,
|
51
|
+
end_line: end_line,
|
52
|
+
section: headertext,
|
53
|
+
extensions: extensions.map(&:to_sym)
|
44
54
|
}
|
45
55
|
start_line = 0
|
46
56
|
markdown_lines = []
|
@@ -48,11 +58,11 @@ def open_spec_file(filename)
|
|
48
58
|
elsif l == '.'
|
49
59
|
state = 2
|
50
60
|
elsif state == 1
|
51
|
-
start_line = line_number - 1 if start_line
|
52
|
-
markdown_lines <<
|
61
|
+
start_line = line_number - 1 if start_line.zero?
|
62
|
+
markdown_lines << line.to_s
|
53
63
|
elsif state == 2
|
54
|
-
html_lines <<
|
55
|
-
elsif state
|
64
|
+
html_lines << line.to_s
|
65
|
+
elsif state.zero? && header_re.match(line)
|
56
66
|
headertext = line.sub(header_re, '').strip
|
57
67
|
end
|
58
68
|
end
|