tight-redcarpet 3.1.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/COPYING +0 -0
- data/README.markdown +10 -9
- data/Rakefile +4 -4
- data/ext/redcarpet/buffer.c +1 -1
- data/ext/redcarpet/buffer.h +1 -1
- data/ext/redcarpet/html.c +81 -25
- data/ext/redcarpet/html.h +7 -1
- data/ext/redcarpet/html_blocks.h +71 -48
- data/ext/redcarpet/markdown.c +14 -12
- data/ext/redcarpet/markdown.h +0 -3
- data/ext/redcarpet/rc_markdown.c +3 -7
- data/ext/redcarpet/rc_render.c +13 -8
- data/lib/redcarpet.rb +41 -74
- data/lib/redcarpet/compat.rb +70 -0
- data/lib/redcarpet/render_strip.rb +2 -2
- data/redcarpet.gemspec +7 -4
- data/test/benchmark.rb +24 -0
- data/test/html5_test.rb +69 -0
- data/test/html_render_test.rb +82 -73
- data/test/html_toc_render_test.rb +36 -9
- data/test/markdown_test.rb +26 -0
- data/test/safe_render_test.rb +36 -0
- data/test/stripdown_render_test.rb +25 -27
- data/test/test_helper.rb +23 -0
- metadata +11 -5
data/test/html_render_test.rb
CHANGED
@@ -3,21 +3,7 @@ require 'test_helper'
|
|
3
3
|
|
4
4
|
class HTMLRenderTest < Redcarpet::TestCase
|
5
5
|
def setup
|
6
|
-
@
|
7
|
-
@rndr = {
|
8
|
-
:no_html => Redcarpet::Render::HTML.new(:filter_html => true),
|
9
|
-
:no_images => Redcarpet::Render::HTML.new(:no_images => true),
|
10
|
-
:no_links => Redcarpet::Render::HTML.new(:no_links => true),
|
11
|
-
:safe_links => Redcarpet::Render::HTML.new(:safe_links_only => true),
|
12
|
-
:escape_html => Redcarpet::Render::HTML.new(:escape_html => true),
|
13
|
-
:hard_wrap => Redcarpet::Render::HTML.new(:hard_wrap => true),
|
14
|
-
:toc_data => Redcarpet::Render::HTML.new(:with_toc_data => true),
|
15
|
-
:prettify => Redcarpet::Render::HTML.new(:prettify => true)
|
16
|
-
}
|
17
|
-
end
|
18
|
-
|
19
|
-
def render_with(rndr, text)
|
20
|
-
Redcarpet::Markdown.new(rndr).render(text)
|
6
|
+
@renderer = Redcarpet::Render::HTML
|
21
7
|
end
|
22
8
|
|
23
9
|
# Hint: overrides filter_html, no_images and no_links
|
@@ -37,45 +23,55 @@ EOS
|
|
37
23
|
<p><img src="/favicon.ico" /></p>
|
38
24
|
EOE
|
39
25
|
|
40
|
-
|
41
|
-
html_equal expected, markdown
|
26
|
+
html_equal expected, render(source, with: [:escape_html])
|
42
27
|
end
|
43
28
|
|
44
29
|
def test_that_filter_html_works
|
45
|
-
markdown =
|
46
|
-
|
30
|
+
markdown = 'Through <em>NO</em> <script>DOUBLE NO</script>'
|
31
|
+
output = render(markdown, with: [:filter_html])
|
32
|
+
|
33
|
+
html_equal "<p>Through NO DOUBLE NO</p>\n", output
|
47
34
|
end
|
48
35
|
|
49
36
|
def test_filter_html_doesnt_break_two_space_hard_break
|
50
|
-
markdown =
|
51
|
-
|
37
|
+
markdown = "Lorem, \nipsum\n"
|
38
|
+
output = render(markdown, with: [:filter_html])
|
39
|
+
|
40
|
+
html_equal "<p>Lorem,<br/>\nipsum</p>\n", output
|
52
41
|
end
|
53
42
|
|
54
43
|
def test_that_no_image_flag_works
|
55
|
-
|
56
|
-
|
44
|
+
markdown = %( <img src="image.png" />)
|
45
|
+
output = render(markdown, with: [:no_images])
|
46
|
+
|
47
|
+
assert_no_match %r{<img}, output
|
57
48
|
end
|
58
49
|
|
59
50
|
def test_that_no_links_flag_works
|
60
|
-
|
61
|
-
|
51
|
+
markdown = %([This link](http://example.net/) <a href="links.html">links</a>)
|
52
|
+
output = render(markdown, with: [:no_links])
|
53
|
+
|
54
|
+
assert_no_match %r{<a }, output
|
62
55
|
end
|
63
56
|
|
64
57
|
def test_that_safelink_flag_works
|
65
|
-
|
66
|
-
|
58
|
+
markdown = "[IRC](irc://chat.freenode.org/#freenode)"
|
59
|
+
output = render(markdown, with: [:safe_links_only])
|
60
|
+
|
61
|
+
html_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>\n", output
|
67
62
|
end
|
68
63
|
|
69
64
|
def test_that_hard_wrap_works
|
70
|
-
|
65
|
+
markdown = <<EOE
|
71
66
|
Hello world,
|
72
67
|
this is just a simple test
|
73
68
|
|
74
69
|
With hard wraps
|
75
70
|
and other *things*.
|
76
71
|
EOE
|
72
|
+
output = render(markdown, with: [:hard_wrap])
|
77
73
|
|
78
|
-
|
74
|
+
assert_match %r{<br>}, output
|
79
75
|
end
|
80
76
|
|
81
77
|
def test_that_link_attributes_work
|
@@ -85,11 +81,11 @@ EOE
|
|
85
81
|
end
|
86
82
|
|
87
83
|
def test_that_link_works_with_quotes
|
88
|
-
|
89
|
-
|
84
|
+
markdown = %([This'link"is](http://example.net/))
|
85
|
+
expected = %(<p><a href="http://example.net/">This'link"is</a></p>\n)
|
90
86
|
|
91
|
-
|
92
|
-
assert_equal
|
87
|
+
assert_equal expected, render(markdown)
|
88
|
+
assert_equal expected, render(markdown, with: [:escape_html])
|
93
89
|
end
|
94
90
|
|
95
91
|
def test_that_code_emphasis_work
|
@@ -111,22 +107,19 @@ However, this should be <em><code>an emphasised codespan</code></em></p>
|
|
111
107
|
</ul>
|
112
108
|
HTML
|
113
109
|
|
114
|
-
|
115
|
-
assert_equal html, output
|
110
|
+
assert_equal html, render(markdown)
|
116
111
|
end
|
117
112
|
|
118
113
|
def test_that_parenthesis_are_handled_into_links
|
119
|
-
markdown =
|
120
|
-
|
121
|
-
output = render_with(Redcarpet::Render::HTML.new, markdown)
|
114
|
+
markdown = %(The [bash man page](man:bash(1))!)
|
115
|
+
expected = %(<p>The <a href="man:bash(1)">bash man page</a>!</p>\n)
|
122
116
|
|
123
|
-
assert_equal
|
117
|
+
assert_equal expected, render(markdown)
|
124
118
|
end
|
125
119
|
|
126
120
|
def test_autolinking_works_as_expected
|
127
|
-
markdown = "
|
128
|
-
|
129
|
-
output = renderer.render(markdown)
|
121
|
+
markdown = "Uri ftp://user:pass@example.com/. Email foo@bar.com and link http://bar.com"
|
122
|
+
output = render(markdown, with: [:autolink])
|
130
123
|
|
131
124
|
assert output.include? '<a href="ftp://user:pass@example.com/">ftp://user:pass@example.com/</a>'
|
132
125
|
assert output.include? 'mailto:foo@bar.com'
|
@@ -155,8 +148,7 @@ MD
|
|
155
148
|
</div>
|
156
149
|
HTML
|
157
150
|
|
158
|
-
|
159
|
-
output = renderer.render(markdown)
|
151
|
+
output = render(markdown, with: [:footnotes])
|
160
152
|
assert_equal html, output
|
161
153
|
end
|
162
154
|
|
@@ -172,61 +164,78 @@ MD
|
|
172
164
|
<p>[^1] And a trailing definition</p>
|
173
165
|
HTML
|
174
166
|
|
175
|
-
|
176
|
-
output = renderer.render(markdown)
|
167
|
+
output = render(markdown, with: [:footnotes])
|
177
168
|
assert_equal html, output
|
178
169
|
end
|
179
170
|
|
180
171
|
def test_footnotes_enabled_but_missing_definition
|
181
172
|
markdown = "Some text with a marker[^1] but no definition."
|
182
|
-
|
173
|
+
expected = "<p>Some text with a marker[^1] but no definition.</p>\n"
|
183
174
|
|
184
|
-
|
185
|
-
|
186
|
-
assert_equal html, output
|
175
|
+
output = render(markdown, with: [:footnotes])
|
176
|
+
assert_equal expected, output
|
187
177
|
end
|
188
178
|
|
189
179
|
def test_autolink_short_domains
|
190
180
|
markdown = "Example of uri ftp://auto/short/domains. Email auto@l.n and link http://a/u/t/o/s/h/o/r/t"
|
191
|
-
|
192
|
-
output = renderer.render(markdown)
|
181
|
+
output = render(markdown, with: [:autolink])
|
193
182
|
|
194
183
|
assert output.include? '<a href="ftp://auto/short/domains">ftp://auto/short/domains</a>'
|
195
184
|
assert output.include? 'mailto:auto@l.n'
|
196
185
|
assert output.include? '<a href="http://a/u/t/o/s/h/o/r/t">http://a/u/t/o/s/h/o/r/t</a>'
|
197
186
|
end
|
198
187
|
|
199
|
-
def test_toc_heading_id
|
200
|
-
markdown = "# First level heading\n## Second level heading"
|
201
|
-
output = render_with(@rndr[:toc_data], markdown)
|
202
|
-
assert_match /<h1 id="first-level-heading">/, output
|
203
|
-
assert_match /<h2 id="second-level-heading">/, output
|
204
|
-
end
|
205
|
-
|
206
188
|
def test_that_prettify_works
|
207
|
-
|
208
|
-
|
189
|
+
markdown = "\tclass Foo\nend"
|
190
|
+
output = render(markdown, with: [:prettify])
|
191
|
+
|
192
|
+
assert output.include?("<pre><code class=\"prettyprint\">")
|
209
193
|
|
210
|
-
|
211
|
-
|
212
|
-
code
|
213
|
-
~~~
|
194
|
+
markdown = "`class`"
|
195
|
+
output = render(markdown, with: [:prettify])
|
214
196
|
|
215
|
-
|
216
|
-
|
197
|
+
assert output.include?("<code class=\"prettyprint\">")
|
198
|
+
end
|
217
199
|
|
218
|
-
|
219
|
-
|
200
|
+
def test_prettify_with_fenced_code_blocks
|
201
|
+
markdown = "~~~ruby\ncode\n~~~"
|
202
|
+
output = render(markdown, with: [:fenced_code_blocks, :prettify])
|
220
203
|
|
221
|
-
assert output.include?("<code class=\"prettyprint ruby\">")
|
204
|
+
assert output.include?("<code class=\"prettyprint lang-ruby\">")
|
222
205
|
end
|
223
206
|
|
224
207
|
def test_safe_links_only_with_anchors
|
225
208
|
markdown = "An [anchor link](#anchor) on a page."
|
226
|
-
|
227
|
-
renderer = Redcarpet::Markdown.new(@rndr[:safe_links])
|
228
|
-
output = renderer.render(markdown)
|
209
|
+
output = render(markdown, with: [:safe_links_only])
|
229
210
|
|
230
211
|
assert_match %r{<a href="#anchor">anchor link</a>}, output
|
231
212
|
end
|
213
|
+
|
214
|
+
def test_autolink_with_link_attributes
|
215
|
+
options = { autolink: true, link_attributes: {rel: "nofollow"} }
|
216
|
+
output = render("https://github.com/", with: options)
|
217
|
+
|
218
|
+
assert_match %r{rel="nofollow"}, output
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_image_unsafe_src_with_safe_links_only
|
222
|
+
markdown = ";)"
|
223
|
+
output = render(markdown, with: [:safe_links_only])
|
224
|
+
|
225
|
+
assert_not_match %r{img src}, output
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_no_styles_option_inside_a_paragraph
|
229
|
+
markdown = "Hello <style> foo { bar: baz; } </style> !"
|
230
|
+
output = render(markdown, with: [:no_styles])
|
231
|
+
|
232
|
+
assert_no_match %r{<style>}, output
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_no_styles_inside_html_block_rendering
|
236
|
+
markdown = "<style> foo { bar: baz; } </style>"
|
237
|
+
output = render(markdown, with: [:no_styles])
|
238
|
+
|
239
|
+
assert_no_match %r{<style>}, output
|
240
|
+
end
|
232
241
|
end
|
@@ -3,13 +3,12 @@ require 'test_helper'
|
|
3
3
|
|
4
4
|
class HTMLTOCRenderTest < Redcarpet::TestCase
|
5
5
|
def setup
|
6
|
-
@
|
6
|
+
@renderer = Redcarpet::Render::HTML_TOC
|
7
7
|
@markdown = "# A title \n## A __nice__ subtitle\n## Another one \n### A sub-sub-title"
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_simple_toc_render
|
11
|
-
|
12
|
-
output = renderer.render(@markdown).strip
|
11
|
+
output = render(@markdown).strip
|
13
12
|
|
14
13
|
assert output.start_with?("<ul>")
|
15
14
|
assert output.end_with?("</ul>")
|
@@ -19,8 +18,7 @@ class HTMLTOCRenderTest < Redcarpet::TestCase
|
|
19
18
|
end
|
20
19
|
|
21
20
|
def test_granular_toc_render
|
22
|
-
|
23
|
-
output = renderer.render(@markdown).strip
|
21
|
+
output = render(@markdown, with: { nesting_level: 2 }).strip
|
24
22
|
|
25
23
|
assert output.start_with?("<ul>")
|
26
24
|
assert output.end_with?("</ul>")
|
@@ -30,8 +28,7 @@ class HTMLTOCRenderTest < Redcarpet::TestCase
|
|
30
28
|
end
|
31
29
|
|
32
30
|
def test_toc_heading_id
|
33
|
-
|
34
|
-
output = renderer.render(@markdown)
|
31
|
+
output = render(@markdown)
|
35
32
|
|
36
33
|
assert_match /a-title/, output
|
37
34
|
assert_match /a-nice-subtitle/, output
|
@@ -40,10 +37,40 @@ class HTMLTOCRenderTest < Redcarpet::TestCase
|
|
40
37
|
end
|
41
38
|
|
42
39
|
def test_toc_heading_with_hyphen_and_equal
|
43
|
-
|
44
|
-
output = renderer.render("# Hello World\n\n-\n\n=")
|
40
|
+
output = render("# Hello World\n\n-\n\n=")
|
45
41
|
|
46
42
|
assert_equal 1, output.scan("<li>").length
|
47
43
|
assert !output.include?('<a href=\"#\"></a>')
|
48
44
|
end
|
45
|
+
|
46
|
+
def test_anchor_generation_with_edge_cases
|
47
|
+
# Imported from ActiveSupport::Inflector#parameterize's tests
|
48
|
+
titles = {
|
49
|
+
"Donald E. Knuth" => "donald-e-knuth",
|
50
|
+
"Random text with *(bad)* characters" => "random-text-with-bad-characters",
|
51
|
+
"Trailing bad characters!@#" => "trailing-bad-characters",
|
52
|
+
"!@#Leading bad characters" => "leading-bad-characters",
|
53
|
+
"Squeeze separators" => "squeeze-separators",
|
54
|
+
"Test with + sign" => "test-with-sign",
|
55
|
+
"Test with a Namespaced::Class" => "test-with-a-namespaced-class"
|
56
|
+
}
|
57
|
+
|
58
|
+
titles.each do |title, anchor|
|
59
|
+
assert_match anchor, render("# #{title}")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_inline_markup_is_not_escaped
|
64
|
+
output = render(@markdown)
|
65
|
+
|
66
|
+
assert_match "A <strong>nice</strong> subtitle", output
|
67
|
+
assert_no_match %r{<}, output
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_inline_markup_escaping
|
71
|
+
output = render(@markdown, with: [:escape_html])
|
72
|
+
|
73
|
+
assert_match "<strong>", output
|
74
|
+
assert_no_match %r{<strong>}, output
|
75
|
+
end
|
49
76
|
end
|
data/test/markdown_test.rb
CHANGED
@@ -238,6 +238,32 @@ fenced
|
|
238
238
|
assert !out.include?("<pre><code>")
|
239
239
|
end
|
240
240
|
|
241
|
+
def test_that_indented_code_preserves_references
|
242
|
+
text = <<indented
|
243
|
+
This is normal text
|
244
|
+
|
245
|
+
Link to [Google][1]
|
246
|
+
|
247
|
+
[1]: http://google.com
|
248
|
+
indented
|
249
|
+
out = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :fenced_code_blocks => true).render(text)
|
250
|
+
assert out.include?("[1]: http://google.com")
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_that_fenced_flag_preserves_references
|
254
|
+
text = <<fenced
|
255
|
+
This is normal text
|
256
|
+
|
257
|
+
```
|
258
|
+
Link to [Google][1]
|
259
|
+
|
260
|
+
[1]: http://google.com
|
261
|
+
```
|
262
|
+
fenced
|
263
|
+
out = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :fenced_code_blocks => true).render(text)
|
264
|
+
assert out.include?("[1]: http://google.com")
|
265
|
+
end
|
266
|
+
|
241
267
|
def test_that_indented_flag_works
|
242
268
|
text = <<indented
|
243
269
|
This is a simple text
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SafeRenderTest < Redcarpet::TestCase
|
4
|
+
def setup
|
5
|
+
@render = Redcarpet::Render::Safe
|
6
|
+
@parser = Redcarpet::Markdown.new(@render, fenced_code_blocks: true)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_safe_links_only_is_enabled_by_default
|
10
|
+
markdown = "[foo](javascript:alert('foo'))"
|
11
|
+
output = @parser.render(markdown)
|
12
|
+
|
13
|
+
assert_not_match %r{a href}, output
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_escape_html_is_enabled_by_default
|
17
|
+
markdown = "<p>Hello world!</p>"
|
18
|
+
output = @parser.render(markdown)
|
19
|
+
|
20
|
+
assert_match %r{<}, output
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_html_escaping_in_code_blocks
|
24
|
+
markdown = "~~~\n<p>Hello!</p>\n~~~"
|
25
|
+
output = @parser.render(markdown)
|
26
|
+
|
27
|
+
assert_match %r{<p>}, output
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_lang_class_is_removed
|
31
|
+
markdown = "~~~ruby\nclass Foo; end\n~~~"
|
32
|
+
output = @parser.render(markdown)
|
33
|
+
|
34
|
+
assert_not_match %r{ruby}, output
|
35
|
+
end
|
36
|
+
end
|
@@ -2,41 +2,39 @@
|
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
4
|
class StripDownRender < Redcarpet::TestCase
|
5
|
-
|
6
5
|
def setup
|
7
|
-
@
|
6
|
+
@parser = Redcarpet::Markdown.new(Redcarpet::Render::StripDown)
|
8
7
|
end
|
9
8
|
|
10
|
-
def
|
11
|
-
markdown =
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
html_equal "Foo bar\n", html
|
9
|
+
def test_titles
|
10
|
+
markdown = "# Foo bar"
|
11
|
+
output = @parser.render(markdown)
|
12
|
+
|
13
|
+
assert_equal "Foo bar\n", output
|
16
14
|
end
|
17
15
|
|
18
|
-
def
|
19
|
-
markdown =
|
20
|
-
|
16
|
+
def test_code_blocks
|
17
|
+
markdown = "\tclass Foo\n\tend"
|
18
|
+
output = @parser.render(markdown)
|
19
|
+
|
20
|
+
assert_equal "class Foo\nend\n", output
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
+
def test_images
|
24
|
+
markdown = "Look at this \n" \
|
25
|
+
"And this: "
|
26
|
+
expected = "Look at this picture http://example.org/picture.png\n" \
|
27
|
+
"And this: http://example.org/image.jpg\n"
|
28
|
+
output = @parser.render(markdown)
|
23
29
|
|
24
|
-
|
25
|
-
|
30
|
+
assert_equal expected, output
|
31
|
+
end
|
26
32
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
Foo bar
|
32
|
-
Hello world! Please visit this site.
|
33
|
-
class Foo
|
34
|
-
end
|
35
|
-
Look at this picture http://example.org/picture.png
|
36
|
-
And this: http://example.org/image.jpg
|
37
|
-
Plaintext
|
33
|
+
def test_links
|
34
|
+
markdown = "Here's an [example](https://github.com)"
|
35
|
+
expected = "Here's an example (https://github.com)\n"
|
36
|
+
output = @parser.render(markdown)
|
38
37
|
|
39
|
-
|
40
|
-
html_equal plaintext, html
|
38
|
+
assert_equal expected, output
|
41
39
|
end
|
42
40
|
end
|