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.

Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/commonmarker.gemspec +1 -1
  3. data/ext/commonmarker/cmark/Makefile +2 -2
  4. data/ext/commonmarker/cmark/extensions/CMakeLists.txt +38 -12
  5. data/ext/commonmarker/cmark/extensions/autolink.c +151 -102
  6. data/ext/commonmarker/cmark/extensions/core-extensions.h +2 -0
  7. data/ext/commonmarker/cmark/extensions/strikethrough.c +15 -10
  8. data/ext/commonmarker/cmark/extensions/table.c +31 -26
  9. data/ext/commonmarker/cmark/src/CMakeLists.txt +4 -1
  10. data/ext/commonmarker/cmark/src/blocks.c +11 -7
  11. data/ext/commonmarker/cmark/src/cmark_extension_api.h +14 -0
  12. data/ext/commonmarker/cmark/src/commonmark.c +7 -5
  13. data/ext/commonmarker/cmark/src/inlines.c +1 -6
  14. data/ext/commonmarker/cmark/src/latex.c +4 -3
  15. data/ext/commonmarker/cmark/src/man.c +4 -3
  16. data/ext/commonmarker/cmark/src/render.c +5 -3
  17. data/ext/commonmarker/cmark/src/render.h +4 -3
  18. data/ext/commonmarker/cmark/src/syntax_extension.c +5 -0
  19. data/ext/commonmarker/cmark/src/syntax_extension.h +1 -0
  20. data/ext/commonmarker/cmark/test/CMakeLists.txt +3 -2
  21. data/ext/commonmarker/cmark/test/cmark.py +69 -23
  22. data/ext/commonmarker/cmark/test/extensions.txt +6 -6
  23. data/ext/commonmarker/cmark/test/roundtrip_tests.py +6 -4
  24. data/ext/commonmarker/cmark/test/spec.txt +420 -4
  25. data/ext/commonmarker/cmark/test/spec_tests.py +12 -6
  26. data/ext/commonmarker/extconf.rb +1 -1
  27. data/lib/commonmarker/renderer/html_renderer.rb +4 -0
  28. data/lib/commonmarker/version.rb +1 -1
  29. data/test/test_helper.rb +5 -2
  30. data/test/test_spec.rb +9 -7
  31. 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, res);
1323
+ cmark_node *processed = ext->postprocess_func(ext, parser, parser->root);
1329
1324
  if (processed)
1330
- res = processed;
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, cmark_escaping escape,
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
- (c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
36
- c == '>' || c == '\\' || c == '`' || c == '!' || 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
- if (closer_num_chars < 3 || opener_num_chars < 3) {
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, cmark_escaping escape,
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, cmark_escaping escape, int32_t c,
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, const char *source, bool wrap,
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 *, cmark_escaping, int32_t,
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 *, cmark_escaping, int32_t,
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
+ }
@@ -23,6 +23,7 @@ struct cmark_syntax_extension {
23
23
  cmark_html_filter_func html_filter_func;
24
24
  cmark_postprocess_func postprocess_func;
25
25
  cmark_opaque_free_func opaque_free_func;
26
+ cmark_commonmark_escape_func commonmark_escape_func;
26
27
  };
27
28
 
28
29
  #endif
@@ -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 -e table -e strikethrough -e autolink -e tagfilter"
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 -e table -e strikethrough -e autolink -e tagfilter"
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 to_html(lib, text):
15
- markdown = lib.cmark_markdown_to_html
16
- markdown.restype = c_char_p
17
- markdown.argtypes = [c_char_p, c_size_t, c_int]
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
- result = markdown(textbytes, textlen, 0).decode('utf-8')
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
- textbytes = text.encode('utf-8')
25
- textlen = len(textbytes)
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
- node = parse_document(textbytes, textlen, 0)
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
- self.to_html = lambda x: pipe_through_prog(prog, x)
41
- self.to_commonmark = lambda x: pipe_through_prog(prog + ' -t commonmark', x)
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 = [ "libcmark.dylib" ]
89
+ libnames = [ ["lib", ".dylib" ] ]
46
90
  elif sysname == 'Windows':
47
- libnames = [ "cmark.dll", "libcmark.dll" ]
91
+ libnames = [ ["", ".dll"], ["lib", ".dll"] ]
48
92
  else:
49
- libnames = [ "libcmark.so" ]
93
+ libnames = [ ["lib", ".so"] ]
50
94
  if not library_dir:
51
95
  library_dir = os.path.join("build", "src")
52
- for libname in libnames:
53
- candidate = os.path.join(library_dir, libname)
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
- self.to_html = lambda x: to_html(cmark, x)
59
- self.to_commonmark = lambda x: to_commonmark(cmark, x)
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