commonmarker 0.10.0 → 0.11.0

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 (161) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -0
  3. data/bin/commonmarker +19 -3
  4. data/ext/commonmarker/cmark/CMakeLists.txt +1 -0
  5. data/ext/commonmarker/cmark/COPYING +2 -24
  6. data/ext/commonmarker/cmark/Makefile +25 -5
  7. data/ext/commonmarker/cmark/README.md +1 -1
  8. data/ext/commonmarker/cmark/api_test/CMakeLists.txt +1 -1
  9. data/ext/commonmarker/cmark/api_test/main.c +25 -27
  10. data/ext/commonmarker/cmark/build/CMakeCache.txt +12 -9
  11. data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CMakeCCompiler.cmake +0 -0
  12. data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CMakeCXXCompiler.cmake +0 -0
  13. data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CMakeDetermineCompilerABI_C.bin +0 -0
  14. data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CMakeDetermineCompilerABI_CXX.bin +0 -0
  15. data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CMakeSystem.cmake +4 -4
  16. data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CompilerIdC/CMakeCCompilerId.c +0 -0
  17. data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CompilerIdC/a.out +0 -0
  18. data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CompilerIdCXX/CMakeCXXCompilerId.cpp +0 -0
  19. data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CompilerIdCXX/a.out +0 -0
  20. data/ext/commonmarker/cmark/build/CMakeFiles/CMakeError.log +6 -6
  21. data/ext/commonmarker/cmark/build/CMakeFiles/CMakeOutput.log +148 -148
  22. data/ext/commonmarker/cmark/build/CMakeFiles/Makefile.cmake +41 -109
  23. data/ext/commonmarker/cmark/build/CMakeFiles/Makefile2 +66 -10
  24. data/ext/commonmarker/cmark/build/CMakeFiles/TargetDirectories.txt +8 -0
  25. data/ext/commonmarker/cmark/build/CMakeFiles/progress.marks +1 -1
  26. data/ext/commonmarker/cmark/build/CTestTestfile.cmake +1 -0
  27. data/ext/commonmarker/cmark/build/Makefile +23 -9
  28. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/build.make +2 -2
  29. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/progress.marks +1 -1
  30. data/ext/commonmarker/cmark/build/api_test/Makefile +9 -9
  31. data/ext/commonmarker/cmark/build/cmake_install.cmake +1 -0
  32. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
  33. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/C.includecache +190 -0
  34. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/DependInfo.cmake +29 -0
  35. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/autolink.c.o +0 -0
  36. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/build.make +249 -0
  37. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/cmake_clean.cmake +15 -0
  38. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/cmake_clean_target.cmake +3 -0
  39. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/core-extensions.c.o +0 -0
  40. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/depend.internal +92 -0
  41. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/depend.make +92 -0
  42. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/ext_scanners.c.o +0 -0
  43. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/flags.make +10 -0
  44. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/link.txt +2 -0
  45. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/progress.make +8 -0
  46. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/strikethrough.c.o +0 -0
  47. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/table.c.o +0 -0
  48. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/whitelist.c.o +0 -0
  49. data/ext/commonmarker/cmark/build/extensions/CMakeFiles/progress.marks +1 -0
  50. data/ext/commonmarker/cmark/build/extensions/Makefile +390 -0
  51. data/ext/commonmarker/cmark/build/extensions/cmake_install.cmake +29 -0
  52. data/ext/commonmarker/cmark/build/extensions/libcmarkextensions.a +0 -0
  53. data/ext/commonmarker/cmark/build/man/Makefile +9 -9
  54. data/ext/commonmarker/cmark/build/src/CMakeFiles/Export/lib/cmake/cmark.cmake +1 -1
  55. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/DependInfo.cmake +7 -19
  56. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/build.make +6 -517
  57. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/cmake_clean.cmake +0 -19
  58. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/flags.make +1 -1
  59. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/link.txt +1 -1
  60. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/progress.make +0 -19
  61. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/DependInfo.cmake +9 -0
  62. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/build.make +112 -4
  63. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/cmake_clean.cmake +4 -0
  64. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/flags.make +1 -1
  65. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/link.txt +1 -1
  66. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/progress.make +24 -20
  67. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/C.includecache +144 -10
  68. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/DependInfo.cmake +9 -0
  69. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/blocks.c.o +0 -0
  70. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/build.make +112 -4
  71. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmake_clean.cmake +4 -0
  72. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmark.c.o +0 -0
  73. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/commonmark.c.o +0 -0
  74. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/depend.internal +74 -0
  75. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/depend.make +74 -0
  76. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/flags.make +1 -1
  77. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/html.c.o +0 -0
  78. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/inlines.c.o +0 -0
  79. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/iterator.c.o +0 -0
  80. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/latex.c.o +0 -0
  81. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/link.txt +1 -1
  82. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/linked_list.c.o +0 -0
  83. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/man.c.o +0 -0
  84. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/node.c.o +0 -0
  85. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/plugin.c.o +0 -0
  86. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/progress.make +24 -20
  87. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/registry.c.o +0 -0
  88. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/scanners.c.o +0 -0
  89. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/syntax_extension.c.o +0 -0
  90. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/xml.c.o +0 -0
  91. data/ext/commonmarker/cmark/build/src/CMakeFiles/progress.marks +1 -1
  92. data/ext/commonmarker/cmark/build/src/Makefile +141 -66
  93. data/ext/commonmarker/cmark/build/src/cmake_install.cmake +4 -0
  94. data/ext/commonmarker/cmark/build/src/libcmark.a +0 -0
  95. data/ext/commonmarker/cmark/build/testdir/CTestTestfile.cmake +3 -1
  96. data/ext/commonmarker/cmark/build/testdir/Makefile +9 -9
  97. data/ext/commonmarker/cmark/extensions/CMakeLists.txt +82 -0
  98. data/ext/commonmarker/cmark/extensions/autolink.c +338 -0
  99. data/ext/commonmarker/cmark/extensions/autolink.h +8 -0
  100. data/ext/commonmarker/cmark/extensions/core-extensions.c +16 -0
  101. data/ext/commonmarker/cmark/extensions/core-extensions.h +16 -0
  102. data/ext/commonmarker/cmark/extensions/ext_scanners.c +585 -0
  103. data/ext/commonmarker/cmark/extensions/ext_scanners.h +20 -0
  104. data/ext/commonmarker/cmark/extensions/ext_scanners.re +65 -0
  105. data/ext/commonmarker/cmark/extensions/strikethrough.c +142 -0
  106. data/ext/commonmarker/cmark/extensions/strikethrough.h +9 -0
  107. data/ext/commonmarker/cmark/extensions/table.c +493 -0
  108. data/ext/commonmarker/cmark/extensions/table.h +8 -0
  109. data/ext/commonmarker/cmark/extensions/whitelist.c +59 -0
  110. data/ext/commonmarker/cmark/extensions/whitelist.h +8 -0
  111. data/ext/commonmarker/cmark/man/man3/cmark.3 +98 -34
  112. data/ext/commonmarker/cmark/src/CMakeLists.txt +16 -1
  113. data/ext/commonmarker/cmark/src/blocks.c +219 -40
  114. data/ext/commonmarker/cmark/src/buffer.h +36 -0
  115. data/ext/commonmarker/cmark/src/cmark.c +5 -1
  116. data/ext/commonmarker/cmark/src/cmark.h +91 -34
  117. data/ext/commonmarker/cmark/src/cmark_ctype.h +7 -0
  118. data/ext/commonmarker/cmark/src/cmark_extension_api.h +655 -0
  119. data/ext/commonmarker/cmark/src/commonmark.c +7 -2
  120. data/ext/commonmarker/cmark/src/houdini.h +12 -6
  121. data/ext/commonmarker/cmark/src/houdini_html_e.c +1 -1
  122. data/ext/commonmarker/cmark/src/html.c +102 -54
  123. data/ext/commonmarker/cmark/src/html.h +27 -0
  124. data/ext/commonmarker/cmark/src/inlines.c +261 -53
  125. data/ext/commonmarker/cmark/src/inlines.h +7 -2
  126. data/ext/commonmarker/cmark/src/iterator.c +12 -7
  127. data/ext/commonmarker/cmark/src/latex.c +5 -2
  128. data/ext/commonmarker/cmark/src/linked_list.c +37 -0
  129. data/ext/commonmarker/cmark/src/main.c +91 -27
  130. data/ext/commonmarker/cmark/src/man.c +18 -2
  131. data/ext/commonmarker/cmark/src/node.c +157 -58
  132. data/ext/commonmarker/cmark/src/node.h +23 -0
  133. data/ext/commonmarker/cmark/src/parser.h +19 -2
  134. data/ext/commonmarker/cmark/src/plugin.c +33 -0
  135. data/ext/commonmarker/cmark/src/plugin.h +34 -0
  136. data/ext/commonmarker/cmark/src/registry.c +60 -0
  137. data/ext/commonmarker/cmark/src/registry.h +24 -0
  138. data/ext/commonmarker/cmark/src/render.h +9 -0
  139. data/ext/commonmarker/cmark/src/scanners.c +265 -391
  140. data/ext/commonmarker/cmark/src/scanners.h +5 -0
  141. data/ext/commonmarker/cmark/src/scanners.re +2 -2
  142. data/ext/commonmarker/cmark/src/syntax_extension.c +110 -0
  143. data/ext/commonmarker/cmark/src/syntax_extension.h +27 -0
  144. data/ext/commonmarker/cmark/suppressions +28 -0
  145. data/ext/commonmarker/cmark/test/CMakeLists.txt +12 -1
  146. data/ext/commonmarker/cmark/test/extensions.txt +173 -0
  147. data/ext/commonmarker/cmark/test/regression.txt +24 -0
  148. data/ext/commonmarker/cmark/test/spec.txt +27 -26
  149. data/ext/commonmarker/cmark/toolchain-mingw32.cmake +1 -1
  150. data/ext/commonmarker/commonmarker.c +132 -15
  151. data/ext/commonmarker/commonmarker.h +4 -0
  152. data/ext/commonmarker/extconf.rb +12 -5
  153. data/lib/commonmarker.rb +8 -6
  154. data/lib/commonmarker/node.rb +13 -2
  155. data/lib/commonmarker/renderer.rb +1 -1
  156. data/lib/commonmarker/version.rb +1 -1
  157. data/test/test_commonmark.rb +34 -0
  158. data/test/test_encoding.rb +2 -1
  159. data/test/test_extensions.rb +50 -0
  160. data/test/test_helper.rb +2 -1
  161. metadata +65 -11
