commonmarker 0.14.3 → 0.14.4
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/commonmarker.gemspec +1 -1
- data/ext/commonmarker/cmark/Makefile +2 -2
- data/ext/commonmarker/cmark/extensions/CMakeLists.txt +38 -12
- data/ext/commonmarker/cmark/extensions/autolink.c +151 -102
- data/ext/commonmarker/cmark/extensions/core-extensions.h +2 -0
- data/ext/commonmarker/cmark/extensions/strikethrough.c +15 -10
- data/ext/commonmarker/cmark/extensions/table.c +31 -26
- data/ext/commonmarker/cmark/src/CMakeLists.txt +4 -1
- data/ext/commonmarker/cmark/src/blocks.c +11 -7
- data/ext/commonmarker/cmark/src/cmark_extension_api.h +14 -0
- data/ext/commonmarker/cmark/src/commonmark.c +7 -5
- data/ext/commonmarker/cmark/src/inlines.c +1 -6
- data/ext/commonmarker/cmark/src/latex.c +4 -3
- data/ext/commonmarker/cmark/src/man.c +4 -3
- data/ext/commonmarker/cmark/src/render.c +5 -3
- data/ext/commonmarker/cmark/src/render.h +4 -3
- data/ext/commonmarker/cmark/src/syntax_extension.c +5 -0
- data/ext/commonmarker/cmark/src/syntax_extension.h +1 -0
- data/ext/commonmarker/cmark/test/CMakeLists.txt +3 -2
- data/ext/commonmarker/cmark/test/cmark.py +69 -23
- data/ext/commonmarker/cmark/test/extensions.txt +6 -6
- data/ext/commonmarker/cmark/test/roundtrip_tests.py +6 -4
- data/ext/commonmarker/cmark/test/spec.txt +420 -4
- data/ext/commonmarker/cmark/test/spec_tests.py +12 -6
- data/ext/commonmarker/extconf.rb +1 -1
- data/lib/commonmarker/renderer/html_renderer.rb +4 -0
- data/lib/commonmarker/version.rb +1 -1
- data/test/test_helper.rb +5 -2
- data/test/test_spec.rb +9 -7
- metadata +6 -6
@@ -482,13 +482,13 @@ static void commonmark_render(cmark_syntax_extension *extension,
|
|
482
482
|
} else if (node->type == CMARK_NODE_TABLE_ROW) {
|
483
483
|
if (entering) {
|
484
484
|
renderer->cr(renderer);
|
485
|
-
renderer->out(renderer, "|", false, LITERAL);
|
485
|
+
renderer->out(renderer, node, "|", false, LITERAL);
|
486
486
|
}
|
487
487
|
} else if (node->type == CMARK_NODE_TABLE_CELL) {
|
488
488
|
if (entering) {
|
489
|
-
renderer->out(renderer, " ", false, LITERAL);
|
489
|
+
renderer->out(renderer, node, " ", false, LITERAL);
|
490
490
|
} else {
|
491
|
-
renderer->out(renderer, " |", false, LITERAL);
|
491
|
+
renderer->out(renderer, node, " |", false, LITERAL);
|
492
492
|
if (((node_table_row *)node->parent->as.opaque)->is_header &&
|
493
493
|
!node->next) {
|
494
494
|
int i;
|
@@ -496,13 +496,13 @@ static void commonmark_render(cmark_syntax_extension *extension,
|
|
496
496
|
uint16_t n_cols =
|
497
497
|
((node_table *)node->parent->parent->as.opaque)->n_columns;
|
498
498
|
renderer->cr(renderer);
|
499
|
-
renderer->out(renderer, "|", false, LITERAL);
|
499
|
+
renderer->out(renderer, node, "|", false, LITERAL);
|
500
500
|
for (i = 0; i < n_cols; i++) {
|
501
501
|
switch (alignments[i]) {
|
502
|
-
case 0: renderer->out(renderer, " --- |", false, LITERAL); break;
|
503
|
-
case 'l': renderer->out(renderer, " :-- |", false, LITERAL); break;
|
504
|
-
case 'c': renderer->out(renderer, " :-: |", false, LITERAL); break;
|
505
|
-
case 'r': renderer->out(renderer, " --: |", false, LITERAL); break;
|
502
|
+
case 0: renderer->out(renderer, node, " --- |", false, LITERAL); break;
|
503
|
+
case 'l': renderer->out(renderer, node, " :-- |", false, LITERAL); break;
|
504
|
+
case 'c': renderer->out(renderer, node, " :-: |", false, LITERAL); break;
|
505
|
+
case 'r': renderer->out(renderer, node, " --: |", false, LITERAL); break;
|
506
506
|
}
|
507
507
|
}
|
508
508
|
renderer->cr(renderer);
|
@@ -525,31 +525,31 @@ static void latex_render(cmark_syntax_extension *extension,
|
|
525
525
|
uint8_t *alignments = get_table_alignments(node);
|
526
526
|
|
527
527
|
renderer->cr(renderer);
|
528
|
-
renderer->out(renderer, "\\begin{table}", false, LITERAL);
|
528
|
+
renderer->out(renderer, node, "\\begin{table}", false, LITERAL);
|
529
529
|
renderer->cr(renderer);
|
530
|
-
renderer->out(renderer, "\\begin{tabular}{", false, LITERAL);
|
530
|
+
renderer->out(renderer, node, "\\begin{tabular}{", false, LITERAL);
|
531
531
|
|
532
532
|
n_cols = ((node_table *)node->as.opaque)->n_columns;
|
533
533
|
for (i = 0; i < n_cols; i++) {
|
534
534
|
switch(alignments[i]) {
|
535
535
|
case 0:
|
536
536
|
case 'l':
|
537
|
-
renderer->out(renderer, "l", false, LITERAL);
|
537
|
+
renderer->out(renderer, node, "l", false, LITERAL);
|
538
538
|
break;
|
539
539
|
case 'c':
|
540
|
-
renderer->out(renderer, "c", false, LITERAL);
|
540
|
+
renderer->out(renderer, node, "c", false, LITERAL);
|
541
541
|
break;
|
542
542
|
case 'r':
|
543
|
-
renderer->out(renderer, "r", false, LITERAL);
|
543
|
+
renderer->out(renderer, node, "r", false, LITERAL);
|
544
544
|
break;
|
545
545
|
}
|
546
546
|
}
|
547
|
-
renderer->out(renderer, "}", false, LITERAL);
|
547
|
+
renderer->out(renderer, node, "}", false, LITERAL);
|
548
548
|
renderer->cr(renderer);
|
549
549
|
} else {
|
550
|
-
renderer->out(renderer, "\\end{tabular}", false, LITERAL);
|
550
|
+
renderer->out(renderer, node, "\\end{tabular}", false, LITERAL);
|
551
551
|
renderer->cr(renderer);
|
552
|
-
renderer->out(renderer, "\\end{table}", false, LITERAL);
|
552
|
+
renderer->out(renderer, node, "\\end{table}", false, LITERAL);
|
553
553
|
renderer->cr(renderer);
|
554
554
|
}
|
555
555
|
} else if (node->type == CMARK_NODE_TABLE_ROW) {
|
@@ -559,9 +559,9 @@ static void latex_render(cmark_syntax_extension *extension,
|
|
559
559
|
} else if (node->type == CMARK_NODE_TABLE_CELL) {
|
560
560
|
if (!entering) {
|
561
561
|
if (node->next) {
|
562
|
-
renderer->out(renderer, " & ", false, LITERAL);
|
562
|
+
renderer->out(renderer, node, " & ", false, LITERAL);
|
563
563
|
} else {
|
564
|
-
renderer->out(renderer, " \\\\", false, LITERAL);
|
564
|
+
renderer->out(renderer, node, " \\\\", false, LITERAL);
|
565
565
|
}
|
566
566
|
}
|
567
567
|
} else {
|
@@ -581,9 +581,9 @@ static void man_render(cmark_syntax_extension *extension,
|
|
581
581
|
uint8_t *alignments = get_table_alignments(node);
|
582
582
|
|
583
583
|
renderer->cr(renderer);
|
584
|
-
renderer->out(renderer, ".TS", false, LITERAL);
|
584
|
+
renderer->out(renderer, node, ".TS", false, LITERAL);
|
585
585
|
renderer->cr(renderer);
|
586
|
-
renderer->out(renderer, "tab(@);", false, LITERAL);
|
586
|
+
renderer->out(renderer, node, "tab(@);", false, LITERAL);
|
587
587
|
renderer->cr(renderer);
|
588
588
|
|
589
589
|
n_cols = ((node_table *)node->as.opaque)->n_columns;
|
@@ -591,24 +591,24 @@ static void man_render(cmark_syntax_extension *extension,
|
|
591
591
|
for (i = 0; i < n_cols; i++) {
|
592
592
|
switch (alignments[i]) {
|
593
593
|
case 'l':
|
594
|
-
renderer->out(renderer, "l", false, LITERAL);
|
594
|
+
renderer->out(renderer, node, "l", false, LITERAL);
|
595
595
|
break;
|
596
596
|
case 0:
|
597
597
|
case 'c':
|
598
|
-
renderer->out(renderer, "c", false, LITERAL);
|
598
|
+
renderer->out(renderer, node, "c", false, LITERAL);
|
599
599
|
break;
|
600
600
|
case 'r':
|
601
|
-
renderer->out(renderer, "r", false, LITERAL);
|
601
|
+
renderer->out(renderer, node, "r", false, LITERAL);
|
602
602
|
break;
|
603
603
|
}
|
604
604
|
}
|
605
605
|
|
606
606
|
if (n_cols) {
|
607
|
-
renderer->out(renderer, ".", false, LITERAL);
|
607
|
+
renderer->out(renderer, node, ".", false, LITERAL);
|
608
608
|
renderer->cr(renderer);
|
609
609
|
}
|
610
610
|
} else {
|
611
|
-
renderer->out(renderer, ".TE", false, LITERAL);
|
611
|
+
renderer->out(renderer, node, ".TE", false, LITERAL);
|
612
612
|
renderer->cr(renderer);
|
613
613
|
}
|
614
614
|
} else if (node->type == CMARK_NODE_TABLE_ROW) {
|
@@ -617,7 +617,7 @@ static void man_render(cmark_syntax_extension *extension,
|
|
617
617
|
}
|
618
618
|
} else if (node->type == CMARK_NODE_TABLE_CELL) {
|
619
619
|
if (!entering && node->next) {
|
620
|
-
renderer->out(renderer, "@", false, LITERAL);
|
620
|
+
renderer->out(renderer, node, "@", false, LITERAL);
|
621
621
|
}
|
622
622
|
} else {
|
623
623
|
assert(false);
|
@@ -719,6 +719,10 @@ static void opaque_free(cmark_syntax_extension *ext, cmark_mem *mem, cmark_node
|
|
719
719
|
}
|
720
720
|
}
|
721
721
|
|
722
|
+
static int escape(cmark_syntax_extension *ext, cmark_node *node, int c) {
|
723
|
+
return c == '|';
|
724
|
+
}
|
725
|
+
|
722
726
|
cmark_syntax_extension *create_table_extension(void) {
|
723
727
|
cmark_syntax_extension *ext = cmark_syntax_extension_new("table");
|
724
728
|
|
@@ -732,6 +736,7 @@ cmark_syntax_extension *create_table_extension(void) {
|
|
732
736
|
cmark_syntax_extension_set_man_render_func(ext, man_render);
|
733
737
|
cmark_syntax_extension_set_html_render_func(ext, html_render);
|
734
738
|
cmark_syntax_extension_set_opaque_free_func(ext, opaque_free);
|
739
|
+
cmark_syntax_extension_set_commonmark_escape_func(ext, escape);
|
735
740
|
CMARK_NODE_TABLE = cmark_syntax_extension_add_node(0);
|
736
741
|
CMARK_NODE_TABLE_ROW = cmark_syntax_extension_add_node(0);
|
737
742
|
CMARK_NODE_TABLE_CELL = cmark_syntax_extension_add_node(0);
|
@@ -58,6 +58,9 @@ set(PROGRAM_SOURCES
|
|
58
58
|
)
|
59
59
|
|
60
60
|
include_directories(. ${CMAKE_CURRENT_BINARY_DIR})
|
61
|
+
include_directories(
|
62
|
+
${PROJECT_BINARY_DIR}/extensions
|
63
|
+
)
|
61
64
|
|
62
65
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmark_version.h.in
|
63
66
|
${CMAKE_CURRENT_BINARY_DIR}/cmark_version.h)
|
@@ -74,7 +77,7 @@ target_link_libraries(${PROGRAM} libcmarkextensions_static)
|
|
74
77
|
|
75
78
|
# Disable the PUBLIC declarations when compiling the executable:
|
76
79
|
set_target_properties(${PROGRAM} PROPERTIES
|
77
|
-
COMPILE_FLAGS -DCMARK_STATIC_DEFINE)
|
80
|
+
COMPILE_FLAGS "-DCMARK_STATIC_DEFINE -DCMARKEXTENSIONS_STATIC_DEFINE")
|
78
81
|
|
79
82
|
# Check integrity of node structure when compiled as debug:
|
80
83
|
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DCMARK_DEBUG_NODES -DDEBUG")
|
@@ -1317,20 +1317,20 @@ cmark_node *cmark_parser_finish(cmark_parser *parser) {
|
|
1317
1317
|
}
|
1318
1318
|
#endif
|
1319
1319
|
|
1320
|
-
res = parser->root;
|
1321
|
-
parser->root = NULL;
|
1322
|
-
|
1323
|
-
cmark_parser_reset(parser);
|
1324
|
-
|
1325
1320
|
for (extensions = parser->syntax_extensions; extensions; extensions = extensions->next) {
|
1326
1321
|
cmark_syntax_extension *ext = (cmark_syntax_extension *) extensions->data;
|
1327
1322
|
if (ext->postprocess_func) {
|
1328
|
-
cmark_node *processed = ext->postprocess_func(ext,
|
1323
|
+
cmark_node *processed = ext->postprocess_func(ext, parser, parser->root);
|
1329
1324
|
if (processed)
|
1330
|
-
|
1325
|
+
parser->root = processed;
|
1331
1326
|
}
|
1332
1327
|
}
|
1333
1328
|
|
1329
|
+
res = parser->root;
|
1330
|
+
parser->root = NULL;
|
1331
|
+
|
1332
|
+
cmark_parser_reset(parser);
|
1333
|
+
|
1334
1334
|
return res;
|
1335
1335
|
}
|
1336
1336
|
|
@@ -1390,3 +1390,7 @@ void cmark_parser_set_backslash_ispunct_func(cmark_parser *parser,
|
|
1390
1390
|
cmark_ispunct_func func) {
|
1391
1391
|
parser->backslash_ispunct = func;
|
1392
1392
|
}
|
1393
|
+
|
1394
|
+
cmark_llist *cmark_parser_get_syntax_extensions(cmark_parser *parser) {
|
1395
|
+
return parser->syntax_extensions;
|
1396
|
+
}
|
@@ -234,6 +234,10 @@ typedef void (*cmark_common_render_func) (cmark_syntax_extension *extension,
|
|
234
234
|
cmark_event_type ev_type,
|
235
235
|
int options);
|
236
236
|
|
237
|
+
typedef int (*cmark_commonmark_escape_func) (cmark_syntax_extension *extension,
|
238
|
+
cmark_node *node,
|
239
|
+
int c);
|
240
|
+
|
237
241
|
typedef void (*cmark_html_render_func) (cmark_syntax_extension *extension,
|
238
242
|
cmark_html_renderer *renderer,
|
239
243
|
cmark_node *node,
|
@@ -245,6 +249,7 @@ typedef int (*cmark_html_filter_func) (cmark_syntax_extension *extension,
|
|
245
249
|
size_t tag_len);
|
246
250
|
|
247
251
|
typedef cmark_node *(*cmark_postprocess_func) (cmark_syntax_extension *extension,
|
252
|
+
cmark_parser *parser,
|
248
253
|
cmark_node *root);
|
249
254
|
|
250
255
|
typedef int (*cmark_ispunct_func) (char c);
|
@@ -344,6 +349,12 @@ CMARK_EXPORT
|
|
344
349
|
void cmark_syntax_extension_set_html_filter_func(cmark_syntax_extension *extension,
|
345
350
|
cmark_html_filter_func func);
|
346
351
|
|
352
|
+
/** See the documentation for 'cmark_syntax_extension'
|
353
|
+
*/
|
354
|
+
CMARK_EXPORT
|
355
|
+
void cmark_syntax_extension_set_commonmark_escape_func(cmark_syntax_extension *extension,
|
356
|
+
cmark_commonmark_escape_func func);
|
357
|
+
|
347
358
|
/** See the documentation for 'cmark_syntax_extension'
|
348
359
|
*/
|
349
360
|
CMARK_EXPORT
|
@@ -672,6 +683,9 @@ int cmark_inline_parser_scan_delimiters(cmark_inline_parser *parser,
|
|
672
683
|
CMARK_EXPORT
|
673
684
|
void cmark_manage_extensions_special_characters(cmark_parser *parser, bool add);
|
674
685
|
|
686
|
+
CMARK_EXPORT
|
687
|
+
cmark_llist *cmark_parser_get_syntax_extensions(cmark_parser *parser);
|
688
|
+
|
675
689
|
#ifdef __cplusplus
|
676
690
|
}
|
677
691
|
#endif
|
@@ -12,8 +12,8 @@
|
|
12
12
|
#include "render.h"
|
13
13
|
#include "syntax_extension.h"
|
14
14
|
|
15
|
-
#define OUT(s, wrap, escaping) renderer->out(renderer, s, wrap, escaping)
|
16
|
-
#define LIT(s) renderer->out(renderer, s, false, LITERAL)
|
15
|
+
#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)
|
16
|
+
#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)
|
17
17
|
#define CR() renderer->cr(renderer)
|
18
18
|
#define BLANKLINE() renderer->blankline(renderer)
|
19
19
|
#define ENCODED_SIZE 20
|
@@ -21,7 +21,8 @@
|
|
21
21
|
|
22
22
|
// Functions to convert cmark_nodes to commonmark strings.
|
23
23
|
|
24
|
-
static CMARK_INLINE void outc(cmark_renderer *renderer,
|
24
|
+
static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node,
|
25
|
+
cmark_escaping escape,
|
25
26
|
int32_t c, unsigned char nextc) {
|
26
27
|
bool needs_escaping = false;
|
27
28
|
bool follows_digit =
|
@@ -32,8 +33,9 @@ static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
|
|
32
33
|
needs_escaping =
|
33
34
|
c < 0x80 && escape != LITERAL &&
|
34
35
|
((escape == NORMAL &&
|
35
|
-
(
|
36
|
-
c == '
|
36
|
+
((node->parent && node->parent->extension && node->parent->extension->commonmark_escape_func && node->parent->extension->commonmark_escape_func(node->extension, node->parent, c)) ||
|
37
|
+
c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
|
38
|
+
c == '>' || c == '\\' || c == '`' || c == '!' ||
|
37
39
|
(c == '&' && cmark_isalpha(nextc)) || (c == '!' && nextc == '[') ||
|
38
40
|
(renderer->begin_content && (c == '-' || c == '+' || c == '=') &&
|
39
41
|
// begin_content doesn't get set to false til we've passed digits
|
@@ -626,12 +626,7 @@ static delimiter *S_insert_emph(subject *subj, delimiter *opener,
|
|
626
626
|
cmark_node *tmp, *tmpnext, *emph;
|
627
627
|
|
628
628
|
// calculate the actual number of characters used from this closer
|
629
|
-
|
630
|
-
use_delims = closer_num_chars <= opener_num_chars ? closer_num_chars
|
631
|
-
: opener_num_chars;
|
632
|
-
} else { // closer and opener both have >= 3 characters
|
633
|
-
use_delims = closer_num_chars % 2 == 0 ? 2 : 1;
|
634
|
-
}
|
629
|
+
use_delims = (closer_num_chars >= 2 && opener_num_chars >=2) ? 2 : 1;
|
635
630
|
|
636
631
|
// remove used characters from associated inlines.
|
637
632
|
opener_num_chars -= use_delims;
|
@@ -12,13 +12,14 @@
|
|
12
12
|
#include "render.h"
|
13
13
|
#include "syntax_extension.h"
|
14
14
|
|
15
|
-
#define OUT(s, wrap, escaping) renderer->out(renderer, s, wrap, escaping)
|
16
|
-
#define LIT(s) renderer->out(renderer, s, false, LITERAL)
|
15
|
+
#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)
|
16
|
+
#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)
|
17
17
|
#define CR() renderer->cr(renderer)
|
18
18
|
#define BLANKLINE() renderer->blankline(renderer)
|
19
19
|
#define LIST_NUMBER_STRING_SIZE 20
|
20
20
|
|
21
|
-
static CMARK_INLINE void outc(cmark_renderer *renderer,
|
21
|
+
static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node,
|
22
|
+
cmark_escaping escape,
|
22
23
|
int32_t c, unsigned char nextc) {
|
23
24
|
if (escape == LITERAL) {
|
24
25
|
cmark_render_code_point(renderer, c);
|
@@ -11,14 +11,15 @@
|
|
11
11
|
#include "render.h"
|
12
12
|
#include "syntax_extension.h"
|
13
13
|
|
14
|
-
#define OUT(s, wrap, escaping) renderer->out(renderer, s, wrap, escaping)
|
15
|
-
#define LIT(s) renderer->out(renderer, s, false, LITERAL)
|
14
|
+
#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)
|
15
|
+
#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)
|
16
16
|
#define CR() renderer->cr(renderer)
|
17
17
|
#define BLANKLINE() renderer->blankline(renderer)
|
18
18
|
#define LIST_NUMBER_SIZE 20
|
19
19
|
|
20
20
|
// Functions to convert cmark_nodes to groff man strings.
|
21
|
-
static void S_outc(cmark_renderer *renderer,
|
21
|
+
static void S_outc(cmark_renderer *renderer, cmark_node *node,
|
22
|
+
cmark_escaping escape, int32_t c,
|
22
23
|
unsigned char nextc) {
|
23
24
|
(void)(nextc);
|
24
25
|
|
@@ -18,7 +18,8 @@ static CMARK_INLINE void S_blankline(cmark_renderer *renderer) {
|
|
18
18
|
}
|
19
19
|
}
|
20
20
|
|
21
|
-
static void S_out(cmark_renderer *renderer,
|
21
|
+
static void S_out(cmark_renderer *renderer, cmark_node *node,
|
22
|
+
const char *source, bool wrap,
|
22
23
|
cmark_escaping escape) {
|
23
24
|
int length = (int)strlen(source);
|
24
25
|
unsigned char nextc;
|
@@ -97,7 +98,7 @@ static void S_out(cmark_renderer *renderer, const char *source, bool wrap,
|
|
97
98
|
renderer->begin_content =
|
98
99
|
renderer->begin_content && cmark_isdigit((char)c) == 1;
|
99
100
|
} else {
|
100
|
-
(renderer->outc)(renderer, escape, c, nextc);
|
101
|
+
(renderer->outc)(renderer, node, escape, c, nextc);
|
101
102
|
renderer->begin_line = false;
|
102
103
|
renderer->begin_content =
|
103
104
|
renderer->begin_content && cmark_isdigit((char)c) == 1;
|
@@ -143,7 +144,8 @@ void cmark_render_code_point(cmark_renderer *renderer, uint32_t c) {
|
|
143
144
|
}
|
144
145
|
|
145
146
|
char *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,
|
146
|
-
void (*outc)(cmark_renderer *,
|
147
|
+
void (*outc)(cmark_renderer *, cmark_node *,
|
148
|
+
cmark_escaping, int32_t,
|
147
149
|
unsigned char),
|
148
150
|
int (*render_node)(cmark_renderer *renderer,
|
149
151
|
cmark_node *node,
|
@@ -24,10 +24,10 @@ struct cmark_renderer {
|
|
24
24
|
bool begin_content;
|
25
25
|
bool no_linebreaks;
|
26
26
|
bool in_tight_list_item;
|
27
|
-
void (*outc)(struct cmark_renderer *, cmark_escaping, int32_t, unsigned char);
|
27
|
+
void (*outc)(struct cmark_renderer *, cmark_node *, cmark_escaping, int32_t, unsigned char);
|
28
28
|
void (*cr)(struct cmark_renderer *);
|
29
29
|
void (*blankline)(struct cmark_renderer *);
|
30
|
-
void (*out)(struct cmark_renderer *, const char *, bool, cmark_escaping);
|
30
|
+
void (*out)(struct cmark_renderer *, cmark_node *, const char *, bool, cmark_escaping);
|
31
31
|
};
|
32
32
|
|
33
33
|
typedef struct cmark_renderer cmark_renderer;
|
@@ -46,7 +46,8 @@ void cmark_render_ascii(cmark_renderer *renderer, const char *s);
|
|
46
46
|
void cmark_render_code_point(cmark_renderer *renderer, uint32_t c);
|
47
47
|
|
48
48
|
char *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,
|
49
|
-
void (*outc)(cmark_renderer *,
|
49
|
+
void (*outc)(cmark_renderer *, cmark_node *,
|
50
|
+
cmark_escaping, int32_t,
|
50
51
|
unsigned char),
|
51
52
|
int (*render_node)(cmark_renderer *renderer,
|
52
53
|
cmark_node *node,
|
@@ -117,3 +117,8 @@ void cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extensi
|
|
117
117
|
cmark_opaque_free_func func) {
|
118
118
|
extension->opaque_free_func = func;
|
119
119
|
}
|
120
|
+
|
121
|
+
void cmark_syntax_extension_set_commonmark_escape_func(cmark_syntax_extension *extension,
|
122
|
+
cmark_commonmark_escape_func func) {
|
123
|
+
extension->commonmark_escape_func = func;
|
124
|
+
}
|
@@ -63,14 +63,15 @@ IF (PYTHONINTERP_FOUND)
|
|
63
63
|
)
|
64
64
|
|
65
65
|
add_test(extensions_executable
|
66
|
-
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" "--no-normalize" "--spec" "${CMAKE_CURRENT_SOURCE_DIR}/extensions.txt" "--program" "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark
|
66
|
+
${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/spec_tests.py" "--no-normalize" "--spec" "${CMAKE_CURRENT_SOURCE_DIR}/extensions.txt" "--program" "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark" "--extensions" "table strikethrough autolink tagfilter"
|
67
67
|
)
|
68
68
|
|
69
69
|
add_test(roundtrip_extensions_executable
|
70
70
|
${PYTHON_EXECUTABLE}
|
71
71
|
"${CMAKE_CURRENT_SOURCE_DIR}/roundtrip_tests.py"
|
72
72
|
"--spec" "${CMAKE_CURRENT_SOURCE_DIR}/extensions.txt"
|
73
|
-
"--program" "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark
|
73
|
+
"--program" "${CMAKE_CURRENT_BINARY_DIR}/../src/cmark"
|
74
|
+
"--extensions" "table strikethrough autolink tagfilter"
|
74
75
|
)
|
75
76
|
|
76
77
|
add_test(regressiontest_executable
|
@@ -11,50 +11,96 @@ def pipe_through_prog(prog, text):
|
|
11
11
|
[result, err] = p1.communicate(input=text.encode('utf-8'))
|
12
12
|
return [p1.returncode, result.decode('utf-8'), err]
|
13
13
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def parse(lib, extlib, text, extensions):
|
15
|
+
register_plugin = lib.cmark_register_plugin
|
16
|
+
register_plugin.argtypes = [c_void_p]
|
17
|
+
|
18
|
+
core_extensions_registration = extlib.core_extensions_registration
|
19
|
+
|
20
|
+
find_syntax_extension = lib.cmark_find_syntax_extension
|
21
|
+
find_syntax_extension.restype = c_void_p
|
22
|
+
find_syntax_extension.argtypes = [c_char_p]
|
23
|
+
|
24
|
+
parser_attach_syntax_extension = lib.cmark_parser_attach_syntax_extension
|
25
|
+
parser_attach_syntax_extension.argtypes = [c_void_p, c_void_p]
|
26
|
+
|
27
|
+
parser_new = lib.cmark_parser_new
|
28
|
+
parser_new.restype = c_void_p
|
29
|
+
parser_new.argtypes = [c_int]
|
30
|
+
|
31
|
+
parser_feed = lib.cmark_parser_feed
|
32
|
+
parser_feed.argtypes = [c_void_p, c_char_p, c_int]
|
33
|
+
|
34
|
+
parser_finish = lib.cmark_parser_finish
|
35
|
+
parser_finish.restype = c_void_p
|
36
|
+
parser_finish.argtypes = [c_void_p]
|
37
|
+
|
38
|
+
register_plugin(core_extensions_registration)
|
39
|
+
|
40
|
+
parser = parser_new(0)
|
41
|
+
for e in set(extensions):
|
42
|
+
ext = find_syntax_extension(bytes(e, 'utf-8'))
|
43
|
+
if not ext:
|
44
|
+
raise Exception("Extension not found: '{}'".format(e))
|
45
|
+
parser_attach_syntax_extension(parser, ext)
|
46
|
+
|
18
47
|
textbytes = text.encode('utf-8')
|
19
48
|
textlen = len(textbytes)
|
20
|
-
|
49
|
+
parser_feed(parser, textbytes, textlen)
|
50
|
+
|
51
|
+
return [parser_finish(parser), parser]
|
52
|
+
|
53
|
+
def to_html(lib, extlib, text, extensions):
|
54
|
+
document, parser = parse(lib, extlib, text, extensions)
|
55
|
+
parser_get_syntax_extensions = lib.cmark_parser_get_syntax_extensions
|
56
|
+
parser_get_syntax_extensions.restype = c_void_p
|
57
|
+
parser_get_syntax_extensions.argtypes = [c_void_p]
|
58
|
+
syntax_extensions = parser_get_syntax_extensions(parser)
|
59
|
+
|
60
|
+
render_html = lib.cmark_render_html
|
61
|
+
render_html.restype = c_char_p
|
62
|
+
render_html.argtypes = [c_void_p, c_int, c_void_p]
|
63
|
+
result = render_html(document, 0, syntax_extensions).decode('utf-8')
|
21
64
|
return [0, result, '']
|
22
65
|
|
23
|
-
def to_commonmark(lib, text):
|
24
|
-
|
25
|
-
|
26
|
-
parse_document = lib.cmark_parse_document
|
27
|
-
parse_document.restype = c_void_p
|
28
|
-
parse_document.argtypes = [c_char_p, c_size_t, c_int]
|
66
|
+
def to_commonmark(lib, extlib, text, extensions):
|
67
|
+
document, _ = parse(lib, extlib, text, extensions)
|
68
|
+
|
29
69
|
render_commonmark = lib.cmark_render_commonmark
|
30
70
|
render_commonmark.restype = c_char_p
|
31
71
|
render_commonmark.argtypes = [c_void_p, c_int, c_int]
|
32
|
-
|
33
|
-
result = render_commonmark(node, 0, 0).decode('utf-8')
|
72
|
+
result = render_commonmark(document, 0, 0).decode('utf-8')
|
34
73
|
return [0, result, '']
|
35
74
|
|
36
75
|
class CMark:
|
37
|
-
def __init__(self, prog=None, library_dir=None):
|
76
|
+
def __init__(self, prog=None, library_dir=None, extensions=None):
|
38
77
|
self.prog = prog
|
78
|
+
self.extensions = []
|
79
|
+
if extensions:
|
80
|
+
self.extensions = extensions.split()
|
81
|
+
|
39
82
|
if prog:
|
40
|
-
|
41
|
-
self.
|
83
|
+
extsfun = lambda exts: ''.join([' -e ' + e for e in set(exts)])
|
84
|
+
self.to_html = lambda x, exts=[]: pipe_through_prog(prog + extsfun(exts + self.extensions), x)
|
85
|
+
self.to_commonmark = lambda x, exts=[]: pipe_through_prog(prog + ' -t commonmark' + extsfun(exts + self.extensions), x)
|
42
86
|
else:
|
43
87
|
sysname = platform.system()
|
44
88
|
if sysname == 'Darwin':
|
45
|
-
libnames = [ "
|
89
|
+
libnames = [ ["lib", ".dylib" ] ]
|
46
90
|
elif sysname == 'Windows':
|
47
|
-
libnames = [ "
|
91
|
+
libnames = [ ["", ".dll"], ["lib", ".dll"] ]
|
48
92
|
else:
|
49
|
-
libnames = [ "
|
93
|
+
libnames = [ ["lib", ".so"] ]
|
50
94
|
if not library_dir:
|
51
95
|
library_dir = os.path.join("build", "src")
|
52
|
-
for
|
53
|
-
candidate = os.path.join(library_dir,
|
96
|
+
for prefix, suffix in libnames:
|
97
|
+
candidate = os.path.join(library_dir, prefix + "cmark" + suffix)
|
54
98
|
if os.path.isfile(candidate):
|
55
99
|
libpath = candidate
|
56
100
|
break
|
57
101
|
cmark = CDLL(libpath)
|
58
|
-
|
59
|
-
|
102
|
+
extlib = CDLL(os.path.join(
|
103
|
+
library_dir, "..", "extensions", prefix + "cmarkextensions" + suffix))
|
104
|
+
self.to_html = lambda x, exts=[]: to_html(cmark, extlib, x, exts + self.extensions)
|
105
|
+
self.to_commonmark = lambda x, exts=[]: to_commonmark(cmark, extlib, x, exts + self.extensions)
|
60
106
|
|