redcarpet 3.4.0 → 3.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +2 -2
- data/README.markdown +24 -23
- data/ext/redcarpet/autolink.c +0 -1
- data/ext/redcarpet/buffer.h +0 -1
- data/ext/redcarpet/houdini_html_e.c +0 -1
- data/ext/redcarpet/html.c +16 -6
- data/ext/redcarpet/html.h +1 -2
- data/ext/redcarpet/html_smartypants.c +17 -2
- data/ext/redcarpet/rc_markdown.c +12 -3
- data/ext/redcarpet/rc_render.c +20 -6
- data/lib/redcarpet.rb +1 -1
- data/lib/redcarpet/compat.rb +0 -2
- data/lib/redcarpet/render_strip.rb +1 -1
- data/redcarpet.gemspec +5 -5
- data/test/custom_render_test.rb +10 -0
- data/test/html_render_test.rb +9 -3
- data/test/html_toc_render_test.rb +31 -1
- data/test/markdown_test.rb +10 -0
- data/test/redcarpet_bin_test.rb +2 -2
- data/test/smarty_html_test.rb +6 -0
- data/test/stripdown_render_test.rb +8 -0
- metadata +12 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3e6ea78031a1e40620168cd57fcbfae06bec5bafabc8f6e600adc552a4fe5b40
|
4
|
+
data.tar.gz: 658dd33e836daa11effa88e0491d09387963ea349751efd278e9fbdac7026066
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b17b0208c25d4e8566fb4a154d0f66e778b702abcf58d1d1227fa2510be421c7496e20fd6402066adba3485778e935b46aff73fd412802eedb89e44470a7ad94
|
7
|
+
data.tar.gz: 1e1c8dd559979b8bd5f4de2d20e1127b2a964c03a267133c3d9a3703f71bce44a2f4dc2efdb0dc0cc331e0ab779bfad23e9b62af0ffc4ee9078896376bd86865
|
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
186
|
-
|
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
|
-
|
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(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/ext/redcarpet/autolink.c
CHANGED
data/ext/redcarpet/buffer.h
CHANGED
data/ext/redcarpet/html.c
CHANGED
@@ -255,8 +255,15 @@ rndr_quote(struct buf *ob, const struct buf *text, void *opaque)
|
|
255
255
|
if (!text || !text->size)
|
256
256
|
return 0;
|
257
257
|
|
258
|
+
struct html_renderopt *options = opaque;
|
259
|
+
|
258
260
|
BUFPUTSL(ob, "<q>");
|
259
|
-
|
261
|
+
|
262
|
+
if (options->flags & HTML_ESCAPE)
|
263
|
+
escape_html(ob, text->data, text->size);
|
264
|
+
else
|
265
|
+
bufput(ob, text->data, text->size);
|
266
|
+
|
260
267
|
BUFPUTSL(ob, "</q>");
|
261
268
|
|
262
269
|
return 1;
|
@@ -326,7 +333,8 @@ rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque)
|
|
326
333
|
if (ob->size)
|
327
334
|
bufputc(ob, '\n');
|
328
335
|
|
329
|
-
if ((options->flags & HTML_TOC) &&
|
336
|
+
if ((options->flags & HTML_TOC) && level >= options->toc_data.nesting_bounds[0] &&
|
337
|
+
level <= options->toc_data.nesting_bounds[1]) {
|
330
338
|
bufprintf(ob, "<h%d id=\"", level);
|
331
339
|
rndr_header_anchor(ob, text);
|
332
340
|
BUFPUTSL(ob, "\">");
|
@@ -655,7 +663,7 @@ rndr_footnote_def(struct buf *ob, const struct buf *text, unsigned int num, void
|
|
655
663
|
bufprintf(ob, "\n<li id=\"fn%d\">\n", num);
|
656
664
|
if (pfound) {
|
657
665
|
bufput(ob, text->data, i);
|
658
|
-
bufprintf(ob, " <a href=\"#fnref%d\"
|
666
|
+
bufprintf(ob, " <a href=\"#fnref%d\">↩</a>", num);
|
659
667
|
bufput(ob, text->data + i, text->size - i);
|
660
668
|
} else if (text) {
|
661
669
|
bufput(ob, text->data, text->size);
|
@@ -666,7 +674,7 @@ rndr_footnote_def(struct buf *ob, const struct buf *text, unsigned int num, void
|
|
666
674
|
static int
|
667
675
|
rndr_footnote_ref(struct buf *ob, unsigned int num, void *opaque)
|
668
676
|
{
|
669
|
-
bufprintf(ob, "<sup id=\"fnref%d\"><a href=\"#fn%d\"
|
677
|
+
bufprintf(ob, "<sup id=\"fnref%d\"><a href=\"#fn%d\">%d</a></sup>", num, num, num);
|
670
678
|
return 1;
|
671
679
|
}
|
672
680
|
|
@@ -675,7 +683,8 @@ toc_header(struct buf *ob, const struct buf *text, int level, void *opaque)
|
|
675
683
|
{
|
676
684
|
struct html_renderopt *options = opaque;
|
677
685
|
|
678
|
-
if (level
|
686
|
+
if (level >= options->toc_data.nesting_bounds[0] &&
|
687
|
+
level <= options->toc_data.nesting_bounds[1]) {
|
679
688
|
/* set the level offset if this is the first header
|
680
689
|
* we're parsing for the document */
|
681
690
|
if (options->toc_data.current_level == 0)
|
@@ -824,7 +833,8 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
|
|
824
833
|
/* Prepare the options pointer */
|
825
834
|
memset(options, 0x0, sizeof(struct html_renderopt));
|
826
835
|
options->flags = render_flags;
|
827
|
-
options->toc_data.
|
836
|
+
options->toc_data.nesting_bounds[0] = 1;
|
837
|
+
options->toc_data.nesting_bounds[1] = 6;
|
828
838
|
|
829
839
|
/* Prepare the callbacks */
|
830
840
|
memcpy(callbacks, &cb_default, sizeof(struct sd_callbacks));
|
data/ext/redcarpet/html.h
CHANGED
@@ -35,7 +35,7 @@ struct html_renderopt {
|
|
35
35
|
struct {
|
36
36
|
int current_level;
|
37
37
|
int level_offset;
|
38
|
-
int
|
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("'", text+(i+1), 5) == 0) {
|
386
|
+
bufput(ob, "’", 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
|
-
|
data/ext/redcarpet/rc_markdown.c
CHANGED
@@ -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
|
-
|
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
|
-
|
data/ext/redcarpet/rc_render.c
CHANGED
@@ -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
|
-
|
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
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
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
|
}
|
data/lib/redcarpet.rb
CHANGED
data/lib/redcarpet/compat.rb
CHANGED
@@ -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,
|
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 = '3.
|
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 = '
|
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,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", "~>
|
69
|
-
s.add_development_dependency "rake-compiler", "~> 0.
|
70
|
-
s.add_development_dependency "test-unit", "~> 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
|
data/test/custom_render_test.rb
CHANGED
@@ -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
|
data/test/html_render_test.rb
CHANGED
@@ -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"
|
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. <a href="#fnref1"
|
150
|
+
<p>It provides additional information. <a href="#fnref1">↩</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
|
-
|
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
|
-
|
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 "<strong>", 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
|
data/test/markdown_test.rb
CHANGED
@@ -220,6 +220,16 @@ class MarkdownTest < Redcarpet::TestCase
|
|
220
220
|
assert_equal '<p>this is a <q>quote</q></p>', output
|
221
221
|
end
|
222
222
|
|
223
|
+
def test_quote_flag_honors_escape_html
|
224
|
+
text = 'We are not "<svg/onload=pwned>"'
|
225
|
+
|
226
|
+
output_enabled = render(text, with: [:quote, :escape_html])
|
227
|
+
output_disabled = render(text, with: [:quote])
|
228
|
+
|
229
|
+
assert_equal "<p>We are not <q><svg/onload=pwned></q></p>", output_enabled
|
230
|
+
assert_equal "<p>We are not <q><svg/onload=pwned></q></p>", output_disabled
|
231
|
+
end
|
232
|
+
|
223
233
|
def test_that_fenced_flag_works
|
224
234
|
text = <<-fenced.strip_heredoc
|
225
235
|
This is a simple test
|
data/test/redcarpet_bin_test.rb
CHANGED
@@ -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 =
|
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
|
data/test/smarty_html_test.rb
CHANGED
@@ -42,4 +42,10 @@ class SmartyHTMLTest < Redcarpet::TestCase
|
|
42
42
|
expected = "It's a test of "code""
|
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>’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,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redcarpet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Natacha Porté
|
8
8
|
- Vicent Martí
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-12-15 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:
|
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:
|
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.
|
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.
|
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.
|
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.
|
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:
|
@@ -111,7 +111,7 @@ homepage: http://github.com/vmg/redcarpet
|
|
111
111
|
licenses:
|
112
112
|
- MIT
|
113
113
|
metadata: {}
|
114
|
-
post_install_message:
|
114
|
+
post_install_message:
|
115
115
|
rdoc_options: []
|
116
116
|
require_paths:
|
117
117
|
- lib
|
@@ -126,9 +126,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
126
|
- !ruby/object:Gem::Version
|
127
127
|
version: '0'
|
128
128
|
requirements: []
|
129
|
-
|
130
|
-
|
131
|
-
signing_key:
|
129
|
+
rubygems_version: 3.1.4
|
130
|
+
signing_key:
|
132
131
|
specification_version: 4
|
133
132
|
summary: Markdown that smells nice
|
134
133
|
test_files:
|