redcarpet 2.0.0b4 → 2.0.0b5
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/Rakefile +2 -2
- data/ext/redcarpet/houdini.h +28 -0
- data/ext/redcarpet/houdini_href_e.c +108 -0
- data/ext/redcarpet/houdini_html_e.c +84 -0
- data/ext/redcarpet/html.c +24 -51
- data/ext/redcarpet/html.h +1 -4
- data/ext/redcarpet/html_smartypants.c +2 -2
- data/ext/redcarpet/markdown.c +40 -12
- data/ext/redcarpet/stack.c +1 -1
- data/lib/redcarpet.rb +1 -1
- data/redcarpet.gemspec +5 -2
- metadata +7 -4
data/Rakefile
CHANGED
@@ -115,8 +115,8 @@ task :gather => 'sundown/src/markdown.h' do |t|
|
|
115
115
|
FileList[
|
116
116
|
'sundown/src/{markdown,buffer,stack,autolink,html_blocks}.h',
|
117
117
|
'sundown/src/{markdown,buffer,stack,autolink}.c',
|
118
|
-
'sundown/html/{html,html_smartypants}.c',
|
119
|
-
'sundown/html/html.h',
|
118
|
+
'sundown/html/{html,html_smartypants,houdini_html_e,houdini_href_e}.c',
|
119
|
+
'sundown/html/{html,houdini}.h',
|
120
120
|
]
|
121
121
|
cp files, 'ext/redcarpet/',
|
122
122
|
:preserve => true,
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#ifndef __HOUDINI_H__
|
2
|
+
#define __HOUDINI_H__
|
3
|
+
|
4
|
+
#include "buffer.h"
|
5
|
+
|
6
|
+
#ifdef HOUDINI_USE_LOCALE
|
7
|
+
# define _isxdigit(c) isxdigit(c)
|
8
|
+
# define _isdigit(c) isdigit(c)
|
9
|
+
#else
|
10
|
+
/*
|
11
|
+
* Helper _isdigit methods -- do not trust the current locale
|
12
|
+
* */
|
13
|
+
# define _isxdigit(c) (strchr("0123456789ABCDEFabcdef", (c)) != NULL)
|
14
|
+
# define _isdigit(c) ((c) >= '0' && (c) <= '9')
|
15
|
+
#endif
|
16
|
+
|
17
|
+
extern void houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size);
|
18
|
+
extern void houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure);
|
19
|
+
extern void houdini_unescape_html(struct buf *ob, const uint8_t *src, size_t size);
|
20
|
+
extern void houdini_escape_uri(struct buf *ob, const uint8_t *src, size_t size);
|
21
|
+
extern void houdini_escape_url(struct buf *ob, const uint8_t *src, size_t size);
|
22
|
+
extern void houdini_escape_href(struct buf *ob, const uint8_t *src, size_t size);
|
23
|
+
extern void houdini_unescape_uri(struct buf *ob, const uint8_t *src, size_t size);
|
24
|
+
extern void houdini_unescape_url(struct buf *ob, const uint8_t *src, size_t size);
|
25
|
+
extern void houdini_escape_js(struct buf *ob, const uint8_t *src, size_t size);
|
26
|
+
extern void houdini_unescape_js(struct buf *ob, const uint8_t *src, size_t size);
|
27
|
+
|
28
|
+
#endif
|
@@ -0,0 +1,108 @@
|
|
1
|
+
#include <assert.h>
|
2
|
+
#include <stdio.h>
|
3
|
+
#include <string.h>
|
4
|
+
|
5
|
+
#include "houdini.h"
|
6
|
+
|
7
|
+
#define ESCAPE_GROW_FACTOR(x) (((x) * 12) / 10)
|
8
|
+
|
9
|
+
/*
|
10
|
+
* The following characters will not be escaped:
|
11
|
+
*
|
12
|
+
* -_.+!*'(),%#@?=;:/,+&$ alphanum
|
13
|
+
*
|
14
|
+
* Note that this character set is the addition of:
|
15
|
+
*
|
16
|
+
* - The characters which are safe to be in an URL
|
17
|
+
* - The characters which are *not* safe to be in
|
18
|
+
* an URL because they are RESERVED characters.
|
19
|
+
*
|
20
|
+
* We asume (lazily) that any RESERVED char that
|
21
|
+
* appears inside an URL is actually meant to
|
22
|
+
* have its native function (i.e. as an URL
|
23
|
+
* component/separator) and hence needs no escaping.
|
24
|
+
*
|
25
|
+
* There are two exceptions: the chacters & (amp)
|
26
|
+
* and ' (single quote) do not appear in the table.
|
27
|
+
* They are meant to appear in the URL as components,
|
28
|
+
* yet they require special HTML-entity escaping
|
29
|
+
* to generate valid HTML markup.
|
30
|
+
*
|
31
|
+
* All other characters will be escaped to %XX.
|
32
|
+
*
|
33
|
+
*/
|
34
|
+
static const char HREF_SAFE[] = {
|
35
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
36
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
37
|
+
0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
38
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
|
39
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
40
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
|
41
|
+
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
42
|
+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
43
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
44
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
45
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
46
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
47
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
48
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
49
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
50
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
51
|
+
};
|
52
|
+
|
53
|
+
void
|
54
|
+
houdini_escape_href(struct buf *ob, const uint8_t *src, size_t size)
|
55
|
+
{
|
56
|
+
static const char hex_chars[] = "0123456789ABCDEF";
|
57
|
+
size_t i = 0, org;
|
58
|
+
char hex_str[3];
|
59
|
+
|
60
|
+
bufgrow(ob, ESCAPE_GROW_FACTOR(size));
|
61
|
+
hex_str[0] = '%';
|
62
|
+
|
63
|
+
while (i < size) {
|
64
|
+
org = i;
|
65
|
+
while (i < size && HREF_SAFE[src[i]] != 0)
|
66
|
+
i++;
|
67
|
+
|
68
|
+
if (i > org)
|
69
|
+
bufput(ob, src + org, i - org);
|
70
|
+
|
71
|
+
/* escaping */
|
72
|
+
if (i >= size)
|
73
|
+
break;
|
74
|
+
|
75
|
+
switch (src[i]) {
|
76
|
+
/* amp appears all the time in URLs, but needs
|
77
|
+
* HTML-entity escaping to be inside an href */
|
78
|
+
case '&':
|
79
|
+
BUFPUTSL(ob, "&");
|
80
|
+
break;
|
81
|
+
|
82
|
+
/* the single quote is a valid URL character
|
83
|
+
* according to the standard; it needs HTML
|
84
|
+
* entity escaping too */
|
85
|
+
case '\'':
|
86
|
+
BUFPUTSL(ob, "'");
|
87
|
+
break;
|
88
|
+
|
89
|
+
/* the space can be escaped to %20 or a plus
|
90
|
+
* sign. we're going with the generic escape
|
91
|
+
* for now. the plus thing is more commonly seen
|
92
|
+
* when building GET strings */
|
93
|
+
#if 0
|
94
|
+
case ' ':
|
95
|
+
bufputc(ob, '+');
|
96
|
+
break;
|
97
|
+
#endif
|
98
|
+
|
99
|
+
/* every other character goes with a %XX escaping */
|
100
|
+
default:
|
101
|
+
hex_str[1] = hex_chars[(src[i] >> 4) & 0xF];
|
102
|
+
hex_str[2] = hex_chars[src[i] & 0xF];
|
103
|
+
bufput(ob, hex_str, 3);
|
104
|
+
}
|
105
|
+
|
106
|
+
i++;
|
107
|
+
}
|
108
|
+
}
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#include <assert.h>
|
2
|
+
#include <stdio.h>
|
3
|
+
#include <string.h>
|
4
|
+
|
5
|
+
#include "houdini.h"
|
6
|
+
|
7
|
+
#define ESCAPE_GROW_FACTOR(x) (((x) * 12) / 10) /* this is very scientific, yes */
|
8
|
+
|
9
|
+
/**
|
10
|
+
* According to the OWASP rules:
|
11
|
+
*
|
12
|
+
* & --> &
|
13
|
+
* < --> <
|
14
|
+
* > --> >
|
15
|
+
* " --> "
|
16
|
+
* ' --> ' ' is not recommended
|
17
|
+
* / --> / forward slash is included as it helps end an HTML entity
|
18
|
+
*
|
19
|
+
*/
|
20
|
+
static const char HTML_ESCAPE_TABLE[] = {
|
21
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
22
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
23
|
+
0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
|
24
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0,
|
25
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
26
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
27
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
28
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
29
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
30
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
31
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
32
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
33
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
34
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
35
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
36
|
+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
37
|
+
};
|
38
|
+
|
39
|
+
static const char *HTML_ESCAPES[] = {
|
40
|
+
"",
|
41
|
+
""",
|
42
|
+
"&",
|
43
|
+
"'",
|
44
|
+
"/",
|
45
|
+
"<",
|
46
|
+
">"
|
47
|
+
};
|
48
|
+
|
49
|
+
void
|
50
|
+
houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure)
|
51
|
+
{
|
52
|
+
size_t i = 0, org, esc;
|
53
|
+
|
54
|
+
bufgrow(ob, ESCAPE_GROW_FACTOR(size));
|
55
|
+
|
56
|
+
while (i < size) {
|
57
|
+
org = i;
|
58
|
+
while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)
|
59
|
+
i++;
|
60
|
+
|
61
|
+
if (i > org)
|
62
|
+
bufput(ob, src + org, i - org);
|
63
|
+
|
64
|
+
/* escaping */
|
65
|
+
if (i >= size)
|
66
|
+
break;
|
67
|
+
|
68
|
+
/* The forward slash is only escaped in secure mode */
|
69
|
+
if (src[i] == '/' && !secure) {
|
70
|
+
bufputc(ob, '/');
|
71
|
+
} else {
|
72
|
+
bufputs(ob, HTML_ESCAPES[esc]);
|
73
|
+
}
|
74
|
+
|
75
|
+
i++;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
void
|
80
|
+
houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size)
|
81
|
+
{
|
82
|
+
houdini_escape_html0(ob, src, size, 1);
|
83
|
+
}
|
84
|
+
|
data/ext/redcarpet/html.c
CHANGED
@@ -23,45 +23,12 @@
|
|
23
23
|
#include <stdio.h>
|
24
24
|
#include <ctype.h>
|
25
25
|
|
26
|
-
#
|
27
|
-
|
28
|
-
static inline void
|
29
|
-
put_escaped_char(struct buf *ob, int c)
|
30
|
-
{
|
31
|
-
switch (c) {
|
32
|
-
case '<': BUFPUTSL(ob, "<"); break;
|
33
|
-
case '>': BUFPUTSL(ob, ">"); break;
|
34
|
-
case '&': BUFPUTSL(ob, "&"); break;
|
35
|
-
case '"': BUFPUTSL(ob, """); break;
|
36
|
-
default: bufputc(ob, c); break;
|
37
|
-
}
|
38
|
-
}
|
39
|
-
|
40
|
-
/* sdhtml_escape • copy the buffer entity-escaping '<', '>', '&' and '"' */
|
41
|
-
void
|
42
|
-
sdhtml_escape(struct buf *ob, const uint8_t *src, size_t size)
|
43
|
-
{
|
44
|
-
size_t i = 0, org;
|
45
|
-
while (i < size) {
|
46
|
-
/* copying directly unescaped characters */
|
47
|
-
org = i;
|
48
|
-
|
49
|
-
while (i < size && src[i] != '<' && src[i] != '>'
|
50
|
-
&& src[i] != '&' && src[i] != '"')
|
51
|
-
i += 1;
|
26
|
+
#include "houdini.h"
|
52
27
|
|
53
|
-
|
54
|
-
|
55
|
-
/* escaping */
|
56
|
-
if (i >= size) break;
|
57
|
-
|
58
|
-
put_escaped_char(ob, src[i]);
|
59
|
-
i++;
|
60
|
-
}
|
61
|
-
}
|
28
|
+
#define USE_XHTML(opt) (opt->flags & HTML_USE_XHTML)
|
62
29
|
|
63
30
|
int
|
64
|
-
|
31
|
+
sdhtml_is_tag(const uint8_t *tag_data, size_t tag_size, const char *tagname)
|
65
32
|
{
|
66
33
|
size_t i;
|
67
34
|
int closed = 0;
|
@@ -112,7 +79,7 @@ rndr_autolink(struct buf *ob, const struct buf *link, enum mkd_autolink type, vo
|
|
112
79
|
BUFPUTSL(ob, "<a href=\"");
|
113
80
|
if (type == MKDA_EMAIL)
|
114
81
|
BUFPUTSL(ob, "mailto:");
|
115
|
-
|
82
|
+
houdini_escape_href(ob, link->data, link->size);
|
116
83
|
|
117
84
|
if (options->link_attributes) {
|
118
85
|
bufputc(ob, '\"');
|
@@ -128,9 +95,9 @@ rndr_autolink(struct buf *ob, const struct buf *link, enum mkd_autolink type, vo
|
|
128
95
|
* want to print the `mailto:` prefix
|
129
96
|
*/
|
130
97
|
if (bufprefix(link, "mailto:") == 0) {
|
131
|
-
|
98
|
+
houdini_escape_html(ob, link->data + 7, link->size - 7);
|
132
99
|
} else {
|
133
|
-
|
100
|
+
houdini_escape_html(ob, link->data, link->size);
|
134
101
|
}
|
135
102
|
|
136
103
|
BUFPUTSL(ob, "</a>");
|
@@ -160,7 +127,7 @@ rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, v
|
|
160
127
|
org++;
|
161
128
|
|
162
129
|
if (cls) bufputc(ob, ' ');
|
163
|
-
|
130
|
+
houdini_escape_html(ob, lang->data + org, i - org);
|
164
131
|
}
|
165
132
|
}
|
166
133
|
|
@@ -169,7 +136,7 @@ rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, v
|
|
169
136
|
BUFPUTSL(ob, "<pre><code>");
|
170
137
|
|
171
138
|
if (text)
|
172
|
-
|
139
|
+
houdini_escape_html(ob, text->data, text->size);
|
173
140
|
|
174
141
|
BUFPUTSL(ob, "</code></pre>\n");
|
175
142
|
}
|
@@ -187,7 +154,7 @@ static int
|
|
187
154
|
rndr_codespan(struct buf *ob, const struct buf *text, void *opaque)
|
188
155
|
{
|
189
156
|
BUFPUTSL(ob, "<code>");
|
190
|
-
if (text)
|
157
|
+
if (text) houdini_escape_html(ob, text->data, text->size);
|
191
158
|
BUFPUTSL(ob, "</code>");
|
192
159
|
return 1;
|
193
160
|
}
|
@@ -263,11 +230,11 @@ rndr_link(struct buf *ob, const struct buf *link, const struct buf *title, const
|
|
263
230
|
BUFPUTSL(ob, "<a href=\"");
|
264
231
|
|
265
232
|
if (link && link->size)
|
266
|
-
|
233
|
+
houdini_escape_href(ob, link->data, link->size);
|
267
234
|
|
268
235
|
if (title && title->size) {
|
269
236
|
BUFPUTSL(ob, "\" title=\"");
|
270
|
-
|
237
|
+
houdini_escape_html(ob, title->data, title->size);
|
271
238
|
}
|
272
239
|
|
273
240
|
if (options->link_attributes) {
|
@@ -387,14 +354,17 @@ rndr_image(struct buf *ob, const struct buf *link, const struct buf *title, cons
|
|
387
354
|
{
|
388
355
|
struct html_renderopt *options = opaque;
|
389
356
|
if (!link || !link->size) return 0;
|
357
|
+
|
390
358
|
BUFPUTSL(ob, "<img src=\"");
|
391
|
-
|
359
|
+
houdini_escape_href(ob, link->data, link->size);
|
392
360
|
BUFPUTSL(ob, "\" alt=\"");
|
361
|
+
|
393
362
|
if (alt && alt->size)
|
394
|
-
|
363
|
+
houdini_escape_html(ob, alt->data, alt->size);
|
364
|
+
|
395
365
|
if (title && title->size) {
|
396
366
|
BUFPUTSL(ob, "\" title=\"");
|
397
|
-
|
367
|
+
houdini_escape_html(ob, title->data, title->size); }
|
398
368
|
|
399
369
|
bufputs(ob, USE_XHTML(options) ? "\"/>" : "\">");
|
400
370
|
return 1;
|
@@ -408,13 +378,16 @@ rndr_raw_html(struct buf *ob, const struct buf *text, void *opaque)
|
|
408
378
|
if ((options->flags & HTML_SKIP_HTML) != 0)
|
409
379
|
return 1;
|
410
380
|
|
411
|
-
if ((options->flags & HTML_SKIP_STYLE) != 0 &&
|
381
|
+
if ((options->flags & HTML_SKIP_STYLE) != 0 &&
|
382
|
+
sdhtml_is_tag(text->data, text->size, "style"))
|
412
383
|
return 1;
|
413
384
|
|
414
|
-
if ((options->flags & HTML_SKIP_LINKS) != 0 &&
|
385
|
+
if ((options->flags & HTML_SKIP_LINKS) != 0 &&
|
386
|
+
sdhtml_is_tag(text->data, text->size, "a"))
|
415
387
|
return 1;
|
416
388
|
|
417
|
-
if ((options->flags & HTML_SKIP_IMAGES) != 0 &&
|
389
|
+
if ((options->flags & HTML_SKIP_IMAGES) != 0 &&
|
390
|
+
sdhtml_is_tag(text->data, text->size, "img"))
|
418
391
|
return 1;
|
419
392
|
|
420
393
|
bufput(ob, text->data, text->size);
|
@@ -493,7 +466,7 @@ static void
|
|
493
466
|
rndr_normal_text(struct buf *ob, const struct buf *text, void *opaque)
|
494
467
|
{
|
495
468
|
if (text)
|
496
|
-
|
469
|
+
houdini_escape_html(ob, text->data, text->size);
|
497
470
|
}
|
498
471
|
|
499
472
|
static void
|
data/ext/redcarpet/html.h
CHANGED
@@ -51,11 +51,8 @@ typedef enum {
|
|
51
51
|
HTML_TAG_CLOSE,
|
52
52
|
} html_tag;
|
53
53
|
|
54
|
-
void
|
55
|
-
sdhtml_escape(struct buf *ob, const uint8_t *src, size_t size);
|
56
|
-
|
57
54
|
int
|
58
|
-
|
55
|
+
sdhtml_is_tag(const uint8_t *tag_data, size_t tag_size, const char *tagname);
|
59
56
|
|
60
57
|
extern void
|
61
58
|
sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options_ptr, unsigned int render_flags);
|
@@ -273,7 +273,7 @@ smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t prev
|
|
273
273
|
i++;
|
274
274
|
|
275
275
|
for (tag = 0; tag < skip_tags_count; ++tag) {
|
276
|
-
if (
|
276
|
+
if (sdhtml_is_tag(text, size, skip_tags[tag]) == HTML_TAG_OPEN)
|
277
277
|
break;
|
278
278
|
}
|
279
279
|
|
@@ -285,7 +285,7 @@ smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t prev
|
|
285
285
|
if (i == size)
|
286
286
|
break;
|
287
287
|
|
288
|
-
if (
|
288
|
+
if (sdhtml_is_tag(text + i, size - i, skip_tags[tag]) == HTML_TAG_CLOSE)
|
289
289
|
break;
|
290
290
|
|
291
291
|
i++;
|
data/ext/redcarpet/markdown.c
CHANGED
@@ -1772,12 +1772,10 @@ parse_htmlblock(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t
|
|
1772
1772
|
return 0;
|
1773
1773
|
|
1774
1774
|
i = 1;
|
1775
|
-
|
1776
|
-
/* look for the closing `>` in the opening tag */
|
1777
1775
|
while (i < size && data[i] != '>' && data[i] != ' ')
|
1778
1776
|
i++;
|
1779
1777
|
|
1780
|
-
if (i < size
|
1778
|
+
if (i < size)
|
1781
1779
|
curtag = find_block_tag((char *)data + 1, i - 1);
|
1782
1780
|
|
1783
1781
|
/* handling of special cases */
|
@@ -1864,7 +1862,14 @@ parse_htmlblock(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t
|
|
1864
1862
|
}
|
1865
1863
|
|
1866
1864
|
static void
|
1867
|
-
parse_table_row(
|
1865
|
+
parse_table_row(
|
1866
|
+
struct buf *ob,
|
1867
|
+
struct sd_markdown *rndr,
|
1868
|
+
uint8_t *data,
|
1869
|
+
size_t size,
|
1870
|
+
size_t columns,
|
1871
|
+
int *col_data,
|
1872
|
+
int header_flag)
|
1868
1873
|
{
|
1869
1874
|
size_t i = 0, col;
|
1870
1875
|
struct buf *row_work = 0;
|
@@ -1897,7 +1902,7 @@ parse_table_row(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t
|
|
1897
1902
|
cell_end--;
|
1898
1903
|
|
1899
1904
|
parse_inline(cell_work, rndr, data + cell_start, 1 + cell_end - cell_start);
|
1900
|
-
rndr->cb.table_cell(row_work, cell_work, col_data[col], rndr->opaque);
|
1905
|
+
rndr->cb.table_cell(row_work, cell_work, col_data[col] | header_flag, rndr->opaque);
|
1901
1906
|
|
1902
1907
|
rndr_popbuf(rndr, BUFFER_SPAN);
|
1903
1908
|
i++;
|
@@ -1905,7 +1910,7 @@ parse_table_row(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t
|
|
1905
1910
|
|
1906
1911
|
for (; col < columns; ++col) {
|
1907
1912
|
struct buf empty_cell = { 0, 0, 0, 0 };
|
1908
|
-
rndr->cb.table_cell(row_work, &empty_cell, col_data[col], rndr->opaque);
|
1913
|
+
rndr->cb.table_cell(row_work, &empty_cell, col_data[col] | header_flag, rndr->opaque);
|
1909
1914
|
}
|
1910
1915
|
|
1911
1916
|
rndr->cb.table_row(ob, row_work, rndr->opaque);
|
@@ -1914,7 +1919,13 @@ parse_table_row(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t
|
|
1914
1919
|
}
|
1915
1920
|
|
1916
1921
|
static size_t
|
1917
|
-
parse_table_header(
|
1922
|
+
parse_table_header(
|
1923
|
+
struct buf *ob,
|
1924
|
+
struct sd_markdown *rndr,
|
1925
|
+
uint8_t *data,
|
1926
|
+
size_t size,
|
1927
|
+
size_t *columns,
|
1928
|
+
int **column_data)
|
1918
1929
|
{
|
1919
1930
|
int pipes;
|
1920
1931
|
size_t i = 0, col, header_end, under_end;
|
@@ -1950,8 +1961,6 @@ parse_table_header(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size
|
|
1950
1961
|
for (col = 0; col < *columns && i < under_end; ++col) {
|
1951
1962
|
size_t dashes = 0;
|
1952
1963
|
|
1953
|
-
(*column_data)[col] |= MKD_TABLE_HEADER;
|
1954
|
-
|
1955
1964
|
while (i < under_end && data[i] == ' ')
|
1956
1965
|
i++;
|
1957
1966
|
|
@@ -1984,12 +1993,23 @@ parse_table_header(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size
|
|
1984
1993
|
if (col < *columns)
|
1985
1994
|
return 0;
|
1986
1995
|
|
1987
|
-
parse_table_row(
|
1996
|
+
parse_table_row(
|
1997
|
+
ob, rndr, data,
|
1998
|
+
header_end,
|
1999
|
+
*columns,
|
2000
|
+
*column_data,
|
2001
|
+
MKD_TABLE_HEADER
|
2002
|
+
);
|
2003
|
+
|
1988
2004
|
return under_end + 1;
|
1989
2005
|
}
|
1990
2006
|
|
1991
2007
|
static size_t
|
1992
|
-
parse_table(
|
2008
|
+
parse_table(
|
2009
|
+
struct buf *ob,
|
2010
|
+
struct sd_markdown *rndr,
|
2011
|
+
uint8_t *data,
|
2012
|
+
size_t size)
|
1993
2013
|
{
|
1994
2014
|
size_t i;
|
1995
2015
|
|
@@ -2020,7 +2040,15 @@ parse_table(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size
|
|
2020
2040
|
break;
|
2021
2041
|
}
|
2022
2042
|
|
2023
|
-
parse_table_row(
|
2043
|
+
parse_table_row(
|
2044
|
+
body_work,
|
2045
|
+
rndr,
|
2046
|
+
data + row_start,
|
2047
|
+
i - row_start,
|
2048
|
+
columns,
|
2049
|
+
col_data, 0
|
2050
|
+
);
|
2051
|
+
|
2024
2052
|
i++;
|
2025
2053
|
}
|
2026
2054
|
|
data/ext/redcarpet/stack.c
CHANGED
data/lib/redcarpet.rb
CHANGED
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 = '2.0.
|
4
|
+
s.version = '2.0.0b5'
|
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 = '2011-09-
|
7
|
+
s.date = '2011-09-14'
|
8
8
|
s.email = 'vicent@github.com'
|
9
9
|
s.homepage = 'http://github.com/tanoku/redcarpet'
|
10
10
|
s.authors = ["Natacha Porté", "Vicent Martí"]
|
@@ -19,6 +19,9 @@ Gem::Specification.new do |s|
|
|
19
19
|
ext/redcarpet/buffer.c
|
20
20
|
ext/redcarpet/buffer.h
|
21
21
|
ext/redcarpet/extconf.rb
|
22
|
+
ext/redcarpet/houdini.h
|
23
|
+
ext/redcarpet/houdini_href_e.c
|
24
|
+
ext/redcarpet/houdini_html_e.c
|
22
25
|
ext/redcarpet/html.c
|
23
26
|
ext/redcarpet/html.h
|
24
27
|
ext/redcarpet/html_blocks.h
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redcarpet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 61
|
5
5
|
prerelease: 5
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 0
|
9
9
|
- 0
|
10
10
|
- b
|
11
|
-
-
|
12
|
-
version: 2.0.
|
11
|
+
- 5
|
12
|
+
version: 2.0.0b5
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- "Natacha Port\xC3\xA9"
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date: 2011-09-
|
21
|
+
date: 2011-09-14 00:00:00 Z
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
24
24
|
name: rake-compiler
|
@@ -52,6 +52,9 @@ files:
|
|
52
52
|
- ext/redcarpet/buffer.c
|
53
53
|
- ext/redcarpet/buffer.h
|
54
54
|
- ext/redcarpet/extconf.rb
|
55
|
+
- ext/redcarpet/houdini.h
|
56
|
+
- ext/redcarpet/houdini_href_e.c
|
57
|
+
- ext/redcarpet/houdini_html_e.c
|
55
58
|
- ext/redcarpet/html.c
|
56
59
|
- ext/redcarpet/html.h
|
57
60
|
- ext/redcarpet/html_blocks.h
|