redcarpet 3.4.0 → 3.5.0

This diff has not been reviewed by any users.
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 54a531e17acc94f275045e633bab8458df9c0075
4
- data.tar.gz: 407c3e570ffbaff80b809ab344fb4a7d27b1b97f
2
+ SHA256:
3
+ metadata.gz: 0ab6ed54cafc5edbbd785307a772251508fe1a8c9d739e7b28a6f1b89e162dfb
4
+ data.tar.gz: b6a8579180b8933a1181be7aeaf4e544e1161499dac1f4fb1c5f34f61585b971
5
5
  SHA512:
6
- metadata.gz: 7d7189a86a6ed3451e823f2b75acfc2c7086f73e02e22ece1490b25fba5df75d149c8d1ce61cef47c7604aa0a941e090bbff93f5623d501d78e3cf2ef5836d89
7
- data.tar.gz: 34e6b6980076319b5094c1766687c31b21ace1d2e5d96f7b291f36f60350d727b40f87f14a870f16601732532ca4ad469a79430312ac5b72eda18ef9f4e1e364
6
+ metadata.gz: bc2a7f4ceab2736677752bde915f9090cabad682cfc71fc680958852d71ae18bc902d8a71ba47453adf689b41e87413bee3d766a8470d333654b6808f5b96b09
7
+ data.tar.gz: e2fb9c0596683da9b2b6c24597a58ebe2b62e958c1f21173a733d0344b6e671b78fedfc2171d7b5c3a1b945a7e0d355329a2d60aeadfe79616dc730d22904816
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source "https://rubygems.org/"
3
3
  gemspec
4
4
 
5
5
  group :benchmark do
6
- gem "benchmark-ips", "~> 2.3.0"
6
+ gem "benchmark-ips", "~> 2.7.2"
7
7
  gem "bluecloth", "~> 2.2.0"
8
- gem "kramdown", "~> 1.8.0"
8
+ gem "kramdown", "~> 1.13.2"
9
9
  end
@@ -3,6 +3,7 @@ Redcarpet is written with sugar, spice and everything nice
3
3
 