@@ -8,12 +8,17 @@ extern "C" {
8
8
  cmark_chunk cmark_clean_url(cmark_mem *mem, cmark_chunk *url);
9
9
  cmark_chunk cmark_clean_title(cmark_mem *mem, cmark_chunk *title);
10
10
 
11
- void cmark_parse_inlines(cmark_mem *mem, cmark_node *parent,
12
- cmark_reference_map *refmap, int options);
11
+ void cmark_parse_inlines(cmark_parser *parser,
12
+ cmark_node *parent,
13
+ cmark_reference_map *refmap,
14
+ int options);
13
15
 
14
16
  bufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_strbuf *input,
15
17
  cmark_reference_map *refmap);
16
18
 
19
+ void cmark_inlines_add_special_character(unsigned char c);
20
+ void cmark_inlines_remove_special_character(unsigned char c);
21
+
17
22
  #ifdef __cplusplus
18
23
  }
19
24
  #endif
@@ -6,12 +6,6 @@
6
6
  #include "cmark.h"
7
7
  #include "iterator.h"
8
8
 
9
- static const int S_leaf_mask =
10
- (1 << CMARK_NODE_HTML_BLOCK) | (1 << CMARK_NODE_THEMATIC_BREAK) |
11
- (1 << CMARK_NODE_CODE_BLOCK) | (1 << CMARK_NODE_TEXT) |
12
- (1 << CMARK_NODE_SOFTBREAK) | (1 << CMARK_NODE_LINEBREAK) |
13
- (1 << CMARK_NODE_CODE) | (1 << CMARK_NODE_HTML_INLINE);
14
-
15
9
  cmark_iter *cmark_iter_new(cmark_node *root) {
16
10
  if (root == NULL) {
17
11
  return NULL;
@@ -30,7 +24,18 @@ cmark_iter *cmark_iter_new(cmark_node *root) {
30
24
  void cmark_iter_free(cmark_iter *iter) { iter->mem->free(iter); }
31
25
 
32
26
  static bool S_is_leaf(cmark_node *node) {
33
- return ((1 << node->type) & S_leaf_mask) != 0;
27
+ switch (node->type) {
28
+ case CMARK_NODE_HTML_BLOCK:
29
+ case CMARK_NODE_THEMATIC_BREAK:
30
+ case CMARK_NODE_CODE_BLOCK:
31
+ case CMARK_NODE_TEXT:
32
+ case CMARK_NODE_SOFTBREAK:
33
+ case CMARK_NODE_LINEBREAK:
34
+ case CMARK_NODE_CODE:
35
+ case CMARK_NODE_HTML_INLINE:
36
+ return 1;
37
+ }
38
+ return 0;
34
39
  }
35
40
 
36
41
  cmark_event_type cmark_iter_next(cmark_iter *iter) {
@@ -10,6 +10,7 @@
10
10
  #include "utf8.h"
11
11
  #include "scanners.h"
12
12
  #include "render.h"
13
+ #include "syntax_extension.h"
13
14
 
14
15
  #define OUT(s, wrap, escaping) renderer->out(renderer, s, wrap, escaping)
15
16
  #define LIT(s) renderer->out(renderer, s, false, LITERAL)
@@ -223,8 +224,10 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
223
224
  "vi", "vii", "viii", "ix", "x"};
224
225
  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);
225
226
 
226
- // avoid warning about unused parameter:
227
- (void)(options);
227
+ if (node->extension && node->extension->latex_render_func) {
228
+ node->extension->latex_render_func(node->extension, renderer, node, ev_type, options);
229
+ return 1;
230
+ }
228
231
 
229
232
  switch (node->type) {
230
233
  case CMARK_NODE_DOCUMENT:
@@ -0,0 +1,37 @@
1
+ #include <stdlib.h>
2
+
3
+ #include "cmark.h"
4
+
5
+ cmark_llist *cmark_llist_append(cmark_llist *head, void *data) {
6
+ cmark_llist *tmp;
7
+ cmark_llist *new_node = (cmark_llist *) malloc(sizeof(cmark_llist));
8
+
9
+ new_node->data = data;
10
+ new_node->next = NULL;
11
+
12
+ if (!head)
13
+ return new_node;
14
+
15
+ for (tmp = head; tmp->next; tmp=tmp->next);
16
+
17
+ tmp->next = new_node;
18
+
19
+ return head;
20
+ }
21
+
22
+ void cmark_llist_free_full(cmark_llist *head, cmark_free_func free_func) {
23
+ cmark_llist *tmp, *prev;
24
+
25
+ for (tmp = head; tmp;) {
26
+ if (free_func)
27
+ free_func(tmp->data);
28
+
29
+ prev = tmp;
30
+ tmp = tmp->next;
31
+ free(prev);
32
+ }
33
+ }
34
+
35
+ void cmark_llist_free(cmark_llist *head) {
36
+ cmark_llist_free_full(head, NULL);
37
+ }
@@ -5,6 +5,12 @@
5
5
  #include "config.h"
6
6
  #include "memory.h"
7
7
  #include "cmark.h"
8
+ #include "cmark_extension_api.h"
9
+ #include "syntax_extension.h"
10
+ #include "parser.h"
11
+ #include "registry.h"
12
+
13
+ #include "../extensions/core-extensions.h"
8
14
 
9
15
  #if defined(_WIN32) && !defined(__CYGWIN__)
10
16
  #include <io.h>
@@ -23,26 +29,28 @@ typedef enum {
23
29
  void print_usage() {
24
30
  printf("Usage: cmark [FILE*]\n");
25
31
  printf("Options:\n");
26
- printf(" --to, -t FORMAT Specify output format (html, xml, man, "
32
+ printf(" --to, -t FORMAT Specify output format (html, xml, man, "
27
33
  "commonmark, latex)\n");
28
- printf(" --width WIDTH Specify wrap width (default 0 = nowrap)\n");
29
- printf(" --sourcepos Include source position attribute\n");
30
- printf(" --hardbreaks Treat newlines as hard line breaks\n");
34
+ printf(" --width WIDTH Specify wrap width (default 0 = nowrap)\n");
35
+ printf(" --sourcepos Include source position attribute\n");
36
+ printf(" --hardbreaks Treat newlines as hard line breaks\n");
31
37
  printf(" --nobreaks Render soft line breaks as spaces\n");
32
- printf(" --safe Suppress raw HTML and dangerous URLs\n");
33
- printf(" --smart Use smart punctuation\n");
34
- printf(" --normalize Consolidate adjacent text nodes\n");
35
- printf(" --help, -h Print usage information\n");
36
- printf(" --version Print version\n");
38
+ printf(" --safe Suppress raw HTML and dangerous URLs\n");
39
+ printf(" --smart Use smart punctuation\n");
40
+ printf(" --normalize Consolidate adjacent text nodes\n");
41
+ printf(" -e, --extension EXTENSION_NAME Specify an extension name to use\n");
42
+ printf(" --list-extensions List available extensions and quit\n");
43
+ printf(" --help, -h Print usage information\n");
44
+ printf(" --version Print version\n");
37
45
  }
38
46
 
39
- static void print_document(cmark_node *document, writer_format writer,
40
- int options, int width) {
47
+ static bool print_document(cmark_node *document, writer_format writer,
48
+ int options, int width, cmark_parser *parser) {
41
49
  char *result;
42
50
 
43
51
  switch (writer) {
44
52
  case FORMAT_HTML:
45
- result = cmark_render_html(document, options);
53
+ result = cmark_render_html(document, options, parser->syntax_extensions);
46
54
  break;
47
55
  case FORMAT_XML:
48
56
  result = cmark_render_xml(document, options);
@@ -58,23 +66,44 @@ static void print_document(cmark_node *document, writer_format writer,
58
66
  break;
59
67
  default:
60
68
  fprintf(stderr, "Unknown format %d\n", writer);
61
- exit(1);
69
+ return false;
62
70
  }
71
+
63
72
  printf("%s", result);
64
73
  free(result);
74
+
75
+ return true;
76
+ }
77
+
78
+ static void print_extensions(void) {
79
+ cmark_llist *syntax_extensions;
80
+ cmark_llist *tmp;
81
+
82
+ printf ("Available extensions:\n");
83
+
84
+ syntax_extensions = cmark_list_syntax_extensions();
85
+ for (tmp = syntax_extensions; tmp; tmp=tmp->next) {
86
+ cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;
87
+ printf("%s\n", ext->name);
88
+ }
89
+
90
+ cmark_llist_free(syntax_extensions);
65
91
  }
66
92
 
67
93
  int main(int argc, char *argv[]) {
68
94
  int i, numfps = 0;
69
95
  int *files;
70
96
  char buffer[4096];
71
- cmark_parser *parser;
97
+ cmark_parser *parser = NULL;
72
98
  size_t bytes;
73
- cmark_node *document;
99
+ cmark_node *document = NULL;
74
100
  int width = 0;
75
101
  char *unparsed;
76
102
  writer_format writer = FORMAT_HTML;
77
103
  int options = CMARK_OPT_DEFAULT;
104
+ int res = 1;
105
+
106
+ cmark_register_plugin(core_extensions_registration);
78
107
 
79
108
  #if defined(_WIN32) && !defined(__CYGWIN__)
80
109
  _setmode(_fileno(stdin), _O_BINARY);
@@ -87,7 +116,10 @@ int main(int argc, char *argv[]) {
87
116
  if (strcmp(argv[i], "--version") == 0) {
88
117
  printf("cmark %s", CMARK_VERSION_STRING);
89
118
  printf(" - CommonMark converter\n(C) 2014-2016 John MacFarlane\n");
90
- exit(0);
119
+ goto success;
120
+ } else if (strcmp(argv[i], "--list-extensions") == 0) {
121
+ print_extensions();
122
+ goto success;
91
123
  } else if (strcmp(argv[i], "--sourcepos") == 0) {
92
124
  options |= CMARK_OPT_SOURCEPOS;
93
125
  } else if (strcmp(argv[i], "--hardbreaks") == 0) {
@@ -105,7 +137,7 @@ int main(int argc, char *argv[]) {
105
137
  } else if ((strcmp(argv[i], "--help") == 0) ||
106
138
  (strcmp(argv[i], "-h") == 0)) {
107
139
  print_usage();
108
- exit(0);
140
+ goto success;
109
141
  } else if (strcmp(argv[i], "--width") == 0) {
110
142
  i += 1;
111
143
  if (i < argc) {
@@ -113,11 +145,11 @@ int main(int argc, char *argv[]) {
113
145
  if (unparsed && strlen(unparsed) > 0) {
114
146
  fprintf(stderr, "failed parsing width '%s' at '%s'\n", argv[i],
115
147
  unparsed);
116
- exit(1);
148
+ goto failure;
117
149
  }
118
150
  } else {
119
151
  fprintf(stderr, "--width requires an argument\n");
120
- exit(1);
152
+ goto failure;
121
153
  }
122
154
  } else if ((strcmp(argv[i], "-t") == 0) || (strcmp(argv[i], "--to") == 0)) {
123
155
  i += 1;
@@ -134,27 +166,48 @@ int main(int argc, char *argv[]) {
134
166
  writer = FORMAT_LATEX;
135
167
  } else {
136
168
  fprintf(stderr, "Unknown format %s\n", argv[i]);
137
- exit(1);
169
+ goto failure;
138
170
  }
139
171
  } else {
140
172
  fprintf(stderr, "No argument provided for %s\n", argv[i - 1]);
141
- exit(1);
173
+ goto failure;
142
174
  }
175
+ } else if ((strcmp(argv[i], "-e") == 0) || (strcmp(argv[i], "--extension") == 0)) {
176
+ i += 1; // Simpler to handle extensions in a second pass, as we can directly register
177
+ // them with the parser.
143
178
  } else if (*argv[i] == '-') {
144
179
  print_usage();
145
- exit(1);
180
+ goto failure;
146
181
  } else { // treat as file argument
147
182
  files[numfps++] = i;
148
183
  }
149
184
  }
150
185
 
151
186
  parser = cmark_parser_new(options);
187
+
188
+ for (i = 1; i < argc; i++) {
189
+ if ((strcmp(argv[i], "-e") == 0) || (strcmp(argv[i], "--extension") == 0)) {
190
+ i += 1;
191
+ if (i < argc) {
192
+ cmark_syntax_extension *syntax_extension = cmark_find_syntax_extension(argv[i]);
193
+ if (!syntax_extension) {
194
+ fprintf(stderr, "Unknown extension %s\n", argv[i]);
195
+ goto failure;
196
+ }
197
+ cmark_parser_attach_syntax_extension(parser, syntax_extension);
198
+ } else {
199
+ fprintf(stderr, "No argument provided for %s\n", argv[i - 1]);
200
+ goto failure;
201
+ }
202
+ }
203
+ }
204
+
152
205
  for (i = 0; i < numfps; i++) {
153
206
  FILE *fp = fopen(argv[files[i]], "rb");
154
207
  if (fp == NULL) {
155
208
  fprintf(stderr, "Error opening file %s: %s\n", argv[files[i]],
156
209
  strerror(errno));
157
- exit(1);
210
+ goto failure;
158
211
  }
159
212
 
160
213
  while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
@@ -178,13 +231,24 @@ int main(int argc, char *argv[]) {
178
231
  }
179
232
 
180
233
  document = cmark_parser_finish(parser);
181
- cmark_parser_free(parser);
182
234
 
183
- print_document(document, writer, options, width);
235
+ if (!print_document(document, writer, options, width, parser))
236
+ goto failure;
237
+
238
+
239
+ success:
240
+ res = 0;
241
+
242
+ failure:
243
+ if (parser)
244
+ cmark_parser_free(parser);
245
+
246
+ if (document)
247
+ cmark_node_free(document);
184
248
 
185
- cmark_node_free(document);
249
+ cmark_release_plugins();
186
250
 
187
251
  free(files);
188
252
 
189
- return 0;
253
+ return res;
190
254
  }
@@ -9,6 +9,7 @@
9
9
  #include "buffer.h"
10
10
  #include "utf8.h"
11
11
  #include "render.h"
12
+ #include "syntax_extension.h"
12
13
 
13
14
  #define OUT(s, wrap, escaping) renderer->out(renderer, s, wrap, escaping)
14
15
  #define LIT(s) renderer->out(renderer, s, false, LITERAL)
@@ -77,11 +78,26 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
77
78
  bool entering = (ev_type == CMARK_EVENT_ENTER);
78
79
  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);
79
80
 
80
- // avoid unused parameter error:
81
- (void)(options);
81
+ if (node->extension && node->extension->man_render_func) {
82
+ node->extension->man_render_func(node->extension, renderer, node, ev_type, options);
83
+ return 1;
84
+ }
82
85
 
83
86
  switch (node->type) {
84
87
  case CMARK_NODE_DOCUMENT:
88
+ if (entering) {
89
+ /* Define a strikethrough macro */
90
+ /* Commenting out because this makes tests fail
91
+ LIT(".de ST");
92
+ CR();
93
+ LIT(".nr ww \\w'\\\\$1'");
94
+ CR();
95
+ LIT("\\Z@\\v'-.25m'\\l'\\\\n[ww]u'@\\\\$1");
96
+ CR();
97
+ LIT("..");
98
+ CR();
99
+ */
100
+ }
85
101
  break;
86
102
 
87
103
  case CMARK_NODE_BLOCK_QUOTE:
@@ -3,55 +3,29 @@
3
3
 
4
4
  #include "config.h"
5
5
  #include "node.h"
6
+ #include "syntax_extension.h"
6
7
 
7
8
  static void S_node_unlink(cmark_node *node);
8
9
 
9
10
  #define NODE_MEM(node) cmark_node_mem(node)
10
11
 
11
- static CMARK_INLINE bool S_is_block(cmark_node *node) {
12
- if (node == NULL) {
12
+ bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type) {
13
+ if (child_type == CMARK_NODE_DOCUMENT) {
13
14
  return false;
14
15
  }
15
- return node->type >= CMARK_NODE_FIRST_BLOCK &&
16
- node->type <= CMARK_NODE_LAST_BLOCK;
17
- }
18
16
 
19
- static CMARK_INLINE bool S_is_inline(cmark_node *node) {
20
- if (node == NULL) {
21
- return false;
22
- }
23
- return node->type >= CMARK_NODE_FIRST_INLINE &&
24
- node->type <= CMARK_NODE_LAST_INLINE;
25
- }
26
-
27
- static bool S_can_contain(cmark_node *node, cmark_node *child) {
28
- cmark_node *cur;
29
-
30
- if (node == NULL || child == NULL) {
31
- return false;
32
- }
33
-
34
- // Verify that child is not an ancestor of node or equal to node.
35
- cur = node;
36
- do {
37
- if (cur == child) {
38
- return false;
39
- }
40
- cur = cur->parent;
41
- } while (cur != NULL);
42
-
43
- if (child->type == CMARK_NODE_DOCUMENT) {
44
- return false;
17
+ if (node->extension && node->extension->can_contain_func) {
18
+ return node->extension->can_contain_func(node->extension, node, child_type);
45
19
  }
46
20
 
47
21
  switch (node->type) {
48
22
  case CMARK_NODE_DOCUMENT:
49
23
  case CMARK_NODE_BLOCK_QUOTE:
50
24
  case CMARK_NODE_ITEM:
51
- return S_is_block(child) && child->type != CMARK_NODE_ITEM;
25
+ return CMARK_NODE_TYPE_BLOCK_P(child_type) && child_type != CMARK_NODE_ITEM;
52
26
 
53
27
  case CMARK_NODE_LIST:
54
- return child->type == CMARK_NODE_ITEM;
28
+ return child_type == CMARK_NODE_ITEM;
55
29
 
56
30
  case CMARK_NODE_CUSTOM_BLOCK:
57
31
  return true;
@@ -63,7 +37,7 @@ static bool S_can_contain(cmark_node *node, cmark_node *child) {
63
37
  case CMARK_NODE_LINK:
64
38
  case CMARK_NODE_IMAGE:
65
39
  case CMARK_NODE_CUSTOM_INLINE:
66
- return S_is_inline(child);
40
+ return CMARK_NODE_TYPE_INLINE_P(child_type);
67
41
 
68
42
  default:
69
43
  break;
@@ -72,6 +46,28 @@ static bool S_can_contain(cmark_node *node, cmark_node *child) {
72
46
  return false;
73
47
  }
74
48
 
49
+ static bool S_can_contain(cmark_node *node, cmark_node *child) {
50
+ cmark_node *cur;
51
+
52
+ if (node == NULL || child == NULL) {
53
+ return false;
54
+ }
55
+ if (NODE_MEM(node) != NODE_MEM(child)) {
56
+ return 0;
57
+ }
58
+
59
+ // Verify that child is not an ancestor of node or equal to node.
60
+ cur = node;
61
+ do {
62
+ if (cur == child) {
63
+ return false;
64
+ }
65
+ cur = cur->parent;
66
+ } while (cur != NULL);
67
+
68
+ return cmark_node_can_contain_type(node, (cmark_node_type) child->type);
69
+ }
70
+
75
71
  cmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem) {
76
72
  cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node));
77
73
  cmark_strbuf_init(mem, &node->content, 0);
@@ -102,35 +98,44 @@ cmark_node *cmark_node_new(cmark_node_type type) {
102
98
  return cmark_node_new_with_mem(type, &DEFAULT_MEM_ALLOCATOR);
103
99
  }
104
100
 
101
+ static void free_node_as(cmark_node *node) {
102
+ switch (node->type) {
103
+ case CMARK_NODE_CODE_BLOCK:
104
+ cmark_chunk_free(NODE_MEM(node), &node->as.code.info);
105
+ cmark_chunk_free(NODE_MEM(node), &node->as.code.literal);
106
+ break;
107
+ case CMARK_NODE_TEXT:
108
+ case CMARK_NODE_HTML_INLINE:
109
+ case CMARK_NODE_CODE:
110
+ case CMARK_NODE_HTML_BLOCK:
111
+ cmark_chunk_free(NODE_MEM(node), &node->as.literal);
112
+ break;
113
+ case CMARK_NODE_LINK:
114
+ case CMARK_NODE_IMAGE:
115
+ cmark_chunk_free(NODE_MEM(node), &node->as.link.url);
116
+ cmark_chunk_free(NODE_MEM(node), &node->as.link.title);
117
+ break;
118
+ case CMARK_NODE_CUSTOM_BLOCK:
119
+ case CMARK_NODE_CUSTOM_INLINE:
120
+ cmark_chunk_free(NODE_MEM(node), &node->as.custom.on_enter);
121
+ cmark_chunk_free(NODE_MEM(node), &node->as.custom.on_exit);
122
+ break;
123
+ default:
124
+ break;
125
+ }
126
+ }
127
+
105
128
  // Free a cmark_node list and any children.
106
129
  static void S_free_nodes(cmark_node *e) {
107
130
  cmark_node *next;
108
131
  while (e != NULL) {
109
132
  cmark_strbuf_free(&e->content);
110
- switch (e->type) {
111
- case CMARK_NODE_CODE_BLOCK:
112
- cmark_chunk_free(NODE_MEM(e), &e->as.code.info);
113
- cmark_chunk_free(NODE_MEM(e), &e->as.code.literal);
114
- break;
115
- case CMARK_NODE_TEXT:
116
- case CMARK_NODE_HTML_INLINE:
117
- case CMARK_NODE_CODE:
118
- case CMARK_NODE_HTML_BLOCK:
119
- cmark_chunk_free(NODE_MEM(e), &e->as.literal);
120
- break;
121
- case CMARK_NODE_LINK:
122
- case CMARK_NODE_IMAGE:
123
- cmark_chunk_free(NODE_MEM(e), &e->as.link.url);
124
- cmark_chunk_free(NODE_MEM(e), &e->as.link.title);
125
- break;
126
- case CMARK_NODE_CUSTOM_BLOCK:
127
- case CMARK_NODE_CUSTOM_INLINE:
128
- cmark_chunk_free(NODE_MEM(e), &e->as.custom.on_enter);
129
- cmark_chunk_free(NODE_MEM(e), &e->as.custom.on_exit);
130
- break;
131
- default:
132
- break;
133
- }
133
+
134
+ if (e->user_data && e->user_data_free_func)
135
+ e->user_data_free_func(e->user_data);
136
+
137
+ free_node_as(e);
138
+
134
139
  if (e->last_child) {
135
140
  // Splice children into list
136
141
  e->last_child->next = e->next;
@@ -156,11 +161,38 @@ cmark_node_type cmark_node_get_type(cmark_node *node) {
156
161
  }
157
162
  }
158
163
 
164
+ int cmark_node_set_type(cmark_node * node, cmark_node_type type) {
165
+ cmark_node_type initial_type;
166
+
167
+ if (type == node->type)
168
+ return 1;
169
+
170
+ initial_type = (cmark_node_type) node->type;
171
+ node->type = type;
172
+
173
+ if (!S_can_contain(node->parent, node)) {
174
+ node->type = initial_type;
175
+ return 0;
176
+ }
177
+
178
+ /* We rollback the type to free the union members appropriately */
179
+ node->type = initial_type;
180
+ free_node_as(node);
181
+
182
+ node->type = type;
183
+
184
+ return 1;
185
+ }
186
+
159
187
  const char *cmark_node_get_type_string(cmark_node *node) {
160
188
  if (node == NULL) {
161
189
  return "NONE";
162
190
  }
163
191
 
192
+ if (node->extension && node->extension->get_type_string_func) {
193
+ return node->extension->get_type_string_func(node->extension, node);
194
+ }
195
+
164
196
  switch (node->type) {
165
197
  case CMARK_NODE_NONE:
166
198
  return "none";
@@ -265,6 +297,15 @@ int cmark_node_set_user_data(cmark_node *node, void *user_data) {
265
297
  return 1;
266
298
  }
267
299
 
300
+ int cmark_node_set_user_data_free_func(cmark_node *node,
301
+ cmark_free_func free_func) {
302
+ if (node == NULL) {
303
+ return 0;
304
+ }
305
+ node->user_data_free_func = free_func;
306
+ return 1;
307
+ }
308
+
268
309
  const char *cmark_node_get_literal(cmark_node *node) {
269
310
  if (node == NULL) {
270
311
  return NULL;
@@ -311,6 +352,15 @@ int cmark_node_set_literal(cmark_node *node, const char *content) {
311
352
  return 0;
312
353
  }
313
354
 
355
+ const char *cmark_node_get_string_content(cmark_node *node) {
356
+ return (char *) node->content.ptr;
357
+ }
358
+
359
+ int cmark_node_set_string_content(cmark_node *node, const char *content) {
360
+ cmark_strbuf_sets(&node->content, content);
361
+ return true;
362
+ }
363
+
314
364
  int cmark_node_get_heading_level(cmark_node *node) {
315
365
  if (node == NULL) {
316
366
  return 0;
@@ -477,6 +527,38 @@ int cmark_node_set_fence_info(cmark_node *node, const char *info) {
477
527
  }
478
528
  }
479
529
 
530
+ int cmark_node_get_fenced(cmark_node *node, int *length, int *offset, char *character) {
531
+ if (node == NULL) {
532
+ return 0;
533
+ }
534
+
535
+ if (node->type == CMARK_NODE_CODE_BLOCK) {
536
+ *length = node->as.code.fence_length;
537
+ *offset = node->as.code.fence_offset;
538
+ *character = node->as.code.fence_char;
539
+ return node->as.code.fenced;
540
+ } else {
541
+ return 0;
542
+ }
543
+ }
544
+
545
+ int cmark_node_set_fenced(cmark_node * node, int fenced,
546
+ int length, int offset, char character) {
547
+ if (node == NULL) {
548
+ return 0;
549
+ }
550
+
551
+ if (node->type == CMARK_NODE_CODE_BLOCK) {
552
+ node->as.code.fenced = fenced;
553
+ node->as.code.fence_length = length;
554
+ node->as.code.fence_offset = offset;
555
+ node->as.code.fence_char = character;
556
+ return 1;
557
+ } else {
558
+ return 0;
559
+ }
560
+ }
561
+
480
562
  const char *cmark_node_get_url(cmark_node *node) {
481
563
  if (node == NULL) {
482
564
  return NULL;
@@ -609,6 +691,23 @@ int cmark_node_set_on_exit(cmark_node *node, const char *on_exit) {
609
691
  return 0;
610
692
  }
611
693
 
694
+ cmark_syntax_extension *cmark_node_get_syntax_extension(cmark_node *node) {
695
+ if (node == NULL) {
696
+ return NULL;
697
+ }
698
+
699
+ return node->extension;
700
+ }
701
+
702
+ int cmark_node_set_syntax_extension(cmark_node *node, cmark_syntax_extension *extension) {
703
+ if (node == NULL) {
704
+ return 0;
705
+ }
706
+
707
+ node->extension = extension;
708
+ return 1;
709
+ }
710
+
612
711
  int cmark_node_get_start_line(cmark_node *node) {
613
712
  if (node == NULL) {
614
713
  return 0;