commonmarker 0.23.7 → 0.23.9
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of commonmarker might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ext/commonmarker/arena.c +1 -1
- data/ext/commonmarker/autolink.c +5 -0
- data/ext/commonmarker/blocks.c +11 -1
- data/ext/commonmarker/cmark-gfm-core-extensions.h +11 -11
- data/ext/commonmarker/cmark-gfm.h +18 -2
- data/ext/commonmarker/cmark-gfm_version.h +2 -2
- data/ext/commonmarker/cmark.c +3 -3
- data/ext/commonmarker/commonmark.c +18 -33
- data/ext/commonmarker/html.c +22 -6
- data/ext/commonmarker/latex.c +6 -4
- data/ext/commonmarker/man.c +7 -11
- data/ext/commonmarker/node.c +59 -28
- data/ext/commonmarker/node.h +35 -14
- data/ext/commonmarker/plaintext.c +12 -29
- data/ext/commonmarker/render.c +15 -7
- data/ext/commonmarker/table.c +1 -1
- data/ext/commonmarker/xml.c +2 -1
- data/lib/commonmarker/renderer/html_renderer.rb +6 -2
- data/lib/commonmarker/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e13ce6bba89ae75cedfa740776ebacf43cc4c304f576aff0d5d795c5b9264e83
|
4
|
+
data.tar.gz: '03805285731cd7a7ddf1b856f572a3625c513d346f3e6fce7805d49a75a8c975'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: daffcc63f38700d806bbc9fa586fdb27855aec89b9fa7a6277accccabff40cb0adfd9e469eec2d992a540b038b5348e2b275b25d191cd1ee4ce38ccdc9a2094a
|
7
|
+
data.tar.gz: bef345d402340ace137b25ba5c0c78255252d347f5f637cfb3dff4c0407b554da958a7a9c14893dee523fd203c4b0ce5f2a5a696cdf83051eb5985aa4e116bab
|
data/ext/commonmarker/arena.c
CHANGED
@@ -99,6 +99,6 @@ static void arena_free(void *ptr) {
|
|
99
99
|
|
100
100
|
cmark_mem CMARK_ARENA_MEM_ALLOCATOR = {arena_calloc, arena_realloc, arena_free};
|
101
101
|
|
102
|
-
cmark_mem *cmark_get_arena_mem_allocator() {
|
102
|
+
cmark_mem *cmark_get_arena_mem_allocator(void) {
|
103
103
|
return &CMARK_ARENA_MEM_ALLOCATOR;
|
104
104
|
}
|
data/ext/commonmarker/autolink.c
CHANGED
@@ -267,6 +267,11 @@ static cmark_node *url_match(cmark_parser *parser, cmark_node *parent,
|
|
267
267
|
cmark_node *text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);
|
268
268
|
text->as.literal = url;
|
269
269
|
cmark_node_append_child(node, text);
|
270
|
+
|
271
|
+
node->start_line = text->start_line = node->end_line = text->end_line = cmark_inline_parser_get_line(inline_parser);
|
272
|
+
|
273
|
+
node->start_column = text->start_column = max_rewind - rewind;
|
274
|
+
node->end_column = text->end_column = cmark_inline_parser_get_column(inline_parser) - 1;
|
270
275
|
|
271
276
|
return node;
|
272
277
|
}
|
data/ext/commonmarker/blocks.c
CHANGED
@@ -27,6 +27,14 @@
|
|
27
27
|
#define CODE_INDENT 4
|
28
28
|
#define TAB_STOP 4
|
29
29
|
|
30
|
+
/**
|
31
|
+
* Very deeply nested lists can cause quadratic performance issues.
|
32
|
+
* This constant is used in open_new_blocks() to limit the nesting
|
33
|
+
* depth. It is unlikely that a non-contrived markdown document will
|
34
|
+
* be nested this deeply.
|
35
|
+
*/
|
36
|
+
#define MAX_LIST_DEPTH 100
|
37
|
+
|
30
38
|
#ifndef MIN
|
31
39
|
#define MIN(x, y) ((x < y) ? x : y)
|
32
40
|
#endif
|
@@ -1119,10 +1127,11 @@ static void open_new_blocks(cmark_parser *parser, cmark_node **container,
|
|
1119
1127
|
bool has_content;
|
1120
1128
|
int save_offset;
|
1121
1129
|
int save_column;
|
1130
|
+
size_t depth = 0;
|
1122
1131
|
|
1123
1132
|
while (cont_type != CMARK_NODE_CODE_BLOCK &&
|
1124
1133
|
cont_type != CMARK_NODE_HTML_BLOCK) {
|
1125
|
-
|
1134
|
+
depth++;
|
1126
1135
|
S_find_first_nonspace(parser, input);
|
1127
1136
|
indented = parser->indent >= CODE_INDENT;
|
1128
1137
|
|
@@ -1224,6 +1233,7 @@ static void open_new_blocks(cmark_parser *parser, cmark_node **container,
|
|
1224
1233
|
(*container)->internal_offset = matched;
|
1225
1234
|
} else if ((!indented || cont_type == CMARK_NODE_LIST) &&
|
1226
1235
|
parser->indent < 4 &&
|
1236
|
+
depth < MAX_LIST_DEPTH &&
|
1227
1237
|
(matched = parse_list_marker(
|
1228
1238
|
parser->mem, input, parser->first_nonspace,
|
1229
1239
|
(*container)->type == CMARK_NODE_PARAGRAPH, &data))) {
|
@@ -6,45 +6,45 @@ extern "C" {
|
|
6
6
|
#endif
|
7
7
|
|
8
8
|
#include "cmark-gfm-extension_api.h"
|
9
|
-
#include "cmark-
|
10
|
-
#include
|
9
|
+
#include "cmark-gfm_export.h"
|
10
|
+
#include <stdbool.h>
|
11
11
|
#include <stdint.h>
|
12
12
|
|
13
|
-
|
13
|
+
CMARK_GFM_EXPORT
|
14
14
|
void cmark_gfm_core_extensions_ensure_registered(void);
|
15
15
|
|
16
|
-
|
16
|
+
CMARK_GFM_EXPORT
|
17
17
|
uint16_t cmark_gfm_extensions_get_table_columns(cmark_node *node);
|
18
18
|
|
19
19
|
/** Sets the number of columns for the table, returning 1 on success and 0 on error.
|
20
20
|
*/
|
21
|
-
|
21
|
+
CMARK_GFM_EXPORT
|
22
22
|
int cmark_gfm_extensions_set_table_columns(cmark_node *node, uint16_t n_columns);
|
23
23
|
|
24
|
-
|
24
|
+
CMARK_GFM_EXPORT
|
25
25
|
uint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node);
|
26
26
|
|
27
27
|
/** Sets the alignments for the table, returning 1 on success and 0 on error.
|
28
28
|
*/
|
29
|
-
|
29
|
+
CMARK_GFM_EXPORT
|
30
30
|
int cmark_gfm_extensions_set_table_alignments(cmark_node *node, uint16_t ncols, uint8_t *alignments);
|
31
31
|
|
32
|
-
|
32
|
+
CMARK_GFM_EXPORT
|
33
33
|
int cmark_gfm_extensions_get_table_row_is_header(cmark_node *node);
|
34
34
|
|
35
35
|
/** Sets whether the node is a table header row, returning 1 on success and 0 on error.
|
36
36
|
*/
|
37
|
-
|
37
|
+
CMARK_GFM_EXPORT
|
38
38
|
int cmark_gfm_extensions_set_table_row_is_header(cmark_node *node, int is_header);
|
39
39
|
|
40
|
-
|
40
|
+
CMARK_GFM_EXPORT
|
41
41
|
bool cmark_gfm_extensions_get_tasklist_item_checked(cmark_node *node);
|
42
42
|
/* For backwards compatibility */
|
43
43
|
#define cmark_gfm_extensions_tasklist_is_checked cmark_gfm_extensions_get_tasklist_item_checked
|
44
44
|
|
45
45
|
/** Sets whether a tasklist item is "checked" (completed), returning 1 on success and 0 on error.
|
46
46
|
*/
|
47
|
-
|
47
|
+
CMARK_GFM_EXPORT
|
48
48
|
int cmark_gfm_extensions_set_tasklist_item_checked(cmark_node *node, bool is_checked);
|
49
49
|
|
50
50
|
#ifdef __cplusplus
|
@@ -111,13 +111,13 @@ typedef struct cmark_mem {
|
|
111
111
|
* realloc and free.
|
112
112
|
*/
|
113
113
|
CMARK_GFM_EXPORT
|
114
|
-
cmark_mem *cmark_get_default_mem_allocator();
|
114
|
+
cmark_mem *cmark_get_default_mem_allocator(void);
|
115
115
|
|
116
116
|
/** An arena allocator; uses system calloc to allocate large
|
117
117
|
* slabs of memory. Memory in these slabs is not reused at all.
|
118
118
|
*/
|
119
119
|
CMARK_GFM_EXPORT
|
120
|
-
cmark_mem *cmark_get_arena_mem_allocator();
|
120
|
+
cmark_mem *cmark_get_arena_mem_allocator(void);
|
121
121
|
|
122
122
|
/** Resets the arena allocator, quickly returning all used memory
|
123
123
|
* to the operating system.
|
@@ -225,6 +225,11 @@ CMARK_GFM_EXPORT cmark_node *cmark_node_first_child(cmark_node *node);
|
|
225
225
|
*/
|
226
226
|
CMARK_GFM_EXPORT cmark_node *cmark_node_last_child(cmark_node *node);
|
227
227
|
|
228
|
+
/** Returns the footnote reference of 'node', or NULL if 'node' doesn't have a
|
229
|
+
* footnote reference.
|
230
|
+
*/
|
231
|
+
CMARK_GFM_EXPORT cmark_node *cmark_node_parent_footnote_def(cmark_node *node);
|
232
|
+
|
228
233
|
/**
|
229
234
|
* ## Iterator
|
230
235
|
*
|
@@ -408,6 +413,17 @@ CMARK_GFM_EXPORT int cmark_node_get_list_tight(cmark_node *node);
|
|
408
413
|
*/
|
409
414
|
CMARK_GFM_EXPORT int cmark_node_set_list_tight(cmark_node *node, int tight);
|
410
415
|
|
416
|
+
/**
|
417
|
+
* Returns item index of 'node'. This is only used when rendering output
|
418
|
+
* formats such as commonmark, which need to output the index. It is not
|
419
|
+
* required for formats such as html or latex.
|
420
|
+
*/
|
421
|
+
CMARK_GFM_EXPORT int cmark_node_get_item_index(cmark_node *node);
|
422
|
+
|
423
|
+
/** Sets item index of 'node'. Returns 1 on success, 0 on failure.
|
424
|
+
*/
|
425
|
+
CMARK_GFM_EXPORT int cmark_node_set_item_index(cmark_node *node, int idx);
|
426
|
+
|
411
427
|
/** Returns the info string from a fenced code block.
|
412
428
|
*/
|
413
429
|
CMARK_GFM_EXPORT const char *cmark_node_get_fence_info(cmark_node *node);
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#ifndef CMARK_GFM_VERSION_H
|
2
2
|
#define CMARK_GFM_VERSION_H
|
3
3
|
|
4
|
-
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) |
|
5
|
-
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.
|
4
|
+
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 11)
|
5
|
+
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.11"
|
6
6
|
|
7
7
|
#endif
|
data/ext/commonmarker/cmark.c
CHANGED
@@ -10,9 +10,9 @@
|
|
10
10
|
cmark_node_type CMARK_NODE_LAST_BLOCK = CMARK_NODE_FOOTNOTE_DEFINITION;
|
11
11
|
cmark_node_type CMARK_NODE_LAST_INLINE = CMARK_NODE_FOOTNOTE_REFERENCE;
|
12
12
|
|
13
|
-
int cmark_version() { return CMARK_GFM_VERSION; }
|
13
|
+
int cmark_version(void) { return CMARK_GFM_VERSION; }
|
14
14
|
|
15
|
-
const char *cmark_version_string() { return CMARK_GFM_VERSION_STRING; }
|
15
|
+
const char *cmark_version_string(void) { return CMARK_GFM_VERSION_STRING; }
|
16
16
|
|
17
17
|
static void *xcalloc(size_t nmem, size_t size) {
|
18
18
|
void *ptr = calloc(nmem, size);
|
@@ -38,7 +38,7 @@ static void xfree(void *ptr) {
|
|
38
38
|
|
39
39
|
cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR = {xcalloc, xrealloc, xfree};
|
40
40
|
|
41
|
-
cmark_mem *cmark_get_default_mem_allocator() {
|
41
|
+
cmark_mem *cmark_get_default_mem_allocator(void) {
|
42
42
|
return &CMARK_DEFAULT_MEM_ALLOCATOR;
|
43
43
|
}
|
44
44
|
|
@@ -153,23 +153,8 @@ static bool is_autolink(cmark_node *node) {
|
|
153
153
|
link_text->as.literal.len) == 0);
|
154
154
|
}
|
155
155
|
|
156
|
-
// if node is a block node, returns node.
|
157
|
-
// otherwise returns first block-level node that is an ancestor of node.
|
158
|
-
// if there is no block-level ancestor, returns NULL.
|
159
|
-
static cmark_node *get_containing_block(cmark_node *node) {
|
160
|
-
while (node) {
|
161
|
-
if (CMARK_NODE_BLOCK_P(node)) {
|
162
|
-
return node;
|
163
|
-
} else {
|
164
|
-
node = node->parent;
|
165
|
-
}
|
166
|
-
}
|
167
|
-
return NULL;
|
168
|
-
}
|
169
|
-
|
170
156
|
static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
171
157
|
cmark_event_type ev_type, int options) {
|
172
|
-
cmark_node *tmp;
|
173
158
|
int list_number;
|
174
159
|
cmark_delim_type list_delim;
|
175
160
|
int numticks;
|
@@ -189,14 +174,17 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
189
174
|
// Don't adjust tight list status til we've started the list.
|
190
175
|
// Otherwise we loose the blank line between a paragraph and
|
191
176
|
// a following list.
|
192
|
-
if (
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
177
|
+
if (entering) {
|
178
|
+
if (node->parent && node->parent->type == CMARK_NODE_ITEM) {
|
179
|
+
renderer->in_tight_list_item = node->parent->parent->as.list.tight;
|
180
|
+
}
|
181
|
+
} else {
|
182
|
+
if (node->type == CMARK_NODE_LIST) {
|
183
|
+
renderer->in_tight_list_item =
|
184
|
+
node->parent &&
|
185
|
+
node->parent->type == CMARK_NODE_ITEM &&
|
186
|
+
node->parent->parent->as.list.tight;
|
187
|
+
}
|
200
188
|
}
|
201
189
|
|
202
190
|
if (node->extension && node->extension->commonmark_render_func) {
|
@@ -234,13 +222,8 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
234
222
|
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
|
235
223
|
marker_width = 4;
|
236
224
|
} else {
|
237
|
-
list_number =
|
225
|
+
list_number = cmark_node_get_item_index(node);
|
238
226
|
list_delim = cmark_node_get_list_delim(node->parent);
|
239
|
-
tmp = node;
|
240
|
-
while (tmp->prev) {
|
241
|
-
tmp = tmp->prev;
|
242
|
-
list_number += 1;
|
243
|
-
}
|
244
227
|
// we ensure a width of at least 4 so
|
245
228
|
// we get nice transition from single digits
|
246
229
|
// to double
|
@@ -405,10 +388,12 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
405
388
|
break;
|
406
389
|
|
407
390
|
case CMARK_NODE_STRONG:
|
408
|
-
if (
|
409
|
-
|
410
|
-
|
411
|
-
|
391
|
+
if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {
|
392
|
+
if (entering) {
|
393
|
+
LIT("**");
|
394
|
+
} else {
|
395
|
+
LIT("**");
|
396
|
+
}
|
412
397
|
}
|
413
398
|
break;
|
414
399
|
|
data/ext/commonmarker/html.c
CHANGED
@@ -63,10 +63,16 @@ static bool S_put_footnote_backref(cmark_html_renderer *renderer, cmark_strbuf *
|
|
63
63
|
if (renderer->written_footnote_ix >= renderer->footnote_ix)
|
64
64
|
return false;
|
65
65
|
renderer->written_footnote_ix = renderer->footnote_ix;
|
66
|
+
char m[32];
|
67
|
+
snprintf(m, sizeof(m), "%d", renderer->written_footnote_ix);
|
66
68
|
|
67
69
|
cmark_strbuf_puts(html, "<a href=\"#fnref-");
|
68
70
|
houdini_escape_href(html, node->as.literal.data, node->as.literal.len);
|
69
|
-
cmark_strbuf_puts(html, "\" class=\"footnote-backref\" data-footnote-backref
|
71
|
+
cmark_strbuf_puts(html, "\" class=\"footnote-backref\" data-footnote-backref data-footnote-backref-idx=\"");
|
72
|
+
cmark_strbuf_puts(html, m);
|
73
|
+
cmark_strbuf_puts(html, "\" aria-label=\"Back to reference ");
|
74
|
+
cmark_strbuf_puts(html, m);
|
75
|
+
cmark_strbuf_puts(html, "\">↩</a>");
|
70
76
|
|
71
77
|
if (node->footnote.def_count > 1)
|
72
78
|
{
|
@@ -78,7 +84,15 @@ static bool S_put_footnote_backref(cmark_html_renderer *renderer, cmark_strbuf *
|
|
78
84
|
houdini_escape_href(html, node->as.literal.data, node->as.literal.len);
|
79
85
|
cmark_strbuf_puts(html, "-");
|
80
86
|
cmark_strbuf_puts(html, n);
|
81
|
-
cmark_strbuf_puts(html, "\" class=\"footnote-backref\" data-footnote-backref
|
87
|
+
cmark_strbuf_puts(html, "\" class=\"footnote-backref\" data-footnote-backref data-footnote-backref-idx=\"");
|
88
|
+
cmark_strbuf_puts(html, m);
|
89
|
+
cmark_strbuf_puts(html, "-");
|
90
|
+
cmark_strbuf_puts(html, n);
|
91
|
+
cmark_strbuf_puts(html, "\" aria-label=\"Back to reference ");
|
92
|
+
cmark_strbuf_puts(html, m);
|
93
|
+
cmark_strbuf_puts(html, "-");
|
94
|
+
cmark_strbuf_puts(html, n);
|
95
|
+
cmark_strbuf_puts(html, "\">↩<sup class=\"footnote-ref\">");
|
82
96
|
cmark_strbuf_puts(html, n);
|
83
97
|
cmark_strbuf_puts(html, "</sup></a>");
|
84
98
|
}
|
@@ -350,10 +364,12 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
|
|
350
364
|
break;
|
351
365
|
|
352
366
|
case CMARK_NODE_STRONG:
|
353
|
-
if (
|
354
|
-
|
355
|
-
|
356
|
-
|
367
|
+
if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {
|
368
|
+
if (entering) {
|
369
|
+
cmark_strbuf_puts(html, "<strong>");
|
370
|
+
} else {
|
371
|
+
cmark_strbuf_puts(html, "</strong>");
|
372
|
+
}
|
357
373
|
}
|
358
374
|
break;
|
359
375
|
|
data/ext/commonmarker/latex.c
CHANGED
@@ -385,10 +385,12 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
385
385
|
break;
|
386
386
|
|
387
387
|
case CMARK_NODE_STRONG:
|
388
|
-
if (
|
389
|
-
|
390
|
-
|
391
|
-
|
388
|
+
if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {
|
389
|
+
if (entering) {
|
390
|
+
LIT("\\textbf{");
|
391
|
+
} else {
|
392
|
+
LIT("}");
|
393
|
+
}
|
392
394
|
}
|
393
395
|
break;
|
394
396
|
|
data/ext/commonmarker/man.c
CHANGED
@@ -74,7 +74,6 @@ static void S_outc(cmark_renderer *renderer, cmark_node *node,
|
|
74
74
|
|
75
75
|
static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
76
76
|
cmark_event_type ev_type, int options) {
|
77
|
-
cmark_node *tmp;
|
78
77
|
int list_number;
|
79
78
|
bool entering = (ev_type == CMARK_EVENT_ENTER);
|
80
79
|
bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);
|
@@ -123,12 +122,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
123
122
|
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
|
124
123
|
LIT("\\[bu] 2");
|
125
124
|
} else {
|
126
|
-
list_number =
|
127
|
-
tmp = node;
|
128
|
-
while (tmp->prev) {
|
129
|
-
tmp = tmp->prev;
|
130
|
-
list_number += 1;
|
131
|
-
}
|
125
|
+
list_number = cmark_node_get_item_index(node);
|
132
126
|
char list_number_s[LIST_NUMBER_SIZE];
|
133
127
|
snprintf(list_number_s, LIST_NUMBER_SIZE, "\"%d.\" 4", list_number);
|
134
128
|
LIT(list_number_s);
|
@@ -225,10 +219,12 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
225
219
|
break;
|
226
220
|
|
227
221
|
case CMARK_NODE_STRONG:
|
228
|
-
if (
|
229
|
-
|
230
|
-
|
231
|
-
|
222
|
+
if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {
|
223
|
+
if (entering) {
|
224
|
+
LIT("\\f[B]");
|
225
|
+
} else {
|
226
|
+
LIT("\\f[]");
|
227
|
+
}
|
232
228
|
}
|
233
229
|
break;
|
234
230
|
|
data/ext/commonmarker/node.c
CHANGED
@@ -5,16 +5,22 @@
|
|
5
5
|
#include "node.h"
|
6
6
|
#include "syntax_extension.h"
|
7
7
|
|
8
|
+
/**
|
9
|
+
* Expensive safety checks are off by default, but can be enabled
|
10
|
+
* by calling cmark_enable_safety_checks().
|
11
|
+
*/
|
12
|
+
static bool enable_safety_checks = false;
|
13
|
+
|
14
|
+
void cmark_enable_safety_checks(bool enable) {
|
15
|
+
enable_safety_checks = enable;
|
16
|
+
}
|
17
|
+
|
8
18
|
static void S_node_unlink(cmark_node *node);
|
9
19
|
|
10
20
|
#define NODE_MEM(node) cmark_node_mem(node)
|
11
21
|
|
12
|
-
|
13
|
-
|
14
|
-
cmark_node__internal_flags CMARK_NODE__LAST_LINE_CHECKED;
|
15
|
-
|
16
|
-
void cmark_register_node_flag(cmark_node__internal_flags *flags) {
|
17
|
-
static uint8_t shift = 0;
|
22
|
+
void cmark_register_node_flag(cmark_node_internal_flags *flags) {
|
23
|
+
static cmark_node_internal_flags nextflag = CMARK_NODE__REGISTER_FIRST;
|
18
24
|
|
19
25
|
// flags should be a pointer to a global variable and this function
|
20
26
|
// should only be called once to initialize its value.
|
@@ -24,24 +30,16 @@ void cmark_register_node_flag(cmark_node__internal_flags *flags) {
|
|
24
30
|
}
|
25
31
|
|
26
32
|
// Check that we haven't run out of bits.
|
27
|
-
if (
|
33
|
+
if (nextflag == 0) {
|
28
34
|
fprintf(stderr, "too many flags in cmark_register_node_flag\n");
|
29
35
|
abort();
|
30
36
|
}
|
31
37
|
|
32
|
-
*flags =
|
33
|
-
|
38
|
+
*flags = nextflag;
|
39
|
+
nextflag <<= 1;
|
34
40
|
}
|
35
41
|
|
36
|
-
void cmark_init_standard_node_flags() {
|
37
|
-
static int initialized = 0;
|
38
|
-
if (!initialized) {
|
39
|
-
initialized = 1;
|
40
|
-
cmark_register_node_flag(&CMARK_NODE__OPEN);
|
41
|
-
cmark_register_node_flag(&CMARK_NODE__LAST_LINE_BLANK);
|
42
|
-
cmark_register_node_flag(&CMARK_NODE__LAST_LINE_CHECKED);
|
43
|
-
}
|
44
|
-
}
|
42
|
+
void cmark_init_standard_node_flags(void) {}
|
45
43
|
|
46
44
|
bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type) {
|
47
45
|
if (child_type == CMARK_NODE_DOCUMENT) {
|
@@ -82,8 +80,6 @@ bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type) {
|
|
82
80
|
}
|
83
81
|
|
84
82
|
static bool S_can_contain(cmark_node *node, cmark_node *child) {
|
85
|
-
cmark_node *cur;
|
86
|
-
|
87
83
|
if (node == NULL || child == NULL) {
|
88
84
|
return false;
|
89
85
|
}
|
@@ -91,14 +87,16 @@ static bool S_can_contain(cmark_node *node, cmark_node *child) {
|
|
91
87
|
return 0;
|
92
88
|
}
|
93
89
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
90
|
+
if (enable_safety_checks) {
|
91
|
+
// Verify that child is not an ancestor of node or equal to node.
|
92
|
+
cmark_node *cur = node;
|
93
|
+
do {
|
94
|
+
if (cur == child) {
|
95
|
+
return false;
|
96
|
+
}
|
97
|
+
cur = cur->parent;
|
98
|
+
} while (cur != NULL);
|
99
|
+
}
|
102
100
|
|
103
101
|
return cmark_node_can_contain_type(node, (cmark_node_type) child->type);
|
104
102
|
}
|
@@ -335,6 +333,14 @@ cmark_node *cmark_node_last_child(cmark_node *node) {
|
|
335
333
|
}
|
336
334
|
}
|
337
335
|
|
336
|
+
cmark_node *cmark_node_parent_footnote_def(cmark_node *node) {
|
337
|
+
if (node == NULL) {
|
338
|
+
return NULL;
|
339
|
+
} else {
|
340
|
+
return node->parent_footnote_def;
|
341
|
+
}
|
342
|
+
}
|
343
|
+
|
338
344
|
void *cmark_node_get_user_data(cmark_node *node) {
|
339
345
|
if (node == NULL) {
|
340
346
|
return NULL;
|
@@ -558,6 +564,31 @@ int cmark_node_set_list_tight(cmark_node *node, int tight) {
|
|
558
564
|
}
|
559
565
|
}
|
560
566
|
|
567
|
+
int cmark_node_get_item_index(cmark_node *node) {
|
568
|
+
if (node == NULL) {
|
569
|
+
return 0;
|
570
|
+
}
|
571
|
+
|
572
|
+
if (node->type == CMARK_NODE_ITEM) {
|
573
|
+
return node->as.list.start;
|
574
|
+
} else {
|
575
|
+
return 0;
|
576
|
+
}
|
577
|
+
}
|
578
|
+
|
579
|
+
int cmark_node_set_item_index(cmark_node *node, int idx) {
|
580
|
+
if (node == NULL || idx < 0) {
|
581
|
+
return 0;
|
582
|
+
}
|
583
|
+
|
584
|
+
if (node->type == CMARK_NODE_ITEM) {
|
585
|
+
node->as.list.start = idx;
|
586
|
+
return 1;
|
587
|
+
} else {
|
588
|
+
return 0;
|
589
|
+
}
|
590
|
+
}
|
591
|
+
|
561
592
|
const char *cmark_node_get_fence_info(cmark_node *node) {
|
562
593
|
if (node == NULL) {
|
563
594
|
return NULL;
|
data/ext/commonmarker/node.h
CHANGED
@@ -48,7 +48,17 @@ typedef struct {
|
|
48
48
|
cmark_chunk on_exit;
|
49
49
|
} cmark_custom;
|
50
50
|
|
51
|
-
|
51
|
+
enum cmark_node__internal_flags {
|
52
|
+
CMARK_NODE__OPEN = (1 << 0),
|
53
|
+
CMARK_NODE__LAST_LINE_BLANK = (1 << 1),
|
54
|
+
CMARK_NODE__LAST_LINE_CHECKED = (1 << 2),
|
55
|
+
|
56
|
+
// Extensions can register custom flags by calling `cmark_register_node_flag`.
|
57
|
+
// This is the starting value for the custom flags.
|
58
|
+
CMARK_NODE__REGISTER_FIRST = (1 << 3),
|
59
|
+
};
|
60
|
+
|
61
|
+
typedef uint16_t cmark_node_internal_flags;
|
52
62
|
|
53
63
|
struct cmark_node {
|
54
64
|
cmark_strbuf content;
|
@@ -68,10 +78,18 @@ struct cmark_node {
|
|
68
78
|
int end_column;
|
69
79
|
int internal_offset;
|
70
80
|
uint16_t type;
|
71
|
-
|
81
|
+
cmark_node_internal_flags flags;
|
72
82
|
|
73
83
|
cmark_syntax_extension *extension;
|
74
84
|
|
85
|
+
/**
|
86
|
+
* Used during cmark_render() to cache the most recent non-NULL
|
87
|
+
* extension, if you go up the parent chain like this:
|
88
|
+
*
|
89
|
+
* node->parent->...parent->extension
|
90
|
+
*/
|
91
|
+
cmark_syntax_extension *ancestor_extension;
|
92
|
+
|
75
93
|
union {
|
76
94
|
int ref_ix;
|
77
95
|
int def_count;
|
@@ -98,22 +116,18 @@ struct cmark_node {
|
|
98
116
|
* which will store the flag value.
|
99
117
|
*/
|
100
118
|
CMARK_GFM_EXPORT
|
101
|
-
void cmark_register_node_flag(
|
119
|
+
void cmark_register_node_flag(cmark_node_internal_flags *flags);
|
102
120
|
|
103
121
|
/**
|
104
|
-
*
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
/**
|
111
|
-
* Uses `cmark_register_node_flag` to initialize the standard node flags.
|
112
|
-
* This function should be called at program startup time. Calling it
|
113
|
-
* multiple times has no additional effect.
|
122
|
+
* DEPRECATED.
|
123
|
+
*
|
124
|
+
* This function was added in cmark-gfm version 0.29.0.gfm.7, and was
|
125
|
+
* required to be called at program start time, which caused
|
126
|
+
* backwards-compatibility issues in applications that use cmark-gfm as a
|
127
|
+
* library. It is now a no-op.
|
114
128
|
*/
|
115
129
|
CMARK_GFM_EXPORT
|
116
|
-
void cmark_init_standard_node_flags();
|
130
|
+
void cmark_init_standard_node_flags(void);
|
117
131
|
|
118
132
|
static CMARK_INLINE cmark_mem *cmark_node_mem(cmark_node *node) {
|
119
133
|
return node->content.mem;
|
@@ -138,6 +152,13 @@ static CMARK_INLINE bool CMARK_NODE_INLINE_P(cmark_node *node) {
|
|
138
152
|
|
139
153
|
CMARK_GFM_EXPORT bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type);
|
140
154
|
|
155
|
+
/**
|
156
|
+
* Enable (or disable) extra safety checks. These extra checks cause
|
157
|
+
* extra performance overhead (in some cases quadratic), so they are only
|
158
|
+
* intended to be used during testing.
|
159
|
+
*/
|
160
|
+
CMARK_GFM_EXPORT void cmark_enable_safety_checks(bool enable);
|
161
|
+
|
141
162
|
#ifdef __cplusplus
|
142
163
|
}
|
143
164
|
#endif
|
@@ -16,23 +16,8 @@ static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node,
|
|
16
16
|
cmark_render_code_point(renderer, c);
|
17
17
|
}
|
18
18
|
|
19
|
-
// if node is a block node, returns node.
|
20
|
-
// otherwise returns first block-level node that is an ancestor of node.
|
21
|
-
// if there is no block-level ancestor, returns NULL.
|
22
|
-
static cmark_node *get_containing_block(cmark_node *node) {
|
23
|
-
while (node) {
|
24
|
-
if (CMARK_NODE_BLOCK_P(node)) {
|
25
|
-
return node;
|
26
|
-
} else {
|
27
|
-
node = node->parent;
|
28
|
-
}
|
29
|
-
}
|
30
|
-
return NULL;
|
31
|
-
}
|
32
|
-
|
33
19
|
static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
34
20
|
cmark_event_type ev_type, int options) {
|
35
|
-
cmark_node *tmp;
|
36
21
|
int list_number;
|
37
22
|
cmark_delim_type list_delim;
|
38
23
|
int i;
|
@@ -46,14 +31,17 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
46
31
|
// Don't adjust tight list status til we've started the list.
|
47
32
|
// Otherwise we loose the blank line between a paragraph and
|
48
33
|
// a following list.
|
49
|
-
if (
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
34
|
+
if (entering) {
|
35
|
+
if (node->parent && node->parent->type == CMARK_NODE_ITEM) {
|
36
|
+
renderer->in_tight_list_item = node->parent->parent->as.list.tight;
|
37
|
+
}
|
38
|
+
} else {
|
39
|
+
if (node->type == CMARK_NODE_LIST) {
|
40
|
+
renderer->in_tight_list_item =
|
41
|
+
node->parent &&
|
42
|
+
node->parent->type == CMARK_NODE_ITEM &&
|
43
|
+
node->parent->parent->as.list.tight;
|
44
|
+
}
|
57
45
|
}
|
58
46
|
|
59
47
|
if (node->extension && node->extension->plaintext_render_func) {
|
@@ -79,13 +67,8 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
79
67
|
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
|
80
68
|
marker_width = 4;
|
81
69
|
} else {
|
82
|
-
list_number =
|
70
|
+
list_number = cmark_node_get_item_index(node);
|
83
71
|
list_delim = cmark_node_get_list_delim(node->parent);
|
84
|
-
tmp = node;
|
85
|
-
while (tmp->prev) {
|
86
|
-
tmp = tmp->prev;
|
87
|
-
list_number += 1;
|
88
|
-
}
|
89
72
|
// we ensure a width of at least 4 so
|
90
73
|
// we get nice transition from single digits
|
91
74
|
// to double
|
data/ext/commonmarker/render.c
CHANGED
@@ -31,13 +31,7 @@ static void S_out(cmark_renderer *renderer, cmark_node *node,
|
|
31
31
|
cmark_chunk remainder = cmark_chunk_literal("");
|
32
32
|
int k = renderer->buffer->size - 1;
|
33
33
|
|
34
|
-
cmark_syntax_extension *ext =
|
35
|
-
cmark_node *n = node;
|
36
|
-
while (n && !ext) {
|
37
|
-
ext = n->extension;
|
38
|
-
if (!ext)
|
39
|
-
n = n->parent;
|
40
|
-
}
|
34
|
+
cmark_syntax_extension *ext = node->ancestor_extension;
|
41
35
|
if (ext && !ext->commonmark_escape_func)
|
42
36
|
ext = NULL;
|
43
37
|
|
@@ -182,6 +176,20 @@ char *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,
|
|
182
176
|
|
183
177
|
while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
|
184
178
|
cur = cmark_iter_get_node(iter);
|
179
|
+
if (cur->extension) {
|
180
|
+
cur->ancestor_extension = cur->extension;
|
181
|
+
} else if (cur->parent) {
|
182
|
+
cur->ancestor_extension = cur->parent->ancestor_extension;
|
183
|
+
}
|
184
|
+
if (cur->type == CMARK_NODE_ITEM) {
|
185
|
+
// Calculate the list item's index, for the benefit of output formats
|
186
|
+
// like commonmark and plaintext.
|
187
|
+
if (cur->prev) {
|
188
|
+
cmark_node_set_item_index(cur, 1 + cmark_node_get_item_index(cur->prev));
|
189
|
+
} else {
|
190
|
+
cmark_node_set_item_index(cur, cmark_node_get_list_start(cur->parent));
|
191
|
+
}
|
192
|
+
}
|
185
193
|
if (!render_node(&renderer, cur, ev_type, options)) {
|
186
194
|
// a false value causes us to skip processing
|
187
195
|
// the node's contents. this is used for
|
data/ext/commonmarker/table.c
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
#include "cmark-gfm-core-extensions.h"
|
13
13
|
|
14
14
|
// Custom node flag, initialized in `create_table_extension`.
|
15
|
-
static
|
15
|
+
static cmark_node_internal_flags CMARK_NODE__TABLE_VISITED;
|
16
16
|
|
17
17
|
cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,
|
18
18
|
CMARK_NODE_TABLE_CELL;
|
data/ext/commonmarker/xml.c
CHANGED
@@ -11,6 +11,7 @@
|
|
11
11
|
#include "syntax_extension.h"
|
12
12
|
|
13
13
|
#define BUFFER_SIZE 100
|
14
|
+
#define MAX_INDENT 40
|
14
15
|
|
15
16
|
// Functions to convert cmark_nodes to XML strings.
|
16
17
|
|
@@ -26,7 +27,7 @@ struct render_state {
|
|
26
27
|
|
27
28
|
static CMARK_INLINE void indent(struct render_state *state) {
|
28
29
|
int i;
|
29
|
-
for (i = 0; i < state->indent; i++) {
|
30
|
+
for (i = 0; i < state->indent && i < MAX_INDENT; i++) {
|
30
31
|
cmark_strbuf_putc(state->xml, ' ');
|
31
32
|
}
|
32
33
|
}
|
@@ -129,8 +129,12 @@ module CommonMarker
|
|
129
129
|
out("<em>", :children, "</em>")
|
130
130
|
end
|
131
131
|
|
132
|
-
def strong(
|
133
|
-
|
132
|
+
def strong(node)
|
133
|
+
if node.parent&.type == :strong
|
134
|
+
out(:children)
|
135
|
+
else
|
136
|
+
out("<strong>", :children, "</strong>")
|
137
|
+
end
|
134
138
|
end
|
135
139
|
|
136
140
|
def link(node)
|
data/lib/commonmarker/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: commonmarker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.23.
|
4
|
+
version: 0.23.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garen Torikian
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-04-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: awesome_print
|