redcarpet 3.3.2 → 3.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,25 @@
1
+ /*
2
+ * Copyright (c) 2015, Vicent Marti
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ * THE SOFTWARE.
21
+ */
22
+
1
23
  #ifndef REDCARPET_H__
2
24
  #define REDCARPET_H__
3
25
 
@@ -1,3 +1,25 @@
1
+ /*
2
+ * Copyright (c) 2015, Vicent Marti
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ * THE SOFTWARE.
21
+ */
22
+
1
23
  #include "stack.h"
2
24
  #include <string.h>
3
25
 
@@ -1,3 +1,25 @@
1
+ /*
2
+ * Copyright (c) 2015, Vicent Marti
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ * THE SOFTWARE.
21
+ */
22
+
1
23
  #ifndef STACK_H__
2
24
  #define STACK_H__
3
25
 
@@ -2,7 +2,7 @@ require 'redcarpet.so'
2
2
  require 'redcarpet/compat'
3
3
 
4
4
  module Redcarpet
5
- VERSION = '3.3.2'
5
+ VERSION = '3.5.1'
6
6
 
7
7
  class Markdown
8
8
  attr_reader :renderer
@@ -47,7 +47,7 @@ module Redcarpet
47
47
  end
48
48
 
49
49
  opts.on_tail("-v", "--version", "Display the current version") do
50
- STDOUT.write "Redcarpet #{Redcarpet::VERSION}"
50
+ STDOUT.puts "Redcarpet #{Redcarpet::VERSION}"
51
51
  exit
52
52
  end
53
53
 
@@ -1,5 +1,3 @@
1
- require 'redcarpet'
2
-
3
1
  # Creates an instance of Redcarpet with the RedCloth API.
4
2
  class RedcarpetCompat
5
3
  attr_accessor :text
@@ -13,7 +13,7 @@ module Redcarpet
13
13
  :autolink, :codespan, :double_emphasis,
14
14
  :emphasis, :underline, :raw_html,
15
15
  :triple_emphasis, :strikethrough,
16
- :superscript,
16
+ :superscript, :highlight, :quote,
17
17
 
18
18
  # footnotes
19
19
  :footnotes, :footnote_def, :footnote_ref,
@@ -43,6 +43,18 @@ module Redcarpet
43
43
  def header(text, header_level)
44
44
  text + "\n"
45
45
  end
46
+
47
+ def table(header, body)
48
+ "#{header}#{body}"
49
+ end
50
+
51
+ def table_row(content)
52
+ content + "\n"
53
+ end
54
+
55
+ def table_cell(content, alignment)
56
+ content + "\t"
57
+ end
46
58
  end
47
59
  end
48
60
  end
@@ -1,10 +1,10 @@
1
1
  # encoding: utf-8
2
2
  Gem::Specification.new do |s|
3
3
  s.name = 'redcarpet'
4
- s.version = '3.3.2'
4
+ s.version = '3.5.1'
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 = '2015-06-22'
7
+ s.date = '2020-12-15'
8
8
  s.email = 'vicent@github.com'
9
9
  s.homepage = 'http://github.com/vmg/redcarpet'
10
10
  s.authors = ["Natacha Porté", "Vicent Martí"]
@@ -65,6 +65,7 @@ Gem::Specification.new do |s|
65
65
  s.executables = ["redcarpet"]
66
66
  s.require_paths = ["lib"]
67
67
 
68
- s.add_development_dependency "rake-compiler", "~> 0.8.3"
69
- s.add_development_dependency "test-unit", "~> 3.0.9"
68
+ s.add_development_dependency "rake", "~> 12.2.1"
69
+ s.add_development_dependency "rake-compiler", "~> 1.0.3"
70
+ s.add_development_dependency "test-unit", "~> 3.2.3"
70
71
  end
@@ -4,7 +4,15 @@ require 'test_helper'
4
4
  class CustomRenderTest < Redcarpet::TestCase
5
5
  class SimpleRender < Redcarpet::Render::HTML
6
6
  def emphasis(text)
