redcarpet 2.2.2 → 2.3.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.
- data/Gemfile +1 -1
- data/README.markdown +155 -132
- data/Rakefile +6 -119
- data/ext/redcarpet/buffer.h +3 -10
- data/ext/redcarpet/extconf.rb +2 -0
- data/ext/redcarpet/html.c +32 -3
- data/ext/redcarpet/html.h +1 -0
- data/ext/redcarpet/html_smartypants.c +55 -5
- data/ext/redcarpet/markdown.c +20 -17
- data/ext/redcarpet/markdown.h +3 -0
- data/ext/redcarpet/rc_markdown.c +9 -2
- data/ext/redcarpet/rc_render.c +23 -5
- data/ext/redcarpet/redcarpet.h +1 -1
- data/ext/redcarpet/stack.c +8 -8
- data/ext/redcarpet/stack.h +6 -6
- data/lib/redcarpet.rb +3 -2
- data/lib/redcarpet/render_strip.rb +12 -4
- data/redcarpet.gemspec +16 -5
- data/test/custom_render_test.rb +28 -0
- data/test/html_render_test.rb +92 -0
- data/test/{redcarpet_test.rb → markdown_test.rb} +53 -240
- data/test/pathological_inputs_test.rb +34 -0
- data/test/redcarpet_compat_test.rb +38 -0
- data/test/smarty_html_test.rb +30 -0
- data/test/smarty_pants_test.rb +43 -0
- data/test/stripdown_render_test.rb +31 -0
- data/test/test_helper.rb +16 -0
- metadata +116 -66
- data/Gemfile.lock +0 -20
data/ext/redcarpet/buffer.h
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/*
|
1
|
+
/*
|
2
2
|
* Copyright (c) 2008, Natacha Porté
|
3
3
|
* Copyright (c) 2011, Vicent Martí
|
4
4
|
*
|
@@ -44,15 +44,7 @@ struct buf {
|
|
44
44
|
size_t unit; /* reallocation unit size (0 = read-only buffer) */
|
45
45
|
};
|
46
46
|
|
47
|
-
/*
|
48
|
-
#define BUF_STATIC(string) \
|
49
|
-
{ (uint8_t *)string, sizeof string -1, sizeof string, 0, 0 }
|
50
|
-
|
51
|
-
/* VOLATILE_BUF: macro for creating a volatile buffer on the stack */
|
52
|
-
#define BUF_VOLATILE(strname) \
|
53
|
-
{ (uint8_t *)strname, strlen(strname), 0, 0, 0 }
|
54
|
-
|
55
|
-
/* BUFPUTSL: optimized bufputs of a string litteral */
|
47
|
+
/* BUFPUTSL: optimized bufputs of a string literal */
|
56
48
|
#define BUFPUTSL(output, literal) \
|
57
49
|
bufput(output, literal, sizeof literal - 1)
|
58
50
|
|
@@ -94,3 +86,4 @@ void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf,
|
|
94
86
|
#endif
|
95
87
|
|
96
88
|
#endif
|
89
|
+
|
data/ext/redcarpet/extconf.rb
CHANGED
data/ext/redcarpet/html.c
CHANGED
@@ -118,11 +118,18 @@ rndr_autolink(struct buf *ob, const struct buf *link, enum mkd_autolink type, vo
|
|
118
118
|
static void
|
119
119
|
rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque)
|
120
120
|
{
|
121
|
+
struct html_renderopt *options = opaque;
|
122
|
+
|
121
123
|
if (ob->size) bufputc(ob, '\n');
|
122
124
|
|
123
125
|
if (lang && lang->size) {
|
124
126
|
size_t i, cls;
|
125
|
-
|
127
|
+
if (options->flags & HTML_PRETTIFY) {
|
128
|
+
BUFPUTSL(ob, "<pre><code class=\"prettyprint");
|
129
|
+
cls++;
|
130
|
+
} else {
|
131
|
+
BUFPUTSL(ob, "<pre><code class=\"");
|
132
|
+
}
|
126
133
|
|
127
134
|
for (i = 0, cls = 0; i < lang->size; ++i, ++cls) {
|
128
135
|
while (i < lang->size && isspace(lang->data[i]))
|
@@ -142,8 +149,11 @@ rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, v
|
|
142
149
|
}
|
143
150
|
|
144
151
|
BUFPUTSL(ob, "\">");
|
145
|
-
} else
|
152
|
+
} else if (options->flags & HTML_PRETTIFY) {
|
153
|
+
BUFPUTSL(ob, "<pre><code class=\"prettyprint\">");
|
154
|
+
} else {
|
146
155
|
BUFPUTSL(ob, "<pre><code>");
|
156
|
+
}
|
147
157
|
|
148
158
|
if (text)
|
149
159
|
escape_html(ob, text->data, text->size);
|
@@ -163,7 +173,11 @@ rndr_blockquote(struct buf *ob, const struct buf *text, void *opaque)
|
|
163
173
|
static int
|
164
174
|
rndr_codespan(struct buf *ob, const struct buf *text, void *opaque)
|
165
175
|
{
|
166
|
-
|
176
|
+
struct html_renderopt *options = opaque;
|
177
|
+
if (options->flags & HTML_PRETTIFY)
|
178
|
+
BUFPUTSL(ob, "<code class=\"prettyprint\">");
|
179
|
+
else
|
180
|
+
BUFPUTSL(ob, "<code>");
|
167
181
|
if (text) escape_html(ob, text->data, text->size);
|
168
182
|
BUFPUTSL(ob, "</code>");
|
169
183
|
return 1;
|
@@ -204,6 +218,19 @@ rndr_emphasis(struct buf *ob, const struct buf *text, void *opaque)
|
|
204
218
|
return 1;
|
205
219
|
}
|
206
220
|
|
221
|
+
static int
|
222
|
+
rndr_underline(struct buf *ob, const struct buf *text, void *opaque)
|
223
|
+
{
|
224
|
+
if (!text || !text->size)
|
225
|
+
return 0;
|
226
|
+
|
227
|
+
BUFPUTSL(ob, "<u>");
|
228
|
+
bufput(ob, text->data, text->size);
|
229
|
+
BUFPUTSL(ob, "</u>");
|
230
|
+
|
231
|
+
return 1;
|
232
|
+
}
|
233
|
+
|
207
234
|
static int
|
208
235
|
rndr_linebreak(struct buf *ob, void *opaque)
|
209
236
|
{
|
@@ -559,6 +586,7 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *optio
|
|
559
586
|
rndr_codespan,
|
560
587
|
rndr_double_emphasis,
|
561
588
|
rndr_emphasis,
|
589
|
+
rndr_underline,
|
562
590
|
NULL,
|
563
591
|
NULL,
|
564
592
|
toc_link,
|
@@ -600,6 +628,7 @@ sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options,
|
|
600
628
|
rndr_codespan,
|
601
629
|
rndr_double_emphasis,
|
602
630
|
rndr_emphasis,
|
631
|
+
rndr_underline,
|
603
632
|
rndr_image,
|
604
633
|
rndr_linebreak,
|
605
634
|
rndr_link,
|
data/ext/redcarpet/html.h
CHANGED
@@ -83,6 +83,26 @@ word_boundary(uint8_t c)
|
|
83
83
|
return c == 0 || isspace(c) || ispunct(c);
|
84
84
|
}
|
85
85
|
|
86
|
+
// If 'text' begins with any kind of single quote (e.g. "'" or "'" etc.),
|
87
|
+
// returns the length of the sequence of characters that makes up the single-
|
88
|
+
// quote. Otherwise, returns zero.
|
89
|
+
static size_t
|
90
|
+
squote_len(const uint8_t *text, size_t size)
|
91
|
+
{
|
92
|
+
static char* single_quote_list[] = { "'", "'", "'", "'", NULL };
|
93
|
+
char** p;
|
94
|
+
|
95
|
+
for (p = single_quote_list; *p; ++p) {
|
96
|
+
size_t len = strlen(*p);
|
97
|
+
if (size >= len && memcmp(text, *p, len) == 0) {
|
98
|
+
return len;
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
return 0;
|
103
|
+
}
|
104
|
+
|
105
|
+
// Converts " or ' at very beginning or end of a word to left or right quote
|
86
106
|
static int
|
87
107
|
smartypants_quotes(struct buf *ob, uint8_t previous_char, uint8_t next_char, uint8_t quote, int *is_open)
|
88
108
|
{
|
@@ -100,23 +120,33 @@ smartypants_quotes(struct buf *ob, uint8_t previous_char, uint8_t next_char, uin
|
|
100
120
|
return 1;
|
101
121
|
}
|
102
122
|
|
123
|
+
// Converts ' to left or right single quote; but the initial ' might be in
|
124
|
+
// different forms, e.g. ' or ' or '.
|
125
|
+
// 'squote_text' points to the original single quote, and 'squote_size' is its length.
|
126
|
+
// 'text' points at the last character of the single-quote, e.g. ' or ;
|
103
127
|
static size_t
|
104
|
-
|
128
|
+
smartypants_squote(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size,
|
129
|
+
const uint8_t *squote_text, size_t squote_size)
|
105
130
|
{
|
106
131
|
if (size >= 2) {
|
107
132
|
uint8_t t1 = tolower(text[1]);
|
133
|
+
int next_squote_len = squote_len(text+1, size-1);
|
108
134
|
|
109
|
-
|
110
|
-
|
111
|
-
|
135
|
+
// convert '' to “ or ”
|
136
|
+
if (next_squote_len > 0) {
|
137
|
+
uint8_t next_char = (size > 1+next_squote_len) ? text[1+next_squote_len] : 0;
|
138
|
+
if (smartypants_quotes(ob, previous_char, next_char, 'd', &smrt->in_dquote))
|
139
|
+
return next_squote_len;
|
112
140
|
}
|
113
141
|
|
142
|
+
// Tom's, isn't, I'm, I'd
|
114
143
|
if ((t1 == 's' || t1 == 't' || t1 == 'm' || t1 == 'd') &&
|
115
144
|
(size == 3 || word_boundary(text[2]))) {
|
116
145
|
BUFPUTSL(ob, "’");
|
117
146
|
return 0;
|
118
147
|
}
|
119
148
|
|
149
|
+
// you're, you'll, you've
|
120
150
|
if (size >= 3) {
|
121
151
|
uint8_t t2 = tolower(text[2]);
|
122
152
|
|
@@ -133,10 +163,18 @@ smartypants_cb__squote(struct buf *ob, struct smartypants_data *smrt, uint8_t pr
|
|
133
163
|
if (smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 's', &smrt->in_squote))
|
134
164
|
return 0;
|
135
165
|
|
136
|
-
|
166
|
+
bufput(ob, squote_text, squote_size);
|
137
167
|
return 0;
|
138
168
|
}
|
139
169
|
|
170
|
+
// Converts ' to left or right single quote.
|
171
|
+
static size_t
|
172
|
+
smartypants_cb__squote(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
|
173
|
+
{
|
174
|
+
return smartypants_squote(ob, smrt, previous_char, text, size, text, 1);
|
175
|
+
}
|
176
|
+
|
177
|
+
// Converts (c), (r), (tm)
|
140
178
|
static size_t
|
141
179
|
smartypants_cb__parens(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
|
142
180
|
{
|
@@ -164,6 +202,7 @@ smartypants_cb__parens(struct buf *ob, struct smartypants_data *smrt, uint8_t pr
|
|
164
202
|
return 0;
|
165
203
|
}
|
166
204
|
|
205
|
+
// Converts "--" to em-dash, etc.
|
167
206
|
static size_t
|
168
207
|
smartypants_cb__dash(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
|
169
208
|
{
|
@@ -181,6 +220,7 @@ smartypants_cb__dash(struct buf *ob, struct smartypants_data *smrt, uint8_t prev
|
|
181
220
|
return 0;
|
182
221
|
}
|
183
222
|
|
223
|
+
// Converts " etc.
|
184
224
|
static size_t
|
185
225
|
smartypants_cb__amp(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
|
186
226
|
{
|
@@ -189,6 +229,11 @@ smartypants_cb__amp(struct buf *ob, struct smartypants_data *smrt, uint8_t previ
|
|
189
229
|
return 5;
|
190
230
|
}
|
191
231
|
|
232
|
+
int len = squote_len(text, size);
|
233
|
+
if (len > 0) {
|
234
|
+
return (len-1) + smartypants_squote(ob, smrt, previous_char, text+(len-1), size-(len-1), text, len);
|
235
|
+
}
|
236
|
+
|
192
237
|
if (size >= 4 && memcmp(text, "�", 4) == 0)
|
193
238
|
return 3;
|
194
239
|
|
@@ -196,6 +241,7 @@ smartypants_cb__amp(struct buf *ob, struct smartypants_data *smrt, uint8_t previ
|
|
196
241
|
return 0;
|
197
242
|
}
|
198
243
|
|
244
|
+
// Converts "..." to ellipsis
|
199
245
|
static size_t
|
200
246
|
smartypants_cb__period(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
|
201
247
|
{
|
@@ -213,6 +259,7 @@ smartypants_cb__period(struct buf *ob, struct smartypants_data *smrt, uint8_t pr
|
|
213
259
|
return 0;
|
214
260
|
}
|
215
261
|
|
262
|
+
// Converts `` to opening double quote
|
216
263
|
static size_t
|
217
264
|
smartypants_cb__backtick(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
|
218
265
|
{
|
@@ -221,9 +268,11 @@ smartypants_cb__backtick(struct buf *ob, struct smartypants_data *smrt, uint8_t
|
|
221
268
|
return 1;
|
222
269
|
}
|
223
270
|
|
271
|
+
bufputc(ob, text[0]);
|
224
272
|
return 0;
|
225
273
|
}
|
226
274
|
|
275
|
+
// Converts 1/2, 1/4, 3/4
|
227
276
|
static size_t
|
228
277
|
smartypants_cb__number(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
|
229
278
|
{
|
@@ -256,6 +305,7 @@ smartypants_cb__number(struct buf *ob, struct smartypants_data *smrt, uint8_t pr
|
|
256
305
|
return 0;
|
257
306
|
}
|
258
307
|
|
308
|
+
// Converts " to left or right double quote
|
259
309
|
static size_t
|
260
310
|
smartypants_cb__dquote(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size)
|
261
311
|
{
|
data/ext/redcarpet/markdown.c
CHANGED
@@ -64,6 +64,7 @@ typedef size_t
|
|
64
64
|
(*char_trigger)(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
65
65
|
|
66
66
|
static size_t char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
67
|
+
static size_t char_underline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
67
68
|
static size_t char_linebreak(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
68
69
|
static size_t char_codespan(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
69
70
|
static size_t char_escape(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);
|
@@ -135,7 +136,7 @@ rndr_newbuf(struct sd_markdown *rndr, int type)
|
|
135
136
|
work->size = 0;
|
136
137
|
} else {
|
137
138
|
work = bufnew(buf_size[type]);
|
138
|
-
|
139
|
+
redcarpet_stack_push(pool, work);
|
139
140
|
}
|
140
141
|
|
141
142
|
return work;
|
@@ -487,8 +488,6 @@ parse_emph1(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size
|
|
487
488
|
struct buf *work = 0;
|
488
489
|
int r;
|
489
490
|
|
490
|
-
if (!rndr->cb.emphasis) return 0;
|
491
|
-
|
492
491
|
/* skipping one symbol if coming from emph3 */
|
493
492
|
if (size > 1 && data[0] == c && data[1] == c) i = 1;
|
494
493
|
|
@@ -507,7 +506,12 @@ parse_emph1(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size
|
|
507
506
|
|
508
507
|
work = rndr_newbuf(rndr, BUFFER_SPAN);
|
509
508
|
parse_inline(work, rndr, data, i);
|
510
|
-
|
509
|
+
|
510
|
+
if (rndr->ext_flags & MKDEXT_UNDERLINE && c == '_')
|
511
|
+
r = rndr->cb.underline(ob, work, rndr->opaque);
|
512
|
+
else
|
513
|
+
r = rndr->cb.emphasis(ob, work, rndr->opaque);
|
514
|
+
|
511
515
|
rndr_popbuf(rndr, BUFFER_SPAN);
|
512
516
|
return r ? i + 1 : 0;
|
513
517
|
}
|
@@ -520,16 +524,10 @@ parse_emph1(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size
|
|
520
524
|
static size_t
|
521
525
|
parse_emph2(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, uint8_t c)
|
522
526
|
{
|
523
|
-
int (*render_method)(struct buf *ob, const struct buf *text, void *opaque);
|
524
527
|
size_t i = 0, len;
|
525
528
|
struct buf *work = 0;
|
526
529
|
int r;
|
527
530
|
|
528
|
-
render_method = (c == '~') ? rndr->cb.strikethrough : rndr->cb.double_emphasis;
|
529
|
-
|
530
|
-
if (!render_method)
|
531
|
-
return 0;
|
532
|
-
|
533
531
|
while (i < size) {
|
534
532
|
len = find_emph_char(data + i, size - i, c);
|
535
533
|
if (!len) return 0;
|
@@ -538,7 +536,12 @@ parse_emph2(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size
|
|
538
536
|
if (i + 1 < size && data[i] == c && data[i + 1] == c && i && !_isspace(data[i - 1])) {
|
539
537
|
work = rndr_newbuf(rndr, BUFFER_SPAN);
|
540
538
|
parse_inline(work, rndr, data, i);
|
541
|
-
|
539
|
+
|
540
|
+
if (c == '~')
|
541
|
+
r = rndr->cb.strikethrough(ob, work, rndr->opaque);
|
542
|
+
else
|
543
|
+
r = rndr->cb.double_emphasis(ob, work, rndr->opaque);
|
544
|
+
|
542
545
|
rndr_popbuf(rndr, BUFFER_SPAN);
|
543
546
|
return r ? i + 2 : 0;
|
544
547
|
}
|
@@ -2102,7 +2105,7 @@ parse_table_header(
|
|
2102
2105
|
while (i < under_end && data[i] == ' ')
|
2103
2106
|
i++;
|
2104
2107
|
|
2105
|
-
if (i < under_end && data[i] != '|')
|
2108
|
+
if (i < under_end && data[i] != '|' && data[i] != '+')
|
2106
2109
|
break;
|
2107
2110
|
|
2108
2111
|
if (dashes < 3)
|
@@ -2230,7 +2233,7 @@ parse_block(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size
|
|
2230
2233
|
else if (prefix_quote(txt_data, end))
|
2231
2234
|
beg += parse_blockquote(ob, rndr, txt_data, end);
|
2232
2235
|
|
2233
|
-
else if (prefix_code(txt_data, end))
|
2236
|
+
else if (!(rndr->ext_flags & MKDEXT_DISABLE_INDENTED_CODE) && prefix_code(txt_data, end))
|
2234
2237
|
beg += parse_blockcode(ob, rndr, txt_data, end);
|
2235
2238
|
|
2236
2239
|
else if (prefix_uli(txt_data, end))
|
@@ -2410,8 +2413,8 @@ sd_markdown_new(
|
|
2410
2413
|
|
2411
2414
|
memcpy(&md->cb, callbacks, sizeof(struct sd_callbacks));
|
2412
2415
|
|
2413
|
-
|
2414
|
-
|
2416
|
+
redcarpet_stack_init(&md->work_bufs[BUFFER_BLOCK], 4);
|
2417
|
+
redcarpet_stack_init(&md->work_bufs[BUFFER_SPAN], 8);
|
2415
2418
|
|
2416
2419
|
memset(md->active_char, 0x0, 256);
|
2417
2420
|
|
@@ -2539,8 +2542,8 @@ sd_markdown_free(struct sd_markdown *md)
|
|
2539
2542
|
for (i = 0; i < (size_t)md->work_bufs[BUFFER_BLOCK].asize; ++i)
|
2540
2543
|
bufrelease(md->work_bufs[BUFFER_BLOCK].item[i]);
|
2541
2544
|
|
2542
|
-
|
2543
|
-
|
2545
|
+
redcarpet_stack_free(&md->work_bufs[BUFFER_SPAN]);
|
2546
|
+
redcarpet_stack_free(&md->work_bufs[BUFFER_BLOCK]);
|
2544
2547
|
|
2545
2548
|
free(md);
|
2546
2549
|
}
|
data/ext/redcarpet/markdown.h
CHANGED
@@ -56,9 +56,11 @@ enum mkd_extensions {
|
|
56
56
|
MKDEXT_FENCED_CODE = (1 << 2),
|
57
57
|
MKDEXT_AUTOLINK = (1 << 3),
|
58
58
|
MKDEXT_STRIKETHROUGH = (1 << 4),
|
59
|
+
MKDEXT_UNDERLINE = (1 << 5),
|
59
60
|
MKDEXT_SPACE_HEADERS = (1 << 6),
|
60
61
|
MKDEXT_SUPERSCRIPT = (1 << 7),
|
61
62
|
MKDEXT_LAX_SPACING = (1 << 8),
|
63
|
+
MKDEXT_DISABLE_INDENTED_CODE = (1 << 9),
|
62
64
|
};
|
63
65
|
|
64
66
|
/* sd_callbacks - functions for rendering parsed data */
|
@@ -82,6 +84,7 @@ struct sd_callbacks {
|
|
82
84
|
int (*codespan)(struct buf *ob, const struct buf *text, void *opaque);
|
83
85
|
int (*double_emphasis)(struct buf *ob, const struct buf *text, void *opaque);
|
84
86
|
int (*emphasis)(struct buf *ob, const struct buf *text, void *opaque);
|
87
|
+
int (*underline)(struct buf *ob, const struct buf *text, void *opaque);
|
85
88
|
int (*image)(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque);
|
86
89
|
int (*linebreak)(struct buf *ob, void *opaque);
|
87
90
|
int (*link)(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *content, void *opaque);
|
data/ext/redcarpet/rc_markdown.c
CHANGED
@@ -38,12 +38,18 @@ static void rb_redcarpet_md_flags(VALUE hash, unsigned int *enabled_extensions_p
|
|
38
38
|
if (rb_hash_lookup(hash, CSTR2SYM("fenced_code_blocks")) == Qtrue)
|
39
39
|
extensions |= MKDEXT_FENCED_CODE;
|
40
40
|
|
41
|
+
if (rb_hash_lookup(hash, CSTR2SYM("disable_indented_code_blocks")) == Qtrue)
|
42
|
+
extensions |= MKDEXT_DISABLE_INDENTED_CODE;
|
43
|
+
|
41
44
|
if (rb_hash_lookup(hash, CSTR2SYM("autolink")) == Qtrue)
|
42
45
|
extensions |= MKDEXT_AUTOLINK;
|
43
46
|
|
44
47
|
if (rb_hash_lookup(hash, CSTR2SYM("strikethrough")) == Qtrue)
|
45
48
|
extensions |= MKDEXT_STRIKETHROUGH;
|
46
49
|
|
50
|
+
if (rb_hash_lookup(hash, CSTR2SYM("underline")) == Qtrue)
|
51
|
+
extensions |= MKDEXT_UNDERLINE;
|
52
|
+
|
47
53
|
if (rb_hash_lookup(hash, CSTR2SYM("lax_spacing")) == Qtrue)
|
48
54
|
extensions |= MKDEXT_LAX_SPACING;
|
49
55
|
|
@@ -121,12 +127,12 @@ static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
|
|
121
127
|
/* render the magic */
|
122
128
|
sd_markdown_render(
|
123
129
|
output_buf,
|
124
|
-
RSTRING_PTR(text),
|
130
|
+
(const uint8_t*)RSTRING_PTR(text),
|
125
131
|
RSTRING_LEN(text),
|
126
132
|
markdown);
|
127
133
|
|
128
134
|
/* build the Ruby string */
|
129
|
-
text = redcarpet_str_new(output_buf->data, output_buf->size, rb_enc_get(text));
|
135
|
+
text = redcarpet_str_new((const char*)output_buf->data, output_buf->size, rb_enc_get(text));
|
130
136
|
|
131
137
|
bufrelease(output_buf);
|
132
138
|
|
@@ -136,6 +142,7 @@ static VALUE rb_redcarpet_md_render(VALUE self, VALUE text)
|
|
136
142
|
return text;
|
137
143
|
}
|
138
144
|
|
145
|
+
__attribute__((visibility("default")))
|
139
146
|
void Init_redcarpet()
|
140
147
|
{
|
141
148
|
rb_mRedcarpet = rb_define_module("Redcarpet");
|
data/ext/redcarpet/rc_render.c
CHANGED
@@ -41,9 +41,9 @@ VALUE rb_cRenderHTML_TOC;
|
|
41
41
|
VALUE rb_mSmartyPants;
|
42
42
|
|
43
43
|
#ifdef HAVE_RUBY_ENCODING_H
|
44
|
-
#define buf2str(t) ((t) ? redcarpet_str_new((t)->data, (t)->size, opt->active_enc) : Qnil)
|
44
|
+
#define buf2str(t) ((t) ? redcarpet_str_new((const char*)(t)->data, (t)->size, opt->active_enc) : Qnil)
|
45
45
|
#else
|
46
|
-
#define buf2str(t) ((t) ? redcarpet_str_new((t)->data, (t)->size, NULL) : Qnil)
|
46
|
+
#define buf2str(t) ((t) ? redcarpet_str_new((const char*)(t)->data, (t)->size, NULL) : Qnil)
|
47
47
|
#endif
|
48
48
|
|
49
49
|
static void
|
@@ -165,6 +165,12 @@ rndr_emphasis(struct buf *ob, const struct buf *text, void *opaque)
|
|
165
165
|
SPAN_CALLBACK("emphasis", 1, buf2str(text));
|
166
166
|
}
|
167
167
|
|
168
|
+
static int
|
169
|
+
rndr_underline(struct buf *ob, const struct buf *text, void *opaque)
|
170
|
+
{
|
171
|
+
SPAN_CALLBACK("underline", 1, buf2str(text));
|
172
|
+
}
|
173
|
+
|
168
174
|
static int
|
169
175
|
rndr_image(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque)
|
170
176
|
{
|
@@ -272,6 +278,7 @@ static struct sd_callbacks rb_redcarpet_callbacks = {
|
|
272
278
|
rndr_codespan,
|
273
279
|
rndr_double_emphasis,
|
274
280
|
rndr_emphasis,
|
281
|
+
rndr_underline,
|
275
282
|
rndr_image,
|
276
283
|
rndr_linebreak,
|
277
284
|
rndr_link,
|
@@ -304,6 +311,7 @@ static const char *rb_redcarpet_method_names[] = {
|
|
304
311
|
"codespan",
|
305
312
|
"double_emphasis",
|
306
313
|
"emphasis",
|
314
|
+
"underline",
|
307
315
|
"image",
|
308
316
|
"linebreak",
|
309
317
|
"link",
|
@@ -321,11 +329,17 @@ static const char *rb_redcarpet_method_names[] = {
|
|
321
329
|
|
322
330
|
static const size_t rb_redcarpet_method_count = sizeof(rb_redcarpet_method_names)/sizeof(char *);
|
323
331
|
|
332
|
+
static void rb_redcarpet_rbase_mark(struct rb_redcarpet_rndr *rndr)
|
333
|
+
{
|
334
|
+
if (rndr->options.link_attributes)
|
335
|
+
rb_gc_mark(rndr->options.link_attributes);
|
336
|
+
}
|
337
|
+
|
324
338
|
static VALUE rb_redcarpet_rbase_alloc(VALUE klass)
|
325
339
|
{
|
326
340
|
struct rb_redcarpet_rndr *rndr = ALLOC(struct rb_redcarpet_rndr);
|
327
341
|
memset(rndr, 0x0, sizeof(struct rb_redcarpet_rndr));
|
328
|
-
return Data_Wrap_Struct(klass,
|
342
|
+
return Data_Wrap_Struct(klass, rb_redcarpet_rbase_mark, NULL, rndr);
|
329
343
|
}
|
330
344
|
|
331
345
|
static void rb_redcarpet__overload(VALUE self, VALUE base_class)
|
@@ -386,6 +400,10 @@ static VALUE rb_redcarpet_html_init(int argc, VALUE *argv, VALUE self)
|
|
386
400
|
if (rb_hash_aref(hash, CSTR2SYM("no_links")) == Qtrue)
|
387
401
|
render_flags |= HTML_SKIP_LINKS;
|
388
402
|
|
403
|
+
/* prettify */
|
404
|
+
if (rb_hash_aref(hash, CSTR2SYM("prettify")) == Qtrue)
|
405
|
+
render_flags |= HTML_PRETTIFY;
|
406
|
+
|
389
407
|
/* filter_style */
|
390
408
|
if (rb_hash_aref(hash, CSTR2SYM("no_styles")) == Qtrue)
|
391
409
|
render_flags |= HTML_SKIP_STYLE;
|
@@ -437,8 +455,8 @@ static VALUE rb_redcarpet_smartypants_render(VALUE self, VALUE text)
|
|
437
455
|
|
438
456
|
output_buf = bufnew(128);
|
439
457
|
|
440
|
-
sdhtml_smartypants(output_buf, RSTRING_PTR(text), RSTRING_LEN(text));
|
441
|
-
result = redcarpet_str_new(output_buf->data, output_buf->size, rb_enc_get(text));
|
458
|
+
sdhtml_smartypants(output_buf, (const uint8_t*)RSTRING_PTR(text), RSTRING_LEN(text));
|
459
|
+
result = redcarpet_str_new((const char*)output_buf->data, output_buf->size, rb_enc_get(text));
|
442
460
|
|
443
461
|
bufrelease(output_buf);
|
444
462
|
return result;
|