redcarpet 3.3.4 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of redcarpet might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.markdown +21 -11
- data/ext/redcarpet/autolink.c +7 -0
- data/ext/redcarpet/houdini_href_e.c +5 -11
- data/ext/redcarpet/html.c +18 -1
- data/ext/redcarpet/html_blocks.h +68 -70
- data/ext/redcarpet/html_smartypants.c +3 -3
- data/ext/redcarpet/markdown.c +5 -7
- data/ext/redcarpet/rc_markdown.c +7 -1
- data/ext/redcarpet/rc_render.c +9 -0
- data/lib/redcarpet.rb +1 -1
- data/lib/redcarpet/cli.rb +1 -1
- data/redcarpet.gemspec +3 -2
- data/test/custom_render_test.rb +30 -1
- data/test/html5_test.rb +51 -38
- data/test/html_render_test.rb +80 -60
- data/test/html_toc_render_test.rb +11 -4
- data/test/markdown_test.rb +216 -181
- data/test/redcarpet_bin_test.rb +2 -2
- data/test/smarty_html_test.rb +5 -5
- data/test/smarty_pants_test.rb +5 -0
- data/test/stripdown_render_test.rb +6 -6
- data/test/test_helper.rb +9 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54a531e17acc94f275045e633bab8458df9c0075
|
4
|
+
data.tar.gz: 407c3e570ffbaff80b809ab344fb4a7d27b1b97f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d7189a86a6ed3451e823f2b75acfc2c7086f73e02e22ece1490b25fba5df75d149c8d1ce61cef47c7604aa0a941e090bbff93f5623d501d78e3cf2ef5836d89
|
7
|
+
data.tar.gz: 34e6b6980076319b5094c1766687c31b21ace1d2e5d96f7b291f36f60350d727b40f87f14a870f16601732532ca4ad469a79430312ac5b72eda18ef9f4e1e364
|
data/README.markdown
CHANGED
@@ -25,7 +25,7 @@ Starting with Redcarpet 3.0, the minimum required Ruby version is 1.9.2 (or Rubi
|
|
25
25
|
|
26
26
|
$ [sudo] gem install redcarpet
|
27
27
|
|
28
|
-
If you need to use it with Ruby 1.8.7, you will
|
28
|
+
If you need to use it with Ruby 1.8.7, you will have to stick with 2.3.0:
|
29
29
|
|
30
30
|
$ [sudo] gem install redcarpet -v 2.3.0
|
31
31
|
|
@@ -185,9 +185,18 @@ When instantiating this render object, you can optionally pass a `nesting_level`
|
|
185
185
|
option which takes an integer and allows you to make it render only headers
|
186
186
|
until a specific level.
|
187
187
|
|
188
|
-
|
189
|
-
|
190
|
-
|
188
|
+
Redcarpet also includes a plaintext renderer, `Redcarpet::Render::StripDown`, that
|
189
|
+
strips out all the formatting:
|
190
|
+
|
191
|
+
~~~~ ruby
|
192
|
+
require 'redcarpet'
|
193
|
+
require 'redcarpet/render_strip'
|
194
|
+
|
195
|
+
markdown = Redcarpet::Markdown.new(Redcarpet::Render::StripDown)
|
196
|
+
|
197
|
+
markdown.render("**This** _is_ an [example](http://example.org/).")
|
198
|
+
# => "This is an example (http://example.org/)."
|
199
|
+
~~~~
|
191
200
|
|
192
201
|
|
193
202
|
And you can even cook your own
|
@@ -197,18 +206,19 @@ Custom renderers are created by inheriting from an existing renderer. The
|
|
197
206
|
built-in renderers, `HTML` and `XHTML` may be extended as such:
|
198
207
|
|
199
208
|
~~~~~ ruby
|
200
|
-
#
|
201
|
-
class
|
202
|
-
def
|
203
|
-
|
209
|
+
# Create a custom renderer that sets a custom class for block-quotes.
|
210
|
+
class CustomRender < Redcarpet::Render::HTML
|
211
|
+
def block_quote(quote)
|
212
|
+
%(<blockquote class="my-custom-class">#{quote}</blockquote>)
|
204
213
|
end
|
205
214
|
end
|
206
215
|
|
207
216
|
markdown = Redcarpet::Markdown.new(HTMLwithPygments, fenced_code_blocks: true)
|
208
217
|
~~~~~
|
209
218
|
|
210
|
-
But new renderers can also be created from scratch
|
211
|
-
|
219
|
+
But new renderers can also be created from scratch by extending the abstract
|
220
|
+
base class `Redcarpet::Render::Base` (see `lib/redcarpet/render_man.rb` for
|
221
|
+
an example implementation of a Manpage renderer):
|
212
222
|
|
213
223
|
~~~~~~ ruby
|
214
224
|
class ManPage < Redcarpet::Render::Base
|
@@ -373,7 +383,7 @@ monkeypatches the Markdown class, you're a terrible human being. Just saying.
|
|
373
383
|
Boring legal stuff
|
374
384
|
------------------
|
375
385
|
|
376
|
-
Copyright (c) 2011-
|
386
|
+
Copyright (c) 2011-2016, Vicent Martí
|
377
387
|
|
378
388
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
379
389
|
of this software and associated documentation files (the "Software"), to deal
|
data/ext/redcarpet/autolink.c
CHANGED
@@ -294,6 +294,13 @@ sd_autolink__url(
|
|
294
294
|
if (link_end == 0)
|
295
295
|
return 0;
|
296
296
|
|
297
|
+
/**
|
298
|
+
* In certain cases, we may refer to a link at the end of a
|
299
|
+
* sentence so the period should not be part of the URL.
|
300
|
+
*/
|
301
|
+
if (data[link_end - 1] == '.')
|
302
|
+
link_end--;
|
303
|
+
|
297
304
|
bufput(link, data - rewind, link_end + rewind);
|
298
305
|
*rewind_p = rewind;
|
299
306
|
|
@@ -44,10 +44,10 @@
|
|
44
44
|
* have its native function (i.e. as an URL
|
45
45
|
* component/separator) and hence needs no escaping.
|
46
46
|
*
|
47
|
-
* There
|
48
|
-
*
|
49
|
-
*
|
50
|
-
*
|
47
|
+
* There is one exception: the ' (single quote)
|
48
|
+
* character does not appear in the table.
|
49
|
+
* It is meant to appear in the URL as components,
|
50
|
+
* however it require special HTML-entity escaping
|
51
51
|
* to generate valid HTML markup.
|
52
52
|
*
|
53
53
|
* All other characters will be escaped to %XX.
|
@@ -56,7 +56,7 @@
|
|
56
56
|
static const char HREF_SAFE[] = {
|
57
57
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
58
58
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
59
|
-
0, 1, 0, 1, 1, 1,
|
59
|
+
0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
60
60
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
|
61
61
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
62
62
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
|
@@ -95,12 +95,6 @@ houdini_escape_href(struct buf *ob, const uint8_t *src, size_t size)
|
|
95
95
|
break;
|
96
96
|
|
97
97
|
switch (src[i]) {
|
98
|
-
/* amp appears all the time in URLs, but needs
|
99
|
-
* HTML-entity escaping to be inside an href */
|
100
|
-
case '&':
|
101
|
-
BUFPUTSL(ob, "&");
|
102
|
-
break;
|
103
|
-
|
104
98
|
/* the single quote is a valid URL character
|
105
99
|
* according to the standard; it needs HTML
|
106
100
|
* entity escaping too */
|
data/ext/redcarpet/html.c
CHANGED
@@ -281,13 +281,20 @@ rndr_header_anchor(struct buf *out, const struct buf *anchor)
|
|
281
281
|
int stripped = 0, inserted = 0;
|
282
282
|
|
283
283
|
for (; i < size; ++i) {
|
284
|
+
// skip html tags
|
284
285
|
if (a[i] == '<') {
|
285
286
|
while (i < size && a[i] != '>')
|
286
287
|
i++;
|
288
|
+
// skip html entities
|
289
|
+
} else if (a[i] == '&') {
|
290
|
+
while (i < size && a[i] != ';')
|
291
|
+
i++;
|
287
292
|
}
|
293
|
+
// replace non-ascii or invalid characters with dashes
|
288
294
|
else if (!isascii(a[i]) || strchr(STRIPPED, a[i])) {
|
289
295
|
if (inserted && !stripped)
|
290
296
|
bufputc(out, '-');
|
297
|
+
// and do it only once
|
291
298
|
stripped = 1;
|
292
299
|
}
|
293
300
|
else {
|
@@ -297,8 +304,18 @@ rndr_header_anchor(struct buf *out, const struct buf *anchor)
|
|
297
304
|
}
|
298
305
|
}
|
299
306
|
|
300
|
-
if
|
307
|
+
// replace the last dash if there was anything added
|
308
|
+
if (stripped && inserted)
|
301
309
|
out->size--;
|
310
|
+
|
311
|
+
// if anchor found empty, use djb2 hash for it
|
312
|
+
if (!inserted && anchor->size) {
|
313
|
+
unsigned long hash = 5381;
|
314
|
+
for (i = 0; i < size; ++i) {
|
315
|
+
hash = ((hash << 5) + hash) + a[i]; /* h * 33 + c */
|
316
|
+
}
|
317
|
+
bufprintf(out, "part-%lx", hash);
|
318
|
+
}
|
302
319
|
}
|
303
320
|
|
304
321
|
static void
|
data/ext/redcarpet/html_blocks.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
/* C code produced by gperf version 3.0.
|
1
|
+
/* C code produced by gperf version 3.0.3 */
|
2
2
|
/* Command-line: gperf -N find_block_tag -H hash_block_tag -C -c -E --ignore-case html_block_names.txt */
|
3
|
-
/* See
|
3
|
+
/* See https://git.io/vPLqa for the list of recognized elements */
|
4
4
|
/* Computed positions: -k'1-2' */
|
5
5
|
|
6
6
|
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
@@ -30,7 +30,7 @@
|
|
30
30
|
error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
|
31
31
|
#endif
|
32
32
|
|
33
|
-
/* maximum key range =
|
33
|
+
/* maximum key range = 72, duplicates = 0 */
|
34
34
|
|
35
35
|
#ifndef GPERF_DOWNCASE
|
36
36
|
#define GPERF_DOWNCASE 1
|
@@ -94,34 +94,34 @@ hash_block_tag (str, len)
|
|
94
94
|
{
|
95
95
|
static const unsigned char asso_values[] =
|
96
96
|
{
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
0,
|
105
|
-
0,
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
97
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
98
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
99
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
100
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
101
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
102
|
+
26, 60, 55, 45, 40, 35, 73, 73, 73, 73,
|
103
|
+
73, 73, 73, 73, 73, 20, 15, 15, 0, 35,
|
104
|
+
0, 25, 10, 10, 5, 73, 73, 0, 15, 15,
|
105
|
+
0, 73, 73, 15, 20, 10, 10, 73, 73, 73,
|
106
|
+
73, 73, 73, 73, 73, 73, 73, 20, 15, 15,
|
107
|
+
0, 35, 0, 25, 10, 10, 5, 73, 73, 0,
|
108
|
+
15, 15, 0, 73, 73, 15, 20, 10, 10, 73,
|
109
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
110
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
111
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
112
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
113
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
114
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
115
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
116
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
117
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
118
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
119
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
120
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
121
|
+
73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
|
122
|
+
73, 73, 73, 73, 73, 73, 73
|
123
123
|
};
|
124
|
-
register int hval = len;
|
124
|
+
register unsigned int hval = len;
|
125
125
|
|
126
126
|
switch (hval)
|
127
127
|
{
|
@@ -135,12 +135,6 @@ hash_block_tag (str, len)
|
|
135
135
|
return hval;
|
136
136
|
}
|
137
137
|
|
138
|
-
#ifdef __GNUC__
|
139
|
-
__inline
|
140
|
-
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
|
141
|
-
__attribute__ ((__gnu_inline__))
|
142
|
-
#endif
|
143
|
-
#endif
|
144
138
|
const char *
|
145
139
|
find_block_tag (str, len)
|
146
140
|
register const char *str;
|
@@ -148,76 +142,80 @@ find_block_tag (str, len)
|
|
148
142
|
{
|
149
143
|
enum
|
150
144
|
{
|
151
|
-
TOTAL_KEYWORDS =
|
145
|
+
TOTAL_KEYWORDS = 43,
|
152
146
|
MIN_WORD_LENGTH = 1,
|
153
147
|
MAX_WORD_LENGTH = 10,
|
154
148
|
MIN_HASH_VALUE = 1,
|
155
|
-
MAX_HASH_VALUE =
|
149
|
+
MAX_HASH_VALUE = 72
|
156
150
|
};
|
157
151
|
|
158
152
|
static const char * const wordlist[] =
|
159
153
|
{
|
160
154
|
"",
|
161
155
|
"p",
|
162
|
-
"
|
163
|
-
"
|
156
|
+
"dl",
|
157
|
+
"del",
|
164
158
|
"form",
|
165
|
-
"
|
159
|
+
"",
|
166
160
|
"footer",
|
167
|
-
"
|
168
|
-
"",
|
161
|
+
"details",
|
162
|
+
"div",
|
163
|
+
"", "",
|
169
164
|
"figure",
|
170
|
-
"
|
165
|
+
"ul",
|
171
166
|
"fieldset",
|
172
|
-
"
|
167
|
+
"",
|
173
168
|
"figcaption",
|
174
169
|
"header",
|
175
|
-
"
|
176
|
-
"
|
177
|
-
"",
|
178
|
-
"
|
170
|
+
"ol",
|
171
|
+
"pre",
|
172
|
+
"math",
|
173
|
+
"video",
|
179
174
|
"script",
|
180
|
-
"
|
181
|
-
"
|
175
|
+
"section",
|
176
|
+
"noscript",
|
182
177
|
"",
|
183
|
-
"
|
178
|
+
"blockquote",
|
184
179
|
"hgroup",
|
185
|
-
"
|
186
|
-
"
|
187
|
-
"",
|
180
|
+
"hr",
|
181
|
+
"ins",
|
182
|
+
"",
|
183
|
+
"style",
|
184
|
+
"output",
|
185
|
+
"summary",
|
186
|
+
"nav",
|
187
|
+
"",
|
188
|
+
"audio",
|
188
189
|
"canvas",
|
189
190
|
"dd",
|
190
|
-
"
|
191
|
+
"h1",
|
191
192
|
"abbr",
|
192
|
-
"audio",
|
193
|
-
"iframe",
|
194
|
-
"address",
|
195
|
-
"ins",
|
196
|
-
"",
|
197
193
|
"table",
|
198
|
-
"",
|
199
|
-
"
|
194
|
+
"iframe",
|
195
|
+
"article",
|
200
196
|
"", "",
|
201
197
|
"aside",
|
202
|
-
"
|
203
|
-
"
|
198
|
+
"",
|
199
|
+
"h6",
|
204
200
|
"", "",
|
205
201
|
"tfoot",
|
206
202
|
"",
|
203
|
+
"h5",
|
204
|
+
"", "", "", "",
|
207
205
|
"h4",
|
208
206
|
"", "", "", "",
|
209
|
-
"
|
207
|
+
"address",
|
210
208
|
"", "", "", "",
|
211
|
-
"
|
209
|
+
"h3",
|
212
210
|
"", "", "", "",
|
213
|
-
"
|
211
|
+
"h2"
|
214
212
|
};
|
215
213
|
|
216
214
|
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
|
217
215
|
{
|
218
|
-
|
216
|
+
unsigned int key = hash_block_tag (str, len);
|
219
217
|
|
220
|
-
if (key <= MAX_HASH_VALUE
|
218
|
+
if (key <= MAX_HASH_VALUE)
|
221
219
|
{
|
222
220
|
register const char *s = wordlist[key];
|
223
221
|
|
@@ -151,6 +151,9 @@ smartypants_squote(struct buf *ob, struct smartypants_data *smrt, uint8_t previo
|
|
151
151
|
return next_squote_len;
|
152
152
|
}
|
153
153
|
|
154
|
+
if (smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 's', &smrt->in_squote))
|
155
|
+
return 0;
|
156
|
+
|
154
157
|
// trailing single quotes: students', tryin'
|
155
158
|
if (word_boundary(t1)) {
|
156
159
|
BUFPUTSL(ob, "’");
|
@@ -178,9 +181,6 @@ smartypants_squote(struct buf *ob, struct smartypants_data *smrt, uint8_t previo
|
|
178
181
|
}
|
179
182
|
}
|
180
183
|
|
181
|
-
if (smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 's', &smrt->in_squote))
|
182
|
-
return 0;
|
183
|
-
|
184
184
|
bufput(ob, squote_text, squote_size);
|
185
185
|
return 0;
|
186
186
|
}
|
data/ext/redcarpet/markdown.c
CHANGED
@@ -92,7 +92,6 @@ typedef size_t
|
|
92
92
|
|
93
93
|
static size_t char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
94
94
|
static size_t char_underline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
95
|
-
static size_t char_highlight(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
96
95
|
static size_t char_quote(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
97
96
|
static size_t char_linebreak(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
98
97
|
static size_t char_codespan(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
@@ -613,7 +612,7 @@ parse_emph1(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size
|
|
613
612
|
if (data[i] == c && !_isspace(data[i - 1])) {
|
614
613
|
|
615
614
|
if (rndr->ext_flags & MKDEXT_NO_INTRA_EMPHASIS) {
|
616
|
-
if (i +
|
615
|
+
if (i + 1 < size && _isalnum(data[i + 1]))
|
617
616
|
continue;
|
618
617
|
}
|
619
618
|
|
@@ -845,7 +844,6 @@ char_quote(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offse
|
|
845
844
|
return end;
|
846
845
|
}
|
847
846
|
|
848
|
-
|
849
847
|
/* char_escape • '\\' backslash escape */
|
850
848
|
static size_t
|
851
849
|
char_escape(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size)
|
@@ -2339,7 +2337,7 @@ parse_table_header(
|
|
2339
2337
|
if (i < under_end && data[i] != '|' && data[i] != '+')
|
2340
2338
|
break;
|
2341
2339
|
|
2342
|
-
if (dashes <
|
2340
|
+
if (dashes < 1)
|
2343
2341
|
break;
|
2344
2342
|
|
2345
2343
|
i++;
|
@@ -2757,10 +2755,13 @@ sd_markdown_new(
|
|
2757
2755
|
if (md->cb.emphasis || md->cb.double_emphasis || md->cb.triple_emphasis) {
|
2758
2756
|
md->active_char['*'] = MD_CHAR_EMPHASIS;
|
2759
2757
|
md->active_char['_'] = MD_CHAR_EMPHASIS;
|
2758
|
+
|
2760
2759
|
if (extensions & MKDEXT_STRIKETHROUGH)
|
2761
2760
|
md->active_char['~'] = MD_CHAR_EMPHASIS;
|
2762
2761
|
if (extensions & MKDEXT_HIGHLIGHT)
|
2763
2762
|
md->active_char['='] = MD_CHAR_EMPHASIS;
|
2763
|
+
if (extensions & MKDEXT_QUOTE)
|
2764
|
+
md->active_char['"'] = MD_CHAR_QUOTE;
|
2764
2765
|
}
|
2765
2766
|
|
2766
2767
|
if (md->cb.codespan)
|
@@ -2785,9 +2786,6 @@ sd_markdown_new(
|
|
2785
2786
|
if (extensions & MKDEXT_SUPERSCRIPT)
|
2786
2787
|
md->active_char['^'] = MD_CHAR_SUPERSCRIPT;
|
2787
2788
|
|
2788
|
-
if (extensions & MKDEXT_QUOTE)
|
2789
|
-
md->active_char['"'] = MD_CHAR_QUOTE;
|
2790
|
-
|
2791
2789
|
/* Extension data */
|
2792
2790
|
md->ext_flags = extensions;
|
2793
2791
|
md->opaque = opaque;
|