7
- "<em class=\"cool\">#{text}</em>"
7
+ if @options[:no_intra_emphasis]
8
+ return %(<em class="no_intra_emphasis">#{text}</em>)
9
+ end
10
+
11
+ %(<em class="cool">#{text}</em>)
12
+ end
13
+
14
+ def header(text, level)
15
+ "My little poney" if @options[:with_toc_data]
8
16
  end
9
17
  end
10
18
 
@@ -14,6 +22,30 @@ class CustomRenderTest < Redcarpet::TestCase
14
22
  md.render("This is *just* a test")
15
23
  end
16
24
 
25
+ def test_renderer_options
26
+ parser = Redcarpet::Markdown.new(SimpleRender.new(with_toc_data: true))
27
+ output = parser.render("# A title")
28
+
29
+ assert_match "My little poney", output
30
+ end
31
+
32
+ def test_markdown_options
33
+ parser = Redcarpet::Markdown.new(SimpleRender, no_intra_emphasis: true)
34
+ output = parser.render("*foo*")
35
+
36
+ assert_match "no_intra_emphasis", output
37
+ end
38
+
39
+ def test_original_options_hash_is_not_mutated
40
+ options = { with_toc_data: true }
41
+ render = SimpleRender.new(options)
42
+ parser = Redcarpet::Markdown.new(render, tables: true)
43
+
44
+ computed_options = render.instance_variable_get(:"@options")
45
+
46
+ refute_equal computed_options.object_id, options.object_id
47
+ end
48
+
17
49
  class NilPreprocessRenderer < Redcarpet::Render::HTML
18
50
  def preprocess(fulldoc)
19
51
  nil
@@ -25,4 +57,11 @@ class CustomRenderTest < Redcarpet::TestCase
25
57
  assert_equal(nil,md.render("Anything"))
26
58
  end
27
59
 
60
+ def test_base_render_without_quote_callback
61
+ # Regression test for https://github.com/vmg/redcarpet/issues/569
62
+ render = Class.new(Redcarpet::Render::Base)
63
+ parser = Redcarpet::Markdown.new render.new, quote: true
64
+
65
+ assert_equal "", parser.render(%(a "quote"))
66
+ end
28
67
  end
@@ -2,68 +2,81 @@ require 'test_helper'
2
2
 
3
3
  class HTML5Test < Redcarpet::TestCase
4
4
  def test_that_html5_works
5
- section = <<EOS
6
- <section>
7
- <p>The quick brown fox jumps over the lazy dog.</p>
8
- </section>
9
- EOS
5
+ section = <<-HTML.chomp.strip_heredoc
6
+ <section>
7
+ <p>The quick brown fox jumps over the lazy dog.</p>
8
+ </section>
9
+ HTML
10
10
 
11
- figure = <<EOS
12
- <figure>
13
- <img src="http://example.org/image.jpg" alt="">
14
- <figcaption>
15
- <p>Hello world!</p>
16
- </figcaption>
17
- </figure>
18
- EOS
11
+ figure = <<-HTML.chomp.strip_heredoc
12
+ <figure>
13
+ <img src="http://example.org/image.jpg" alt="">
14
+ <figcaption>
15
+ <p>Hello world!</p>
16
+ </figcaption>
17
+ </figure>
18
+ HTML
19
19
 
20
20
  assert_renders section, section
21
21
  assert_renders figure, figure
22
22
  end
23
23
 
24
24
  def test_that_html5_works_with_code_blocks
25
- section = <<EOS
25
+ section = <<-HTML
26
26
  \t<section>
27
27
  \t\t<p>The quick brown fox jumps over the lazy dog.</p>
28
28
  \t</section>
29
- EOS
29
+ HTML
30
30
 
31
- section_expected = <<EOE
32
- <pre><code>&lt;section&gt;
33
- &lt;p&gt;The quick brown fox jumps over the lazy dog.&lt;/p&gt;
34
- &lt;/section&gt;
35
- </code></pre>
36
- EOE
31
+ section_expected = <<-HTML.chomp.strip_heredoc
32
+ <pre><code>&lt;section&gt;
33
+ &lt;p&gt;The quick brown fox jumps over the lazy dog.&lt;/p&gt;
34
+ &lt;/section&gt;
35
+ </code></pre>
36
+ HTML
37
37
 
38
- header = <<EOS
38
+ header = <<-HTML
39
39
  <header>
40
40
  <hgroup>
41
41
  <h1>Section heading</h1>
42
42
  <h2>Subhead</h2>
43
43
  </hgroup>
44
44
  </header>
45
- EOS
45
+ HTML
46
46
 
47
- header_expected = <<EOE
48
- <pre><code>&lt;header&gt;
49
- &lt;hgroup&gt;
50
- &lt;h1&gt;Section heading&lt;/h1&gt;
51
- &lt;h2&gt;Subhead&lt;/h2&gt;
52
- &lt;/hgroup&gt;
53
- &lt;/header&gt;
54
- </code></pre>
55
- EOE
47
+ header_expected = <<-HTML.chomp.strip_heredoc
48
+ <pre><code>&lt;header&gt;
49
+ &lt;hgroup&gt;
50
+ &lt;h1&gt;Section heading&lt;/h1&gt;
51
+ &lt;h2&gt;Subhead&lt;/h2&gt;
52
+ &lt;/hgroup&gt;
53
+ &lt;/header&gt;
54
+ </code></pre>
55
+ HTML
56
56
 
57
57
  assert_renders section_expected, section
58
58
  assert_renders header_expected, header
59
59
  end
60
60
 
61
61
  def test_script_tag_recognition
62
- markdown = <<-Md
63
- <script type="text/javascript">
64
- alert('Foo!');
65
- </script>
66
- Md
67
- assert_renders markdown, markdown
62
+ html = <<-HTML.chomp.strip_heredoc
63
+ <script type="text/javascript">
64
+ alert('Foo!');
65
+ </script>
66
+ HTML
67
+
68
+ assert_renders html, html
69
+ end
70
+
71
+ def test_new_html5_tags_not_escaped
72
+ details = <<-HTML.chomp.strip_heredoc
73
+ <details>
74
+ log:
75
+
76
+ </details>
77
+ HTML
78
+
79
+ assert_renders details, details
68
80
  end
81
+
69
82
  end
@@ -8,20 +8,20 @@ class HTMLRenderTest < Redcarpet::TestCase
8
8
 
9
9
  # Hint: overrides filter_html, no_images and no_links
10
10
  def test_that_escape_html_works
11
- source = <<EOS
12
- Through <em>NO</em> <script>DOUBLE NO</script>
11
+ source = <<-HTML.strip_heredoc
12
+ Through <em>NO</em> <script>DOUBLE NO</script>
13
13
 
14
- <script>BAD</script>
14
+ <script>BAD</script>
15
15
 
16
- <img src="/favicon.ico" />
17
- EOS
18
- expected = <<EOE
19
- <p>Through &lt;em&gt;NO&lt;/em&gt; &lt;script&gt;DOUBLE NO&lt;/script&gt;</p>
16
+ <img src="/favicon.ico" />
17
+ HTML
18
+ expected = <<-HTML.chomp.strip_heredoc
19
+ <p>Through &lt;em&gt;NO&lt;/em&gt; &lt;script&gt;DOUBLE NO&lt;/script&gt;</p>
20
20
 
21
- <p>&lt;script&gt;BAD&lt;/script&gt;</p>
21
+ <p>&lt;script&gt;BAD&lt;/script&gt;</p>
22
22
 
23
- <p>&lt;img src=&quot;/favicon.ico&quot; /&gt;</p>
24
- EOE
23
+ <p>&lt;img src=&quot;/favicon.ico&quot; /&gt;</p>
24
+ HTML
25
25
 
26
26
  assert_equal expected, render(source, with: [:escape_html])
27
27
  end
@@ -30,14 +30,14 @@ EOE
30
30
  markdown = 'Through <em>NO</em> <script>DOUBLE NO</script>'
31
31
  output = render(markdown, with: [:filter_html])
32
32
 
33
- assert_equal "<p>Through NO DOUBLE NO</p>\n", output
33
+ assert_equal "<p>Through NO DOUBLE NO</p>", output
34
34
  end
35
35
 
36
36
  def test_filter_html_doesnt_break_two_space_hard_break
37
37
  markdown = "Lorem, \nipsum\n"
38
38
  output = render(markdown, with: [:filter_html])
39
39
 
40
- assert_equal "<p>Lorem,<br>\nipsum</p>\n", output
40
+ assert_equal "<p>Lorem,<br>\nipsum</p>", output
41
41
  end
42
42
 
43
43
  def test_that_no_image_flag_works
@@ -47,6 +47,12 @@ EOE
47
47
  assert_no_match %r{<img}, output
48
48
  end
49
49
 
50
+ def test_that_links_with_ampersands_work
51
+ markdown = %([/?a=b&c=d](/?a=b&c=d))
52
+ output = render(markdown)
53
+ assert_equal "<p><a href=\"/?a=b&c=d\">/?a=b&amp;c=d</a></p>", output
54
+ end
55
+
50
56
  def test_that_no_links_flag_works
51
57
  markdown = %([This link](http://example.net/) <a href="links.html">links</a>)
52
58
  output = render(markdown, with: [:no_links])
@@ -58,17 +64,17 @@ EOE
58
64
  markdown = "[IRC](irc://chat.freenode.org/#freenode)"
59
65
  output = render(markdown, with: [:safe_links_only])
60
66
 
61
- assert_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>\n", output
67
+ assert_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>", output
62
68
  end
63
69
 
64
70
  def test_that_hard_wrap_works
65
- markdown = <<EOE
66
- Hello world,
67
- this is just a simple test
71
+ markdown = <<-Markdown.strip_heredoc
72
+ Hello world,
73
+ this is just a simple test
68
74
 
69
- With hard wraps
70
- and other *things*.
71
- EOE
75
+ With hard wraps
76
+ and other *things*.
77
+ Markdown
72
78
  output = render(markdown, with: [:hard_wrap])
73
79
 
74
80
  assert_match %r{<br>}, output
@@ -82,37 +88,37 @@ EOE
82
88
 
83
89
  def test_that_link_works_with_quotes
84
90
  markdown = %([This'link"is](http://example.net/))
85
- expected = %(<p><a href="http://example.net/">This&#39;link&quot;is</a></p>\n)
91
+ expected = %(<p><a href="http://example.net/">This&#39;link&quot;is</a></p>)
86
92
 
87
93
  assert_equal expected, render(markdown)
88
94
  assert_equal expected, render(markdown, with: [:escape_html])
89
95
  end
90
96
 
91
97
  def test_that_code_emphasis_work
92
- markdown = <<-MD
93
- This should be **`a bold codespan`**
94
- However, this should be *`an emphasised codespan`*
98
+ markdown = <<-Markdown.strip_heredoc
99
+ This should be **`a bold codespan`**
100
+ However, this should be *`an emphasised codespan`*
95
101
 
96
- * **`ABC`** or **`DEF`**
97
- * Foo bar
98
- MD
102
+ * **`ABC`** or **`DEF`**
103
+ * Foo bar
104
+ Markdown
99
105
 
100
- html = <<HTML
101
- <p>This should be <strong><code>a bold codespan</code></strong>
102
- However, this should be <em><code>an emphasised codespan</code></em></p>
106
+ html = <<-HTML.chomp.strip_heredoc
107
+ <p>This should be <strong><code>a bold codespan</code></strong>
108
+ However, this should be <em><code>an emphasised codespan</code></em></p>
103
109
 
104
- <ul>
105
- <li><strong><code>ABC</code></strong> or <strong><code>DEF</code></strong></li>
106
- <li>Foo bar</li>
107
- </ul>
108
- HTML
110
+ <ul>
111
+ <li><strong><code>ABC</code></strong> or <strong><code>DEF</code></strong></li>
112
+ <li>Foo bar</li>
113
+ </ul>
114
+ HTML
109
115
 
110
116
  assert_equal html, render(markdown)
111
117
  end
112
118
 
113
119
  def test_that_parenthesis_are_handled_into_links
114
120
  markdown = %(The [bash man page](man:bash(1))!)
115
- expected = %(<p>The <a href="man:bash(1)">bash man page</a>!</p>\n)
121
+ expected = %(<p>The <a href="man:bash(1)">bash man page</a>!</p>)
116
122
 
117
123
  assert_equal expected, render(markdown)
118
124
  end
@@ -127,42 +133,42 @@ HTML
127
133
  end
128
134
 
129
135
  def test_that_footnotes_work
130
- markdown = <<-MD
131
- This is a footnote.[^1]
136
+ markdown = <<-Markdown.strip_heredoc
137
+ This is a footnote.[^1]
132
138
 
133
- [^1]: It provides additional information.
134
- MD
139
+ [^1]: It provides additional information.
140
+ Markdown
135
141
 
136
- html = <<HTML
137
- <p>This is a footnote.<sup id="fnref1"><a href="#fn1" rel="footnote">1</a></sup></p>
142
+ html = <<-HTML.chomp.strip_heredoc
143
+ <p>This is a footnote.<sup id="fnref1"><a href="#fn1">1</a></sup></p>
138
144
 
139
- <div class="footnotes">
140
- <hr>
141
- <ol>
145
+ <div class="footnotes">
146
+ <hr>
147
+ <ol>
142
148
 
143
- <li id="fn1">
144
- <p>It provides additional information.&nbsp;<a href="#fnref1" rev="footnote">&#8617;</a></p>
145
- </li>
149
+ <li id="fn1">
150
+ <p>It provides additional information.&nbsp;<a href="#fnref1">&#8617;</a></p>
151
+ </li>
146
152
 
147
- </ol>
148
- </div>
149
- HTML
153
+ </ol>
154
+ </div>
155
+ HTML
150
156
 
151
157
  output = render(markdown, with: [:footnotes])
152
158
  assert_equal html, output
153
159
  end
154
160
 
155
161
  def test_footnotes_enabled_but_missing_marker
156
- markdown = <<MD
157
- Some text without a marker
162
+ markdown = <<-Markdown.strip_heredoc
163
+ Some text without a marker
158
164
 
159
- [^1] And a trailing definition
160
- MD
161
- html = <<HTML
162
- <p>Some text without a marker</p>
165
+ [^1] And a trailing definition
166
+ Markdown
167
+ html = <<-HTML.chomp.strip_heredoc
168
+ <p>Some text without a marker</p>
163
169
 
164
- <p>[^1] And a trailing definition</p>
165
- HTML
170
+ <p>[^1] And a trailing definition</p>
171
+ HTML
166
172
 
167
173
  output = render(markdown, with: [:footnotes])
168
174
  assert_equal html, output
@@ -170,7 +176,7 @@ HTML
170
176
 
171
177
  def test_footnotes_enabled_but_missing_definition
172
178
  markdown = "Some text with a marker[^1] but no definition."
173
- expected = "<p>Some text with a marker[^1] but no definition.</p>\n"
179
+ expected = "<p>Some text with a marker[^1] but no definition.</p>"
174
180
 
175
181
  output = render(markdown, with: [:footnotes])
176
182
  assert_equal expected, output
@@ -238,4 +244,31 @@ HTML
238
244
 
239
245
  assert_no_match %r{<style>}, output
240
246
  end
247
+
248
+ def test_non_ascii_removal_in_header_anchors
249
+ markdown = "# Glühlampe"
250
+ html = "<h1 id=\"gl-hlampe\">Glühlampe</h1>"
251
+
252
+ assert_equal html, render(markdown, with: [:with_toc_data])
253
+ end
254
+
255
+ def test_utf8_only_header_anchors
256
+ markdown = "# 見出し"
257
+ if 1.size == 4 # 32-bit architecture
258
+ html = "<h1 id=\"part-a194139f\">見出し</h1>"
259
+ elsif 1.size == 8 # 64-bit architecture
260
+ html = "<h1 id=\"part-37870bfa194139f\">見出し</h1>"
261
+ else
262
+ raise "unknown integer size"
263
+ end
264
+
265
+ assert_equal html, render(markdown, with: [:with_toc_data])
266
+ end
267
+
268
+ def test_escape_entities_removal_from_anchor
269
+ output = render("# Foo's & Bar's", with: [:with_toc_data])
270
+ result = %(<h1 id="foos-bars">Foo&#39;s &amp; Bar&#39;s</h1>)
271
+
272
+ assert_equal result, output
273
+ end
241
274
  end