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
@@ -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
+ }