redcarpet 1.0.0 → 2.0.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.
@@ -1,106 +1,328 @@
1
- # encoding: utf-8
1
+ # coding: UTF-8
2
2
  rootdir = File.dirname(File.dirname(__FILE__))
3
3
  $LOAD_PATH.unshift "#{rootdir}/lib"
4
4
 
5
+ if defined? Encoding
6
+ Encoding.default_internal = 'UTF-8'
7
+ end
8
+
5
9
  require 'test/unit'
6
10
  require 'redcarpet'
11
+ require 'redcarpet/render_man'
12
+ require 'nokogiri'
7
13
 
8
- class RedcarpetTest < Test::Unit::TestCase
9
- def test_that_discount_does_not_blow_up_with_weird_formatting_case
10
- text = (<<-TEXT).gsub(/^ {4}/, '').rstrip
11
- 1. some text
14
+ def html_equal(html_a, html_b)
15
+ assert_equal Nokogiri::HTML::DocumentFragment.parse(html_a).to_html,
16
+ Nokogiri::HTML::DocumentFragment.parse(html_b).to_html
17
+ end
12
18
 
13
- 1.
14
- TEXT
15
- Redcarpet.new(text).to_html
19
+ class SmartyPantsTest < Test::Unit::TestCase
20
+ def setup
21
+ @pants = Redcarpet::Render::SmartyPants
16
22
  end
17
23
 
18
- def test_that_smart_converts_double_quotes_to_curly_quotes
19
- rd = Redcarpet.new(%("Quoted text"), :smart)
20
- assert_equal %(<p>&ldquo;Quoted text&rdquo;</p>\n), rd.to_html
24
+ def test_that_smart_converts_single_quotes_in_words_that_end_in_re
25
+ markdown = @pants.render("<p>They're not for sale.</p>")
26
+ assert_equal "<p>They&rsquo;re not for sale.</p>", markdown
21
27
  end
22
28
 
