tight-redcarpet 3.1.1 → 3.2.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.
@@ -1547,7 +1547,7 @@ prefix_oli(uint8_t *data, size_t size)
1547
1547
  return i + 2;
1548
1548
  }
1549
1549
 
1550
- /* prefix_uli • returns ordered list item prefix */
1550
+ /* prefix_uli • returns unordered list item prefix */
1551
1551
  static size_t
1552
1552
  prefix_uli(uint8_t *data, size_t size)
1553
1553
  {
@@ -1619,7 +1619,7 @@ parse_blockquote(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t
1619
1619
  static size_t
1620
1620
  parse_htmlblock(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, int do_render);
1621
1621
 
1622
- /* parse_blockquote • handles parsing of a regular paragraph */
1622
+ /* parse_paragraph • handles parsing of a regular paragraph */
1623
1623
  static size_t
1624
1624
  parse_paragraph(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size)
1625
1625
  {
@@ -1630,15 +1630,11 @@ parse_paragraph(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t
1630
1630
  while (i < size) {
1631
1631
  for (end = i + 1; end < size && data[end - 1] != '\n'; end++) /* empty */;
1632
1632
 
1633
- if (is_empty(data + i, size - i)) {
1634
- last_is_empty = 1;
1633
+ if (is_empty(data + i, size - i))
1635
1634
  break;
1636
- }
1637
1635
 
1638
- if (!last_is_empty && (level = is_headerline(data + i, size - i)) != 0) {
1639
- last_is_empty = 0;
1636
+ if (!last_is_empty && (level = is_headerline(data + i, size - i)) != 0)
1640
1637
  break;
1641
- }
1642
1638
 
1643
1639
  last_is_empty = 0;
1644
1640
 
@@ -2804,6 +2800,7 @@ sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, str
2804
2800
 
2805
2801
  struct buf *text;
2806
2802
  size_t beg, end;
2803
+ int in_fence = 0;
2807
2804
 
2808
2805
  text = bufnew(64);
2809
2806
  if (!text)
@@ -2815,7 +2812,8 @@ sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, str
2815
2812
  /* reset the references table */
2816
2813
  memset(&md->refs, 0x0, REF_TABLE_SIZE * sizeof(void *));
2817
2814
 
2818
- int footnotes_enabled = md->ext_flags & MKDEXT_FOOTNOTES;
2815
+ int footnotes_enabled = md->ext_flags & MKDEXT_FOOTNOTES;
2816
+ int codefences_enabled = md->ext_flags & MKDEXT_FENCED_CODE;
2819
2817
 
2820
2818
  /* reset the footnotes lists */
2821
2819
  if (footnotes_enabled) {
@@ -2831,10 +2829,13 @@ sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, str
2831
2829
  if (doc_size >= 3 && memcmp(document, UTF8_BOM, 3) == 0)
2832
2830
  beg += 3;
2833
2831
 
2834
- while (beg < doc_size) /* iterating over lines */
2835
- if (footnotes_enabled && is_footnote(document, beg, doc_size, &end, &md->footnotes_found))
2832
+ while (beg < doc_size) { /* iterating over lines */
2833
+ if (codefences_enabled && (is_codefence(document + beg, doc_size - beg, NULL) != 0))
2834
+ in_fence = !in_fence;
2835
+
2836
+ if (!in_fence && footnotes_enabled && is_footnote(document, beg, doc_size, &end, &md->footnotes_found))
2836
2837
  beg = end;
2837
- else if (is_ref(document, beg, doc_size, &end, md->refs))
2838
+ else if (!in_fence && is_ref(document, beg, doc_size, &end, md->refs))
2838
2839
  beg = end;
2839
2840
  else { /* skipping to the next line */
2840
2841
  end = beg;
@@ -2854,6 +2855,7 @@ sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, str
2854
2855
 
2855
2856
  beg = end;
2856
2857
  }
2858
+ }
2857
2859
 
2858
2860
  /* pre-grow the output buffer to minimize allocations */
2859
2861
  bufgrow(ob, MARKDOWN_GROW(text->size));
@@ -104,9 +104,6 @@ struct sd_callbacks {
104
104
  void (*doc_footer)(struct buf *ob, void *opaque);
105
105
  };
106
106
 
107
- /* header methods used internally in Redcarpet */
108
- char* header_anchor(struct buf *text);
109
-
110
107
  struct sd_markdown;
111
108
 
112
109
  /*********
@@ -122,13 +122,9 @@ static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
122
122
  if (NIL_P(text))
123
123
  return Qnil;
124
124
 
125
- #ifdef HAVE_RUBY_ENCODING_H
126
- {
127
- struct rb_redcarpet_rndr *renderer;
128
- Data_Get_Struct(rb_rndr, struct rb_redcarpet_rndr, renderer);
129
- renderer->options.active_enc = rb_enc_get(text);
130
- }
131
- #endif
125
+ struct rb_redcarpet_rndr *renderer;
126
+ Data_Get_Struct(rb_rndr, struct rb_redcarpet_rndr, renderer);
127
+ renderer->options.active_enc = rb_enc_get(text);
132
128
 
133
129
  /* initialize buffers */
134
130
  output_buf = bufnew(128);
@@ -472,25 +472,30 @@ static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self)
472
472
  static VALUE rb_redcarpet_htmltoc_init(int argc, VALUE *argv, VALUE self)
473
473
  {
474
474
  struct rb_redcarpet_rndr *rndr;
475
- int nesting_level = 6;
476
- VALUE hash, key = Qnil;
475
+ unsigned int render_flags = HTML_TOC;
476
+ VALUE hash, nesting_level = Qnil;
477
477
 
478
478
  Data_Get_Struct(self, struct rb_redcarpet_rndr, rndr);
479
479
 
480
480
  if (rb_scan_args(argc, argv, "01", &hash) == 1) {
481
481
  Check_Type(hash, T_HASH);
482
482
 
483
- key = CSTR2SYM("nesting_level");
483
+ /* escape_html */
484
+ if (rb_hash_aref(hash, CSTR2SYM("escape_html")) == Qtrue)
485
+ render_flags |= HTML_ESCAPE;
484
486
 
485
- if (RTEST(rb_hash_aref(hash, key))) {
486
- Check_Type(rb_hash_aref(hash, key), T_FIXNUM);
487
- nesting_level = NUM2INT(rb_hash_aref(hash, key));
488
- }
487
+ /* Nesting level */
488
+ nesting_level = rb_hash_aref(hash, CSTR2SYM("nesting_level"));
489
489
  }
490
490
 
491
- sdhtml_toc_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, nesting_level);
491
+ sdhtml_toc_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, render_flags);
492
492
  rb_redcarpet__overload(self, rb_cRenderHTML_TOC);
493
493
 
494
+ if (!(NIL_P(nesting_level)))
495
+ rndr->options.html.toc_data.nesting_level = NUM2INT(nesting_level);
496
+ else
497
+ rndr->options.html.toc_data.nesting_level = 6;
498
+
494
499
  return Qnil;
495
500
  }
496
501
 
data/lib/redcarpet.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require 'redcarpet.so'
2
+ require 'redcarpet/compat'
2
3
 
3
4
  module Redcarpet
4
- VERSION = '3.1.1'
5
+ VERSION = '3.2.0'
5
6
 
6
7
  class Markdown
7
8
  attr_reader :renderer
@@ -11,8 +12,8 @@ module Redcarpet
11
12
 
12
13
  # XHTML Renderer
13
14
  class XHTML < HTML
14
- def initialize(extensions={})
15
- super(extensions.merge(:xhtml => true))
15
+ def initialize(extensions = {})
16
+ super(extensions.merge(xhtml: true))
16
17
  end
17
18
  end
18
19
 
@@ -21,6 +22,43 @@ module Redcarpet
21
22
  include SmartyPants
22
23
  end
23
24
 
25
+ # A renderer object you can use to deal with users' input. It
26
+ # enables +escape_html+ and +safe_links_only+ by default.
27
+ #
28
+ # The +block_code+ callback is also overriden not to include
29
+ # the lang's class as the user can basically specify anything
30
+ # with the vanilla one.
31
+ class Safe < HTML
32
+ def initialize(extensions = {})
33
+ super({
34
+ escape_html: true,
35
+ safe_links_only: true
36
+ }.merge(extensions))
37
+ end
38
+
39
+ def block_code(code, lang)
40
+ "<pre>" \
41
+ "<code>#{html_escape(code)}</code>" \
42
+ "</pre>"
43
+ end
44
+
45
+ private
46
+
47
+ # TODO: This is far from ideal to have such method as we
48
+ # are duplicating existing code from Houdini. This method
49
+ # should be defined at the C level.
50
+ def html_escape(string)
51
+ string.gsub(/['&\"<>\/]/, {
52
+ '&' => '&amp;',
53
+ '<' => '&lt;',
54
+ '>' => '&gt;',
55
+ '"' => '&quot;',
56
+ "'" => '&#x27;',
57
+ "/" => '&#x2F',
58
+ })
59
+ end
60
+ end
61
+
24
62
  # SmartyPants Mixin module
25
63
  #
26
64
  # Implements SmartyPants.postprocess, which
@@ -52,74 +90,3 @@ module Redcarpet
52
90
  end
53
91
  end
54
92
  end
55
-
56
- # Compatibility class;
57
- # Creates an instance of Redcarpet with the RedCloth API.
58
- class RedcarpetCompat
59
- attr_accessor :text
60
-
61
- def initialize(text, *exts)
62
- exts_hash, render_hash = *parse_extensions_and_renderer_options(exts)
63
- @text = text
64
- renderer = Redcarpet::Render::HTML.new(render_hash)
65
- @markdown = Redcarpet::Markdown.new(renderer, exts_hash)
66
- end
67
-
68
- def to_html(*_dummy)
69
- @markdown.render(@text)
70
- end
71
-
72
- private
73
-
74
- EXTENSION_MAP = {
75
- # old name => new name
76
- :autolink => :autolink,
77
- :fenced_code => :fenced_code_blocks,
78
- :filter_html => :filter_html,
79
- :hard_wrap => :hard_wrap,
80
- :prettify => :prettify,
81
- :lax_htmlblock => :lax_spacing,
82
- :no_image => :no_images,
83
- :no_intraemphasis => :no_intra_emphasis,
84
- :no_links => :no_links,
85
- :filter_styles => :no_styles,
86
- :safelink => :safe_links_only,
87
- :space_header => :space_after_headers,
88
- :strikethrough => :strikethrough,
89
- :tables => :tables,
90
- :generate_toc => :with_toc_data,
91
- :xhtml => :xhtml,
92
- # old names with no new mapping
93
- :gh_blockcode => nil,
94
- :no_tables => nil,
95
- :smart => nil,
96
- :strict => nil
97
- }
98
-
99
- RENDERER_OPTIONS = [:filter_html, :no_images, :no_links, :no_styles,
100
- :safe_links_only, :with_toc_data, :hard_wrap, :prettify, :xhtml]
101
-
102
- def rename_extensions(exts)
103
- exts.map do |old_name|
104
- if new_name = EXTENSION_MAP[old_name]
105
- new_name
106
- else
107
- old_name
108
- end
109
- end.compact
110
- end
111
-
112
- # Returns two hashes, the extensions and renderer options
113
- # given the extension list
114
- def parse_extensions_and_renderer_options(exts)
115
- exts = rename_extensions(exts)
116
- exts.partition {|ext| !RENDERER_OPTIONS.include?(ext) }.
117
- map {|list| list_to_truthy_hash(list) }
118
- end
119
-
120
- # Turns a list of symbols into a hash of <tt>symbol => true</tt>.
121
- def list_to_truthy_hash(list)
122
- list.inject({}) {|h, k| h[k] = true; h }
123
- end
124
- end
125
-
@@ -1,3 +1,73 @@
1
1
  require 'redcarpet'
2
2
 
3
+ # Creates an instance of Redcarpet with the RedCloth API.
4
+ class RedcarpetCompat
5
+ attr_accessor :text
6
+
7
+ def initialize(text, *exts)
8
+ exts_hash, render_hash = *parse_extensions_and_renderer_options(exts)
9
+ @text = text
10
+ renderer = Redcarpet::Render::HTML.new(render_hash)
11
+ @markdown = Redcarpet::Markdown.new(renderer, exts_hash)
12
+ end
13
+
14
+ def to_html(*_dummy)
15
+ @markdown.render(text)
16
+ end
17
+
18
+ private
19
+
20
+ EXTENSION_MAP = {
21
+ # old name => new name
22
+ :autolink => :autolink,
23
+ :fenced_code => :fenced_code_blocks,
24
+ :filter_html => :filter_html,
25
+ :hard_wrap => :hard_wrap,
26
+ :prettify => :prettify,
27
+ :lax_htmlblock => :lax_spacing,
28
+ :no_image => :no_images,
29
+ :no_intraemphasis => :no_intra_emphasis,
30
+ :no_links => :no_links,
31
+ :filter_styles => :no_styles,
32
+ :safelink => :safe_links_only,
33
+ :space_header => :space_after_headers,
34
+ :strikethrough => :strikethrough,
35
+ :tables => :tables,
36
+ :generate_toc => :with_toc_data,
37
+ :xhtml => :xhtml,
38
+
39
+ # old names with no new mapping
40
+ :gh_blockcode => nil,
41
+ :no_tables => nil,
42
+ :smart => nil,
43
+ :strict => nil
44
+ }
45
+
46
+ RENDERER_OPTIONS = [:filter_html, :no_images, :no_links, :no_styles,
47
+ :safe_links_only, :with_toc_data, :hard_wrap, :prettify, :xhtml]
48
+
49
+ def rename_extensions(exts)
50
+ exts.map do |old_name|
51
+ if new_name = EXTENSION_MAP[old_name]
52
+ new_name
53
+ else
54
+ old_name
55
+ end
56
+ end.compact
57
+ end
58
+
59
+ # Returns two hashes, the extensions and renderer options
60
+ # given the extension list
61
+ def parse_extensions_and_renderer_options(exts)
62
+ exts = rename_extensions(exts)
63
+ exts.partition {|ext| !RENDERER_OPTIONS.include?(ext) }.
64
+ map {|list| list_to_truthy_hash(list) }
65
+ end
66
+
67
+ # Turns a list of symbols into a hash of <tt>symbol => true</tt>.
68
+ def list_to_truthy_hash(list)
69
+ list.inject({}) {|h, k| h[k] = true; h }
70
+ end
71
+ end
72
+
3
73
  Markdown = RedcarpetCompat unless defined? Markdown
@@ -26,9 +26,9 @@ module Redcarpet
26
26
  end
27
27
  end
28
28
 
29
- # Other methods where the text content is in another argument
29
+ # Other methods where we don't return only a specific argument
30
30
  def link(link, title, content)
31
- content
31
+ "#{content} (#{link})"
32
32
  end
33
33
 
34
34
  def image(link, title, content)
data/redcarpet.gemspec CHANGED
@@ -1,10 +1,10 @@
1
1
  # encoding: utf-8
2
2
  Gem::Specification.new do |s|
3
3
  s.name = 'tight-redcarpet'
4
- s.version = '3.1.1'
4
+ s.version = '3.2.0'
5
5
  s.summary = "Markdown that smells nice (patch level 'tight')"
6
6
  s.description = 'A fast, safe and extensible Markdown to (X)HTML parser patched to have smaller headings and no quote-escaping'
7
- s.date = '2014-07-04'
7
+ s.date = '2015-01-08'
8
8
  s.email = 'ujifgc@github.com'
9
9
  s.homepage = 'http://github.com/ujifgc/redcarpet'
10
10
  s.authors = ["Natacha Porté", "Vicent Martí", "Igor Bochkariov"]
@@ -41,16 +41,19 @@ Gem::Specification.new do |s|
41
41
  lib/redcarpet/render_man.rb
42
42
  lib/redcarpet/render_strip.rb
43
43
  redcarpet.gemspec
44
- test/test_helper.rb
44
+ test/benchmark.rb
45
45
  test/custom_render_test.rb
46
+ test/html5_test.rb
46
47
  test/html_render_test.rb
47
48
  test/html_toc_render_test.rb
48
49
  test/markdown_test.rb
49
50
  test/pathological_inputs_test.rb
50
51
  test/redcarpet_compat_test.rb
52
+ test/safe_render_test.rb
51
53
  test/smarty_html_test.rb
52
54
  test/smarty_pants_test.rb
53
55
  test/stripdown_render_test.rb
56
+ test/test_helper.rb
54
57
  ]
55
58
  # = MANIFEST =
56
59
  s.test_files = s.files.grep(%r{^test/})
@@ -59,7 +62,7 @@ Gem::Specification.new do |s|
59
62
  s.executables = ["redcarpet"]
60
63
  s.require_paths = ["lib"]
61
64
 
62
- s.add_development_dependency "nokogiri", "~> 1.6.0"
65
+ s.add_development_dependency "nokogiri", "~> 1.6.3.1"
63
66
  s.add_development_dependency "rake-compiler", "~> 0.8.3"
64
67
  s.add_development_dependency "test-unit", "~> 2.5.4"
65
68
  end
data/test/benchmark.rb ADDED
@@ -0,0 +1,24 @@
1
+ # coding: UTF-8
2
+ # Thanks Kramdown for the inspiration!
3
+ require 'benchmark/ips'
4
+
5
+ require 'redcarpet'
6
+ require 'bluecloth'
7
+ require 'kramdown'
8
+
9
+ markdown = File.read(File.join(File.dirname(__FILE__), "fixtures/benchmark.md"))
10
+
11
+ # Let's bench!
12
+ Benchmark.ips do |bench|
13
+ bench.report("Redcarpet") do
14
+ Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(markdown)
15
+ end
16
+
17
+ bench.report("BlueCloth") do
18
+ BlueCloth.new(markdown).to_html
19
+ end
20
+
21
+ bench.report("Kramdown") do
22
+ Kramdown::Document.new(markdown).to_html
23
+ end
24
+ end
@@ -0,0 +1,69 @@
1
+ require 'test_helper'
2
+
3
+ class HTML5Test < Redcarpet::TestCase
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
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
19
+
20
+ assert_renders section, section
21
+ assert_renders figure, figure
22
+ end
23
+
24
+ def test_that_html5_works_with_code_blocks
25
+ section = <<EOS
26
+ \t<section>
27
+ \t\t<p>The quick brown fox jumps over the lazy dog.</p>
28
+ \t</section>
29
+ EOS
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
37
+
38
+ header = <<EOS
39
+ <header>
40
+ <hgroup>
41
+ <h1>Section heading</h1>
42
+ <h2>Subhead</h2>
43
+ </hgroup>
44
+ </header>
45
+ EOS
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
56
+
57
+ assert_renders section_expected, section
58
+ assert_renders header_expected, header
59
+ end
60
+
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
68
+ end
69
+ end