markly 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/conduct.md +133 -0
- data/ext/markly/arena.c +9 -8
- data/ext/markly/autolink.c +217 -134
- data/ext/markly/blocks.c +27 -2
- 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/commonmark.c +19 -34
- data/ext/markly/extconf.rb +8 -1
- data/ext/markly/html.c +22 -6
- data/ext/markly/inlines.c +148 -51
- data/ext/markly/latex.c +6 -4
- data/ext/markly/man.c +7 -11
- data/ext/markly/map.c +11 -4
- data/ext/markly/map.h +5 -2
- data/ext/markly/markly.c +582 -586
- data/ext/markly/markly.h +1 -1
- data/ext/markly/node.c +76 -10
- data/ext/markly/node.h +42 -1
- data/ext/markly/parser.h +1 -0
- data/ext/markly/plaintext.c +12 -29
- data/ext/markly/references.c +1 -0
- data/ext/markly/render.c +15 -7
- data/ext/markly/scanners.c +13916 -10380
- data/ext/markly/scanners.h +8 -0
- data/ext/markly/scanners.re +47 -8
- data/ext/markly/strikethrough.c +1 -1
- data/ext/markly/table.c +81 -31
- data/ext/markly/xml.c +2 -1
- 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 +61 -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)
|
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
|
|
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/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/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
|