redcarpet 1.0.1 → 1.1.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.
Potentially problematic release.
This version of redcarpet might be problematic. Click here for more details.
- data/ext/markdown.c +4 -3
- data/ext/render.c +161 -56
- data/redcarpet.gemspec +1 -1
- metadata +3 -3
data/ext/markdown.c
CHANGED
@@ -480,8 +480,8 @@ char_linebreak(struct buf *ob, struct render *rndr, char *data, size_t offset, s
|
|
480
480
|
|
481
481
|
/* char_codespan • '`' parsing a code span (assuming codespan != 0) */
|
482
482
|
static size_t
|
483
|
-
char_codespan(struct buf *ob, struct render *rndr,
|
484
|
-
|
483
|
+
char_codespan(struct buf *ob, struct render *rndr, char *data, size_t offset, size_t size)
|
484
|
+
{
|
485
485
|
size_t end, nb = 0, i, f_begin, f_end;
|
486
486
|
|
487
487
|
/* counting the number of backticks in the delimiter */
|
@@ -510,7 +510,8 @@ char_codespan(struct buf *ob, struct render *rndr,
|
|
510
510
|
else {
|
511
511
|
if (!rndr->make.codespan(ob, 0, &rndr->make.render_options))
|
512
512
|
end = 0; }
|
513
|
-
return end;
|
513
|
+
return end;
|
514
|
+
}
|
514
515
|
|
515
516
|
|
516
517
|
/* char_escape • '\\' backslash escape */
|
data/ext/render.c
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
|
20
20
|
#include <strings.h>
|
21
21
|
#include <stdlib.h>
|
22
|
+
#include <stdio.h>
|
22
23
|
|
23
24
|
|
24
25
|
static int is_safe_link(const char *link, size_t link_len)
|
@@ -55,7 +56,8 @@ put_scaped_char(struct buf *ob, char c)
|
|
55
56
|
|
56
57
|
/* lus_attr_escape • copy the buffer entity-escaping '<', '>', '&' and '"' */
|
57
58
|
static void
|
58
|
-
lus_attr_escape(struct buf *ob, const char *src, size_t size)
|
59
|
+
lus_attr_escape(struct buf *ob, const char *src, size_t size)
|
60
|
+
{
|
59
61
|
size_t i = 0, org;
|
60
62
|
while (i < size) {
|
61
63
|
/* copying directly unescaped characters */
|
@@ -120,7 +122,8 @@ rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, struct m
|
|
120
122
|
}
|
121
123
|
|
122
124
|
static void
|
123
|
-
rndr_blockcode(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
125
|
+
rndr_blockcode(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
126
|
+
{
|
124
127
|
if (ob->size) bufputc(ob, '\n');
|
125
128
|
BUFPUTSL(ob, "<pre><code>");
|
126
129
|
if (text) lus_attr_escape(ob, text->data, text->size);
|
@@ -128,14 +131,16 @@ rndr_blockcode(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
|
128
131
|
}
|
129
132
|
|
130
133
|
static void
|
131
|
-
rndr_blockquote(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
134
|
+
rndr_blockquote(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
135
|
+
{
|
132
136
|
BUFPUTSL(ob, "<blockquote>\n");
|
133
137
|
if (text) bufput(ob, text->data, text->size);
|
134
138
|
BUFPUTSL(ob, "</blockquote>");
|
135
139
|
}
|
136
140
|
|
137
141
|
static int
|
138
|
-
rndr_codespan(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
142
|
+
rndr_codespan(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
143
|
+
{
|
139
144
|
BUFPUTSL(ob, "<code>");
|
140
145
|
if (text) lus_attr_escape(ob, text->data, text->size);
|
141
146
|
BUFPUTSL(ob, "</code>");
|
@@ -143,7 +148,8 @@ rndr_codespan(struct buf *ob, struct buf *text, struct mkd_renderopt *options) {
|
|
143
148
|
}
|
144
149
|
|
145
150
|
static int
|
146
|
-
rndr_double_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *options)
|
151
|
+
rndr_double_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *options)
|
152
|
+
{
|
147
153
|
if (!text || !text->size) return 0;
|
148
154
|
BUFPUTSL(ob, "<strong>");
|
149
155
|
bufput(ob, text->data, text->size);
|
@@ -152,7 +158,8 @@ rndr_double_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_render
|
|
152
158
|
}
|
153
159
|
|
154
160
|
static int
|
155
|
-
rndr_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *options)
|
161
|
+
rndr_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *options)
|
162
|
+
{
|
156
163
|
if (!text || !text->size) return 0;
|
157
164
|
BUFPUTSL(ob, "<em>");
|
158
165
|
if (text) bufput(ob, text->data, text->size);
|
@@ -161,7 +168,8 @@ rndr_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *op
|
|
161
168
|
}
|
162
169
|
|
163
170
|
static void
|
164
|
-
rndr_header(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *options)
|
171
|
+
rndr_header(struct buf *ob, struct buf *text, int level, struct mkd_renderopt *options)
|
172
|
+
{
|
165
173
|
if (ob->size) bufputc(ob, '\n');
|
166
174
|
bufprintf(ob, "<h%d>", level);
|
167
175
|
if (text) bufput(ob, text->data, text->size);
|
@@ -186,7 +194,8 @@ rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *conte
|
|
186
194
|
}
|
187
195
|
|
188
196
|
static void
|
189
|
-
rndr_list(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *options)
|
197
|
+
rndr_list(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *options)
|
198
|
+
{
|
190
199
|
if (ob->size) bufputc(ob, '\n');
|
191
200
|
bufput(ob, flags & MKD_LIST_ORDERED ? "<ol>\n" : "<ul>\n", 5);
|
192
201
|
if (text) bufput(ob, text->data, text->size);
|
@@ -194,9 +203,9 @@ rndr_list(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *opt
|
|
194
203
|
}
|
195
204
|
|
196
205
|
static void
|
197
|
-
rndr_listitem(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *options)
|
198
|
-
|
199
|
-
BUFPUTSL(ob, "<li
|
206
|
+
rndr_listitem(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt *options)
|
207
|
+
{
|
208
|
+
BUFPUTSL(ob, "<li>");
|
200
209
|
if (text) {
|
201
210
|
while (text->size && text->data[text->size - 1] == '\n')
|
202
211
|
text->size -= 1;
|
@@ -205,7 +214,8 @@ rndr_listitem(struct buf *ob, struct buf *text, int flags, struct mkd_renderopt
|
|
205
214
|
}
|
206
215
|
|
207
216
|
static void
|
208
|
-
rndr_paragraph(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
217
|
+
rndr_paragraph(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
218
|
+
{
|
209
219
|
size_t i = 0;
|
210
220
|
|
211
221
|
if (ob->size) bufputc(ob, '\n');
|
@@ -223,7 +233,8 @@ rndr_paragraph(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
|
223
233
|
}
|
224
234
|
|
225
235
|
static void
|
226
|
-
rndr_raw_block(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
236
|
+
rndr_raw_block(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
237
|
+
{
|
227
238
|
size_t org, sz;
|
228
239
|
if (!text) return;
|
229
240
|
sz = text->size;
|
@@ -237,7 +248,8 @@ rndr_raw_block(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
|
237
248
|
}
|
238
249
|
|
239
250
|
static int
|
240
|
-
rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *options)
|
251
|
+
rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_renderopt *options)
|
252
|
+
{
|
241
253
|
if (!text || !text->size) return 0;
|
242
254
|
BUFPUTSL(ob, "<strong><em>");
|
243
255
|
bufput(ob, text->data, text->size);
|
@@ -251,13 +263,15 @@ rndr_triple_emphasis(struct buf *ob, struct buf *text, char c, struct mkd_render
|
|
251
263
|
**********************/
|
252
264
|
|
253
265
|
static void
|
254
|
-
rndr_hrule(struct buf *ob, struct mkd_renderopt *options)
|
266
|
+
rndr_hrule(struct buf *ob, struct mkd_renderopt *options)
|
267
|
+
{
|
255
268
|
if (ob->size) bufputc(ob, '\n');
|
256
269
|
BUFPUTSL(ob, "<hr />\n");
|
257
270
|
}
|
258
271
|
|
259
272
|
static int
|
260
|
-
rndr_image(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, struct mkd_renderopt *options)
|
273
|
+
rndr_image(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, struct mkd_renderopt *options)
|
274
|
+
{
|
261
275
|
if (!link || !link->size) return 0;
|
262
276
|
BUFPUTSL(ob, "<img src=\"");
|
263
277
|
lus_attr_escape(ob, link->data, link->size);
|
@@ -272,13 +286,15 @@ rndr_image(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt,
|
|
272
286
|
}
|
273
287
|
|
274
288
|
static int
|
275
|
-
rndr_linebreak(struct buf *ob, struct mkd_renderopt *options)
|
289
|
+
rndr_linebreak(struct buf *ob, struct mkd_renderopt *options)
|
290
|
+
{
|
276
291
|
BUFPUTSL(ob, "<br />\n");
|
277
292
|
return 1;
|
278
293
|
}
|
279
294
|
|
280
295
|
static int
|
281
|
-
rndr_raw_html(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
296
|
+
rndr_raw_html(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
297
|
+
{
|
282
298
|
int escape_html = 0;
|
283
299
|
|
284
300
|
if (options->flags & RENDER_SKIP_HTML)
|
@@ -331,12 +347,9 @@ static struct {
|
|
331
347
|
{ '&', "�", 0, 3 },
|
332
348
|
};
|
333
349
|
|
334
|
-
static const char *smartypants_squotes[] = {"‘", "’"};
|
335
|
-
static const char *smartypants_dquotes[] = {"“", "”"};
|
336
|
-
|
337
350
|
#define SUBS_COUNT (sizeof(smartypants_subs) / sizeof(smartypants_subs[0]))
|
338
351
|
|
339
|
-
static
|
352
|
+
static inline
|
340
353
|
word_boundary(char c)
|
341
354
|
{
|
342
355
|
return isspace(c) || ispunct(c);
|
@@ -373,31 +386,69 @@ smartypants_cmpsub(const struct buf *buf, size_t start, const char *prefix)
|
|
373
386
|
return (*prefix == '>');
|
374
387
|
}
|
375
388
|
|
376
|
-
|
377
|
-
|
389
|
+
static int
|
390
|
+
smartypants_quotes(struct buf *ob, struct buf *text, size_t i, int is_open)
|
391
|
+
{
|
392
|
+
char ent[8];
|
393
|
+
|
394
|
+
if (is_open && i + 1 < text->size && !word_boundary(text->data[i + 1]))
|
395
|
+
return 0;
|
396
|
+
|
397
|
+
if (!is_open && i > 0 && !word_boundary(text->data[i - 1]))
|
398
|
+
return 0;
|
399
|
+
|
400
|
+
snprintf(ent, sizeof(ent), "&%c%cquo;",
|
401
|
+
is_open ? 'r' : 'l',
|
402
|
+
text->data[i] == '\'' ? 's' : 'd');
|
403
|
+
|
404
|
+
bufputs(ob, ent);
|
405
|
+
return 1;
|
406
|
+
}
|
407
|
+
|
378
408
|
static void
|
379
|
-
|
409
|
+
rndr_normal_text(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
380
410
|
{
|
381
411
|
size_t i;
|
382
|
-
int open_single = 0, open_double = 0;
|
412
|
+
int open_single = 0, open_double = 0, open_tag = 0;
|
383
413
|
|
384
|
-
int autolink = (flags & RENDER_AUTOLINK);
|
385
|
-
int smartypants = (flags & RENDER_SMARTYPANTS);
|
414
|
+
int autolink = (options->flags & RENDER_AUTOLINK);
|
415
|
+
int smartypants = (options->flags & RENDER_SMARTYPANTS);
|
416
|
+
|
417
|
+
if (!text)
|
418
|
+
return;
|
419
|
+
|
420
|
+
if (!autolink && !smartypants) {
|
421
|
+
lus_attr_escape(ob, text->data, text->size);
|
422
|
+
return;
|
423
|
+
}
|
386
424
|
|
387
425
|
for (i = 0; i < text->size; ++i) {
|
388
426
|
size_t sub;
|
389
427
|
char c = text->data[i];
|
390
428
|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
429
|
+
/*
|
430
|
+
* Autolinking
|
431
|
+
*/
|
432
|
+
if (autolink) {
|
433
|
+
/* Autolinking is not standarized in the Markdown spec.
|
434
|
+
* We only check for links after special characters, i.e.
|
435
|
+
* immediately after a space or a parenthesis */
|
436
|
+
if (i == 0 || (isspace(text->data[i - 1]) || text->data[i - 1] == '(') &&
|
437
|
+
is_safe_link(text->data + i, text->size - i)) {
|
438
|
+
size_t j = i + i;
|
439
|
+
|
440
|
+
while (j < text->size && !isspace(text->data[j]))
|
441
|
+
j++;
|
442
|
+
|
443
|
+
rndr_autolink2(ob, &text->data[i], j - i, MKDA_NORMAL);
|
444
|
+
i = j;
|
445
|
+
continue;
|
446
|
+
}
|
399
447
|
}
|
400
448
|
|
449
|
+
/*
|
450
|
+
* Smartypants subsitutions
|
451
|
+
*/
|
401
452
|
if (smartypants) {
|
402
453
|
for (sub = 0; sub < SUBS_COUNT; ++sub) {
|
403
454
|
if (c == smartypants_subs[sub].c0 &&
|
@@ -415,37 +466,91 @@ smartypants_and_autolink(struct buf *ob, struct buf *text, unsigned int flags)
|
|
415
466
|
continue;
|
416
467
|
|
417
468
|
switch (c) {
|
469
|
+
case '<':
|
470
|
+
open_tag = 1;
|
471
|
+
break;
|
472
|
+
|
473
|
+
case '>':
|
474
|
+
open_tag = 0;
|
475
|
+
break;
|
476
|
+
|
477
|
+
#if 0
|
478
|
+
/*
|
479
|
+
* FIXME: this is bongos.
|
480
|
+
*
|
481
|
+
* The markdown spec defines that code blocks can be delimited
|
482
|
+
* by more than one backtick, e.g.
|
483
|
+
*
|
484
|
+
* ``There is a literal backtick (`) here.``
|
485
|
+
* <p><code>There is a literal backtick (`) here.</code></p>
|
486
|
+
*
|
487
|
+
* Obviously, there's no way to differentiate between the start
|
488
|
+
* of a code block and the start of a quoted string for smartypants
|
489
|
+
*
|
490
|
+
* Look at this piece of Python code:
|
491
|
+
*
|
492
|
+
* ``result = ''.join(['this', 'is', 'bongos'])``
|
493
|
+
*
|
494
|
+
* This MD expression is clearly ambiguous since it can be parsed as:
|
495
|
+
*
|
496
|
+
* <p>“result = ”.join ...</p>
|
497
|
+
*
|
498
|
+
* Or also as:
|
499
|
+
*
|
500
|
+
* <p><code>result = ''.join(['this', 'is', 'bongos'])</code></p>
|
501
|
+
*
|
502
|
+
* Fuck everything about this. This is temporarily disabled, because at GitHub
|
503
|
+
* it's probably smarter to prioritize code blocks than pretty cutesy punctuation.
|
504
|
+
*
|
505
|
+
* The equivalent closing tag for the (``), ('') has also been disabled, because
|
506
|
+
* it makes no sense to have closing tags without opening tags.
|
507
|
+
*/
|
508
|
+
case '`':
|
509
|
+
if (open_tag == 0) {
|
510
|
+
if (i + 1 < text->size && text->data[i + 1] == '`') {
|
511
|
+
BUFPUTSL(ob, "“"); i++;
|
512
|
+
continue;
|
513
|
+
}
|
514
|
+
}
|
515
|
+
break;
|
516
|
+
#endif
|
517
|
+
|
418
518
|
case '\"':
|
419
|
-
|
420
|
-
|
421
|
-
|
519
|
+
if (open_tag == 0) {
|
520
|
+
if (smartypants_quotes(ob, text, i, open_double)) {
|
521
|
+
open_double = !open_double;
|
522
|
+
continue;
|
523
|
+
}
|
524
|
+
}
|
525
|
+
break;
|
422
526
|
|
423
527
|
case '\'':
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
528
|
+
if (open_tag == 0) {
|
529
|
+
|
530
|
+
#if 0 /* temporarily disabled, see previous comment */
|
531
|
+
if (i + 1 < text->size && text->data[i + 1] == '\'') {
|
532
|
+
BUFPUTSL(ob, "”"); i++;
|
533
|
+
continue;
|
534
|
+
}
|
535
|
+
#endif
|
536
|
+
|
537
|
+
if (smartypants_quotes(ob, text, i, open_single)) {
|
538
|
+
open_single = !open_single;
|
539
|
+
continue;
|
540
|
+
}
|
541
|
+
}
|
542
|
+
break;
|
429
543
|
}
|
430
544
|
}
|
431
545
|
|
546
|
+
/*
|
547
|
+
* Copy raw character
|
548
|
+
*/
|
432
549
|
if (!put_scaped_char(ob, c))
|
433
550
|
bufputc(ob, c);
|
434
551
|
}
|
435
552
|
}
|
436
553
|
|
437
|
-
static void
|
438
|
-
rndr_normal_text(struct buf *ob, struct buf *text, struct mkd_renderopt *options)
|
439
|
-
{
|
440
|
-
if (!text)
|
441
|
-
return;
|
442
|
-
|
443
|
-
if (options->flags & RENDER_SMARTYPANTS || options->flags & RENDER_AUTOLINK)
|
444
|
-
smartypants_and_autolink(ob, text, options->flags);
|
445
|
-
else
|
446
|
-
lus_attr_escape(ob, text->data, text->size);
|
447
|
-
}
|
448
|
-
|
449
554
|
void
|
450
555
|
init_renderer(struct mkd_renderer *renderer,
|
451
556
|
unsigned int render_flags, void *opaque,
|
data/redcarpet.gemspec
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redcarpet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Natacha Port\xC3\xA9"
|