redcarpet 3.3.2 → 3.5.1

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,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