qiita_marker 0.23.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +50 -0
- data/Rakefile +113 -0
- data/bin/qiita_marker +123 -0
- data/ext/qiita_marker/arena.c +103 -0
- data/ext/qiita_marker/autolink.c +425 -0
- data/ext/qiita_marker/autolink.h +8 -0
- data/ext/qiita_marker/blocks.c +1596 -0
- data/ext/qiita_marker/buffer.c +278 -0
- data/ext/qiita_marker/buffer.h +116 -0
- data/ext/qiita_marker/case_fold_switch.inc +4327 -0
- data/ext/qiita_marker/chunk.h +135 -0
- data/ext/qiita_marker/cmark-gfm-core-extensions.h +54 -0
- data/ext/qiita_marker/cmark-gfm-extension_api.h +736 -0
- data/ext/qiita_marker/cmark-gfm-extensions_export.h +42 -0
- data/ext/qiita_marker/cmark-gfm.h +817 -0
- data/ext/qiita_marker/cmark-gfm_export.h +42 -0
- data/ext/qiita_marker/cmark-gfm_version.h +7 -0
- data/ext/qiita_marker/cmark.c +55 -0
- data/ext/qiita_marker/cmark_ctype.c +44 -0
- data/ext/qiita_marker/cmark_ctype.h +33 -0
- data/ext/qiita_marker/commonmark.c +529 -0
- data/ext/qiita_marker/config.h +76 -0
- data/ext/qiita_marker/core-extensions.c +27 -0
- data/ext/qiita_marker/entities.inc +2138 -0
- data/ext/qiita_marker/ext_scanners.c +879 -0
- data/ext/qiita_marker/ext_scanners.h +24 -0
- data/ext/qiita_marker/extconf.rb +7 -0
- data/ext/qiita_marker/footnotes.c +63 -0
- data/ext/qiita_marker/footnotes.h +27 -0
- data/ext/qiita_marker/houdini.h +57 -0
- data/ext/qiita_marker/houdini_href_e.c +100 -0
- data/ext/qiita_marker/houdini_html_e.c +66 -0
- data/ext/qiita_marker/houdini_html_u.c +149 -0
- data/ext/qiita_marker/html.c +486 -0
- data/ext/qiita_marker/html.h +27 -0
- data/ext/qiita_marker/inlines.c +1691 -0
- data/ext/qiita_marker/inlines.h +29 -0
- data/ext/qiita_marker/iterator.c +159 -0
- data/ext/qiita_marker/iterator.h +26 -0
- data/ext/qiita_marker/latex.c +466 -0
- data/ext/qiita_marker/linked_list.c +37 -0
- data/ext/qiita_marker/man.c +278 -0
- data/ext/qiita_marker/map.c +122 -0
- data/ext/qiita_marker/map.h +41 -0
- data/ext/qiita_marker/node.c +979 -0
- data/ext/qiita_marker/node.h +125 -0
- data/ext/qiita_marker/parser.h +58 -0
- data/ext/qiita_marker/plaintext.c +235 -0
- data/ext/qiita_marker/plugin.c +36 -0
- data/ext/qiita_marker/plugin.h +34 -0
- data/ext/qiita_marker/qiita_marker.c +1321 -0
- data/ext/qiita_marker/qiita_marker.h +16 -0
- data/ext/qiita_marker/references.c +42 -0
- data/ext/qiita_marker/references.h +26 -0
- data/ext/qiita_marker/registry.c +63 -0
- data/ext/qiita_marker/registry.h +24 -0
- data/ext/qiita_marker/render.c +205 -0
- data/ext/qiita_marker/render.h +62 -0
- data/ext/qiita_marker/scanners.c +10520 -0
- data/ext/qiita_marker/scanners.h +62 -0
- data/ext/qiita_marker/scanners.re +341 -0
- data/ext/qiita_marker/strikethrough.c +167 -0
- data/ext/qiita_marker/strikethrough.h +9 -0
- data/ext/qiita_marker/syntax_extension.c +149 -0
- data/ext/qiita_marker/syntax_extension.h +34 -0
- data/ext/qiita_marker/table.c +822 -0
- data/ext/qiita_marker/table.h +12 -0
- data/ext/qiita_marker/tagfilter.c +60 -0
- data/ext/qiita_marker/tagfilter.h +8 -0
- data/ext/qiita_marker/tasklist.c +156 -0
- data/ext/qiita_marker/tasklist.h +8 -0
- data/ext/qiita_marker/utf8.c +317 -0
- data/ext/qiita_marker/utf8.h +35 -0
- data/ext/qiita_marker/xml.c +181 -0
- data/lib/qiita_marker/config.rb +52 -0
- data/lib/qiita_marker/node/inspect.rb +57 -0
- data/lib/qiita_marker/node.rb +83 -0
- data/lib/qiita_marker/renderer/html_renderer.rb +252 -0
- data/lib/qiita_marker/renderer.rb +135 -0
- data/lib/qiita_marker/version.rb +5 -0
- data/lib/qiita_marker.rb +45 -0
- data/qiita_marker.gemspec +40 -0
- data/test/benchmark.rb +32 -0
- data/test/fixtures/curly.md +1 -0
- data/test/fixtures/dingus.md +10 -0
- data/test/fixtures/strong.md +1 -0
- data/test/fixtures/table.md +10 -0
- data/test/test_attributes.rb +24 -0
- data/test/test_basics.rb +35 -0
- data/test/test_commands.rb +72 -0
- data/test/test_commonmark.rb +36 -0
- data/test/test_doc.rb +130 -0
- data/test/test_encoding.rb +23 -0
- data/test/test_extensions.rb +116 -0
- data/test/test_footnotes.rb +60 -0
- data/test/test_gc.rb +47 -0
- data/test/test_helper.rb +71 -0
- data/test/test_linebreaks.rb +15 -0
- data/test/test_maliciousness.rb +262 -0
- data/test/test_node.rb +89 -0
- data/test/test_options.rb +37 -0
- data/test/test_pathological_inputs.rb +94 -0
- data/test/test_plaintext.rb +46 -0
- data/test/test_renderer.rb +47 -0
- data/test/test_smartpunct.rb +27 -0
- data/test/test_spec.rb +30 -0
- data/test/test_tasklists.rb +43 -0
- data/test/test_xml.rb +107 -0
- metadata +313 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'minitest/benchmark' if ENV['BENCH']
|
5
|
+
|
6
|
+
def markdown(str)
|
7
|
+
QiitaMarker.render_doc(str).to_html
|
8
|
+
end
|
9
|
+
|
10
|
+
# list of pairs consisting of input and a regex that must match the output.
|
11
|
+
pathological = {
|
12
|
+
'nested strong emph' =>
|
13
|
+
["#{'*a **a ' * 65_000}b#{' a** a*' * 65_000}",
|
14
|
+
Regexp.compile('(<em>a <strong>a ){65_000}b( a</strong> a</em>){65_000}')],
|
15
|
+
'many emph closers with no openers' =>
|
16
|
+
[('a_ ' * 65_000),
|
17
|
+
Regexp.compile('(a[_] ){64999}a_')],
|
18
|
+
'many emph openers with no closers' =>
|
19
|
+
[('_a ' * 65_000),
|
20
|
+
Regexp.compile('(_a ){64999}_a')],
|
21
|
+
'many link closers with no openers' =>
|
22
|
+
[('a]' * 65_000),
|
23
|
+
Regexp.compile('(a\]){65_000}')],
|
24
|
+
'many link openers with no closers' =>
|
25
|
+
[('[a' * 65_000),
|
26
|
+
Regexp.compile('(\[a){65_000}')],
|
27
|
+
'mismatched openers and closers' =>
|
28
|
+
[('*a_ ' * 50_000),
|
29
|
+
Regexp.compile('([*]a[_] ){49999}[*]a_')],
|
30
|
+
'link openers and emph closers' =>
|
31
|
+
[('[ a_' * 50_000),
|
32
|
+
Regexp.compile('(\[ a_){50000}')],
|
33
|
+
'hard link/emph case' =>
|
34
|
+
['**x [a*b**c*](d)',
|
35
|
+
Regexp.compile('\\*\\*x <a href=\'d\'>a<em>b</em><em>c</em></a>')],
|
36
|
+
'nested brackets' =>
|
37
|
+
["#{'[' * 50_000}a#{']' * 50_000}",
|
38
|
+
Regexp.compile('\[{50000}a\]{50000}')],
|
39
|
+
'nested block quotes' =>
|
40
|
+
["#{'> ' * 50_000}a",
|
41
|
+
Regexp.compile('(<blockquote>\n){50000}')],
|
42
|
+
'U+0000 in input' =>
|
43
|
+
['abc\u0000de\u0000',
|
44
|
+
Regexp.compile('abc\ufffd?de\ufffd?')]
|
45
|
+
}
|
46
|
+
|
47
|
+
pathological.each_pair do |name, description|
|
48
|
+
define_method("test_#{name}") do
|
49
|
+
input, = description
|
50
|
+
assert markdown(input)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
if ENV['BENCH']
|
55
|
+
class PathologicalInputsPerformanceTest < Minitest::Benchmark
|
56
|
+
def test_bench_pathological_one
|
57
|
+
assert_performance_linear 0.99 do |n|
|
58
|
+
star = '*' * (n * 10)
|
59
|
+
markdown("#{star}#{star}hi#{star}#{star}")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_bench_pathological_two
|
64
|
+
assert_performance_linear 0.99 do |n|
|
65
|
+
c = '`t`t`t`t`t`t' * (n * 10)
|
66
|
+
markdown(c)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_bench_pathological_three
|
71
|
+
assert_performance_linear 0.99 do |n|
|
72
|
+
markdown(" [a]: #{'A' * n}\n\n#{'[a][]' * n}\n")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_bench_pathological_four
|
77
|
+
assert_performance_linear 0.5 do |n|
|
78
|
+
markdown("#{'[' * n}a#{']' * n}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_bench_pathological_five
|
83
|
+
assert_performance_linear 0.99 do |n|
|
84
|
+
markdown("#{'**a *a ' * n}#{'a* a**' * n}")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_bench_unbound_recursion
|
89
|
+
assert_performance_linear 0.99 do |n|
|
90
|
+
markdown("#{'[' * n}foo#{'](bar)' * n}")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestPlaintext < 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
|
+
QiitaMarker.render_doc(doc, :DEFAULT, %i[table])
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_to_commonmark
|
28
|
+
compare = render_doc(@markdown).to_plaintext
|
29
|
+
|
30
|
+
assert_equal <<~PLAINTEXT, compare
|
31
|
+
Hi there!
|
32
|
+
|
33
|
+
1. I am a numeric list.
|
34
|
+
2. I continue the list.
|
35
|
+
|
36
|
+
- Suddenly, an unordered list!
|
37
|
+
- What fun!
|
38
|
+
|
39
|
+
Okay, enough.
|
40
|
+
|
41
|
+
| a | b |
|
42
|
+
| --- | --- |
|
43
|
+
| c | d |
|
44
|
+
PLAINTEXT
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestRenderer < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@doc = QiitaMarker.render_doc('Hi *there*')
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_html_renderer
|
11
|
+
renderer = HtmlRenderer.new
|
12
|
+
result = renderer.render(@doc)
|
13
|
+
assert_equal "<p>Hi <em>there</em></p>\n", result
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_multiple_tables
|
17
|
+
content = <<~DOC
|
18
|
+
| Input | Expected | Actual |
|
19
|
+
| ----------- | ---------------- | --------- |
|
20
|
+
| One | Two | Three |
|
21
|
+
|
22
|
+
| Header | Row | Example |
|
23
|
+
| :------: | ---: | :------ |
|
24
|
+
| Foo | Bar | Baz |
|
25
|
+
DOC
|
26
|
+
doc = QiitaMarker.render_doc(content, :DEFAULT, %i[autolink table tagfilter])
|
27
|
+
results = QiitaMarker::HtmlRenderer.new.render(doc)
|
28
|
+
assert_equal 2, results.scan(/<tbody>/).size
|
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
|
47
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class SmartPunctTest < Minitest::Test
|
6
|
+
smart_punct = open_spec_file('smart_punct.txt')
|
7
|
+
|
8
|
+
smart_punct.each do |testcase|
|
9
|
+
doc = QiitaMarker.render_doc(testcase[:markdown], :SMART)
|
10
|
+
html = QiitaMarker.render_html(testcase[:markdown], :SMART)
|
11
|
+
|
12
|
+
define_method("test_smart_punct_example_#{testcase[:example]}") do
|
13
|
+
doc_rendered = doc.to_html.strip
|
14
|
+
html_rendered = html.strip
|
15
|
+
|
16
|
+
assert_equal testcase[:html], doc_rendered, testcase[:markdown]
|
17
|
+
assert_equal testcase[:html], html_rendered, testcase[:markdown]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_smart_hardbreak_no_spaces_render_doc
|
22
|
+
markdown = "\"foo\"\nbaz"
|
23
|
+
result = "<p>“foo”<br />\nbaz</p>\n"
|
24
|
+
doc = QiitaMarker.render_doc(markdown, :SMART)
|
25
|
+
assert_equal result, doc.to_html([:HARDBREAKS])
|
26
|
+
end
|
27
|
+
end
|
data/test/test_spec.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
class TestSpec < Minitest::Test
|
7
|
+
spec = open_spec_file('spec.txt')
|
8
|
+
|
9
|
+
spec.each do |testcase|
|
10
|
+
next if testcase[:extensions].include?(:disabled)
|
11
|
+
|
12
|
+
doc = QiitaMarker.render_doc(testcase[:markdown], :DEFAULT, testcase[:extensions])
|
13
|
+
|
14
|
+
define_method("test_to_html_example_#{testcase[:example]}") do
|
15
|
+
actual = doc.to_html(:UNSAFE, testcase[:extensions]).rstrip
|
16
|
+
assert_equal testcase[:html], actual, testcase[:markdown]
|
17
|
+
end
|
18
|
+
|
19
|
+
define_method("test_html_renderer_example_#{testcase[:example]}") do
|
20
|
+
actual = HtmlRenderer.new(options: :UNSAFE, extensions: testcase[:extensions]).render(doc).rstrip
|
21
|
+
assert_equal testcase[:html], actual, testcase[:markdown]
|
22
|
+
end
|
23
|
+
|
24
|
+
define_method("test_sourcepos_example_#{testcase[:example]}") do
|
25
|
+
lhs = doc.to_html(%i[UNSAFE SOURCEPOS], testcase[:extensions]).rstrip
|
26
|
+
rhs = HtmlRenderer.new(options: %i[UNSAFE SOURCEPOS], extensions: testcase[:extensions]).render(doc).rstrip
|
27
|
+
assert_equal lhs, rhs, testcase[:markdown]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestTasklists < Minitest::Test
|
6
|
+
def setup
|
7
|
+
text = <<-MD
|
8
|
+
- [x] Add task list
|
9
|
+
- [ ] Define task list
|
10
|
+
MD
|
11
|
+
@doc = QiitaMarker.render_doc(text, :DEFAULT, %i[tasklist])
|
12
|
+
@expected = <<~HTML
|
13
|
+
<ul>
|
14
|
+
<li><input type="checkbox" checked="" disabled="" /> Add task list</li>
|
15
|
+
<li><input type="checkbox" disabled="" /> Define task list</li>
|
16
|
+
</ul>
|
17
|
+
HTML
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_to_html
|
21
|
+
assert_equal @expected, @doc.to_html
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_html_renderer
|
25
|
+
assert_equal @expected, QiitaMarker::HtmlRenderer.new.render(@doc)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_tasklist_state
|
29
|
+
list = @doc.first_child
|
30
|
+
assert_equal 'checked', list.first_child.tasklist_state
|
31
|
+
assert list.first_child.tasklist_item_checked?
|
32
|
+
assert_equal 'unchecked', list.first_child.next.tasklist_state
|
33
|
+
refute list.first_child.next.tasklist_item_checked?
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_set_tasklist_state
|
37
|
+
list = @doc.first_child
|
38
|
+
list.first_child.tasklist_item_checked = false
|
39
|
+
refute list.first_child.tasklist_item_checked?
|
40
|
+
list.first_child.next.tasklist_item_checked = true
|
41
|
+
assert list.first_child.next.tasklist_item_checked?
|
42
|
+
end
|
43
|
+
end
|
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
|
+
QiitaMarker.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">"quotes" should be escaped</text>
|
103
|
+
</paragraph>
|
104
|
+
</document>
|
105
|
+
XML
|
106
|
+
end
|
107
|
+
end
|