markly 0.7.0 → 0.8.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/conduct.md +133 -0
- data/ext/markly/Makefile +270 -0
- data/ext/markly/arena.c +9 -8
- data/ext/markly/arena.o +0 -0
- data/ext/markly/autolink.c +217 -134
- data/ext/markly/autolink.o +0 -0
- data/ext/markly/blocks.c +27 -2
- data/ext/markly/blocks.o +0 -0
- data/ext/markly/buffer.o +0 -0
- data/ext/markly/cmark-gfm-core-extensions.h +11 -11
- data/ext/markly/cmark-gfm-extension_api.h +1 -0
- data/ext/markly/cmark-gfm.h +18 -2
- data/ext/markly/cmark.c +3 -3
- data/ext/markly/cmark.o +0 -0
- data/ext/markly/cmark_ctype.o +0 -0
- data/ext/markly/commonmark.c +19 -34
- data/ext/markly/commonmark.o +0 -0
- data/ext/markly/core-extensions.o +0 -0
- data/ext/markly/ext_scanners.o +0 -0
- data/ext/markly/extconf.rb +8 -1
- data/ext/markly/footnotes.o +0 -0
- data/ext/markly/houdini_href_e.o +0 -0
- data/ext/markly/houdini_html_e.o +0 -0
- data/ext/markly/houdini_html_u.o +0 -0
- data/ext/markly/html.c +22 -6
- data/ext/markly/html.o +0 -0
- data/ext/markly/inlines.c +148 -51
- data/ext/markly/inlines.o +0 -0
- data/ext/markly/iterator.o +0 -0
- data/ext/markly/latex.c +6 -4
- data/ext/markly/latex.o +0 -0
- data/ext/markly/linked_list.o +0 -0
- data/ext/markly/man.c +7 -11
- data/ext/markly/man.o +0 -0
- data/ext/markly/map.c +11 -4
- data/ext/markly/map.h +5 -2
- data/ext/markly/map.o +0 -0
- data/ext/markly/markly.bundle +0 -0
- data/ext/markly/markly.c +582 -586
- data/ext/markly/markly.h +1 -1
- data/ext/markly/markly.o +0 -0
- data/ext/markly/node.c +76 -10
- data/ext/markly/node.h +42 -1
- data/ext/markly/node.o +0 -0
- data/ext/markly/parser.h +1 -0
- data/ext/markly/plaintext.c +12 -29
- data/ext/markly/plaintext.o +0 -0
- data/ext/markly/plugin.o +0 -0
- data/ext/markly/references.c +1 -0
- data/ext/markly/references.o +0 -0
- data/ext/markly/registry.o +0 -0
- data/ext/markly/render.c +15 -7
- data/ext/markly/render.o +0 -0
- data/ext/markly/scanners.c +13916 -10380
- data/ext/markly/scanners.h +8 -0
- data/ext/markly/scanners.o +0 -0
- data/ext/markly/scanners.re +47 -8
- data/ext/markly/strikethrough.c +1 -1
- data/ext/markly/strikethrough.o +0 -0
- data/ext/markly/syntax_extension.o +0 -0
- data/ext/markly/table.c +81 -31
- data/ext/markly/table.o +0 -0
- data/ext/markly/tagfilter.o +0 -0
- data/ext/markly/tasklist.o +0 -0
- data/ext/markly/utf8.o +0 -0
- data/ext/markly/xml.c +2 -1
- data/ext/markly/xml.o +0 -0
- data/lib/markly/flags.rb +16 -0
- data/lib/markly/node/inspect.rb +59 -53
- data/lib/markly/node.rb +125 -58
- data/lib/markly/renderer/generic.rb +129 -124
- data/lib/markly/renderer/html.rb +294 -275
- data/lib/markly/version.rb +7 -1
- data/lib/markly.rb +36 -30
- data/license.md +39 -0
- data/readme.md +36 -0
- data.tar.gz.sig +0 -0
- metadata +98 -29
- metadata.gz.sig +0 -0
- data/bin/markly +0 -94
- data/lib/markly/markly.bundle +0 -0
data/ext/markly/scanners.h
CHANGED
@@ -15,6 +15,10 @@ bufsize_t _scan_autolink_uri(const unsigned char *p);
|
|
15
15
|
bufsize_t _scan_autolink_email(const unsigned char *p);
|
16
16
|
bufsize_t _scan_html_tag(const unsigned char *p);
|
17
17
|
bufsize_t _scan_liberal_html_tag(const unsigned char *p);
|
18
|
+
bufsize_t _scan_html_comment(const unsigned char *p);
|
19
|
+
bufsize_t _scan_html_pi(const unsigned char *p);
|
20
|
+
bufsize_t _scan_html_declaration(const unsigned char *p);
|
21
|
+
bufsize_t _scan_html_cdata(const unsigned char *p);
|
18
22
|
bufsize_t _scan_html_block_start(const unsigned char *p);
|
19
23
|
bufsize_t _scan_html_block_start_7(const unsigned char *p);
|
20
24
|
bufsize_t _scan_html_block_end_1(const unsigned char *p);
|
@@ -37,6 +41,10 @@ bufsize_t _scan_footnote_definition(const unsigned char *p);
|
|
37
41
|
#define scan_autolink_email(c, n) _scan_at(&_scan_autolink_email, c, n)
|
38
42
|
#define scan_html_tag(c, n) _scan_at(&_scan_html_tag, c, n)
|
39
43
|
#define scan_liberal_html_tag(c, n) _scan_at(&_scan_liberal_html_tag, c, n)
|
44
|
+
#define scan_html_comment(c, n) _scan_at(&_scan_html_comment, c, n)
|
45
|
+
#define scan_html_pi(c, n) _scan_at(&_scan_html_pi, c, n)
|
46
|
+
#define scan_html_declaration(c, n) _scan_at(&_scan_html_declaration, c, n)
|
47
|
+
#define scan_html_cdata(c, n) _scan_at(&_scan_html_cdata, c, n)
|
40
48
|
#define scan_html_block_start(c, n) _scan_at(&_scan_html_block_start, c, n)
|
41
49
|
#define scan_html_block_start_7(c, n) _scan_at(&_scan_html_block_start_7, c, n)
|
42
50
|
#define scan_html_block_end_1(c, n) _scan_at(&_scan_html_block_end_1, c, n)
|
Binary file
|
data/ext/markly/scanners.re
CHANGED
@@ -54,16 +54,15 @@ bufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c,
|
|
54
54
|
opentag = tagname attribute* spacechar* [/]? [>];
|
55
55
|
closetag = [/] tagname spacechar* [>];
|
56
56
|
|
57
|
-
htmlcomment = "
|
57
|
+
htmlcomment = "--" ([^\x00-]+ | "-" [^\x00-] | "--" [^\x00>])* "-->";
|
58
58
|
|
59
|
-
processinginstruction =
|
59
|
+
processinginstruction = ([^?>\x00]+ | [?][^>\x00] | [>])+;
|
60
60
|
|
61
|
-
declaration =
|
61
|
+
declaration = [A-Z]+ spacechar+ [^>\x00]*;
|
62
62
|
|
63
|
-
cdata = "
|
63
|
+
cdata = "CDATA[" ([^\]\x00]+ | "]" [^\]\x00] | "]]" [^>\x00])*;
|
64
64
|
|
65
|
-
htmltag = opentag | closetag
|
66
|
-
declaration | cdata;
|
65
|
+
htmltag = opentag | closetag;
|
67
66
|
|
68
67
|
in_parens_nosp = [(] (reg_char|escaped_char|[\\])* [)];
|
69
68
|
|
@@ -133,6 +132,46 @@ bufsize_t _scan_liberal_html_tag(const unsigned char *p)
|
|
133
132
|
*/
|
134
133
|
}
|
135
134
|
|
135
|
+
bufsize_t _scan_html_comment(const unsigned char *p)
|
136
|
+
{
|
137
|
+
const unsigned char *marker = NULL;
|
138
|
+
const unsigned char *start = p;
|
139
|
+
/*!re2c
|
140
|
+
htmlcomment { return (bufsize_t)(p - start); }
|
141
|
+
* { return 0; }
|
142
|
+
*/
|
143
|
+
}
|
144
|
+
|
145
|
+
bufsize_t _scan_html_pi(const unsigned char *p)
|
146
|
+
{
|
147
|
+
const unsigned char *marker = NULL;
|
148
|
+
const unsigned char *start = p;
|
149
|
+
/*!re2c
|
150
|
+
processinginstruction { return (bufsize_t)(p - start); }
|
151
|
+
* { return 0; }
|
152
|
+
*/
|
153
|
+
}
|
154
|
+
|
155
|
+
bufsize_t _scan_html_declaration(const unsigned char *p)
|
156
|
+
{
|
157
|
+
const unsigned char *marker = NULL;
|
158
|
+
const unsigned char *start = p;
|
159
|
+
/*!re2c
|
160
|
+
declaration { return (bufsize_t)(p - start); }
|
161
|
+
* { return 0; }
|
162
|
+
*/
|
163
|
+
}
|
164
|
+
|
165
|
+
bufsize_t _scan_html_cdata(const unsigned char *p)
|
166
|
+
{
|
167
|
+
const unsigned char *marker = NULL;
|
168
|
+
const unsigned char *start = p;
|
169
|
+
/*!re2c
|
170
|
+
cdata { return (bufsize_t)(p - start); }
|
171
|
+
* { return 0; }
|
172
|
+
*/
|
173
|
+
}
|
174
|
+
|
136
175
|
// Try to match an HTML block tag start line, returning
|
137
176
|
// an integer code for the type of block (1-6, matching the spec).
|
138
177
|
// #7 is handled by a separate function, below.
|
@@ -140,7 +179,7 @@ bufsize_t _scan_html_block_start(const unsigned char *p)
|
|
140
179
|
{
|
141
180
|
const unsigned char *marker = NULL;
|
142
181
|
/*!re2c
|
143
|
-
[<] ('script'|'pre'|'style') (spacechar | [>]) { return 1; }
|
182
|
+
[<] ('script'|'pre'|'textarea'|'style') (spacechar | [>]) { return 1; }
|
144
183
|
'<!--' { return 2; }
|
145
184
|
'<?' { return 3; }
|
146
185
|
'<!' [A-Z] { return 4; }
|
@@ -167,7 +206,7 @@ bufsize_t _scan_html_block_end_1(const unsigned char *p)
|
|
167
206
|
const unsigned char *marker = NULL;
|
168
207
|
const unsigned char *start = p;
|
169
208
|
/*!re2c
|
170
|
-
[^\n\x00]* [<] [/] ('script'|'pre'|'style') [>] { return (bufsize_t)(p - start); }
|
209
|
+
[^\n\x00]* [<] [/] ('script'|'pre'|'textarea'|'style') [>] { return (bufsize_t)(p - start); }
|
171
210
|
* { return 0; }
|
172
211
|
*/
|
173
212
|
}
|
data/ext/markly/strikethrough.c
CHANGED
@@ -67,6 +67,7 @@ static delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser,
|
|
67
67
|
strikethrough->end_column = closer->inl_text->start_column + closer->inl_text->as.literal.len - 1;
|
68
68
|
cmark_node_free(closer->inl_text);
|
69
69
|
|
70
|
+
done:
|
70
71
|
delim = closer;
|
71
72
|
while (delim != NULL && delim != opener) {
|
72
73
|
tmp_delim = delim->previous;
|
@@ -76,7 +77,6 @@ static delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser,
|
|
76
77
|
|
77
78
|
cmark_inline_parser_remove_delimiter(inline_parser, opener);
|
78
79
|
|
79
|
-
done:
|
80
80
|
return res;
|
81
81
|
}
|
82
82
|
|
Binary file
|
Binary file
|
data/ext/markly/table.c
CHANGED
@@ -11,13 +11,21 @@
|
|
11
11
|
#include "table.h"
|
12
12
|
#include "cmark-gfm-core-extensions.h"
|
13
13
|
|
14
|
+
// Custom node flag, initialized in `create_table_extension`.
|
15
|
+
static cmark_node_internal_flags CMARK_NODE__TABLE_VISITED;
|
16
|
+
|
14
17
|
cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,
|
15
18
|
CMARK_NODE_TABLE_CELL;
|
16
19
|
|
20
|
+
typedef struct {
|
21
|
+
cmark_strbuf *buf;
|
22
|
+
int start_offset, end_offset, internal_offset;
|
23
|
+
} node_cell;
|
24
|
+
|
17
25
|
typedef struct {
|
18
26
|
uint16_t n_columns;
|
19
27
|
int paragraph_offset;
|
20
|
-
|
28
|
+
node_cell *cells;
|
21
29
|
} table_row;
|
22
30
|
|
23
31
|
typedef struct {
|
@@ -29,24 +37,24 @@ typedef struct {
|
|
29
37
|
bool is_header;
|
30
38
|
} node_table_row;
|
31
39
|
|
32
|
-
|
33
|
-
cmark_strbuf *buf;
|
34
|
-
int start_offset, end_offset, internal_offset;
|
35
|
-
} node_cell;
|
36
|
-
|
37
|
-
static void free_table_cell(cmark_mem *mem, void *data) {
|
38
|
-
node_cell *cell = (node_cell *)data;
|
40
|
+
static void free_table_cell(cmark_mem *mem, node_cell *cell) {
|
39
41
|
cmark_strbuf_free((cmark_strbuf *)cell->buf);
|
40
42
|
mem->free(cell->buf);
|
41
|
-
|
43
|
+
}
|
44
|
+
|
45
|
+
static void free_row_cells(cmark_mem *mem, table_row *row) {
|
46
|
+
while (row->n_columns > 0) {
|
47
|
+
free_table_cell(mem, &row->cells[--row->n_columns]);
|
48
|
+
}
|
49
|
+
mem->free(row->cells);
|
50
|
+
row->cells = NULL;
|
42
51
|
}
|
43
52
|
|
44
53
|
static void free_table_row(cmark_mem *mem, table_row *row) {
|
45
54
|
if (!row)
|
46
55
|
return;
|
47
56
|
|
48
|
-
|
49
|
-
|
57
|
+
free_row_cells(mem, row);
|
50
58
|
mem->free(row);
|
51
59
|
}
|
52
60
|
|
@@ -111,6 +119,24 @@ static cmark_strbuf *unescape_pipes(cmark_mem *mem, unsigned char *string, bufsi
|
|
111
119
|
return res;
|
112
120
|
}
|
113
121
|
|
122
|
+
// Adds a new cell to the end of the row. A pointer to the new cell is returned
|
123
|
+
// for the caller to initialize.
|
124
|
+
static node_cell* append_row_cell(cmark_mem *mem, table_row *row) {
|
125
|
+
const uint32_t n_columns = row->n_columns + 1;
|
126
|
+
// realloc when n_columns is a power of 2
|
127
|
+
if ((n_columns & (n_columns-1)) == 0) {
|
128
|
+
// make sure we never wrap row->n_columns
|
129
|
+
// offset will != len and our exit will clean up as intended
|
130
|
+
if (n_columns > UINT16_MAX) {
|
131
|
+
return NULL;
|
132
|
+
}
|
133
|
+
// Use realloc to double the size of the buffer.
|
134
|
+
row->cells = (node_cell *)mem->realloc(row->cells, (2 * n_columns - 1) * sizeof(node_cell));
|
135
|
+
}
|
136
|
+
row->n_columns = (uint16_t)n_columns;
|
137
|
+
return &row->cells[n_columns-1];
|
138
|
+
}
|
139
|
+
|
114
140
|
static table_row *row_from_string(cmark_syntax_extension *self,
|
115
141
|
cmark_parser *parser, unsigned char *string,
|
116
142
|
int len) {
|
@@ -129,6 +155,7 @@ static table_row *row_from_string(cmark_syntax_extension *self,
|
|
129
155
|
bufsize_t cell_matched = 1, pipe_matched = 1, offset;
|
130
156
|
int expect_more_cells = 1;
|
131
157
|
int row_end_offset = 0;
|
158
|
+
int int_overflow_abort = 0;
|
132
159
|
|
133
160
|
row = (table_row *)parser->mem->calloc(1, sizeof(table_row));
|
134
161
|
row->n_columns = 0;
|
@@ -151,18 +178,22 @@ static table_row *row_from_string(cmark_syntax_extension *self,
|
|
151
178
|
cell_matched);
|
152
179
|
cmark_strbuf_trim(cell_buf);
|
153
180
|
|
154
|
-
node_cell *cell = (
|
181
|
+
node_cell *cell = append_row_cell(parser->mem, row);
|
182
|
+
if (!cell) {
|
183
|
+
int_overflow_abort = 1;
|
184
|
+
cmark_strbuf_free(cell_buf);
|
185
|
+
parser->mem->free(cell_buf);
|
186
|
+
break;
|
187
|
+
}
|
155
188
|
cell->buf = cell_buf;
|
156
189
|
cell->start_offset = offset;
|
157
190
|
cell->end_offset = offset + cell_matched - 1;
|
191
|
+
cell->internal_offset = 0;
|
158
192
|
|
159
|
-
while (cell->start_offset >
|
193
|
+
while (cell->start_offset > row->paragraph_offset && string[cell->start_offset - 1] != '|') {
|
160
194
|
--cell->start_offset;
|
161
195
|
++cell->internal_offset;
|
162
196
|
}
|
163
|
-
|
164
|
-
row->n_columns += 1;
|
165
|
-
row->cells = cmark_llist_append(parser->mem, row->cells, cell);
|
166
197
|
}
|
167
198
|
|
168
199
|
offset += cell_matched + pipe_matched;
|
@@ -180,9 +211,7 @@ static table_row *row_from_string(cmark_syntax_extension *self,
|
|
180
211
|
if (row_end_offset && offset != len) {
|
181
212
|
row->paragraph_offset = offset;
|
182
213
|
|
183
|
-
|
184
|
-
row->cells = NULL;
|
185
|
-
row->n_columns = 0;
|
214
|
+
free_row_cells(parser->mem, row);
|
186
215
|
|
187
216
|
// Scan past the (optional) leading pipe.
|
188
217
|
offset += scan_table_cell_end(string, len, offset);
|
@@ -194,7 +223,7 @@ static table_row *row_from_string(cmark_syntax_extension *self,
|
|
194
223
|
}
|
195
224
|
}
|
196
225
|
|
197
|
-
if (offset != len || row->n_columns == 0) {
|
226
|
+
if (offset != len || row->n_columns == 0 || int_overflow_abort) {
|
198
227
|
free_table_row(parser->mem, row);
|
199
228
|
row = NULL;
|
200
229
|
}
|
@@ -233,6 +262,10 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
233
262
|
const char *parent_string;
|
234
263
|
uint16_t i;
|
235
264
|
|
265
|
+
if (parent_container->flags & CMARK_NODE__TABLE_VISITED) {
|
266
|
+
return parent_container;
|
267
|
+
}
|
268
|
+
|
236
269
|
if (!scan_table_start(input, len, cmark_parser_get_first_nonspace(parser))) {
|
237
270
|
return parent_container;
|
238
271
|
}
|
@@ -241,6 +274,11 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
241
274
|
marker_row = row_from_string(self, parser,
|
242
275
|
input + cmark_parser_get_first_nonspace(parser),
|
243
276
|
len - cmark_parser_get_first_nonspace(parser));
|
277
|
+
// assert may be optimized out, don't rely on it for security boundaries
|
278
|
+
if (!marker_row) {
|
279
|
+
return parent_container;
|
280
|
+
}
|
281
|
+
|
244
282
|
assert(marker_row);
|
245
283
|
|
246
284
|
cmark_arena_push();
|
@@ -255,6 +293,7 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
255
293
|
free_table_row(parser->mem, marker_row);
|
256
294
|
free_table_row(parser->mem, header_row);
|
257
295
|
cmark_arena_pop();
|
296
|
+
parent_container->flags |= CMARK_NODE__TABLE_VISITED;
|
258
297
|
return parent_container;
|
259
298
|
}
|
260
299
|
|
@@ -264,6 +303,12 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
264
303
|
len - cmark_parser_get_first_nonspace(parser));
|
265
304
|
header_row = row_from_string(self, parser, (unsigned char *)parent_string,
|
266
305
|
(int)strlen(parent_string));
|
306
|
+
// row_from_string can return NULL, add additional check to ensure n_columns match
|
307
|
+
if (!marker_row || !header_row || header_row->n_columns != marker_row->n_columns) {
|
308
|
+
free_table_row(parser->mem, marker_row);
|
309
|
+
free_table_row(parser->mem, header_row);
|
310
|
+
return parent_container;
|
311
|
+
}
|
267
312
|
}
|
268
313
|
|
269
314
|
if (!cmark_node_set_type(parent_container, CMARK_NODE_TABLE)) {
|
@@ -281,11 +326,12 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
281
326
|
parent_container->as.opaque = parser->mem->calloc(1, sizeof(node_table));
|
282
327
|
set_n_table_columns(parent_container, header_row->n_columns);
|
283
328
|
|
329
|
+
// allocate alignments based on marker_row->n_columns
|
330
|
+
// since we populate the alignments array based on marker_row->cells
|
284
331
|
uint8_t *alignments =
|
285
|
-
(uint8_t *)parser->mem->calloc(
|
286
|
-
|
287
|
-
|
288
|
-
node_cell *node = (node_cell *)it->data;
|
332
|
+
(uint8_t *)parser->mem->calloc(marker_row->n_columns, sizeof(uint8_t));
|
333
|
+
for (i = 0; i < marker_row->n_columns; ++i) {
|
334
|
+
node_cell *node = &marker_row->cells[i];
|
289
335
|
bool left = node->buf->ptr[0] == ':', right = node->buf->ptr[node->buf->size - 1] == ':';
|
290
336
|
|
291
337
|
if (left && right)
|
@@ -308,10 +354,8 @@ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
|
|
308
354
|
ntr->is_header = true;
|
309
355
|
|
310
356
|
{
|
311
|
-
|
312
|
-
|
313
|
-
for (tmp = header_row->cells; tmp; tmp = tmp->next) {
|
314
|
-
node_cell *cell = (node_cell *) tmp->data;
|
357
|
+
for (i = 0; i < header_row->n_columns; ++i) {
|
358
|
+
node_cell *cell = &header_row->cells[i];
|
315
359
|
cmark_node *header_cell = cmark_parser_add_child(parser, table_header,
|
316
360
|
CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);
|
317
361
|
header_cell->start_line = header_cell->end_line = parent_container->start_line;
|
@@ -351,12 +395,17 @@ static cmark_node *try_opening_table_row(cmark_syntax_extension *self,
|
|
351
395
|
row = row_from_string(self, parser, input + cmark_parser_get_first_nonspace(parser),
|
352
396
|
len - cmark_parser_get_first_nonspace(parser));
|
353
397
|
|
398
|
+
if (!row) {
|
399
|
+
// clean up the dangling node
|
400
|
+
cmark_node_free(table_row_block);
|
401
|
+
return NULL;
|
402
|
+
}
|
403
|
+
|
354
404
|
{
|
355
|
-
cmark_llist *tmp;
|
356
405
|
int i, table_columns = get_n_table_columns(parent_container);
|
357
406
|
|
358
|
-
for (
|
359
|
-
node_cell *cell =
|
407
|
+
for (i = 0; i < row->n_columns && i < table_columns; ++i) {
|
408
|
+
node_cell *cell = &row->cells[i];
|
360
409
|
cmark_node *node = cmark_parser_add_child(parser, table_row_block,
|
361
410
|
CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);
|
362
411
|
node->internal_offset = cell->internal_offset;
|
@@ -759,6 +808,7 @@ static int escape(cmark_syntax_extension *self, cmark_node *node, int c) {
|
|
759
808
|
cmark_syntax_extension *create_table_extension(void) {
|
760
809
|
cmark_syntax_extension *self = cmark_syntax_extension_new("table");
|
761
810
|
|
811
|
+
cmark_register_node_flag(&CMARK_NODE__TABLE_VISITED);
|
762
812
|
cmark_syntax_extension_set_match_block_func(self, matches);
|
763
813
|
cmark_syntax_extension_set_open_block_func(self, try_opening_table_block);
|
764
814
|
cmark_syntax_extension_set_get_type_string_func(self, get_type_string);
|
data/ext/markly/table.o
ADDED
Binary file
|
Binary file
|
Binary file
|
data/ext/markly/utf8.o
ADDED
Binary file
|
data/ext/markly/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
|
}
|
data/ext/markly/xml.o
ADDED
Binary file
|
data/lib/markly/flags.rb
CHANGED
@@ -1,12 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2020-2023, by Samuel Williams.
|
5
|
+
|
3
6
|
module Markly
|
7
|
+
# The default parsing system.
|
4
8
|
DEFAULT = 0
|
9
|
+
# Replace illegal sequences with the replacement character `U+FFFD`.
|
5
10
|
VALIDATE_UTF8 = 1 << 9
|
11
|
+
# Use smart punctuation (curly quotes, etc.).
|
6
12
|
SMART = 1 << 10
|
13
|
+
# Support liberal parsing of inline HTML tags.
|
7
14
|
LIBERAL_HTML_TAG = 1 << 12
|
15
|
+
# Parse footnotes.
|
8
16
|
FOOTNOTES = 1 << 13
|
17
|
+
# Support strikethrough using double tildes.
|
9
18
|
STRIKETHROUGH_DOUBLE_TILDE = 1 << 14
|
19
|
+
# Allow raw/custom HTML and unsafe links.
|
10
20
|
UNSAFE = 1 << 17
|
11
21
|
|
12
22
|
PARSE_FLAGS = {
|
@@ -18,11 +28,17 @@ module Markly
|
|
18
28
|
unsafe: UNSAFE,
|
19
29
|
}
|
20
30
|
|
31
|
+
# Include source position in rendered HTML.
|
21
32
|
SOURCE_POSITION = 1 << 1
|
33
|
+
# Treat `\n` as hardbreaks (by adding `<br/>`).
|
22
34
|
HARD_BREAKS = 1 << 2
|
35
|
+
# Translate `\n` in the source to a single whitespace.
|
23
36
|
NO_BREAKS = 1 << 4
|
37
|
+
# Use GitHub-style `<pre lang>` for fenced code blocks.
|
24
38
|
GITHUB_PRE_LANG = 1 << 11
|
39
|
+
# Use `style` insted of `align` for table cells.
|
25
40
|
TABLE_PREFER_STYLE_ATTRIBUTES = 1 << 15
|
41
|
+
# Include full info strings of code blocks in separate attribute.
|
26
42
|
FULL_INFO_STRING = 1 << 16
|
27
43
|
|
28
44
|
RENDER_FLAGS = {
|
data/lib/markly/node/inspect.rb
CHANGED
@@ -1,59 +1,65 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2017, by Goro Fuji.
|
5
|
+
# Copyright, 2017-2019, by Garen Torikian.
|
6
|
+
# Copyright, 2020, by Olle Jonsson.
|
7
|
+
# Copyright, 2020-2023, by Samuel Williams.
|
8
|
+
|
3
9
|
require 'pp'
|
4
10
|
|
5
11
|
module Markly
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
12
|
+
class Node
|
13
|
+
module Inspect
|
14
|
+
PP_INDENT_SIZE = 2
|
15
|
+
|
16
|
+
def inspect
|
17
|
+
PP.pp(self, +'', Float::INFINITY)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param printer [PrettyPrint] pp
|
21
|
+
def pretty_print(printer)
|
22
|
+
printer.group(PP_INDENT_SIZE, "#<#{self.class}(#{type}):", '>') do
|
23
|
+
printer.breakable
|
24
|
+
|
25
|
+
attrs = %i[
|
26
|
+
source_position
|
27
|
+
string_content
|
28
|
+
url
|
29
|
+
title
|
30
|
+
header_level
|
31
|
+
list_type
|
32
|
+
list_start
|
33
|
+
list_tight
|
34
|
+
fence_info
|
35
|
+
].map do |name|
|
36
|
+
begin
|
37
|
+
[name, __send__(name)]
|
38
|
+
rescue Error
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
end.compact
|
42
|
+
|
43
|
+
printer.seplist(attrs) do |name, value|
|
44
|
+
printer.text "#{name}="
|
45
|
+
printer.pp value
|
46
|
+
end
|
47
|
+
|
48
|
+
if first_child
|
49
|
+
printer.breakable
|
50
|
+
printer.group(PP_INDENT_SIZE) do
|
51
|
+
children = []
|
52
|
+
node = first_child
|
53
|
+
while node
|
54
|
+
children << node
|
55
|
+
node = node.next
|
56
|
+
end
|
57
|
+
printer.text 'children='
|
58
|
+
printer.pp children
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
59
65
|
end
|