23
- def test_that_smart_converts_double_quotes_to_curly_quotes_before_a_heading
24
- rd = Redcarpet.new(%("Quoted text"\n\n# Heading), :smart)
25
- assert_equal %(<p>&ldquo;Quoted text&rdquo;</p>\n\n<h1>Heading</h1>\n), rd.to_html
29
+ def test_that_smart_converts_single_quotes_in_words_that_end_in_ll
30
+ markdown = @pants.render("<p>Well that'll be the day</p>")
31
+ assert_equal "<p>Well that&rsquo;ll be the day</p>", markdown
26
32
  end
27
33
 
28
- def test_that_smart_converts_double_quotes_to_curly_quotes_after_a_heading
29
- rd = Redcarpet.new(%(# Heading\n\n"Quoted text"), :smart)
30
- assert_equal %(<h1>Heading</h1>\n\n<p>&ldquo;Quoted text&rdquo;</p>\n), rd.to_html
34
+ def test_that_smart_converts_double_quotes_to_curly_quotes
35
+ rd = @pants.render(%(<p>"Quoted text"</p>))
36
+ assert_equal %(<p>&ldquo;Quoted text&rdquo;</p>), rd
31
37
  end
32
38
 
33
39
  def test_that_smart_gives_ve_suffix_a_rsquo
34
- rd = Redcarpet.new("I've been meaning to tell you ..", :smart)
35
- assert_equal "<p>I&rsquo;ve been meaning to tell you ..</p>\n", rd.to_html
40
+ rd = @pants.render("<p>I've been meaning to tell you ..</p>")
41
+ assert_equal "<p>I&rsquo;ve been meaning to tell you ..</p>", rd
36
42
  end
37
43
 
38
44
  def test_that_smart_gives_m_suffix_a_rsquo
39
- rd = Redcarpet.new("I'm not kidding", :smart)
40
- assert_equal "<p>I&rsquo;m not kidding</p>\n", rd.to_html
45
+ rd = @pants.render("<p>I'm not kidding</p>")
46
+ assert_equal "<p>I&rsquo;m not kidding</p>", rd
41
47
  end
42
48
 
43
49
  def test_that_smart_gives_d_suffix_a_rsquo
44
- rd = Redcarpet.new("what'd you say?", :smart)
45
- assert_equal "<p>what&rsquo;d you say?</p>\n", rd.to_html
50
+ rd = @pants.render("<p>what'd you say?</p>")
51
+ assert_equal "<p>what&rsquo;d you say?</p>", rd
46
52
  end
53
+ end
47
54
 
48
- if "".respond_to?(:encoding)
49
- def test_should_return_string_in_same_encoding_as_input
50
- input = "Yogācāra"
51
- output = Redcarpet.new(input).to_html
52
- assert_equal input.encoding.name, output.encoding.name
53
- end
55
+ class HTMLRenderTest < Test::Unit::TestCase
56
+ def setup
57
+ @markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
58
+ @rndr = {
59
+ :no_html => Redcarpet::Render::HTML.new(:filter_html => true),
60
+ :no_images => Redcarpet::Render::HTML.new(:no_images => true),
61
+ :no_links => Redcarpet::Render::HTML.new(:no_links => true),
62
+ :safe_links => Redcarpet::Render::HTML.new(:safe_links_only => true),
63
+ }
64
+ end
65
+
66
+ def render_with(rndr, text)
67
+ Redcarpet::Markdown.new(rndr).render(text)
68
+ end
69
+
70
+ def test_that_filter_html_works
71
+ markdown = render_with(@rndr[:no_html], 'Through <em>NO</em> <script>DOUBLE NO</script>')
72
+ html_equal "<p>Through NO DOUBLE NO</p>", markdown
73
+ end
74
+
75
+ def test_filter_html_doesnt_break_two_space_hard_break
76
+ markdown = render_with(@rndr[:no_html], "Lorem, \nipsum\n")
77
+ html_equal "<p>Lorem,<br/>\nipsum</p>\n", markdown
54
78
  end
55
79
 
56
80
  def test_that_no_image_flag_works
57
- rd = Redcarpet.new(%(![dust mite](http://dust.mite/image.png) <img src="image.png" />), :no_image)
58
- assert rd.to_html !~ /<img/
81
+ rd = render_with(@rndr[:no_images], %(![dust mite](http://dust.mite/image.png) <img src="image.png" />))
82
+ assert rd !~ /<img/
59
83
  end
60
84
 
61
85
  def test_that_no_links_flag_works
62
- rd = Redcarpet.new(%([This link](http://example.net/) <a href="links.html">links</a>), :no_links)
63
- assert rd.to_html !~ /<a /
86
+ rd = render_with(@rndr[:no_links], %([This link](http://example.net/) <a href="links.html">links</a>))
87
+ assert rd !~ /<a /
88
+ end
89
+
90
+ def test_that_safelink_flag_works
91
+ rd = render_with(@rndr[:safe_links], "[IRC](irc://chat.freenode.org/#freenode)")
92
+ html_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>\n", rd
93
+ end
94
+ end
95
+
96
+ class MarkdownTest < Test::Unit::TestCase
97
+
98
+ def setup
99
+ @markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
100
+ end
101
+
102
+ def render_with(flags, text)
103
+ Redcarpet::Markdown.new(Redcarpet::Render::HTML, flags).render(text)
104
+ end
105
+
106
+ def test_that_simple_one_liner_goes_to_html
107
+ assert_respond_to @markdown, :render
108
+ html_equal "<p>Hello World.</p>", @markdown.render("Hello World.")
109
+ end
110
+
111
+ def test_that_inline_markdown_goes_to_html
112
+ markdown = @markdown.render('_Hello World_!')
113
+ html_equal "<p><em>Hello World</em>!</p>", markdown
114
+ end
115
+
116
+ def test_that_inline_markdown_starts_and_ends_correctly
117
+ markdown = render_with({:no_intra_emphasis => true}, '_start _ foo_bar bar_baz _ end_ *italic* **bold** <a>_blah_</a>')
118
+
119
+ html_equal "<p><em>start _ foo_bar bar_baz _ end</em> <em>italic</em> <strong>bold</strong> <a><em>blah</em></a></p>", markdown
120
+
121
+ markdown = @markdown.render("Run 'rake radiant:extensions:rbac_base:migrate'")
122
+ html_equal "<p>Run 'rake radiant:extensions:rbac_base:migrate'</p>", markdown
123
+ end
124
+
125
+ def test_that_urls_are_not_doubly_escaped
126
+ markdown = @markdown.render('[Page 2](/search?query=Markdown+Test&page=2)')
127
+ html_equal "<p><a href=\"/search?query=Markdown+Test&amp;page=2\">Page 2</a></p>\n", markdown
128
+ end
129
+
130
+ def test_simple_inline_html
131
+ #markdown = Markdown.new("before\n\n<div>\n foo\n</div>\nafter")
132
+ markdown = @markdown.render("before\n\n<div>\n foo\n</div>\n\nafter")
133
+ html_equal "<p>before</p>\n\n<div>\n foo\n</div>\n\n<p>after</p>\n", markdown
134
+ end
135
+
136
+ def test_that_html_blocks_do_not_require_their_own_end_tag_line
137
+ markdown = @markdown.render("Para 1\n\n<div><pre>HTML block\n</pre></div>\n\nPara 2 [Link](#anchor)")
138
+ html_equal "<p>Para 1</p>\n\n<div><pre>HTML block\n</pre></div>\n\n<p>Para 2 <a href=\"#anchor\">Link</a></p>\n",
139
+ markdown
140
+ end
141
+
142
+ # This isn't in the spec but is Markdown.pl behavior.
143
+ def test_block_quotes_preceded_by_spaces
144
+ markdown = @markdown.render(
145
+ "A wise man once said:\n\n" +
146
+ " > Isn't it wonderful just to be alive.\n"
147
+ )
148
+ html_equal "<p>A wise man once said:</p>\n\n" +
149
+ "<blockquote><p>Isn't it wonderful just to be alive.</p>\n</blockquote>\n",
150
+ markdown
151
+ end
152
+
153
+ def test_para_before_block_html_should_not_wrap_in_p_tag
154
+ markdown = render_with({:lax_html_blocks => true},
155
+ "Things to watch out for\n" +
156
+ "<ul>\n<li>Blah</li>\n</ul>\n")
157
+
158
+ html_equal "<p>Things to watch out for</p>\n\n" +
159
+ "<ul>\n<li>Blah</li>\n</ul>\n", markdown
160
+ end
161
+
162
+ # http://github.com/rtomayko/rdiscount/issues/#issue/13
163
+ def test_headings_with_trailing_space
164
+ text = "The Ant-Sugar Tales \n" +
165
+ "=================== \n\n" +
166
+ "By Candice Yellowflower \n"
167
+ html_equal "<h1>The Ant-Sugar Tales </h1>\n\n<p>By Candice Yellowflower </p>\n", @markdown.render(text)
64
168
  end
65
169
 
66
- def test_that_strict_flag_works
67
- rd = Redcarpet.new("foo_bar_baz", :strict)
68
- assert_equal "<p>foo<em>bar</em>baz</p>\n", rd.to_html
170
+ def test_that_intra_emphasis_works
171
+ rd = render_with({}, "foo_bar_baz")
172
+ html_equal "<p>foo<em>bar</em>baz</p>\n", rd
173
+
174
+ rd = render_with({:no_intra_emphasis => true},"foo_bar_baz")
175
+ html_equal "<p>foo_bar_baz</p>\n", rd
69
176
  end
70
177
 
71
178
  def test_that_autolink_flag_works
72
- rd = Redcarpet.new("http://github.com/rtomayko/rdiscount", :autolink)
73
- assert_equal "<p><a href=\"http://github.com/rtomayko/rdiscount\">http://github.com/rtomayko/rdiscount</a></p>\n", rd.to_html
179
+ rd = render_with({:autolink => true}, "http://github.com/rtomayko/rdiscount")
180
+ html_equal "<p><a href=\"http://github.com/rtomayko/rdiscount\">http://github.com/rtomayko/rdiscount</a></p>\n", rd
74
181
  end
75
182
 
76
- def test_that_safelink_flag_works
77
- rd = Redcarpet.new("[IRC](irc://chat.freenode.org/#freenode)", :safelink)
78
- assert_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>\n", rd.to_html
183
+ if "".respond_to?(:encoding)
184
+ def test_should_return_string_in_same_encoding_as_input
185
+ input = "Yogācāra"
186
+ output = @markdown.render(input)
187
+ assert_equal input.encoding.name, output.encoding.name
188
+ end
79
189
  end
80
190
 
81
191
  def test_that_tags_can_have_dashes_and_underscores
82
- rd = Redcarpet.new("foo <asdf-qwerty>bar</asdf-qwerty> and <a_b>baz</a_b>")
83
- assert_equal "<p>foo <asdf-qwerty>bar</asdf-qwerty> and <a_b>baz</a_b></p>\n", rd.to_html
192
+ rd = @markdown.render("foo <asdf-qwerty>bar</asdf-qwerty> and <a_b>baz</a_b>")
193
+ html_equal "<p>foo <asdf-qwerty>bar</asdf-qwerty> and <a_b>baz</a_b></p>\n", rd
194
+ end
195
+
196
+ def test_link_syntax_is_not_processed_within_code_blocks
197
+ markdown = @markdown.render(" This is a code block\n This is a link [[1]] inside\n")
198
+ html_equal "<pre><code>This is a code block\nThis is a link [[1]] inside\n</code></pre>\n",
199
+ markdown
200
+ end
201
+
202
+ def test_whitespace_after_urls
203
+ rd = render_with({:autolink => true}, "Japan: http://www.abc.net.au/news/events/japan-quake-2011/beforeafter.htm (yes, japan)")
204
+ exp = %{<p>Japan: <a href="http://www.abc.net.au/news/events/japan-quake-2011/beforeafter.htm">http://www.abc.net.au/news/events/japan-quake-2011/beforeafter.htm</a> (yes, japan)</p>}
205
+ html_equal exp, rd
84
206
  end
207
+
208
+ def test_memory_leak_when_parsing_char_links
209
+ @markdown.render(<<-leaks)
210
+ 2. Identify the wild-type cluster and determine all clusters
211
+ containing or contained by it:
212
+
213
+ wildtype <- wildtype.cluster(h)
214
+ wildtype.mask <- logical(nclust)
215
+ wildtype.mask[c(contains(h, wildtype),
216
+ wildtype,
217
+ contained.by(h, wildtype))] <- TRUE
85
218
 
86
- def xtest_pathological_1
219
+ This could be more elegant.
220
+ leaks
221
+ end
222
+
223
+ def test_infinite_loop_in_header
224
+ html_equal @markdown.render(<<-header), "<h1>Body</h1>"
225
+ ######
226
+ #Body#
227
+ ######
228
+ header
229
+ end
230
+
231
+ def test_that_tables_flag_works
232
+ text = <<EOS
233
+ aaa | bbbb
234
+ -----|------
235
+ hello|sailor
236
+ EOS
237
+
238
+ assert render_with({}, text) !~ /<table/
239
+
240
+ assert render_with({:tables => true}, text) =~ /<table/
241
+ end
242
+
243
+ def test_strikethrough_flag_works
244
+ text = "this is ~some~ striked ~~text~~"
245
+
246
+ assert render_with({}, text) !~ /<del/
247
+
248
+ assert render_with({:strikethrough => true}, text) =~ /<del/
249
+ end
250
+
251
+ def test_that_fenced_flag_works
252
+ text = <<fenced
253
+ This is a simple test
254
+
255
+ ~~~~~
256
+ This is some awesome code
257
+ with tabs and shit
258
+ ~~~
259
+ fenced
260
+
261
+ assert render_with({}, text) !~ /<code/
262
+
263
+ assert render_with({:fenced_code_blocks => true}, text) =~ /<code/
264
+ end
265
+
266
+ def test_that_headers_are_linkable
267
+ markdown = @markdown.render('### Hello [GitHub](http://github.com)')
268
+ html_equal "<h3>Hello <a href=\"http://github.com\">GitHub</a></h3>", markdown
269
+ end
270
+
271
+ def test_autolinking_with_ent_chars
272
+ markdown = render_with({:autolink => true}, <<text)
273
+ This a stupid link: https://github.com/rtomayko/tilt/issues?milestone=1&state=open
274
+ text
275
+ html_equal "<p>This a stupid link: <a href=\"https://github.com/rtomayko/tilt/issues?milestone=1&state=open\">https://github.com/rtomayko/tilt/issues?milestone=1&amp;state=open</a></p>\n", markdown
276
+ end
277
+
278
+ def test_spaced_headers
279
+ rd = render_with({:space_after_headers => true}, "#123 a header yes\n")
280
+ assert rd !~ /<h1>/
281
+ end
282
+ end
283
+
284
+ class CustomRenderTest < Test::Unit::TestCase
285
+ class SimpleRender < Redcarpet::Render::HTML
286
+ def emphasis(text)
287
+ "<em class=\"cool\">#{text}</em>"
288
+ end
289
+ end
290
+
291
+ def test_simple_overload
292
+ md = Redcarpet::Markdown.new(SimpleRender)
293
+ html_equal "<p>This is <em class=\"cool\">just</em> a test</p>",
294
+ md.render("This is *just* a test")
295
+ end
296
+ end
297
+
298
+ # Disabled by default
299
+ # (these are the easy ones -- the evil ones are not disclosed)
300
+ class PathologicalInputsTest # < Test::Unit::TestCase
301
+ def setup
302
+ @markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
303
+ end
304
+
305
+ def test_pathological_1
87
306
  star = '*' * 250000
88
- Redcarpet.new("#{star}#{star} hi #{star}#{star}").to_html
307
+ @markdown.render("#{star}#{star} hi #{star}#{star}")
89
308
  end
90
309
 
91
- def xtest_pathological_2
310
+ def test_pathological_2
92
311
  crt = '^' * 255
93
312
  str = "#{crt}(\\)"
94
- Redcarpet.new("#{str*300}").to_html
313
+ @markdown.render("#{str*300}")
95
314
  end
96
315
 
97
- def xtest_pathological_3
316
+ def test_pathological_3
98
317
  c = "`t`t`t`t`t`t" * 20000000
99
- Redcarpet.new(c).to_html
318
+ @markdown.render(c)
100
319
  end
101
320
 
102
- def xtest_pathological_4
103
- Redcarpet.new(" [^a]: #{ "A" * 10000 }\n#{ "[^a][]" * 1000000 }\n").to_html.size
321
+ def test_pathological_4
322
+ @markdown.render(" [^a]: #{ "A" * 10000 }\n#{ "[^a][]" * 1000000 }\n")
104
323
  end
105
324
 
325
+ def test_unbound_recursion
326
+ @markdown.render(("[" * 10000) + "foo" + ("](bar)" * 10000))
327
+ end
106
328
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redcarpet
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
- - 1
7
+ - 2
8
8
  - 0
9
9
  - 0
10
- version: 1.0.0
10
+ version: 2.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Natacha Port\xC3\xA9"
@@ -16,16 +16,28 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-03-29 00:00:00 +03:00
20
- default_executable:
21
- dependencies: []
22
-
23
- description:
19
+ date: 2011-09-14 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rake-compiler
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: A fast, safe and extensible Markdown to (X)HTML parser
24
36
  email: vicent@github.com
25
37
  executables:
26
38
  - redcarpet
27
39
  extensions:
28
- - ext/extconf.rb
40
+ - ext/redcarpet/extconf.rb
29
41
  extra_rdoc_files:
30
42
  - COPYING
31
43
  files:
@@ -33,23 +45,29 @@ files:
33
45
  - README.markdown
34
46
  - Rakefile
35
47
  - bin/redcarpet
36
- - ext/array.c
37
- - ext/array.h
38
- - ext/buffer.c
39
- - ext/buffer.h
40
- - ext/extconf.rb
41
- - ext/markdown.c
42
- - ext/markdown.h
43
- - ext/redcarpet.c
44
- - ext/render.c
45
- - lib/markdown.rb
48
+ - ext/redcarpet/autolink.c
49
+ - ext/redcarpet/autolink.h
50
+ - ext/redcarpet/buffer.c
51
+ - ext/redcarpet/buffer.h
52
+ - ext/redcarpet/extconf.rb
53
+ - ext/redcarpet/houdini.h
54
+ - ext/redcarpet/houdini_href_e.c
55
+ - ext/redcarpet/houdini_html_e.c
56
+ - ext/redcarpet/html.c
57
+ - ext/redcarpet/html.h
58
+ - ext/redcarpet/html_blocks.h
59
+ - ext/redcarpet/html_smartypants.c
60
+ - ext/redcarpet/markdown.c
61
+ - ext/redcarpet/markdown.h
62
+ - ext/redcarpet/rc_markdown.c
63
+ - ext/redcarpet/rc_render.c
64
+ - ext/redcarpet/redcarpet.h
65
+ - ext/redcarpet/stack.c
66
+ - ext/redcarpet/stack.h
46
67
  - lib/redcarpet.rb
68
+ - lib/redcarpet/render_man.rb
47
69
  - redcarpet.gemspec
48
- - test/benchmark.rb
49
- - test/benchmark.txt
50
- - test/markdown_test.rb
51
70
  - test/redcarpet_test.rb
52
- has_rdoc: true
53
71
  homepage: http://github.com/tanoku/redcarpet
54
72
  licenses: []
55
73
 
@@ -79,10 +97,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
97
  requirements: []
80
98
 
81
99
  rubyforge_project:
82
- rubygems_version: 1.6.2
100
+ rubygems_version: 1.8.6
83
101
  signing_key:
84
102
  specification_version: 3
85
- summary: Ruby bindings for libupskirt
103
+ summary: Markdown that smells nice
86
104
  test_files:
87
- - test/markdown_test.rb
88
105
  - test/redcarpet_test.rb