4
4
  [![Build Status](https://travis-ci.org/vmg/redcarpet.svg?branch=master)](https://travis-ci.org/vmg/redcarpet)
5
5
  [![Dependency Status](https://www.versioneye.com/ruby/redcarpet/badge.svg)](https://www.versioneye.com/ruby/redcarpet)
6
+ [![Help Contribute to Open Source](https://www.codetriage.com/vmg/redcarpet/badges/users.svg)](https://www.codetriage.com/vmg/redcarpet)
6
7
 
7
8
  Redcarpet is a Ruby library for Markdown processing that smells like
8
9
  butterflies and popcorn.
@@ -45,10 +46,10 @@ output.
45
46
  The `Redcarpet::Markdown` object is encouraged to be instantiated once with the
46
47
  required settings, and reused between parses.
47
48
 
48
- ~~~~~ ruby
49
+ ~~~~ ruby
49
50
  # Initializes a Markdown parser
50
51
  markdown = Redcarpet::Markdown.new(renderer, extensions = {})
51
- ~~~~~
52
+ ~~~~
52
53
 
53
54
  Here, the `renderer` variable refers to a renderer object, inheriting
54
55
  from `Redcarpet::Render::Base`. If the given object has not been
@@ -59,10 +60,10 @@ Unlike in the RedCloth API, the text to render is passed as an argument
59
60
  and not stored inside the `Markdown` instance, to encourage reusability.
60
61
  Example:
61
62
 
62
- ~~~~~ ruby
63
+ ~~~~ ruby
63
64
  markdown.render("This is *bongos*, indeed.")
64
65
  # => "<p>This is <em>bongos</em>, indeed.</p>"
65
- ~~~~~
66
+ ~~~~
66
67
 
67
68
  You can also specify a hash containing the Markdown extensions which the
68
69
  parser will identify. The following extensions are accepted:
@@ -119,9 +120,9 @@ within the document (e.g. `[^1]: This is a footnote.`).
119
120
 
120
121
  Example:
121
122
 
122
- ~~~ruby
123
+ ~~~~ ruby
123
124
  markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
124
- ~~~~~
125
+ ~~~~
125
126
 
126
127
  Darling, I packed you a couple renderers for lunch
127
128
  --------------------------------------------------
@@ -136,9 +137,9 @@ All the rendering flags that previously applied only to HTML output have
136
137
  now been moved to the `Redcarpet::Render::HTML` class, and may be enabled when
137
138
  instantiating the renderer:
138
139
 
139
- ~~~~~ ruby
140
+ ~~~~ ruby
140
141
  Redcarpet::Render::HTML.new(render_options = {})
141
- ~~~~~
142
+ ~~~~
142
143
 
143
144
  Initializes an HTML renderer. The following flags are available:
144
145
 
@@ -172,9 +173,9 @@ Markdown document had newlines (by default, Markdown ignores these newlines).
172
173
 
173
174
  Example:
174
175
 
175
- ~~~~~ ruby
176
+ ~~~~ ruby
176
177
  renderer = Redcarpet::Render::HTML.new(no_links: true, hard_wrap: true)
177
- ~~~~~
178
+ ~~~~
178
179
 
179
180
 
180
181
  The `HTML` renderer has an alternate version, `Redcarpet::Render::HTML_TOC`,
@@ -182,8 +183,8 @@ which will output a table of contents in HTML based on the headers of the
182
183
  Markdown document.
183
184
 
184
185
  When instantiating this render object, you can optionally pass a `nesting_level`
185
- option which takes an integer and allows you to make it render only headers
186
- until a specific level.
186
+ option which takes an integer or a range and allows you to make it render only
187
+ headers at certain levels.
187
188
 
188
189
  Redcarpet also includes a plaintext renderer, `Redcarpet::Render::StripDown`, that
189
190
  strips out all the formatting:
@@ -205,7 +206,7 @@ And you can even cook your own
205
206
  Custom renderers are created by inheriting from an existing renderer. The
206
207
  built-in renderers, `HTML` and `XHTML` may be extended as such:
207
208
 
208
- ~~~~~ ruby
209
+ ~~~~ ruby
209
210
  # Create a custom renderer that sets a custom class for block-quotes.
210
211
  class CustomRender < Redcarpet::Render::HTML
211
212
  def block_quote(quote)
@@ -213,18 +214,18 @@ class CustomRender < Redcarpet::Render::HTML
213
214
  end
214
215
  end
215
216
 
216
- markdown = Redcarpet::Markdown.new(HTMLwithPygments, fenced_code_blocks: true)
217
- ~~~~~
217
+ markdown = Redcarpet::Markdown.new(CustomRender, fenced_code_blocks: true)
218
+ ~~~~
218
219
 
219
220
  But new renderers can also be created from scratch by extending the abstract
220
221
  base class `Redcarpet::Render::Base` (see `lib/redcarpet/render_man.rb` for
221
222
  an example implementation of a Manpage renderer):
222
223
 
223
- ~~~~~~ ruby
224
+ ~~~~ ruby
224
225
  class ManPage < Redcarpet::Render::Base
225
226
  # you get the drill -- keep going from here
226
227
  end
227
- ~~~~~
228
+ ~~~~
228
229
 
229
230
  The following instance methods may be implemented by the renderer:
230
231
 
@@ -312,7 +313,7 @@ or after the rendering process begins:
312
313
  * postprocess(full_document)
313
314
 
314
315
  You can look at
315
- ["How to extend the Redcarpet 2 Markdown library?"](http://dev.af83.com/2012/02/27/howto-extend-the-redcarpet2-markdown-lib.html)
316
+ ["How to extend the Redcarpet 2 Markdown library?"](https://web.archive.org/web/20170505231254/http://dev.af83.com/2012/02/27/howto-extend-the-redcarpet2-markdown-lib.html)
316
317
  for some more explanations.
317
318
 
318
319
  Also, now our Pants are much smarter
@@ -337,7 +338,7 @@ end
337
338
 
338
339
  # Standalone
339
340
  Redcarpet::Render::SmartyPants.render("<p>Oh SmartyPants, you're so crazy...</p>")
340
- ~~~~~
341
+ ~~~~
341
342
 
342
343
  SmartyPants works on top of already-rendered HTML, and will ignore replacements
343
344
  inside the content of HTML tags and inside specific HTML blocks such as
@@ -362,16 +363,16 @@ renderer-independent, the results will be completely unreliable!
362
363
  Still, if major forces (let's say, tornadoes or other natural disasters) force you
363
364
  to keep a Markdown-compatibility layer, Redcarpet also supports this:
364
365
 
365
- ~~~~~ ruby
366
+ ~~~~ ruby
366
367
  require 'redcarpet/compat'
367
- ~~~~~
368
+ ~~~~
368
369
 
369
370
  Requiring the compatibility library will declare a `Markdown` class with the
370
371
  classical RedCloth API, e.g.
371
372
 
372
- ~~~~~ ruby
373
+ ~~~~ ruby
373
374
  Markdown.new('this is my text').to_html
374
- ~~~~~
375
+ ~~~~
375
376
 
376
377
  This class renders 100% standards compliant Markdown with 0 extensions. Nada.
377
378
  Don't even try to enable extensions with a compatibility layer, because
@@ -306,4 +306,3 @@ sd_autolink__url(
306
306
 
307
307
  return link_end;
308
308
  }
309
-
@@ -86,4 +86,3 @@ void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf,
86
86
  #endif
87
87
 
88
88
  #endif
89
-
@@ -102,4 +102,3 @@ houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size)
102
102
  {
103
103
  houdini_escape_html0(ob, src, size, 1);
104
104
  }
105
-
@@ -326,7 +326,8 @@ rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque)
326
326
  if (ob->size)
327
327
  bufputc(ob, '\n');
328
328
 
329
- if ((options->flags & HTML_TOC) && (level <= options->toc_data.nesting_level)) {
329
+ if ((options->flags & HTML_TOC) && level >= options->toc_data.nesting_bounds[0] &&
330
+ level <= options->toc_data.nesting_bounds[1]) {
330
331
  bufprintf(ob, "<h%d id=\"", level);
331
332
  rndr_header_anchor(ob, text);
332
333
  BUFPUTSL(ob, "\">");
@@ -655,7 +656,7 @@ rndr_footnote_def(struct buf *ob, const struct buf *text, unsigned int num, void
655
656
  bufprintf(ob, "\n<li id=\"fn%d\">\n", num);
656
657
  if (pfound) {
657
658
  bufput(ob, text->data, i);
658
- bufprintf(ob, "&nbsp;<a href=\"#fnref%d\" rev=\"footnote\">&#8617;</a>", num);
659
+ bufprintf(ob, "&nbsp;<a href=\"#fnref%d\">&#8617;</a>", num);
659
660
  bufput(ob, text->data + i, text->size - i);
660
661
  } else if (text) {
661
662
  bufput(ob, text->data, text->size);
@@ -666,7 +667,7 @@ rndr_footnote_def(struct buf *ob, const struct buf *text, unsigned int num, void
666
667
  static int
667
668
  rndr_footnote_ref(struct buf *ob, unsigned int num, void *opaque)
668
669
  {
669
- bufprintf(ob, "<sup id=\"fnref%d\"><a href=\"#fn%d\" rel=\"footnote\">%d</a></sup>", num, num, num);
670
+ bufprintf(ob, "<sup id=\"fnref%d\"><a href=\"#fn%d\">%d</a></sup>", num, num, num);
670
671
  return 1;
671
672
  }
672
673
 
@@ -675,7 +676,8 @@ toc_header(struct buf *ob, const struct buf *text, int level, void *opaque)
675
676
  {
676
677
  struct html_renderopt *options = opaque;
677
678
 
678
- if (level <= options->toc_data.nesting_level) {
679
+ if (level >= options->toc_data.nesting_bounds[0] &&
680
+ level <= options->toc_data.nesting_bounds[1]) {
679
681
  /* set the level offset if this is the first header
680
682
  * we're parsing for the document */
681
683
  if (options->toc_data.current_level == 0)
@@ -824,7 +826,8 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
824
826
  /* Prepare the options pointer */
825
827
  memset(options, 0x0, sizeof(struct html_renderopt));
826
828
  options->flags = render_flags;
827
- options->toc_data.nesting_level = 99;
829
+ options->toc_data.nesting_bounds[0] = 1;
830
+ options->toc_data.nesting_bounds[1] = 6;
828
831
 
829
832
  /* Prepare the callbacks */
830
833
  memcpy(callbacks, &cb_default, sizeof(struct sd_callbacks));
@@ -35,7 +35,7 @@ struct html_renderopt {
35
35
  struct {
36
36
  int current_level;
37
37
  int level_offset;
38
- int nesting_level;
38
+ int nesting_bounds[2];
39
39
  } toc_data;
40
40
 
41
41
  unsigned int flags;
@@ -81,4 +81,3 @@ sdhtml_smartypants(struct buf *ob, const uint8_t *text, size_t size);
81
81
  #endif
82
82
 
83
83
  #endif
84
-
@@ -341,6 +341,7 @@ smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t prev
341
341
  };
342
342
  static const size_t skip_tags_count = 8;
343
343
 
344
+ size_t next_to_closing_a = 0;
344
345
  size_t tag, i = 0;
345
346
 
346
347
  while (i < size && text[i] != '>')
@@ -369,7 +370,23 @@ smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t prev
369
370
  i++;
370
371
  }
371
372
 
373
+ if (sdhtml_is_tag(text, size, "a") == HTML_TAG_CLOSE) {
374
+ while (i < size && text[i] != '>')
375
+ i++;
376
+
377
+ next_to_closing_a = 1;
378
+ }
379
+
372
380
  bufput(ob, text, i + 1);
381
+
382
+ // Pretty tricky: since people may refer to something or someone
383
+ // with a link but use the possessive form right after it, we need
384
+ // to check whether a single quote is next to a closing "</a"> tag.
385
+ if (next_to_closing_a && strncmp("&#39;", text+(i+1), 5) == 0) {
386
+ bufput(ob, "&rsquo;", 7);
387
+ i += 5;
388
+ }
389
+
373
390
  return i;
374
391
  }
375
392
 
@@ -453,5 +470,3 @@ sdhtml_smartypants(struct buf *ob, const uint8_t *text, size_t size)
453
470
  }
454
471
  }
455
472
  }
456
-
457
-
@@ -24,6 +24,7 @@
24
24
 
25
25
  VALUE rb_mRedcarpet;
26
26
  VALUE rb_cMarkdown;
27
+ VALUE rb_cRenderHTML_TOC;
27
28
 
28
29
  extern VALUE rb_cRenderBase;
29
30
 
@@ -101,12 +102,21 @@ static VALUE rb_redcarpet_md__new(int argc, VALUE *argv, VALUE klass)
101
102
  if (!rb_obj_is_kind_of(rb_rndr, rb_cRenderBase))
102
103
  rb_raise(rb_eTypeError, "Invalid Renderer instance given");
103
104
 
105
+ /**
106
+ * Automatically enable the `fenced_code_blocks` option if
107
+ * given a kind of `HTML_TOC` object since many languages
108
+ * like Ruby use the sharp to comment code so these comments
109
+ * would be processed as titles.
110
+ */
111
+ if (rb_obj_is_kind_of(rb_rndr, rb_cRenderHTML_TOC))
112
+ extensions |= MKDEXT_FENCED_CODE;
113
+
104
114
  Data_Get_Struct(rb_rndr, struct rb_redcarpet_rndr, rndr);
105
115
 
106
116
  /* Merge the current options in the @options hash */
107
117
  if (hash != Qnil) {
108
- rndr_options = rb_iv_get(rb_rndr, "@options");
109
- rb_funcall(rndr_options, rb_intern("merge!"), 1, hash);
118
+ rndr_options = rb_funcall(rb_iv_get(rb_rndr, "@options"), rb_intern("merge"), 1, hash);
119
+ rb_iv_set(rb_rndr, "@options", rndr_options);
110
120
  }
111
121
 
112
122
  markdown = sd_markdown_new(extensions, 16, &rndr->callbacks, &rndr->options);
@@ -171,4 +181,3 @@ void Init_redcarpet()
171
181
 
172
182
  Init_redcarpet_rndr();
173
183
  }
174
-
@@ -40,10 +40,10 @@
40
40
  }
41
41
 
42
42
  extern VALUE rb_mRedcarpet;
43
+ extern VALUE rb_cRenderHTML_TOC;
43
44
  VALUE rb_mRender;
44
45
  VALUE rb_cRenderBase;
45
46
  VALUE rb_cRenderHTML;
46
- VALUE rb_cRenderHTML_TOC;
47
47
  VALUE rb_mSmartyPants;
48
48
 
49
49
  #define buf2str(t) ((t) ? rb_enc_str_new((const char*)(t)->data, (t)->size, opt->active_enc) : Qnil)
@@ -390,6 +390,7 @@ static VALUE rb_redcarpet_rbase_alloc(VALUE klass)
390
390
  static void rb_redcarpet__overload(VALUE self, VALUE base_class)
391
391
  {
392
392
  struct rb_redcarpet_rndr *rndr;
393
+ VALUE options_ivar;
393
394
 
394
395
  Data_Get_Struct(self, struct rb_redcarpet_rndr, rndr);
395
396
  rndr->options.self = self;
@@ -411,7 +412,8 @@ static void rb_redcarpet__overload(VALUE self, VALUE base_class)
411
412
  }
412
413
  }
413
414
 
414
- if (rb_iv_get(self, "@options") == Qnil)
415
+ options_ivar = rb_attr_get(self, rb_intern("@options"));
416
+ if (options_ivar == Qundef || options_ivar == Qnil)
415
417
  rb_iv_set(self, "@options", rb_hash_new());
416
418
  }
417
419
 
@@ -511,10 +513,22 @@ static VALUE rb_redcarpet_htmltoc_init(int argc, VALUE *argv, VALUE self)
511
513
  sdhtml_toc_renderer(&rndr->callbacks, (struct html_renderopt *)&rndr->options.html, render_flags);
512
514
  rb_redcarpet__overload(self, rb_cRenderHTML_TOC);
513
515
 
514
- if (!(NIL_P(nesting_level)))
515
- rndr->options.html.toc_data.nesting_level = NUM2INT(nesting_level);
516
- else
517
- rndr->options.html.toc_data.nesting_level = 6;
516
+ /* Check whether we are dealing with a Range object by
517
+ checking whether the object responds to min and max */
518
+ if (rb_respond_to(nesting_level, rb_intern("min")) &&
519
+ rb_respond_to(nesting_level, rb_intern("max"))) {
520
+ int min = NUM2INT(rb_funcall(nesting_level, rb_intern("min"), 0));
521
+ int max = NUM2INT(rb_funcall(nesting_level, rb_intern("max"), 0));
522
+
523
+ rndr->options.html.toc_data.nesting_bounds[0] = min;
524
+ rndr->options.html.toc_data.nesting_bounds[1] = max;
525
+ } else if (FIXNUM_P(nesting_level)) {
526
+ rndr->options.html.toc_data.nesting_bounds[0] = 1;
527
+ rndr->options.html.toc_data.nesting_bounds[1] = NUM2INT(nesting_level);
528
+ } else {
529
+ rndr->options.html.toc_data.nesting_bounds[0] = 1;
530
+ rndr->options.html.toc_data.nesting_bounds[1] = 6;
531
+ }
518
532
 
519
533
  return Qnil;
520
534
  }
@@ -2,7 +2,7 @@ require 'redcarpet.so'
2
2
  require 'redcarpet/compat'
3
3
 
4
4
  module Redcarpet
5
- VERSION = '3.4.0'
5
+ VERSION = '3.5.0'
6
6
 
7
7
  class Markdown
8
8
  attr_reader :renderer
@@ -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, :highlight,
16
+ :superscript, :highlight, :quote,
17
17
 
18
18
  # footnotes
19
19
  :footnotes, :footnote_def, :footnote_ref,
@@ -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.4.0'
4
+ s.version = '3.5.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 = '2016-12-25'
7
+ s.date = '2019-07-29'
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,7 +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", "~> 10.5"
69
- s.add_development_dependency "rake-compiler", "~> 0.9.5"
70
- s.add_development_dependency "test-unit", "~> 3.1.3"
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"
71
71
  end
@@ -36,6 +36,16 @@ class CustomRenderTest < Redcarpet::TestCase
36
36
  assert_match "no_intra_emphasis", output
37
37
  end
38
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
+
39
49
  class NilPreprocessRenderer < Redcarpet::Render::HTML
40
50
  def preprocess(fulldoc)
41
51
  nil
@@ -140,14 +140,14 @@ class HTMLRenderTest < Redcarpet::TestCase
140
140
  Markdown
141
141
 
142
142
  html = <<-HTML.chomp.strip_heredoc
143
- <p>This is a footnote.<sup id="fnref1"><a href="#fn1" rel="footnote">1</a></sup></p>
143
+ <p>This is a footnote.<sup id="fnref1"><a href="#fn1">1</a></sup></p>
144
144
 
145
145
  <div class="footnotes">
146
146
  <hr>
147
147
  <ol>
148
148
 
149
149
  <li id="fn1">
150
- <p>It provides additional information.&nbsp;<a href="#fnref1" rev="footnote">&#8617;</a></p>
150
+ <p>It provides additional information.&nbsp;<a href="#fnref1">&#8617;</a></p>
151
151
  </li>
152
152
 
153
153
  </ol>
@@ -254,7 +254,13 @@ class HTMLRenderTest < Redcarpet::TestCase
254
254
 
255
255
  def test_utf8_only_header_anchors
256
256
  markdown = "# 見出し"
257
- html = "<h1 id=\"part-37870bfa194139f\">見出し</h1>"
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
258
264
 
259
265
  assert_equal html, render(markdown, with: [:with_toc_data])
260
266
  end
@@ -33,6 +33,20 @@ class HTMLTOCRenderTest < Redcarpet::TestCase
33
33
  assert !output.include?("A sub-sub title")
34
34
  end
35
35
 
36
+ def test_granular_toc_render_with_range
37
+ output = render(@markdown, with: { nesting_level: 2..5 }).strip
38
+
39
+ assert output.start_with?("<ul>")
40
+ assert output.end_with?("</ul>")
41
+
42
+ assert output.match("Another one")
43
+ assert output.match("A sub-sub-title")
44
+ assert output.match("見出し")
45
+
46
+ refute output.match("A title")
47
+ refute output.match("A really tiny title")
48
+ end
49
+
36
50
  def test_toc_heading_id
37
51
  output = render(@markdown)
38
52
 
@@ -40,7 +54,8 @@ class HTMLTOCRenderTest < Redcarpet::TestCase
40
54
  assert_match /a-nice-subtitle/, output
41
55
  assert_match /another-one/, output
42
56
  assert_match /a-sub-sub-title/, output
43
- assert_match /part-37870bfa194139f/, output
57
+ # the part number length varies depending on architecture (32b or 64b)
58
+ assert_match /part-(37870bf)?a194139f/, output
44
59
  end
45
60
 
46
61
  def test_toc_heading_with_hyphen_and_equal
@@ -79,4 +94,19 @@ class HTMLTOCRenderTest < Redcarpet::TestCase
79
94
  assert_match "&lt;strong&gt;", output
80
95
  assert_no_match %r{<strong>}, output
81
96
  end
97
+
98
+ def test_ignoring_fenced_code_blocks_comments
99
+ markdown = <<-Markdown.strip_heredoc
100
+ # Hello world !
101
+
102
+ ~~~ruby
103
+ # This is a comment
104
+ ~~~
105
+ Markdown
106
+
107
+ output = render(markdown)
108
+
109
+ assert output.match("Hello world")
110
+ refute output.match("This is a comment")
111
+ end
82
112
  end
@@ -64,8 +64,8 @@ class RedcarpetBinTest < Redcarpet::TestCase
64
64
 
65
65
  def run_bin(*args)
66
66
  bin_path = File.expand_path('../../bin/redcarpet', __FILE__)
67
- ruby = "ruby " if RUBY_PLATFORM =~ /mswin|mingw/
68
- IO.popen("#{ruby}#{bin_path} #{args.join(" ")}") do |stream|
67
+ ruby = RbConfig.ruby
68
+ IO.popen("#{ruby} #{bin_path} #{args.join(" ")}") do |stream|
69
69
  @output = stream.read
70
70
  end
71
71
  end
@@ -42,4 +42,10 @@ class SmartyHTMLTest < Redcarpet::TestCase
42
42
  expected = "It&#39;s a test of &quot;code&quot;"
43
43
  assert rd.include?(expected), "\"#{rd}\" should contain \"#{expected}\""
44
44
  end
45
+
46
+ def test_that_smartyhtml_ignores_links_for_single_quotes
47
+ output = render("[John](link)'s cat")
48
+ expected = %(<p><a href="link">John</a>&rsquo;s cat</p>)
49
+ assert_equal expected, output
50
+ end
45
51
  end
@@ -58,4 +58,12 @@ class StripDownRender < Redcarpet::TestCase
58
58
 
59
59
  assert_equal expected, output
60
60
  end
61
+
62
+ def test_with_quote_option_enabled
63
+ markdown = %(A common idiom is "Hello world")
64
+ expected = %(A common idiom is Hello world)
65
+ output = render(markdown, with: [:quote])
66
+
67
+ assert_equal expected, output
68
+ end
61
69
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redcarpet
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Natacha Porté
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-12-25 00:00:00.000000000 Z
12
+ date: 2019-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -17,42 +17,42 @@ dependencies:
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '10.5'
20
+ version: 12.2.1
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '10.5'
27
+ version: 12.2.1
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rake-compiler
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 0.9.5
34
+ version: 1.0.3
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 0.9.5
41
+ version: 1.0.3
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: test-unit
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: 3.1.3
48
+ version: 3.2.3
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: 3.1.3
55
+ version: 3.2.3
56
56
  description: A fast, safe and extensible Markdown to (X)HTML parser
57
57
  email: vicent@github.com
58
58
  executables:
@@ -126,8 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
126
  - !ruby/object:Gem::Version
127
127
  version: '0'
128
128
  requirements: []
129
- rubyforge_project:
130
- rubygems_version: 2.5.2
129
+ rubygems_version: 3.0.3
131
130
  signing_key:
132
131
  specification_version: 4
133
132
  summary: Markdown that smells nice