redcarpet 2.2.2 → 2.3.0
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/Gemfile +1 -1
- data/README.markdown +155 -132
- data/Rakefile +6 -119
- data/ext/redcarpet/buffer.h +3 -10
- data/ext/redcarpet/extconf.rb +2 -0
- data/ext/redcarpet/html.c +32 -3
- data/ext/redcarpet/html.h +1 -0
- data/ext/redcarpet/html_smartypants.c +55 -5
- data/ext/redcarpet/markdown.c +20 -17
- data/ext/redcarpet/markdown.h +3 -0
- data/ext/redcarpet/rc_markdown.c +9 -2
- data/ext/redcarpet/rc_render.c +23 -5
- data/ext/redcarpet/redcarpet.h +1 -1
- data/ext/redcarpet/stack.c +8 -8
- data/ext/redcarpet/stack.h +6 -6
- data/lib/redcarpet.rb +3 -2
- data/lib/redcarpet/render_strip.rb +12 -4
- data/redcarpet.gemspec +16 -5
- data/test/custom_render_test.rb +28 -0
- data/test/html_render_test.rb +92 -0
- data/test/{redcarpet_test.rb → markdown_test.rb} +53 -240
- data/test/pathological_inputs_test.rb +34 -0
- data/test/redcarpet_compat_test.rb +38 -0
- data/test/smarty_html_test.rb +30 -0
- data/test/smarty_pants_test.rb +43 -0
- data/test/stripdown_render_test.rb +31 -0
- data/test/test_helper.rb +16 -0
- metadata +116 -66
- data/Gemfile.lock +0 -20
data/ext/redcarpet/redcarpet.h
CHANGED
data/ext/redcarpet/stack.c
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#include <string.h>
|
3
3
|
|
4
4
|
int
|
5
|
-
|
5
|
+
redcarpet_stack_grow(struct stack *st, size_t new_size)
|
6
6
|
{
|
7
7
|
void **new_st;
|
8
8
|
|
@@ -26,7 +26,7 @@ stack_grow(struct stack *st, size_t new_size)
|
|
26
26
|
}
|
27
27
|
|
28
28
|
void
|
29
|
-
|
29
|
+
redcarpet_stack_free(struct stack *st)
|
30
30
|
{
|
31
31
|
if (!st)
|
32
32
|
return;
|
@@ -39,7 +39,7 @@ stack_free(struct stack *st)
|
|
39
39
|
}
|
40
40
|
|
41
41
|
int
|
42
|
-
|
42
|
+
redcarpet_stack_init(struct stack *st, size_t initial_size)
|
43
43
|
{
|
44
44
|
st->item = NULL;
|
45
45
|
st->size = 0;
|
@@ -48,11 +48,11 @@ stack_init(struct stack *st, size_t initial_size)
|
|
48
48
|
if (!initial_size)
|
49
49
|
initial_size = 8;
|
50
50
|
|
51
|
-
return
|
51
|
+
return redcarpet_stack_grow(st, initial_size);
|
52
52
|
}
|
53
53
|
|
54
54
|
void *
|
55
|
-
|
55
|
+
redcarpet_stack_pop(struct stack *st)
|
56
56
|
{
|
57
57
|
if (!st->size)
|
58
58
|
return NULL;
|
@@ -61,9 +61,9 @@ stack_pop(struct stack *st)
|
|
61
61
|
}
|
62
62
|
|
63
63
|
int
|
64
|
-
|
64
|
+
redcarpet_stack_push(struct stack *st, void *item)
|
65
65
|
{
|
66
|
-
if (
|
66
|
+
if (redcarpet_stack_grow(st, st->size * 2) < 0)
|
67
67
|
return -1;
|
68
68
|
|
69
69
|
st->item[st->size++] = item;
|
@@ -71,7 +71,7 @@ stack_push(struct stack *st, void *item)
|
|
71
71
|
}
|
72
72
|
|
73
73
|
void *
|
74
|
-
|
74
|
+
redcarpet_stack_top(struct stack *st)
|
75
75
|
{
|
76
76
|
if (!st->size)
|
77
77
|
return NULL;
|
data/ext/redcarpet/stack.h
CHANGED
@@ -13,14 +13,14 @@ struct stack {
|
|
13
13
|
size_t asize;
|
14
14
|
};
|
15
15
|
|
16
|
-
void
|
17
|
-
int
|
18
|
-
int
|
16
|
+
void redcarpet_stack_free(struct stack *);
|
17
|
+
int redcarpet_stack_grow(struct stack *, size_t);
|
18
|
+
int redcarpet_stack_init(struct stack *, size_t);
|
19
19
|
|
20
|
-
int
|
20
|
+
int redcarpet_stack_push(struct stack *, void *);
|
21
21
|
|
22
|
-
void *
|
23
|
-
void *
|
22
|
+
void *redcarpet_stack_pop(struct stack *);
|
23
|
+
void *redcarpet_stack_top(struct stack *);
|
24
24
|
|
25
25
|
#ifdef __cplusplus
|
26
26
|
}
|
data/lib/redcarpet.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'redcarpet.so'
|
2
2
|
|
3
3
|
module Redcarpet
|
4
|
-
VERSION = '2.
|
4
|
+
VERSION = '2.3.0'
|
5
5
|
|
6
6
|
class Markdown
|
7
7
|
attr_reader :renderer
|
@@ -77,6 +77,7 @@ class RedcarpetCompat
|
|
77
77
|
:fenced_code => :fenced_code_blocks,
|
78
78
|
:filter_html => :filter_html,
|
79
79
|
:hard_wrap => :hard_wrap,
|
80
|
+
:prettify => :prettify,
|
80
81
|
:lax_htmlblock => :lax_spacing,
|
81
82
|
:no_image => :no_images,
|
82
83
|
:no_intraemphasis => :no_intra_emphasis,
|
@@ -96,7 +97,7 @@ class RedcarpetCompat
|
|
96
97
|
}
|
97
98
|
|
98
99
|
RENDERER_OPTIONS = [:filter_html, :no_images, :no_links, :no_styles,
|
99
|
-
:safe_links_only, :with_toc_data, :hard_wrap, :xhtml]
|
100
|
+
:safe_links_only, :with_toc_data, :hard_wrap, :prettify, :xhtml]
|
100
101
|
|
101
102
|
def rename_extensions(exts)
|
102
103
|
exts.map do |old_name|
|
@@ -8,13 +8,13 @@ module Redcarpet
|
|
8
8
|
[
|
9
9
|
# block-level calls
|
10
10
|
:block_code, :block_quote,
|
11
|
-
:block_html, :
|
12
|
-
:list_item, :paragraph,
|
11
|
+
:block_html, :list, :list_item,
|
13
12
|
|
14
13
|
# span-level calls
|
15
14
|
:autolink, :codespan, :double_emphasis,
|
16
|
-
:emphasis, :
|
17
|
-
:
|
15
|
+
:emphasis, :underline, :raw_html,
|
16
|
+
:triple_emphasis, :strikethrough,
|
17
|
+
:superscript,
|
18
18
|
|
19
19
|
# low level rendering
|
20
20
|
:entity, :normal_text
|
@@ -28,6 +28,14 @@ module Redcarpet
|
|
28
28
|
def link(link, title, content)
|
29
29
|
content
|
30
30
|
end
|
31
|
+
|
32
|
+
def paragraph(text)
|
33
|
+
text + "\n"
|
34
|
+
end
|
35
|
+
|
36
|
+
def header(text, header_level)
|
37
|
+
text + "\n"
|
38
|
+
end
|
31
39
|
end
|
32
40
|
end
|
33
41
|
end
|
data/redcarpet.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = 'redcarpet'
|
4
|
-
s.version = '2.
|
4
|
+
s.version = '2.3.0'
|
5
5
|
s.summary = "Markdown that smells nice"
|
6
6
|
s.description = 'A fast, safe and extensible Markdown to (X)HTML parser'
|
7
|
-
s.date = '
|
7
|
+
s.date = '2013-05-22'
|
8
8
|
s.email = 'vicent@github.com'
|
9
9
|
s.homepage = 'http://github.com/vmg/redcarpet'
|
10
10
|
s.authors = ["Natacha Porté", "Vicent Martí"]
|
@@ -12,7 +12,6 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.files = %w[
|
13
13
|
COPYING
|
14
14
|
Gemfile
|
15
|
-
Gemfile.lock
|
16
15
|
README.markdown
|
17
16
|
Rakefile
|
18
17
|
bin/redcarpet
|
@@ -41,14 +40,26 @@ Gem::Specification.new do |s|
|
|
41
40
|
lib/redcarpet/render_strip.rb
|
42
41
|
redcarpet.gemspec
|
43
42
|
sundown
|
44
|
-
test/
|
43
|
+
test/test_helper.rb
|
44
|
+
test/custom_render_test.rb
|
45
|
+
test/html_render_test.rb
|
46
|
+
test/markdown_test.rb
|
47
|
+
test/pathological_inputs_test.rb
|
48
|
+
test/redcarpet_compat_test.rb
|
49
|
+
test/smarty_html_test.rb
|
50
|
+
test/smarty_pants_test.rb
|
51
|
+
test/stripdown_render_test.rb
|
45
52
|
]
|
46
53
|
# = MANIFEST =
|
47
|
-
s.test_files =
|
54
|
+
s.test_files = s.files.grep(%r{^test/})
|
48
55
|
s.extra_rdoc_files = ["COPYING"]
|
49
56
|
s.extensions = ["ext/redcarpet/extconf.rb"]
|
50
57
|
s.executables = ["redcarpet"]
|
51
58
|
s.require_paths = ["lib"]
|
59
|
+
|
52
60
|
s.add_development_dependency "nokogiri"
|
53
61
|
s.add_development_dependency "rake-compiler"
|
62
|
+
s.add_development_dependency "test-unit"
|
63
|
+
s.add_development_dependency "bluecloth"
|
64
|
+
s.add_development_dependency "kramdown"
|
54
65
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class CustomRenderTest < Test::Unit::TestCase
|
5
|
+
class SimpleRender < Redcarpet::Render::HTML
|
6
|
+
def emphasis(text)
|
7
|
+
"<em class=\"cool\">#{text}</em>"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_simple_overload
|
12
|
+
md = Redcarpet::Markdown.new(SimpleRender)
|
13
|
+
html_equal "<p>This is <em class=\"cool\">just</em> a test</p>\n",
|
14
|
+
md.render("This is *just* a test")
|
15
|
+
end
|
16
|
+
|
17
|
+
class NilPreprocessRenderer < Redcarpet::Render::HTML
|
18
|
+
def preprocess(fulldoc)
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_preprocess_returning_nil
|
24
|
+
md = Redcarpet::Markdown.new(NilPreprocessRenderer)
|
25
|
+
assert_equal(nil,md.render("Anything"))
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class HTMLRenderTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
|
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
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def render_with(rndr, text)
|
18
|
+
Redcarpet::Markdown.new(rndr).render(text)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Hint: overrides filter_html, no_images and no_links
|
22
|
+
def test_that_escape_html_works
|
23
|
+
source = <<EOS
|
24
|
+
Through <em>NO</em> <script>DOUBLE NO</script>
|
25
|
+
|
26
|
+
<script>BAD</script>
|
27
|
+
|
28
|
+
<img src="/favicon.ico" />
|
29
|
+
EOS
|
30
|
+
expected = <<EOE
|
31
|
+
<p>Through <em>NO</em> <script>DOUBLE NO</script></p>
|
32
|
+
|
33
|
+
<p><script>BAD</script></p>
|
34
|
+
|
35
|
+
<p><img src="/favicon.ico" /></p>
|
36
|
+
EOE
|
37
|
+
|
38
|
+
markdown = render_with(@rndr[:escape_html], source)
|
39
|
+
html_equal expected, markdown
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_that_filter_html_works
|
43
|
+
markdown = render_with(@rndr[:no_html], 'Through <em>NO</em> <script>DOUBLE NO</script>')
|
44
|
+
html_equal "<p>Through NO DOUBLE NO</p>\n", markdown
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_filter_html_doesnt_break_two_space_hard_break
|
48
|
+
markdown = render_with(@rndr[:no_html], "Lorem, \nipsum\n")
|
49
|
+
html_equal "<p>Lorem,<br/>\nipsum</p>\n", markdown
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_that_no_image_flag_works
|
53
|
+
rd = render_with(@rndr[:no_images], %(![dust mite](http://dust.mite/image.png) <img src="image.png" />))
|
54
|
+
assert rd !~ /<img/
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_that_no_links_flag_works
|
58
|
+
rd = render_with(@rndr[:no_links], %([This link](http://example.net/) <a href="links.html">links</a>))
|
59
|
+
assert rd !~ /<a /
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_that_safelink_flag_works
|
63
|
+
rd = render_with(@rndr[:safe_links], "[IRC](irc://chat.freenode.org/#freenode)")
|
64
|
+
html_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>\n", rd
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_that_hard_wrap_works
|
68
|
+
rd = render_with(@rndr[:hard_wrap], <<EOE)
|
69
|
+
Hello world,
|
70
|
+
this is just a simple test
|
71
|
+
|
72
|
+
With hard wraps
|
73
|
+
and other *things*.
|
74
|
+
EOE
|
75
|
+
|
76
|
+
assert rd =~ /<br>/
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_that_link_attributes_work
|
80
|
+
rndr = Redcarpet::Render::HTML.new(:link_attributes => {:rel => 'blank'})
|
81
|
+
md = Redcarpet::Markdown.new(rndr)
|
82
|
+
assert md.render('This is a [simple](http://test.com) test.').include?('rel="blank"')
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_that_link_works_with_quotes
|
86
|
+
rd = render_with(Redcarpet::Render::HTML.new, %([This'link"is](http://example.net/)))
|
87
|
+
assert_equal "<p><a href=\"http://example.net/\">This'link"is</a></p>\n", rd
|
88
|
+
|
89
|
+
rd = render_with(@rndr[:escape_html], %([This'link"is](http://example.net/)))
|
90
|
+
assert_equal "<p><a href=\"http://example.net/\">This'link"is</a></p>\n", rd
|
91
|
+
end
|
92
|
+
end
|
@@ -1,139 +1,5 @@
|
|
1
1
|
# coding: UTF-8
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift "#{rootdir}/lib"
|
4
|
-
|
5
|
-
if defined? Encoding
|
6
|
-
Encoding.default_internal = 'UTF-8'
|
7
|
-
end
|
8
|
-
|
9
|
-
require 'test/unit'
|
10
|
-
require 'redcarpet'
|
11
|
-
require 'redcarpet/render_man'
|
12
|
-
require 'nokogiri'
|
13
|
-
|
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
|
18
|
-
|
19
|
-
class SmartyPantsTest < Test::Unit::TestCase
|
20
|
-
def setup
|
21
|
-
@pants = Redcarpet::Render::SmartyPants
|
22
|
-
end
|
23
|
-
|
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’re not for sale.</p>", markdown
|
27
|
-
end
|
28
|
-
|
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’ll be the day</p>", markdown
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_that_smart_converts_double_quotes_to_curly_quotes
|
35
|
-
rd = @pants.render(%(<p>"Quoted text"</p>))
|
36
|
-
assert_equal %(<p>“Quoted text”</p>), rd
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_that_smart_gives_ve_suffix_a_rsquo
|
40
|
-
rd = @pants.render("<p>I've been meaning to tell you ..</p>")
|
41
|
-
assert_equal "<p>I’ve been meaning to tell you ..</p>", rd
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_that_smart_gives_m_suffix_a_rsquo
|
45
|
-
rd = @pants.render("<p>I'm not kidding</p>")
|
46
|
-
assert_equal "<p>I’m not kidding</p>", rd
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_that_smart_gives_d_suffix_a_rsquo
|
50
|
-
rd = @pants.render("<p>what'd you say?</p>")
|
51
|
-
assert_equal "<p>what’d you say?</p>", rd
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
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
|
-
:escape_html => Redcarpet::Render::HTML.new(:escape_html => true),
|
64
|
-
:hard_wrap => Redcarpet::Render::HTML.new(:hard_wrap => true),
|
65
|
-
}
|
66
|
-
end
|
67
|
-
|
68
|
-
def render_with(rndr, text)
|
69
|
-
Redcarpet::Markdown.new(rndr).render(text)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Hint: overrides filter_html, no_images and no_links
|
73
|
-
def test_that_escape_html_works
|
74
|
-
source = <<EOS
|
75
|
-
Through <em>NO</em> <script>DOUBLE NO</script>
|
76
|
-
|
77
|
-
<script>BAD</script>
|
78
|
-
|
79
|
-
<img src="/favicon.ico" />
|
80
|
-
EOS
|
81
|
-
expected = <<EOE
|
82
|
-
<p>Through <em>NO</em> <script>DOUBLE NO</script></p>
|
83
|
-
|
84
|
-
<p><script>BAD</script></p>
|
85
|
-
|
86
|
-
<p><img src="/favicon.ico" />
|
87
|
-
|
88
|
-
EOE
|
89
|
-
|
90
|
-
markdown = render_with(@rndr[:escape_html], source)
|
91
|
-
html_equal expected, markdown
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_that_filter_html_works
|
95
|
-
markdown = render_with(@rndr[:no_html], 'Through <em>NO</em> <script>DOUBLE NO</script>')
|
96
|
-
html_equal "<p>Through NO DOUBLE NO</p>", markdown
|
97
|
-
end
|
98
|
-
|
99
|
-
def test_filter_html_doesnt_break_two_space_hard_break
|
100
|
-
markdown = render_with(@rndr[:no_html], "Lorem, \nipsum\n")
|
101
|
-
html_equal "<p>Lorem,<br/>\nipsum</p>\n", markdown
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_that_no_image_flag_works
|
105
|
-
rd = render_with(@rndr[:no_images], %(![dust mite](http://dust.mite/image.png) <img src="image.png" />))
|
106
|
-
assert rd !~ /<img/
|
107
|
-
end
|
108
|
-
|
109
|
-
def test_that_no_links_flag_works
|
110
|
-
rd = render_with(@rndr[:no_links], %([This link](http://example.net/) <a href="links.html">links</a>))
|
111
|
-
assert rd !~ /<a /
|
112
|
-
end
|
113
|
-
|
114
|
-
def test_that_safelink_flag_works
|
115
|
-
rd = render_with(@rndr[:safe_links], "[IRC](irc://chat.freenode.org/#freenode)")
|
116
|
-
html_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>\n", rd
|
117
|
-
end
|
118
|
-
|
119
|
-
def test_that_hard_wrap_works
|
120
|
-
rd = render_with(@rndr[:hard_wrap], <<EOE)
|
121
|
-
Hello world,
|
122
|
-
this is just a simple test
|
123
|
-
|
124
|
-
With hard wraps
|
125
|
-
and other *things*.
|
126
|
-
EOE
|
127
|
-
|
128
|
-
assert rd =~ /<br>/
|
129
|
-
end
|
130
|
-
|
131
|
-
def test_that_link_attributes_work
|
132
|
-
rndr = Redcarpet::Render::HTML.new(:link_attributes => {:rel => 'blank'})
|
133
|
-
md = Redcarpet::Markdown.new(rndr)
|
134
|
-
assert md.render('This is a [simple](http://test.com) test.').include?('rel="blank"')
|
135
|
-
end
|
136
|
-
end
|
2
|
+
require 'test_helper'
|
137
3
|
|
138
4
|
class MarkdownTest < Test::Unit::TestCase
|
139
5
|
|
@@ -147,21 +13,21 @@ class MarkdownTest < Test::Unit::TestCase
|
|
147
13
|
|
148
14
|
def test_that_simple_one_liner_goes_to_html
|
149
15
|
assert_respond_to @markdown, :render
|
150
|
-
html_equal "<p>Hello World.</p
|
16
|
+
html_equal "<p>Hello World.</p>\n", @markdown.render("Hello World.")
|
151
17
|
end
|
152
18
|
|
153
19
|
def test_that_inline_markdown_goes_to_html
|
154
20
|
markdown = @markdown.render('_Hello World_!')
|
155
|
-
html_equal "<p><em>Hello World</em>!</p
|
21
|
+
html_equal "<p><em>Hello World</em>!</p>\n", markdown
|
156
22
|
end
|
157
23
|
|
158
24
|
def test_that_inline_markdown_starts_and_ends_correctly
|
159
25
|
markdown = render_with({:no_intra_emphasis => true}, '_start _ foo_bar bar_baz _ end_ *italic* **bold** <a>_blah_</a>')
|
160
26
|
|
161
|
-
html_equal "<p><em>start _ foo_bar bar_baz _ end</em> <em>italic</em> <strong>bold</strong> <a><em>blah</em></a></p
|
27
|
+
html_equal "<p><em>start _ foo_bar bar_baz _ end</em> <em>italic</em> <strong>bold</strong> <a><em>blah</em></a></p>\n", markdown
|
162
28
|
|
163
29
|
markdown = @markdown.render("Run 'rake radiant:extensions:rbac_base:migrate'")
|
164
|
-
html_equal "<p>Run 'rake radiant:extensions:rbac_base:migrate'</p
|
30
|
+
html_equal "<p>Run 'rake radiant:extensions:rbac_base:migrate'</p>\n", markdown
|
165
31
|
end
|
166
32
|
|
167
33
|
def test_that_urls_are_not_doubly_escaped
|
@@ -234,7 +100,7 @@ class MarkdownTest < Test::Unit::TestCase
|
|
234
100
|
output = @markdown.render(input)
|
235
101
|
assert_equal input.encoding.name, output.encoding.name
|
236
102
|
end
|
237
|
-
|
103
|
+
|
238
104
|
def test_should_accept_non_utf8_or_ascii
|
239
105
|
input = "testing \xAB\xCD".force_encoding('ASCII-8BIT')
|
240
106
|
output = @markdown.render(input)
|
@@ -255,7 +121,7 @@ class MarkdownTest < Test::Unit::TestCase
|
|
255
121
|
|
256
122
|
def test_whitespace_after_urls
|
257
123
|
rd = render_with({:autolink => true}, "Japan: http://www.abc.net.au/news/events/japan-quake-2011/beforeafter.htm (yes, japan)")
|
258
|
-
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
|
124
|
+
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>\n}
|
259
125
|
html_equal exp, rd
|
260
126
|
end
|
261
127
|
|
@@ -263,19 +129,19 @@ class MarkdownTest < Test::Unit::TestCase
|
|
263
129
|
@markdown.render(<<-leaks)
|
264
130
|
2. Identify the wild-type cluster and determine all clusters
|
265
131
|
containing or contained by it:
|
266
|
-
|
132
|
+
|
267
133
|
wildtype <- wildtype.cluster(h)
|
268
134
|
wildtype.mask <- logical(nclust)
|
269
135
|
wildtype.mask[c(contains(h, wildtype),
|
270
136
|
wildtype,
|
271
137
|
contained.by(h, wildtype))] <- TRUE
|
272
|
-
|
138
|
+
|
273
139
|
This could be more elegant.
|
274
140
|
leaks
|
275
141
|
end
|
276
142
|
|
277
143
|
def test_infinite_loop_in_header
|
278
|
-
html_equal @markdown.render(<<-header)
|
144
|
+
html_equal "<h1>Body</h1>\n", @markdown.render(<<-header)
|
279
145
|
######
|
280
146
|
#Body#
|
281
147
|
######
|
@@ -294,6 +160,18 @@ EOS
|
|
294
160
|
assert render_with({:tables => true}, text) =~ /<table/
|
295
161
|
end
|
296
162
|
|
163
|
+
def test_that_tables_work_with_org_table_syntax
|
164
|
+
text = <<EOS
|
165
|
+
| aaa | bbbb |
|
166
|
+
|-----+------|
|
167
|
+
|hello|sailor|
|
168
|
+
EOS
|
169
|
+
|
170
|
+
assert render_with({}, text) !~ /<table/
|
171
|
+
|
172
|
+
assert render_with({:tables => true}, text) =~ /<table/
|
173
|
+
end
|
174
|
+
|
297
175
|
def test_strikethrough_flag_works
|
298
176
|
text = "this is ~some~ striked ~~text~~"
|
299
177
|
|
@@ -302,6 +180,16 @@ EOS
|
|
302
180
|
assert render_with({:strikethrough => true}, text) =~ /<del/
|
303
181
|
end
|
304
182
|
|
183
|
+
def test_underline_flag_works
|
184
|
+
text = "this is *some* text that is _underlined_. ___boom___"
|
185
|
+
|
186
|
+
refute render_with({}, text).include? '<u>underlined</u>'
|
187
|
+
|
188
|
+
output = render_with({:underline => true}, text)
|
189
|
+
assert output.include? '<u>underlined</u>'
|
190
|
+
assert output.include? '<em>some</em>'
|
191
|
+
end
|
192
|
+
|
305
193
|
def test_that_fenced_flag_works
|
306
194
|
text = <<fenced
|
307
195
|
This is a simple test
|
@@ -326,9 +214,29 @@ fenced
|
|
326
214
|
assert !out.include?("<pre><code>")
|
327
215
|
end
|
328
216
|
|
217
|
+
def test_that_prettify_works
|
218
|
+
text = "foo\nbar\n```\nsome\ncode\n```\nbaz"
|
219
|
+
out = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(:prettify => true), :fenced_code_blocks => true).render(text)
|
220
|
+
assert !out.include?("<pre><code class=\"prettyprint\">")
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_that_indented_flag_works
|
224
|
+
text = <<indented
|
225
|
+
This is a simple text
|
226
|
+
|
227
|
+
This is some awesome code
|
228
|
+
with shit
|
229
|
+
|
230
|
+
And this is again a simple text
|
231
|
+
indented
|
232
|
+
|
233
|
+
assert render_with({}, text) =~ /<code/
|
234
|
+
assert render_with({:disable_indented_code_blocks => true}, text) !~ /<code/
|
235
|
+
end
|
236
|
+
|
329
237
|
def test_that_headers_are_linkable
|
330
238
|
markdown = @markdown.render('### Hello [GitHub](http://github.com)')
|
331
|
-
html_equal "<h3>Hello <a href=\"http://github.com\">GitHub</a></h3
|
239
|
+
html_equal "<h3>Hello <a href=\"http://github.com\">GitHub</a></h3>\n", markdown
|
332
240
|
end
|
333
241
|
|
334
242
|
def test_autolinking_with_ent_chars
|
@@ -344,104 +252,9 @@ text
|
|
344
252
|
end
|
345
253
|
|
346
254
|
def test_proper_intra_emphasis
|
347
|
-
md = Redcarpet::Markdown.new(Redcarpet::Render::HTML, :no_intra_emphasis => true)
|
348
255
|
assert render_with({:no_intra_emphasis => true}, "http://en.wikipedia.org/wiki/Dave_Allen_(comedian)") !~ /<em>/
|
349
256
|
assert render_with({:no_intra_emphasis => true}, "this fails: hello_world_") !~ /<em>/
|
350
257
|
assert render_with({:no_intra_emphasis => true}, "this also fails: hello_world_#bye") !~ /<em>/
|
351
258
|
assert render_with({:no_intra_emphasis => true}, "this works: hello_my_world") !~ /<em>/
|
352
259
|
end
|
353
260
|
end
|
354
|
-
|
355
|
-
class CustomRenderTest < Test::Unit::TestCase
|
356
|
-
class SimpleRender < Redcarpet::Render::HTML
|
357
|
-
def emphasis(text)
|
358
|
-
"<em class=\"cool\">#{text}</em>"
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
def test_simple_overload
|
363
|
-
md = Redcarpet::Markdown.new(SimpleRender)
|
364
|
-
html_equal "<p>This is <em class=\"cool\">just</em> a test</p>",
|
365
|
-
md.render("This is *just* a test")
|
366
|
-
end
|
367
|
-
|
368
|
-
class NilPreprocessRenderer < Redcarpet::Render::HTML
|
369
|
-
def preprocess(fulldoc)
|
370
|
-
nil
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
def test_preprocess_returning_nil
|
375
|
-
md = Redcarpet::Markdown.new(NilPreprocessRenderer)
|
376
|
-
assert_equal(nil,md.render("Anything"))
|
377
|
-
end
|
378
|
-
|
379
|
-
end
|
380
|
-
|
381
|
-
class RedcarpetCompatTest < Test::Unit::TestCase
|
382
|
-
def test_simple_compat_api
|
383
|
-
html = RedcarpetCompat.new("This is_just_a test").to_html
|
384
|
-
html_equal "<p>This is<em>just</em>a test</p>", html
|
385
|
-
end
|
386
|
-
|
387
|
-
def test_compat_api_enables_extensions
|
388
|
-
html = RedcarpetCompat.new("This is_just_a test", :no_intra_emphasis).to_html
|
389
|
-
html_equal "<p>This is_just_a test</p>", html
|
390
|
-
end
|
391
|
-
|
392
|
-
def test_compat_api_knows_fenced_code_extension
|
393
|
-
text = "```ruby\nx = 'foo'\n```"
|
394
|
-
html = RedcarpetCompat.new(text, :fenced_code).to_html
|
395
|
-
html_equal "<pre><code class=\"ruby\">x = 'foo'\n</code></pre>", html
|
396
|
-
end
|
397
|
-
|
398
|
-
def test_compat_api_ignores_gh_blockcode_extension
|
399
|
-
text = "```ruby\nx = 'foo'\n```"
|
400
|
-
html = RedcarpetCompat.new(text, :fenced_code, :gh_blockcode).to_html
|
401
|
-
html_equal "<pre><code class=\"ruby\">x = 'foo'\n</code></pre>", html
|
402
|
-
end
|
403
|
-
|
404
|
-
def test_compat_api_knows_no_intraemphasis_extension
|
405
|
-
html = RedcarpetCompat.new("This is_just_a test", :no_intraemphasis).to_html
|
406
|
-
html_equal "<p>This is_just_a test</p>", html
|
407
|
-
end
|
408
|
-
|
409
|
-
def test_translate_outdated_extensions
|
410
|
-
# these extensions are no longer used
|
411
|
-
exts = [:gh_blockcode, :no_tables, :smart, :strict]
|
412
|
-
html = RedcarpetCompat.new('"TEST"', *exts).to_html
|
413
|
-
html_equal "<p>"TEST"</p>", html
|
414
|
-
end
|
415
|
-
end
|
416
|
-
|
417
|
-
# Disabled by default
|
418
|
-
# (these are the easy ones -- the evil ones are not disclosed)
|
419
|
-
class PathologicalInputsTest # < Test::Unit::TestCase
|
420
|
-
def setup
|
421
|
-
@markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
|
422
|
-
end
|
423
|
-
|
424
|
-
def test_pathological_1
|
425
|
-
star = '*' * 250000
|
426
|
-
@markdown.render("#{star}#{star} hi #{star}#{star}")
|
427
|
-
end
|
428
|
-
|
429
|
-
def test_pathological_2
|
430
|
-
crt = '^' * 255
|
431
|
-
str = "#{crt}(\\)"
|
432
|
-
@markdown.render("#{str*300}")
|
433
|
-
end
|
434
|
-
|
435
|
-
def test_pathological_3
|
436
|
-
c = "`t`t`t`t`t`t" * 20000000
|
437
|
-
@markdown.render(c)
|
438
|
-
end
|
439
|
-
|
440
|
-
def test_pathological_4
|
441
|
-
@markdown.render(" [^a]: #{ "A" * 10000 }\n#{ "[^a][]" * 1000000 }\n")
|
442
|
-
end
|
443
|
-
|
444
|
-
def test_unbound_recursion
|
445
|
-
@markdown.render(("[" * 10000) + "foo" + ("](bar)" * 10000))
|
446
|
-
end
|
447
|
-
end
|