commonmarker 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -0,0 +1,20 @@
1
+ #include "cmark.h"
2
+ #include "chunk.h"
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+ bufsize_t _ext_scan_at(bufsize_t (*scanner)(const unsigned char *), unsigned char *ptr,
9
+ int len, bufsize_t offset);
10
+ bufsize_t _scan_table_start(const unsigned char *p);
11
+ bufsize_t _scan_table_cell(const unsigned char *p);
12
+ bufsize_t _scan_table_row_end(const unsigned char *p);
13
+
14
+ #define scan_table_start(c, l, n) _ext_scan_at(&_scan_table_start, c, l, n)
15
+ #define scan_table_cell(c, l, n) _ext_scan_at(&_scan_table_cell, c, l, n)
16
+ #define scan_table_row_end(c, l, n) _ext_scan_at(&_scan_table_row_end, c, l, n)
17
+
18
+ #ifdef __cplusplus
19
+ }
20
+ #endif
@@ -0,0 +1,65 @@
1
+ #include <stdlib.h>
2
+ #include "ext_scanners.h"
3
+
4
+ bufsize_t _ext_scan_at(bufsize_t (*scanner)(const unsigned char *), unsigned char *ptr, int len, bufsize_t offset)
5
+ {
6
+ bufsize_t res;
7
+
8
+ if (ptr == NULL || offset > len) {
9
+ return 0;
10
+ } else {
11
+ unsigned char lim = ptr[len];
12
+
13
+ ptr[len] = '\0';
14
+ res = scanner(ptr + offset);
15
+ ptr[len] = lim;
16
+ }
17
+
18
+ return res;
19
+ }
20
+
21
+ /*!re2c
22
+ re2c:define:YYCTYPE = "unsigned char";
23
+ re2c:define:YYCURSOR = p;
24
+ re2c:define:YYMARKER = marker;
25
+ re2c:define:YYCTXMARKER = marker;
26
+ re2c:yyfill:enable = 0;
27
+
28
+ spacechar = [ \t\v\f];
29
+ newline = [\r]?[\n];
30
+
31
+ escaped_char = [\\][|!"#$%&'()*+,./:;<=>?@[\\\]^_`{}~-];
32
+
33
+ table_marker = [|](spacechar*[-]+spacechar*);
34
+ table_cell = [|](escaped_char|[^|\r\n])+;
35
+ */
36
+
37
+ bufsize_t _scan_table_cell(const unsigned char *p)
38
+ {
39
+ const unsigned char *marker = NULL;
40
+ const unsigned char *start = p;
41
+ /*!re2c
42
+ table_cell { return (bufsize_t)(p - start); }
43
+ .? { return 0; }
44
+ */
45
+ }
46
+
47
+ bufsize_t _scan_table_row_end(const unsigned char *p)
48
+ {
49
+ const unsigned char *marker = NULL;
50
+ const unsigned char *start = p;
51
+ /*!re2c
52
+ [|]newline { return (bufsize_t)(p - start); }
53
+ .? { return 0; }
54
+ */
55
+ }
56
+
57
+ bufsize_t _scan_table_start(const unsigned char *p)
58
+ {
59
+ const unsigned char *marker = NULL;
60
+ const unsigned char *start = p;
61
+ /*!re2c
62
+ (table_marker)+ [|]newline { return (bufsize_t)(p - start); }
63
+ .? { return 0; }
64
+ */
65
+ }
@@ -0,0 +1,142 @@
1
+ #include "strikethrough.h"
2
+ #include <parser.h>
3
+
4
+ cmark_node_type CMARK_NODE_STRIKETHROUGH;
5
+
6
+ static cmark_node *match(cmark_syntax_extension *self,
7
+ cmark_parser *parser,
8
+ cmark_node *parent,
9
+ unsigned char character,
10
+ cmark_inline_parser *inline_parser)
11
+ {
12
+ cmark_node *res = NULL;
13
+ int left_flanking, right_flanking, punct_before, punct_after;
14
+ int num_delims;
15
+
16
+ if (character != '~')
17
+ return NULL;
18
+
19
+ num_delims = cmark_inline_parser_scan_delimiters(inline_parser, 100, '~',
20
+ &left_flanking, &right_flanking, &punct_before, &punct_after);
21
+
22
+ res = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);
23
+ cmark_node_set_literal(res, "~");
24
+
25
+ if (left_flanking || right_flanking) {
26
+ cmark_inline_parser_push_delimiter(inline_parser, character, left_flanking, right_flanking, res);
27
+ }
28
+
29
+ return res;
30
+ }
31
+
32
+ static delimiter *insert(cmark_syntax_extension *self,
33
+ cmark_parser *parser,
34
+ cmark_inline_parser *inline_parser,
35
+ delimiter *opener,
36
+ delimiter *closer)
37
+ {
38
+ cmark_node *strikethrough;
39
+ cmark_node *tmp, *next;
40
+ delimiter *delim, *tmp_delim;
41
+ delimiter *res = closer->next;
42
+
43
+ strikethrough = opener->inl_text;
44
+
45
+ if (!cmark_node_set_type(strikethrough, CMARK_NODE_STRIKETHROUGH))
46
+ goto done;
47
+
48
+ cmark_node_set_syntax_extension(strikethrough, self);
49
+
50
+ cmark_node_set_string_content(strikethrough, "~");
51
+ tmp = cmark_node_next(opener->inl_text);
52
+
53
+ while (tmp) {
54
+ if (tmp == closer->inl_text)
55
+ break;
56
+ next = cmark_node_next(tmp);
57
+ cmark_node_append_child(strikethrough, tmp);
58
+ tmp = next;
59
+ }
60
+
61
+ cmark_node_free(closer->inl_text);
62
+
63
+ delim = closer;
64
+ while (delim != NULL && delim != opener) {
65
+ tmp_delim = delim->previous;
66
+ cmark_inline_parser_remove_delimiter(inline_parser, delim);
67
+ delim = tmp_delim;
68
+ }
69
+
70
+ cmark_inline_parser_remove_delimiter(inline_parser, opener);
71
+
72
+ done:
73
+ return res;
74
+ }
75
+
76
+ static const char *get_type_string(cmark_syntax_extension *extension, cmark_node *node) {
77
+ return node->type == CMARK_NODE_STRIKETHROUGH ? "strikethrough" : "<unknown>";
78
+ }
79
+
80
+ static int can_contain(cmark_syntax_extension *extension, cmark_node *node, cmark_node_type child_type) {
81
+ if (node->type != CMARK_NODE_STRIKETHROUGH)
82
+ return false;
83
+
84
+ return CMARK_NODE_TYPE_INLINE_P(child_type);
85
+ }
86
+
87
+ static void commonmark_render(cmark_syntax_extension *extension, cmark_renderer *renderer, cmark_node *node, cmark_event_type ev_type, int options) {
88
+ renderer->out(renderer, cmark_node_get_string_content(node), false, LITERAL);
89
+ }
90
+
91
+ static void latex_render(cmark_syntax_extension *extension, cmark_renderer *renderer, cmark_node *node, cmark_event_type ev_type, int options) {
92
+ // requires \usepackage{ulem}
93
+ bool entering = (ev_type == CMARK_EVENT_ENTER);
94
+ if (entering) {
95
+ renderer->out(renderer, "\\sout{", false, LITERAL);
96
+ } else {
97
+ renderer->out(renderer, "}", false, LITERAL);
98
+ }
99
+ }
100
+
101
+ static void man_render(cmark_syntax_extension *extension, cmark_renderer *renderer, cmark_node *node, cmark_event_type ev_type, int options) {
102
+ bool entering = (ev_type == CMARK_EVENT_ENTER);
103
+ if (entering) {
104
+ renderer->cr(renderer);
105
+ renderer->out(renderer, ".ST \"", false, LITERAL);
106
+ } else {
107
+ renderer->out(renderer, "\"", false, LITERAL);
108
+ renderer->cr(renderer);
109
+ }
110
+ }
111
+
112
+ static void html_render(cmark_syntax_extension *extension,
113
+ cmark_html_renderer *renderer, cmark_node *node,
114
+ cmark_event_type ev_type, int options) {
115
+ bool entering = (ev_type == CMARK_EVENT_ENTER);
116
+ if (entering) {
117
+ cmark_strbuf_puts(renderer->html, "<del>");
118
+ } else {
119
+ cmark_strbuf_puts(renderer->html, "</del>");
120
+ }
121
+ }
122
+
123
+ cmark_syntax_extension *create_strikethrough_extension(void) {
124
+ cmark_syntax_extension *ext = cmark_syntax_extension_new("strikethrough");
125
+ cmark_llist *special_chars = NULL;
126
+
127
+ cmark_syntax_extension_set_get_type_string_func(ext, get_type_string);
128
+ cmark_syntax_extension_set_can_contain_func(ext, can_contain);
129
+ cmark_syntax_extension_set_commonmark_render_func(ext, commonmark_render);
130
+ cmark_syntax_extension_set_latex_render_func(ext, latex_render);
131
+ cmark_syntax_extension_set_man_render_func(ext, man_render);
132
+ cmark_syntax_extension_set_html_render_func(ext, html_render);
133
+ CMARK_NODE_STRIKETHROUGH = cmark_syntax_extension_add_node(1);
134
+
135
+ cmark_syntax_extension_set_match_inline_func(ext, match);
136
+ cmark_syntax_extension_set_inline_from_delim_func(ext, insert);
137
+
138
+ special_chars = cmark_llist_append(special_chars, (void *) '~');
139
+ cmark_syntax_extension_set_special_inline_chars(ext, special_chars);
140
+
141
+ return ext;
142
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef STRIKETHROUGH_H
2
+ #define STRIKETHROUGH_H
3
+
4
+ #include "core-extensions.h"
5
+
6
+ extern cmark_node_type CMARK_NODE_STRIKETHROUGH;
7
+ cmark_syntax_extension *create_strikethrough_extension(void);
8
+
9
+ #endif
@@ -0,0 +1,493 @@
1
+ #include <parser.h>
2
+ #include <html.h>
3
+
4
+ #include "table.h"
5
+ #include "strikethrough.h"
6
+ #include "ext_scanners.h"
7
+
8
+
9
+ static cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW, CMARK_NODE_TABLE_CELL;
10
+
11
+ typedef struct {
12
+ int n_columns;
13
+ cmark_llist *cells;
14
+ } table_row;
15
+
16
+ // WARNING: if these grow too large they simply won't fit in the union
17
+ // (cmark_node.as). If you add anything you should probably change it to be
18
+ // heap allocated and store the pointer in cmark_node.as.opaque instead.
19
+ typedef struct {
20
+ int n_columns;
21
+ } node_table;
22
+
23
+ typedef struct {
24
+ bool is_header;
25
+ } node_table_row;
26
+
27
+
28
+ static int get_n_table_columns(cmark_node *node) {
29
+ if (!node || node->type != CMARK_NODE_TABLE)
30
+ return -1;
31
+
32
+ return ((node_table *) &node->as.opaque)->n_columns;
33
+ }
34
+
35
+ static int set_n_table_columns(cmark_node *node, int n_columns) {
36
+ if (!node || node->type != CMARK_NODE_TABLE)
37
+ return 0;
38
+
39
+ ((node_table *) &node->as.opaque)->n_columns = n_columns;
40
+ return 1;
41
+ }
42
+
43
+ static int is_table_header(cmark_node *node, int is_table_header) {
44
+ if (!node || node->type != CMARK_NODE_TABLE_ROW)
45
+ return 0;
46
+
47
+ ((node_table_row *) &node->as.opaque)->is_header = is_table_header;
48
+ return 1;
49
+ }
50
+
51
+ static void free_table_cell(void *data) {
52
+ cmark_strbuf_free((cmark_strbuf *) data);
53
+ free(data);
54
+ }
55
+
56
+ static void free_table_row(table_row *row) {
57
+ if (!row)
58
+ return;
59
+
60
+ cmark_llist_free_full(row->cells, (cmark_free_func) free_table_cell);
61
+
62
+ free(row);
63
+ }
64
+
65
+ static cmark_strbuf *unescape_pipes(cmark_mem *mem, unsigned char *string, bufsize_t len) {
66
+ cmark_strbuf *res = (cmark_strbuf *)malloc(sizeof(cmark_strbuf));
67
+ bufsize_t r, w;
68
+
69
+ cmark_strbuf_init(mem, res, len + 1);
70
+ cmark_strbuf_put(res, string, len);
71
+ cmark_strbuf_putc(res, '\0');
72
+
73
+ for (r = 0, w = 0; r < len; ++r) {
74
+ if (res->ptr[r] == '\\' && res->ptr[r + 1] == '|')
75
+ r++;
76
+
77
+ res->ptr[w++] = res->ptr[r];
78
+ }
79
+
80
+ cmark_strbuf_truncate(res, w);
81
+
82
+ return res;
83
+ }
84
+
85
+ static table_row *row_from_string(cmark_mem *mem, unsigned char *string, int len) {
86
+ table_row *row = NULL;
87
+ bufsize_t cell_matched = 0;
88
+ bufsize_t cell_offset = 0;
89
+
90
+ row = (table_row *) malloc(sizeof(table_row));
91
+ row->n_columns = 0;
92
+ row->cells = NULL;
93
+
94
+ do {
95
+ cell_matched = scan_table_cell(string, len, cell_offset);
96
+ if (cell_matched) {
97
+ cmark_strbuf *cell_buf = unescape_pipes(mem, string + cell_offset + 1,
98
+ cell_matched - 1);
99
+ row->n_columns += 1;
100
+ row->cells = cmark_llist_append(row->cells, cell_buf);
101
+ }
102
+ cell_offset += cell_matched;
103
+ } while (cell_matched);
104
+
105
+ cell_matched = scan_table_row_end(string, len, cell_offset);
106
+ cell_offset += cell_matched;
107
+
108
+ if (!cell_matched || cell_offset != len) {
109
+ free_table_row(row);
110
+ row = NULL;
111
+ }
112
+
113
+ return row;
114
+ }
115
+
116
+ static cmark_node *try_opening_table_header(cmark_syntax_extension *self,
117
+ cmark_parser *parser,
118
+ cmark_node *parent_container,
119
+ unsigned char *input,
120
+ int len) {
121
+ bufsize_t matched = scan_table_start(input, len, cmark_parser_get_first_nonspace(parser));
122
+ cmark_node *table_header;
123
+ table_row *header_row = NULL;
124
+ table_row *marker_row = NULL;
125
+ const char *parent_string;
126
+
127
+ if (!matched)
128
+ goto done;
129
+
130
+ parent_string = cmark_node_get_string_content(parent_container);
131
+
132
+ header_row = row_from_string(parser->mem, (unsigned char *) parent_string, strlen(parent_string));
133
+
134
+ if (!header_row) {
135
+ goto done;
136
+ }
137
+
138
+ marker_row = row_from_string(parser->mem, input + cmark_parser_get_first_nonspace(parser),
139
+ len - cmark_parser_get_first_nonspace(parser));
140
+
141
+ assert(marker_row);
142
+
143
+ if (header_row->n_columns != marker_row->n_columns) {
144
+ goto done;
145
+ }
146
+
147
+ if (!cmark_node_set_type(parent_container, CMARK_NODE_TABLE)) {
148
+ goto done;
149
+ }
150
+
151
+ cmark_node_set_syntax_extension(parent_container, self);
152
+ set_n_table_columns(parent_container, header_row->n_columns);
153
+
154
+ table_header = cmark_parser_add_child(parser, parent_container,
155
+ CMARK_NODE_TABLE_ROW, cmark_parser_get_offset(parser));
156
+ cmark_node_set_syntax_extension(table_header, self);
157
+ is_table_header(table_header, true);
158
+
159
+ {
160
+ cmark_llist *tmp;
161
+
162
+ for (tmp = header_row->cells; tmp; tmp = tmp->next) {
163
+ cmark_strbuf *cell_buf = (cmark_strbuf *) tmp->data;
164
+ cmark_node *header_cell = cmark_parser_add_child(parser, table_header,
165
+ CMARK_NODE_TABLE_CELL, cmark_parser_get_offset(parser));
166
+ cmark_node_set_string_content(header_cell, (char *) cell_buf->ptr);
167
+ cmark_node_set_syntax_extension(header_cell, self);
168
+ }
169
+ }
170
+
171
+ cmark_parser_advance_offset(parser, (char *) input,
172
+ strlen((char *) input) - 1 - cmark_parser_get_offset(parser),
173
+ false);
174
+ done:
175
+ free_table_row(header_row);
176
+ free_table_row(marker_row);
177
+ return parent_container;
178
+ }
179
+
180
+ static cmark_node *try_opening_table_row(cmark_syntax_extension *self,
181
+ cmark_parser *parser,
182
+ cmark_node *parent_container,
183
+ unsigned char *input,
184
+ int len) {
185
+ cmark_node *table_row_block;
186
+ table_row *row;
187
+
188
+ if (cmark_parser_is_blank(parser))
189
+ return NULL;
190
+
191
+ table_row_block = cmark_parser_add_child(parser, parent_container,
192
+ CMARK_NODE_TABLE_ROW, cmark_parser_get_offset(parser));
193
+
194
+ cmark_node_set_syntax_extension(table_row_block, self);
195
+
196
+ /* We don't advance the offset here */
197
+
198
+ row = row_from_string(parser->mem, input + cmark_parser_get_first_nonspace(parser),
199
+ len - cmark_parser_get_first_nonspace(parser));
200
+
201
+ {
202
+ cmark_llist *tmp;
203
+
204
+ for (tmp = row->cells; tmp; tmp = tmp->next) {
205
+ cmark_strbuf *cell_buf = (cmark_strbuf *) tmp->data;
206
+ cmark_node *cell = cmark_parser_add_child(parser, table_row_block,
207
+ CMARK_NODE_TABLE_CELL, cmark_parser_get_offset(parser));
208
+ cmark_node_set_string_content(cell, (char *) cell_buf->ptr);
209
+ cmark_node_set_syntax_extension(cell, self);
210
+ }
211
+ }
212
+
213
+ free_table_row(row);
214
+
215
+ cmark_parser_advance_offset(parser, (char *) input,
216
+ len - 1 - cmark_parser_get_offset(parser),
217
+ false);
218
+
219
+ return table_row_block;
220
+ }
221
+
222
+ static cmark_node *try_opening_table_block(cmark_syntax_extension *syntax_extension,
223
+ int indented,
224
+ cmark_parser *parser,
225
+ cmark_node *parent_container,
226
+ unsigned char *input,
227
+ int len) {
228
+ cmark_node_type parent_type = cmark_node_get_type(parent_container);
229
+
230
+ if (!indented && parent_type == CMARK_NODE_PARAGRAPH) {
231
+ return try_opening_table_header(syntax_extension, parser, parent_container, input, len);
232
+ } else if (!indented && parent_type == CMARK_NODE_TABLE) {
233
+ return try_opening_table_row(syntax_extension, parser, parent_container, input, len);
234
+ }
235
+
236
+ return NULL;
237
+ }
238
+
239
+ static int matches(cmark_syntax_extension *self,
240
+ cmark_parser *parser,
241
+ unsigned char *input,
242
+ int len,
243
+ cmark_node *parent_container) {
244
+ int res = 0;
245
+
246
+ if (cmark_node_get_type(parent_container) == CMARK_NODE_TABLE) {
247
+ table_row *new_row = row_from_string(parser->mem, input + cmark_parser_get_first_nonspace(parser),
248
+ len - cmark_parser_get_first_nonspace(parser));
249
+ if (new_row) {
250
+ if (new_row->n_columns == get_n_table_columns(parent_container))
251
+ res = 1;
252
+ }
253
+ free_table_row(new_row);
254
+ }
255
+
256
+ return res;
257
+ }
258
+
259
+ static const char *get_type_string(cmark_syntax_extension *ext, cmark_node *node) {
260
+ if (node->type == CMARK_NODE_TABLE) {
261
+ return "table";
262
+ } else if (node->type == CMARK_NODE_TABLE_ROW) {
263
+ if (((node_table_row *) &node->as.opaque)->is_header)
264
+ return "table_header";
265
+ else
266
+ return "table_row";
267
+ } else if (node->type == CMARK_NODE_TABLE_CELL) {
268
+ return "table_cell";
269
+ }
270
+
271
+ return "<unknown>";
272
+ }
273
+
274
+ static int can_contain(cmark_syntax_extension *extension, cmark_node *node, cmark_node_type child_type) {
275
+ if (node->type == CMARK_NODE_TABLE) {
276
+ return child_type == CMARK_NODE_TABLE_ROW;
277
+ } else if (node->type == CMARK_NODE_TABLE_ROW) {
278
+ return child_type == CMARK_NODE_TABLE_CELL;
279
+ } else if (node->type == CMARK_NODE_TABLE_CELL) {
280
+ return child_type == CMARK_NODE_TEXT ||
281
+ child_type == CMARK_NODE_CODE ||
282
+ child_type == CMARK_NODE_EMPH ||
283
+ child_type == CMARK_NODE_STRONG ||
284
+ child_type == CMARK_NODE_LINK ||
285
+ child_type == CMARK_NODE_IMAGE ||
286
+ child_type == CMARK_NODE_STRIKETHROUGH;
287
+ }
288
+ return false;
289
+ }
290
+
291
+ static int contains_inlines(cmark_syntax_extension *extension, cmark_node *node) {
292
+ return node->type == CMARK_NODE_TABLE_CELL;
293
+ }
294
+
295
+ static void commonmark_render(cmark_syntax_extension *extension, cmark_renderer *renderer, cmark_node *node, cmark_event_type ev_type, int options) {
296
+ bool entering = (ev_type == CMARK_EVENT_ENTER);
297
+
298
+ if (node->type == CMARK_NODE_TABLE) {
299
+ renderer->blankline(renderer);
300
+ } else if (node->type == CMARK_NODE_TABLE_ROW) {
301
+ if (entering) {
302
+ renderer->cr(renderer);
303
+ renderer->out(renderer, "|", false, LITERAL);
304
+ }
305
+ } else if (node->type == CMARK_NODE_TABLE_CELL) {
306
+ if (entering) {
307
+ } else {
308
+ renderer->out(renderer, " |", false, LITERAL);
309
+ if (((node_table_row *) &node->parent->as.opaque)->is_header && !node->next) {
310
+ int i;
311
+ int n_cols = ((node_table *) &node->parent->parent->as.opaque)->n_columns;
312
+ renderer->cr(renderer);
313
+ renderer->out(renderer, "|", false, LITERAL);
314
+ for (i = 0; i < n_cols; i++) {
315
+ renderer->out(renderer, " --- |", false, LITERAL);
316
+ }
317
+ renderer->cr(renderer);
318
+ }
319
+ }
320
+ } else {
321
+ assert(false);
322
+ }
323
+ }
324
+
325
+ static void latex_render(cmark_syntax_extension *extension, cmark_renderer *renderer, cmark_node *node, cmark_event_type ev_type, int options) {
326
+ bool entering = (ev_type == CMARK_EVENT_ENTER);
327
+
328
+ if (node->type == CMARK_NODE_TABLE) {
329
+ if (entering) {
330
+ int i, n_cols;
331
+ renderer->cr(renderer);
332
+ renderer->out(renderer, "\\begin{table}", false, LITERAL);
333
+ renderer->cr(renderer);
334
+ renderer->out(renderer, "\\begin{tabular}{", false, LITERAL);
335
+
336
+ n_cols = ((node_table *) &node->as.opaque)->n_columns;
337
+ for (i = 0; i < n_cols; i++) {
338
+ renderer->out(renderer, "l", false, LITERAL);
339
+ }
340
+ renderer->out(renderer, "}", false, LITERAL);
341
+ renderer->cr(renderer);
342
+ } else {
343
+ renderer->out(renderer, "\\end{tabular}", false, LITERAL);
344
+ renderer->cr(renderer);
345
+ renderer->out(renderer, "\\end{table}", false, LITERAL);
346
+ renderer->cr(renderer);
347
+ }
348
+ } else if (node->type == CMARK_NODE_TABLE_ROW) {
349
+ if (!entering) {
350
+ renderer->cr(renderer);
351
+ }
352
+ } else if (node->type == CMARK_NODE_TABLE_CELL) {
353
+ if (!entering) {
354
+ if (node->next) {
355
+ renderer->out(renderer, " & ", false, LITERAL);
356
+ } else {
357
+ renderer->out(renderer, " \\\\", false, LITERAL);
358
+ }
359
+ }
360
+ } else {
361
+ assert(false);
362
+ }
363
+ }
364
+
365
+ static void man_render(cmark_syntax_extension *extension, cmark_renderer *renderer, cmark_node *node, cmark_event_type ev_type, int options) {
366
+ bool entering = (ev_type == CMARK_EVENT_ENTER);
367
+
368
+ if (node->type == CMARK_NODE_TABLE) {
369
+ if (entering) {
370
+ int i, n_cols;
371
+ renderer->cr(renderer);
372
+ renderer->out(renderer, ".TS", false, LITERAL);
373
+ renderer->cr(renderer);
374
+ renderer->out(renderer, "tab(@);", false, LITERAL);
375
+ renderer->cr(renderer);
376
+
377
+ n_cols = ((node_table *) &node->as.opaque)->n_columns;
378
+
379
+ for (i = 0; i < n_cols; i++) {
380
+ renderer->out(renderer, "c", false, LITERAL);
381
+ }
382
+
383
+ if (n_cols) {
384
+ renderer->out(renderer, ".", false, LITERAL);
385
+ renderer->cr(renderer);
386
+ }
387
+ } else {
388
+ renderer->out(renderer, ".TE", false, LITERAL);
389
+ renderer->cr(renderer);
390
+ }
391
+ } else if (node->type == CMARK_NODE_TABLE_ROW) {
392
+ if (!entering) {
393
+ renderer->cr(renderer);
394
+ }
395
+ } else if (node->type == CMARK_NODE_TABLE_CELL) {
396
+ if (!entering && node->next) {
397
+ renderer->out(renderer, "@", false, LITERAL);
398
+ }
399
+ } else {
400
+ assert(false);
401
+ }
402
+ }
403
+
404
+ struct html_table_state {
405
+ int need_closing_table_body : 1;
406
+ int in_table_header : 1;
407
+ };
408
+
409
+ static void html_render(cmark_syntax_extension *extension,
410
+ cmark_html_renderer *renderer, cmark_node *node,
411
+ cmark_event_type ev_type, int options) {
412
+ bool entering = (ev_type == CMARK_EVENT_ENTER);
413
+ cmark_strbuf *html = renderer->html;
414
+
415
+ // XXX: we just monopolise renderer->opaque.
416
+ struct html_table_state *table_state = (struct html_table_state *) &renderer->opaque;
417
+
418
+ if (node->type == CMARK_NODE_TABLE) {
419
+ if (entering) {
420
+ cmark_html_render_cr(html);
421
+ cmark_strbuf_puts(html, "<table");
422
+ cmark_html_render_sourcepos(node, html, options);
423
+ cmark_strbuf_putc(html, '>');
424
+ table_state->need_closing_table_body = false;
425
+ } else {
426
+ if (table_state->need_closing_table_body)
427
+ cmark_strbuf_puts(html, "</tbody>");
428
+ table_state->need_closing_table_body = false;
429
+ cmark_strbuf_puts(html, "</table>\n");
430
+ }
431
+ } else if (node->type == CMARK_NODE_TABLE_ROW) {
432
+ if (entering) {
433
+ cmark_html_render_cr(html);
434
+ if (((node_table_row *) &node->as.opaque)->is_header) {
435
+ table_state->in_table_header = true;
436
+ cmark_strbuf_puts(html, "<thead>");
437
+ cmark_html_render_cr(html);
438
+ }
439
+ cmark_strbuf_puts(html, "<tr");
440
+ cmark_html_render_sourcepos(node, html, options);
441
+ cmark_strbuf_putc(html, '>');
442
+ } else {
443
+ cmark_html_render_cr(html);
444
+ cmark_strbuf_puts(html, "</tr>");
445
+ if (((node_table_row *) &node->as.opaque)->is_header) {
446
+ cmark_html_render_cr(html);
447
+ cmark_strbuf_puts(html, "</thead>");
448
+ cmark_html_render_cr(html);
449
+ cmark_strbuf_puts(html, "<tbody>");
450
+ table_state->need_closing_table_body = true;
451
+ table_state->in_table_header = false;
452
+ }
453
+ }
454
+ } else if (node->type == CMARK_NODE_TABLE_CELL) {
455
+ if (entering) {
456
+ cmark_html_render_cr(html);
457
+ if (table_state->in_table_header) {
458
+ cmark_strbuf_puts(html, "<th");
459
+ } else {
460
+ cmark_strbuf_puts(html, "<td");
461
+ }
462
+ cmark_html_render_sourcepos(node, html, options);
463
+ cmark_strbuf_putc(html, '>');
464
+ } else {
465
+ if (table_state->in_table_header) {
466
+ cmark_strbuf_puts(html, "</th>");
467
+ } else {
468
+ cmark_strbuf_puts(html, "</td>");
469
+ }
470
+ }
471
+ } else {
472
+ assert(false);
473
+ }
474
+ }
475
+
476
+ cmark_syntax_extension *create_table_extension(void) {
477
+ cmark_syntax_extension *ext = cmark_syntax_extension_new("table");
478
+
479
+ cmark_syntax_extension_set_match_block_func(ext, matches);
480
+ cmark_syntax_extension_set_open_block_func(ext, try_opening_table_block);
481
+ cmark_syntax_extension_set_get_type_string_func(ext, get_type_string);
482
+ cmark_syntax_extension_set_can_contain_func(ext, can_contain);
483
+ cmark_syntax_extension_set_contains_inlines_func(ext, contains_inlines);
484
+ cmark_syntax_extension_set_commonmark_render_func(ext, commonmark_render);
485
+ cmark_syntax_extension_set_latex_render_func(ext, latex_render);
486
+ cmark_syntax_extension_set_man_render_func(ext, man_render);
487
+ cmark_syntax_extension_set_html_render_func(ext, html_render);
488
+ CMARK_NODE_TABLE = cmark_syntax_extension_add_node(0);
489
+ CMARK_NODE_TABLE_ROW = cmark_syntax_extension_add_node(0);
490
+ CMARK_NODE_TABLE_CELL = cmark_syntax_extension_add_node(0);
491
+
492
+ return ext;
493
+ }