redcarpet 1.17.2 → 2.0.0b
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of redcarpet might be problematic. Click here for more details.
- data/README.markdown +232 -37
- data/Rakefile +13 -15
- data/bin/redcarpet +1 -1
- data/ext/redcarpet/autolink.c +5 -5
- data/ext/redcarpet/autolink.h +7 -4
- data/ext/redcarpet/html.c +83 -71
- data/ext/redcarpet/html.h +14 -5
- data/ext/redcarpet/html_smartypants.c +35 -11
- data/ext/redcarpet/markdown.c +153 -85
- data/ext/redcarpet/markdown.h +6 -10
- data/ext/redcarpet/rc_markdown.c +108 -0
- data/ext/redcarpet/rc_render.c +469 -0
- data/lib/redcarpet.rb +68 -106
- data/redcarpet.gemspec +8 -11
- data/test/redcarpet_test.rb +206 -122
- metadata +17 -18
- data/ext/redcarpet/redcarpet.c +0 -161
- data/lib/markdown.rb +0 -1
- data/test/benchmark.rb +0 -56
- data/test/benchmark.txt +0 -306
- data/test/markdown_test.rb +0 -186
data/lib/redcarpet.rb
CHANGED
@@ -1,112 +1,74 @@
|
|
1
|
-
|
2
|
-
# language. Upskirt is safe, fast and production ready.
|
3
|
-
#
|
4
|
-
# Redcarpet is Upskirt with a touch of Ruby. It is mostly based on Ryan
|
5
|
-
# Tomayko's RDiscount, and inspired by Rick Astley wearing a kilt.
|
6
|
-
#
|
7
|
-
# Redcarpet is a drop-in replacement for BlueCloth, RedCloth and RDiscount.
|
8
|
-
#
|
9
|
-
# == Usage
|
10
|
-
#
|
11
|
-
# Redcarpet implements the basic protocol popularized by RedCloth and adopted
|
12
|
-
# by BlueCloth:
|
13
|
-
# require 'redcarpet'
|
14
|
-
# markdown = Redcarpet.new("Hello World!")
|
15
|
-
# puts markdown.to_html
|
16
|
-
#
|
17
|
-
# == Replacing BlueCloth
|
18
|
-
#
|
19
|
-
# Inject Redcarpet into your BlueCloth-using code by replacing your bluecloth
|
20
|
-
# require statements with the following:
|
21
|
-
# begin
|
22
|
-
# require 'redcarpet'
|
23
|
-
# BlueCloth = Redcarpet
|
24
|
-
# rescue LoadError
|
25
|
-
# require 'bluecloth'
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
class Redcarpet
|
29
|
-
VERSION = '1.17.2'
|
30
|
-
|
31
|
-
# Original Markdown formatted text.
|
32
|
-
attr_reader :text
|
33
|
-
|
34
|
-
# Set true to have smarty-like quote translation performed.
|
35
|
-
attr_accessor :smart
|
36
|
-
|
37
|
-
# Do not output <tt><style></tt> tags included in the source text.
|
38
|
-
attr_accessor :filter_styles
|
39
|
-
|
40
|
-
# Do not output any raw HTML included in the source text.
|
41
|
-
attr_accessor :filter_html
|
42
|
-
|
43
|
-
# Do not process <tt>![]</tt> and remove <tt><img></tt> tags from the output.
|
44
|
-
attr_accessor :no_image
|
45
|
-
|
46
|
-
# Do not process <tt>[]</tt> and remove <tt><a></tt> tags from the output.
|
47
|
-
attr_accessor :no_links
|
48
|
-
|
49
|
-
# Treat newlines in paragraphs as real line breaks, GitHub style
|
50
|
-
attr_accessor :hard_wrap
|
51
|
-
|
52
|
-
# Generate safer HTML for code blocks (no custom CSS classes)
|
53
|
-
attr_accessor :gh_blockcode
|
54
|
-
|
55
|
-
# Don't make hyperlinks from <tt>[][]</tt> links that have unknown URL types.
|
56
|
-
attr_accessor :safelink
|
57
|
-
|
58
|
-
# Add TOC anchors to every header
|
59
|
-
attr_accessor :generate_toc
|
60
|
-
|
61
|
-
# Enable the Autolinking extension
|
62
|
-
attr_accessor :autolink
|
63
|
-
|
64
|
-
# Enable PHP-Markdown tables extension
|
65
|
-
attr_accessor :tables
|
66
|
-
|
67
|
-
# Enable PHP-Markdown ~~strikethrough~~ extension
|
68
|
-
attr_accessor :strikethrough
|
69
|
-
|
70
|
-
# Enable PHP-Markdown fenced code extension
|
71
|
-
attr_accessor :fenced_code
|
72
|
-
|
73
|
-
# Allow HTML blocks inside of paragraphs without being surrounded by newlines
|
74
|
-
attr_accessor :lax_htmlblock
|
75
|
-
|
76
|
-
# Do not render emphasis_inside_words
|
77
|
-
attr_accessor :no_intraemphasis
|
78
|
-
|
79
|
-
# Generate XHTML 1.0 compilant self-closing tags (e.g. <br/>)
|
80
|
-
attr_accessor :xhtml
|
81
|
-
|
82
|
-
# Force a space between header hashes and the header itself
|
83
|
-
attr_accessor :space_header
|
1
|
+
require 'redcarpet.so'
|
84
2
|
|
85
|
-
|
86
|
-
|
87
|
-
|
3
|
+
module Redcarpet
|
4
|
+
VERSION = '2.0.0b'
|
5
|
+
|
6
|
+
class Markdown
|
7
|
+
# Available Markdown extensions
|
8
|
+
attr_accessor :no_intra_emphasis
|
9
|
+
attr_accessor :tables
|
10
|
+
attr_accessor :fenced_code_blocks
|
11
|
+
attr_accessor :autolink
|
12
|
+
attr_accessor :strikethrough
|
13
|
+
attr_accessor :lax_html_blocks
|
14
|
+
attr_accessor :space_after_headers
|
15
|
+
attr_accessor :superscript
|
16
|
+
|
17
|
+
attr_accessor :renderer
|
18
|
+
|
19
|
+
def initialize(renderer, extensions={})
|
20
|
+
if renderer.instance_of? Class
|
21
|
+
renderer = renderer.new
|
22
|
+
end
|
23
|
+
|
24
|
+
@renderer = renderer
|
25
|
+
extensions.each_pair { |k, v| send("#{k}=", v) }
|
26
|
+
end
|
88
27
|
end
|
89
|
-
end
|
90
|
-
|
91
|
-
Markdown = Redcarpet unless defined? Markdown
|
92
28
|
|
93
|
-
|
94
|
-
|
95
|
-
#
|
96
|
-
class
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
29
|
+
module Render
|
30
|
+
|
31
|
+
# XHTML Renderer
|
32
|
+
class XHTML < HTML
|
33
|
+
def initialize(extensions={})
|
34
|
+
super(extensions.merge(:xhtml => true))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# HTML + SmartyPants renderer
|
39
|
+
class SmartyHTML < HTML
|
40
|
+
include SmartyPants
|
41
|
+
end
|
42
|
+
|
43
|
+
# SmartyPants Mixin module
|
44
|
+
#
|
45
|
+
# Implements SmartyPants.postprocess, which
|
46
|
+
# performs smartypants replacements on the HTML file,
|
47
|
+
# once it has been fully rendered.
|
48
|
+
#
|
49
|
+
# To add SmartyPants postprocessing to your custom
|
50
|
+
# renderers, just mixin the module `include SmartyPants`
|
51
|
+
#
|
52
|
+
# You can also use this as a standalone SmartyPants
|
53
|
+
# implementation.
|
54
|
+
#
|
55
|
+
# Example:
|
56
|
+
#
|
57
|
+
# # Mixin
|
58
|
+
# class CoolRenderer < HTML
|
59
|
+
# include SmartyPants
|
60
|
+
# # more code here
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# # Standalone
|
64
|
+
# Redcarpet::Render::SmartyPants.postprocess("you're")
|
65
|
+
#
|
66
|
+
module SmartyPants
|
67
|
+
extend self
|
68
|
+
def self.render(text)
|
69
|
+
postprocess text
|
70
|
+
end
|
71
|
+
end
|
109
72
|
end
|
110
73
|
end
|
111
74
|
|
112
|
-
require 'redcarpet.so'
|
data/redcarpet.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'redcarpet'
|
3
|
-
s.version = '
|
4
|
-
s.summary = "
|
5
|
-
s.description = 'A fast and
|
6
|
-
s.date = '2011-
|
3
|
+
s.version = '2.0.0b'
|
4
|
+
s.summary = "Markdown that smells nice"
|
5
|
+
s.description = 'A fast, safe and extensible Markdown to (X)HTML parser'
|
6
|
+
s.date = '2011-08-03'
|
7
7
|
s.email = 'vicent@github.com'
|
8
8
|
s.homepage = 'http://github.com/tanoku/redcarpet'
|
9
9
|
s.authors = ["Natacha Porté", "Vicent Martí"]
|
@@ -25,18 +25,15 @@ Gem::Specification.new do |s|
|
|
25
25
|
ext/redcarpet/html_smartypants.c
|
26
26
|
ext/redcarpet/markdown.c
|
27
27
|
ext/redcarpet/markdown.h
|
28
|
-
ext/redcarpet/
|
29
|
-
|
28
|
+
ext/redcarpet/rc_markdown.c
|
29
|
+
ext/redcarpet/rc_render.c
|
30
30
|
lib/redcarpet.rb
|
31
31
|
redcarpet.gemspec
|
32
|
-
|
33
|
-
test/benchmark.txt
|
34
|
-
test/markdown_test.rb
|
32
|
+
sundown
|
35
33
|
test/redcarpet_test.rb
|
36
|
-
upskirt
|
37
34
|
]
|
38
35
|
# = MANIFEST =
|
39
|
-
s.test_files = ["test/
|
36
|
+
s.test_files = ["test/redcarpet_test.rb"]
|
40
37
|
s.extra_rdoc_files = ["COPYING"]
|
41
38
|
s.extensions = ["ext/redcarpet/extconf.rb"]
|
42
39
|
s.executables = ["redcarpet"]
|
data/test/redcarpet_test.rb
CHANGED
@@ -1,139 +1,204 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
rootdir = File.dirname(File.dirname(__FILE__))
|
3
2
|
$LOAD_PATH.unshift "#{rootdir}/lib"
|
4
3
|
|
5
4
|
require 'test/unit'
|
6
5
|
require 'redcarpet'
|
6
|
+
require 'nokogiri'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def html_equal(html_a, html_b)
|
9
|
+
assert_equal Nokogiri::HTML::DocumentFragment.parse(html_a).to_html,
|
10
|
+
Nokogiri::HTML::DocumentFragment.parse(html_b).to_html
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
Redcarpet
|
13
|
+
class SmartyPantsTest < Test::Unit::TestCase
|
14
|
+
def setup
|
15
|
+
@pants = Redcarpet::Render::SmartyPants
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
18
|
+
def test_that_smart_converts_single_quotes_in_words_that_end_in_re
|
19
|
+
markdown = @pants.render("<p>They're not for sale.</p>")
|
20
|
+
html_equal "<p>They’re not for sale.</p>", markdown
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
23
|
+
def test_that_smart_converts_single_quotes_in_words_that_end_in_ll
|
24
|
+
markdown = @pants.render("<p>Well that'll be the day</p>")
|
25
|
+
html_equal "<p>Well that’ll be the day</p>", markdown
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
rd =
|
30
|
-
|
28
|
+
def test_that_smart_converts_double_quotes_to_curly_quotes
|
29
|
+
rd = @pants.render(%(<p>"Quoted text"</p>))
|
30
|
+
html_equal %(<p>“Quoted text”</p>), rd
|
31
31
|
end
|
32
32
|
|
33
33
|
def test_that_smart_gives_ve_suffix_a_rsquo
|
34
|
-
rd =
|
35
|
-
|
34
|
+
rd = @pants.render("<p>I've been meaning to tell you ..</p>")
|
35
|
+
html_equal "<p>I’ve been meaning to tell you ..</p>\n", rd
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_that_smart_gives_m_suffix_a_rsquo
|
39
|
-
rd =
|
40
|
-
|
39
|
+
rd = @pants.render("<p>I'm not kidding</p>")
|
40
|
+
html_equal "<p>I’m not kidding</p>\n", rd
|
41
41
|
end
|
42
42
|
|
43
43
|
def test_that_smart_gives_d_suffix_a_rsquo
|
44
|
-
rd =
|
45
|
-
|
44
|
+
rd = @pants.render("<p>what'd you say?</p>")
|
45
|
+
html_equal "<p>what’d you say?</p>\n", rd
|
46
46
|
end
|
47
|
+
end
|
47
48
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
49
|
+
class HTMLRenderTest < Test::Unit::TestCase
|
50
|
+
def setup
|
51
|
+
@markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
|
52
|
+
@rndr = {
|
53
|
+
:no_html => Redcarpet::Render::HTML.new(:filter_html => true),
|
54
|
+
:no_image => Redcarpet::Render::HTML.new(:no_image => true),
|
55
|
+
:no_links => Redcarpet::Render::HTML.new(:no_links => true),
|
56
|
+
:safe_links => Redcarpet::Render::HTML.new(:safe_links_only => true),
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_that_filter_html_works
|
61
|
+
markdown = @markdown.render_with(@rndr[:no_html], 'Through <em>NO</em> <script>DOUBLE NO</script>')
|
62
|
+
html_equal "<p>Through NO DOUBLE NO</p>", markdown
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_filter_html_doesnt_break_two_space_hard_break
|
66
|
+
markdown = @markdown.render_with(@rndr[:no_html], "Lorem, \nipsum\n")
|
67
|
+
html_equal "<p>Lorem,<br/>\nipsum</p>\n", markdown
|
54
68
|
end
|
55
69
|
|
56
70
|
def test_that_no_image_flag_works
|
57
|
-
rd =
|
58
|
-
assert rd
|
71
|
+
rd = @markdown.render_with(@rndr[:no_image], %(![dust mite](http://dust.mite/image.png) <img src="image.png" />))
|
72
|
+
assert rd !~ /<img/
|
59
73
|
end
|
60
74
|
|
61
75
|
def test_that_no_links_flag_works
|
62
|
-
rd =
|
63
|
-
assert rd
|
76
|
+
rd = @markdown.render_with(@rndr[:no_links], %([This link](http://example.net/) <a href="links.html">links</a>))
|
77
|
+
assert rd !~ /<a /
|
64
78
|
end
|
65
79
|
|
66
|
-
def
|
67
|
-
rd =
|
68
|
-
|
80
|
+
def test_that_safelink_flag_works
|
81
|
+
rd = @markdown.render_with(@rndr[:safe_links], "[IRC](irc://chat.freenode.org/#freenode)")
|
82
|
+
html_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>\n", rd
|
69
83
|
end
|
70
84
|
|
71
|
-
|
72
|
-
|
73
|
-
|
85
|
+
end
|
86
|
+
|
87
|
+
class MarkdownTest < Test::Unit::TestCase
|
88
|
+
|
89
|
+
def setup
|
90
|
+
@markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
|
74
91
|
end
|
75
92
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
93
|
+
def test_that_simple_one_liner_goes_to_html
|
94
|
+
assert_respond_to @markdown, :render
|
95
|
+
html_equal "<p>Hello World.</p>", @markdown.render("Hello World.")
|
79
96
|
end
|
80
97
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
98
|
+
def test_that_inline_markdown_goes_to_html
|
99
|
+
markdown = @markdown.render('_Hello World_!')
|
100
|
+
html_equal "<p><em>Hello World</em>!</p>", markdown
|
84
101
|
end
|
85
|
-
|
86
|
-
def
|
87
|
-
|
88
|
-
|
102
|
+
|
103
|
+
def test_that_inline_markdown_starts_and_ends_correctly
|
104
|
+
@markdown.no_intra_emphasis = true
|
105
|
+
markdown = @markdown.render('_start _ foo_bar bar_baz _ end_ *italic* **bold** <a>_blah_</a>')
|
106
|
+
|
107
|
+
html_equal "<p><em>start _ foo_bar bar_baz _ end</em> <em>italic</em> <strong>bold</strong> <a><em>blah</em></a></p>", markdown
|
108
|
+
|
109
|
+
markdown = @markdown.render("Run 'rake radiant:extensions:rbac_base:migrate'")
|
110
|
+
html_equal "<p>Run 'rake radiant:extensions:rbac_base:migrate'</p>", markdown
|
89
111
|
end
|
90
112
|
|
91
|
-
def
|
92
|
-
|
93
|
-
|
94
|
-
Redcarpet.new("#{str*300}").to_html
|
113
|
+
def test_that_urls_are_not_doubly_escaped
|
114
|
+
markdown = @markdown.render('[Page 2](/search?query=Markdown+Test&page=2)')
|
115
|
+
html_equal "<p><a href=\"/search?query=Markdown+Test&page=2\">Page 2</a></p>\n", markdown
|
95
116
|
end
|
96
117
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
118
|
+
def test_simple_inline_html
|
119
|
+
#markdown = Markdown.new("before\n\n<div>\n foo\n</div>\nafter")
|
120
|
+
markdown = @markdown.render("before\n\n<div>\n foo\n</div>\n\nafter")
|
121
|
+
html_equal "<p>before</p>\n\n<div>\n foo\n</div>\n\n<p>after</p>\n", markdown
|
100
122
|
end
|
101
123
|
|
102
|
-
def
|
103
|
-
|
124
|
+
def test_that_html_blocks_do_not_require_their_own_end_tag_line
|
125
|
+
markdown = @markdown.render("Para 1\n\n<div><pre>HTML block\n</pre></div>\n\nPara 2 [Link](#anchor)")
|
126
|
+
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",
|
127
|
+
markdown
|
104
128
|
end
|
105
129
|
|
106
|
-
|
107
|
-
|
130
|
+
# This isn't in the spec but is Markdown.pl behavior.
|
131
|
+
def test_block_quotes_preceded_by_spaces
|
132
|
+
markdown = @markdown.render(
|
133
|
+
"A wise man once said:\n\n" +
|
134
|
+
" > Isn't it wonderful just to be alive.\n"
|
135
|
+
)
|
136
|
+
html_equal "<p>A wise man once said:</p>\n\n" +
|
137
|
+
"<blockquote><p>Isn't it wonderful just to be alive.</p>\n</blockquote>\n",
|
138
|
+
markdown
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_para_before_block_html_should_not_wrap_in_p_tag
|
142
|
+
@markdown.lax_html_blocks = true
|
143
|
+
markdown = @markdown.render(
|
144
|
+
"Things to watch out for\n" +
|
145
|
+
"<ul>\n<li>Blah</li>\n</ul>\n")
|
108
146
|
|
109
|
-
|
110
|
-
markdown
|
147
|
+
html_equal "<p>Things to watch out for</p>\n\n" +
|
148
|
+
"<ul>\n<li>Blah</li>\n</ul>\n", markdown
|
111
149
|
end
|
112
150
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
151
|
+
# http://github.com/rtomayko/rdiscount/issues/#issue/13
|
152
|
+
def test_headings_with_trailing_space
|
153
|
+
text = "The Ant-Sugar Tales \n" +
|
154
|
+
"=================== \n\n" +
|
155
|
+
"By Candice Yellowflower \n"
|
156
|
+
html_equal "<h1>The Ant-Sugar Tales </h1>\n\n<p>By Candice Yellowflower </p>\n", @markdown.render(text)
|
117
157
|
end
|
118
158
|
|
119
|
-
def
|
120
|
-
rd =
|
121
|
-
|
122
|
-
|
159
|
+
def test_that_intra_emphasis_works
|
160
|
+
rd = @markdown.render("foo_bar_baz")
|
161
|
+
html_equal "<p>foo<em>bar</em>baz</p>\n", rd
|
162
|
+
|
163
|
+
@markdown.no_intra_emphasis = true
|
164
|
+
rd = @markdown.render("foo_bar_baz")
|
165
|
+
html_equal "<p>foo_bar_baz</p>\n", rd
|
123
166
|
end
|
124
167
|
|
125
|
-
def
|
126
|
-
|
127
|
-
|
128
|
-
|
168
|
+
def test_that_autolink_flag_works
|
169
|
+
@markdown.autolink = true
|
170
|
+
rd = @markdown.render("http://github.com/rtomayko/rdiscount")
|
171
|
+
html_equal "<p><a href=\"http://github.com/rtomayko/rdiscount\">http://github.com/rtomayko/rdiscount</a></p>\n", rd
|
129
172
|
end
|
130
173
|
|
131
|
-
|
132
|
-
|
174
|
+
if "".respond_to?(:encoding)
|
175
|
+
def test_should_return_string_in_same_encoding_as_input
|
176
|
+
input = "Yogācāra"
|
177
|
+
output = @markdown.render(input)
|
178
|
+
assert_equal input.encoding.name, output.encoding.name
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_that_tags_can_have_dashes_and_underscores
|
183
|
+
rd = @markdown.render("foo <asdf-qwerty>bar</asdf-qwerty> and <a_b>baz</a_b>")
|
184
|
+
html_equal "<p>foo <asdf-qwerty>bar</asdf-qwerty> and <a_b>baz</a_b></p>\n", rd
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_link_syntax_is_not_processed_within_code_blocks
|
188
|
+
markdown = @markdown.render(" This is a code block\n This is a link [[1]] inside\n")
|
189
|
+
html_equal "<pre><code>This is a code block\nThis is a link [[1]] inside\n</code></pre>\n",
|
190
|
+
markdown
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_whitespace_after_urls
|
194
|
+
@markdown.autolink = true
|
195
|
+
rd = @markdown.render("Japan: http://www.abc.net.au/news/events/japan-quake-2011/beforeafter.htm (yes, japan)")
|
196
|
+
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>}
|
197
|
+
html_equal exp, rd
|
133
198
|
end
|
134
199
|
|
135
200
|
def test_memory_leak_when_parsing_char_links
|
136
|
-
|
201
|
+
@markdown.render(<<-leaks)
|
137
202
|
2. Identify the wild-type cluster and determine all clusters
|
138
203
|
containing or contained by it:
|
139
204
|
|
@@ -148,7 +213,7 @@ class RedcarpetTest < Test::Unit::TestCase
|
|
148
213
|
end
|
149
214
|
|
150
215
|
def test_infinite_loop_in_header
|
151
|
-
|
216
|
+
html_equal @markdown.render(<<-header), "<h1>Body</h1>"
|
152
217
|
######
|
153
218
|
#Body#
|
154
219
|
######
|
@@ -162,14 +227,19 @@ class RedcarpetTest < Test::Unit::TestCase
|
|
162
227
|
hello|sailor
|
163
228
|
EOS
|
164
229
|
|
165
|
-
assert
|
166
|
-
|
230
|
+
assert @markdown.render(text) !~ /<table/
|
231
|
+
|
232
|
+
@markdown.tables = true
|
233
|
+
assert @markdown.render(text) =~ /<table/
|
167
234
|
end
|
168
235
|
|
169
236
|
def test_strikethrough_flag_works
|
170
237
|
text = "this is ~some~ striked ~~text~~"
|
171
|
-
|
172
|
-
assert
|
238
|
+
|
239
|
+
assert @markdown.render(text) !~ /<del/
|
240
|
+
|
241
|
+
@markdown.strikethrough = true
|
242
|
+
assert @markdown.render(text) =~ /<del/
|
173
243
|
end
|
174
244
|
|
175
245
|
def test_that_fenced_flag_works
|
@@ -182,60 +252,74 @@ This is some awesome code
|
|
182
252
|
~~~
|
183
253
|
fenced
|
184
254
|
|
185
|
-
assert
|
186
|
-
|
255
|
+
assert @markdown.render(text) !~ /<code/
|
256
|
+
|
257
|
+
@markdown.fenced_code_blocks = true
|
258
|
+
assert @markdown.render(text) =~ /<code/
|
187
259
|
end
|
188
260
|
|
189
|
-
def
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
with custom CSS classes
|
194
|
-
~~~~~
|
195
|
-
fenced
|
261
|
+
def test_that_headers_are_linkable
|
262
|
+
markdown = @markdown.render('### Hello [GitHub](http://github.com)')
|
263
|
+
html_equal "<h3>Hello <a href=\"http://github.com\">GitHub</a></h3>", markdown
|
264
|
+
end
|
196
265
|
|
197
|
-
|
198
|
-
|
266
|
+
def test_autolinking_with_ent_chars
|
267
|
+
@markdown.autolink = true
|
268
|
+
markdown = @markdown.render(<<text)
|
269
|
+
This a stupid link: https://github.com/rtomayko/tilt/issues?milestone=1&state=open
|
270
|
+
text
|
271
|
+
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&state=open</a></p>\n", markdown
|
199
272
|
end
|
200
273
|
|
201
|
-
def
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
274
|
+
def test_spaced_headers
|
275
|
+
@markdown.space_after_headers = true
|
276
|
+
rd = @markdown.render("#123 a header yes\n")
|
277
|
+
assert rd !~ /<h1>/
|
278
|
+
end
|
279
|
+
end
|
206
280
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
281
|
+
class CustomRenderTest < Test::Unit::TestCase
|
282
|
+
class SimpleRender < Redcarpet::Render::HTML
|
283
|
+
def emphasis(text)
|
284
|
+
"<em class=\"cool\">#{text}</em>"
|
285
|
+
end
|
212
286
|
end
|
213
287
|
|
214
|
-
def
|
215
|
-
|
216
|
-
|
288
|
+
def test_simple_overload
|
289
|
+
md = Redcarpet::Markdown.new(SimpleRender)
|
290
|
+
html_equal "<p>This is <em class=\"cool\">just</em> a test</p>",
|
291
|
+
md.render("This is *just* a test")
|
217
292
|
end
|
293
|
+
end
|
218
294
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
295
|
+
# Disabled by default
|
296
|
+
# (these are the easy ones -- the evil ones are not disclosed)
|
297
|
+
class PathologicalInputsTest # < Test::Unit::TestCase
|
298
|
+
def setup
|
299
|
+
@markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
|
300
|
+
end
|
301
|
+
|
302
|
+
def test_pathological_1
|
303
|
+
star = '*' * 250000
|
304
|
+
@markdown.render("#{star}#{star} hi #{star}#{star}")
|
224
305
|
end
|
225
306
|
|
226
|
-
def
|
227
|
-
|
228
|
-
|
229
|
-
|
307
|
+
def test_pathological_2
|
308
|
+
crt = '^' * 255
|
309
|
+
str = "#{crt}(\\)"
|
310
|
+
@markdown.render("#{str*300}")
|
311
|
+
end
|
230
312
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
assert rd.to_html =~ /<br>/
|
313
|
+
def test_pathological_3
|
314
|
+
c = "`t`t`t`t`t`t" * 20000000
|
315
|
+
@markdown.render(c)
|
235
316
|
end
|
236
317
|
|
237
|
-
def
|
238
|
-
|
239
|
-
|
318
|
+
def test_pathological_4
|
319
|
+
@markdown.render(" [^a]: #{ "A" * 10000 }\n#{ "[^a][]" * 1000000 }\n")
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_unbound_recursion
|
323
|
+
@markdown.render(("[" * 10000) + "foo" + ("](bar)" * 10000))
|
240
324
|
end
|
241
325
|
end
|