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
@@ -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)
@@ -148,8 +149,7 @@ static bool is_autolink(cmark_node *node) {
148
149
  // if there is no block-level ancestor, returns NULL.
149
150
  static cmark_node *get_containing_block(cmark_node *node) {
150
151
  while (node) {
151
- if (node->type >= CMARK_NODE_FIRST_BLOCK &&
152
- node->type <= CMARK_NODE_LAST_BLOCK) {
152
+ if (CMARK_NODE_BLOCK_P(node)) {
153
153
  return node;
154
154
  } else {
155
155
  node = node->parent;
@@ -188,6 +188,11 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
188
188
  cmark_node_get_list_tight(tmp->parent->parent)));
189
189
  }
190
190
 
191
+ if (node->extension && node->extension->commonmark_render_func) {
192
+ node->extension->commonmark_render_func(node->extension, renderer, node, ev_type, options);
193
+ return 1;
194
+ }
195
+
191
196
  switch (node->type) {
192
197
  case CMARK_NODE_DOCUMENT:
193
198
  break;
@@ -31,17 +31,23 @@ extern "C" {
31
31
  #define HOUDINI_ESCAPED_SIZE(x) (((x)*12) / 10)
32
32
  #define HOUDINI_UNESCAPED_SIZE(x) (x)
33
33
 
34
- extern bufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src,
34
+ CMARK_EXPORT
35
+ bufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src,
35
36
  bufsize_t size);
36
- extern int houdini_escape_html(cmark_strbuf *ob, const uint8_t *src,
37
+ CMARK_EXPORT
38
+ int houdini_escape_html(cmark_strbuf *ob, const uint8_t *src,
37
39
  bufsize_t size);
38
- extern int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src,
40
+ CMARK_EXPORT
41
+ int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src,
39
42
  bufsize_t size, int secure);
40
- extern int houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src,
43
+ CMARK_EXPORT
44
+ int houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src,
41
45
  bufsize_t size);
42
- extern void houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src,
46
+ CMARK_EXPORT
47
+ void houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src,
43
48
  bufsize_t size);
44
- extern int houdini_escape_href(cmark_strbuf *ob, const uint8_t *src,
49
+ CMARK_EXPORT
50
+ int houdini_escape_href(cmark_strbuf *ob, const uint8_t *src,
45
51
  bufsize_t size);
46
52
 
47
53
  #ifdef __cplusplus
@@ -48,7 +48,7 @@ int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src, bufsize_t size,
48
48
  if (unlikely(i >= size))
49
49
  break;
50
50
 
51
- /* The forward slash is only escaped in secure mode */
51
+ /* The forward slash and single quote are only escaped in secure mode */
52
52
  if ((src[i] == '/' || src[i] == '\'') && !secure) {
53
53
  cmark_strbuf_putc(ob, src[i]);
54
54
  } else {
@@ -5,12 +5,10 @@
5
5
  #include "cmark_ctype.h"
6
6
  #include "config.h"
7
7
  #include "cmark.h"
8
- #include "node.h"
9
- #include "buffer.h"
10
8
  #include "houdini.h"
11
9
  #include "scanners.h"
12
-
13
- #define BUFFER_SIZE 100
10
+ #include "syntax_extension.h"
11
+ #include "html.h"
14
12
 
15
13
  // Functions to convert cmark_nodes to HTML strings.
16
14
 
@@ -19,44 +17,67 @@ static void escape_html(cmark_strbuf *dest, const unsigned char *source,
19
17
  houdini_escape_html0(dest, source, length, 0);
20
18
  }
21
19
 
22
- static CMARK_INLINE void cr(cmark_strbuf *html) {
23
- if (html->size && html->ptr[html->size - 1] != '\n')
24
- cmark_strbuf_putc(html, '\n');
25
- }
20
+ static void filter_html_block(cmark_html_renderer *renderer, uint8_t *data, size_t len) {
21
+ cmark_strbuf *html = renderer->html;
22
+ cmark_llist *it;
23
+ cmark_syntax_extension *ext;
24
+ bool filtered;
25
+ uint8_t *match;
26
+
27
+ while (len) {
28
+ match = (uint8_t *) memchr(data, '<', len);
29
+ if (!match)
30
+ break;
26
31
 
27
- struct render_state {
28
- cmark_strbuf *html;
29
- cmark_node *plain;
30
- };
32
+ if (match != data) {
33
+ cmark_strbuf_put(html, data, match - data);
34
+ len -= (match - data);
35
+ data = match;
36
+ }
31
37
 
32
- static void S_render_sourcepos(cmark_node *node, cmark_strbuf *html,
33
- int options) {
34
- char buffer[BUFFER_SIZE];
35
- if (CMARK_OPT_SOURCEPOS & options) {
36
- snprintf(buffer, BUFFER_SIZE, " data-sourcepos=\"%d:%d-%d:%d\"",
37
- cmark_node_get_start_line(node), cmark_node_get_start_column(node),
38
- cmark_node_get_end_line(node), cmark_node_get_end_column(node));
39
- cmark_strbuf_puts(html, buffer);
38
+ filtered = false;
39
+ for (it = renderer->filter_extensions; it; it = it->next) {
40
+ ext = ((cmark_syntax_extension *) it->data);
41
+ if (!ext->html_filter_func(ext, data, len)) {
42
+ filtered = true;
43
+ break;
44
+ }
45
+ }
46
+
47
+ if (!filtered) {
48
+ cmark_strbuf_putc(html, '<');
49
+ } else {
50
+ cmark_strbuf_puts(html, "&lt;");
51
+ }
52
+
53
+ ++data;
54
+ --len;
40
55
  }
56
+
57
+ if (len)
58
+ cmark_strbuf_put(html, data, len);
41
59
  }
42
60
 
43
- static int S_render_node(cmark_node *node, cmark_event_type ev_type,
44
- struct render_state *state, int options) {
61
+ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
62
+ cmark_event_type ev_type, int options) {
45
63
  cmark_node *parent;
46
64
  cmark_node *grandparent;
47
- cmark_strbuf *html = state->html;
65
+ cmark_strbuf *html = renderer->html;
66
+ cmark_llist *it;
67
+ cmark_syntax_extension *ext;
48
68
  char start_heading[] = "<h0";
49
69
  char end_heading[] = "</h0";
50
70
  bool tight;
71
+ bool filtered;
51
72
  char buffer[BUFFER_SIZE];
52
73
 
53
74
  bool entering = (ev_type == CMARK_EVENT_ENTER);
54
75
 
55
- if (state->plain == node) { // back at original node
56
- state->plain = NULL;
76
+ if (renderer->plain == node) { // back at original node
77
+ renderer->plain = NULL;
57
78
  }
58
79
 
59
- if (state->plain != NULL) {
80
+ if (renderer->plain != NULL) {
60
81
  switch (node->type) {
61
82
  case CMARK_NODE_TEXT:
62
83
  case CMARK_NODE_CODE:
@@ -75,18 +96,23 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
75
96
  return 1;
76
97
  }
77
98
 
99
+ if (node->extension && node->extension->html_render_func) {
100
+ node->extension->html_render_func(node->extension, renderer, node, ev_type, options);
101
+ return 1;
102
+ }
103
+
78
104
  switch (node->type) {
79
105
  case CMARK_NODE_DOCUMENT:
80
106
  break;
81
107
 
82
108
  case CMARK_NODE_BLOCK_QUOTE:
83
109
  if (entering) {
84
- cr(html);
110
+ cmark_html_render_cr(html);
85
111
  cmark_strbuf_puts(html, "<blockquote");
86
- S_render_sourcepos(node, html, options);
112
+ cmark_html_render_sourcepos(node, html, options);
87
113
  cmark_strbuf_puts(html, ">\n");
88
114
  } else {
89
- cr(html);
115
+ cmark_html_render_cr(html);
90
116
  cmark_strbuf_puts(html, "</blockquote>\n");
91
117
  }
92
118
  break;
@@ -96,19 +122,19 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
96
122
  int start = node->as.list.start;
97
123
 
98
124
  if (entering) {
99
- cr(html);
125
+ cmark_html_render_cr(html);
100
126
  if (list_type == CMARK_BULLET_LIST) {
101
127
  cmark_strbuf_puts(html, "<ul");
102
- S_render_sourcepos(node, html, options);
128
+ cmark_html_render_sourcepos(node, html, options);
103
129
  cmark_strbuf_puts(html, ">\n");
104
130
  } else if (start == 1) {
105
131
  cmark_strbuf_puts(html, "<ol");
106
- S_render_sourcepos(node, html, options);
132
+ cmark_html_render_sourcepos(node, html, options);
107
133
  cmark_strbuf_puts(html, ">\n");
108
134
  } else {
109
135
  snprintf(buffer, BUFFER_SIZE, "<ol start=\"%d\"", start);
110
136
  cmark_strbuf_puts(html, buffer);
111
- S_render_sourcepos(node, html, options);
137
+ cmark_html_render_sourcepos(node, html, options);
112
138
  cmark_strbuf_puts(html, ">\n");
113
139
  }
114
140
  } else {
@@ -120,9 +146,9 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
120
146
 
121
147
  case CMARK_NODE_ITEM:
122
148
  if (entering) {
123
- cr(html);
149
+ cmark_html_render_cr(html);
124
150
  cmark_strbuf_puts(html, "<li");
125
- S_render_sourcepos(node, html, options);
151
+ cmark_html_render_sourcepos(node, html, options);
126
152
  cmark_strbuf_putc(html, '>');
127
153
  } else {
128
154
  cmark_strbuf_puts(html, "</li>\n");
@@ -131,10 +157,10 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
131
157
 
132
158
  case CMARK_NODE_HEADING:
133
159
  if (entering) {
134
- cr(html);
160
+ cmark_html_render_cr(html);
135
161
  start_heading[2] = (char)('0' + node->as.heading.level);
136
162
  cmark_strbuf_puts(html, start_heading);
137
- S_render_sourcepos(node, html, options);
163
+ cmark_html_render_sourcepos(node, html, options);
138
164
  cmark_strbuf_putc(html, '>');
139
165
  } else {
140
166
  end_heading[3] = (char)('0' + node->as.heading.level);
@@ -144,11 +170,11 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
144
170
  break;
145
171
 
146
172
  case CMARK_NODE_CODE_BLOCK:
147
- cr(html);
173
+ cmark_html_render_cr(html);
148
174
 
149
175
  if (node->as.code.info.len == 0) {
150
176
  cmark_strbuf_puts(html, "<pre");
151
- S_render_sourcepos(node, html, options);
177
+ cmark_html_render_sourcepos(node, html, options);
152
178
  cmark_strbuf_puts(html, "><code>");
153
179
  } else {
154
180
  bufsize_t first_tag = 0;
@@ -158,7 +184,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
158
184
  }
159
185
 
160
186
  cmark_strbuf_puts(html, "<pre");
161
- S_render_sourcepos(node, html, options);
187
+ cmark_html_render_sourcepos(node, html, options);
162
188
  cmark_strbuf_puts(html, "><code class=\"language-");
163
189
  escape_html(html, node->as.code.info.data, first_tag);
164
190
  cmark_strbuf_puts(html, "\">");
@@ -169,17 +195,19 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
169
195
  break;
170
196
 
171
197
  case CMARK_NODE_HTML_BLOCK:
172
- cr(html);
198
+ cmark_html_render_cr(html);
173
199
  if (options & CMARK_OPT_SAFE) {
174
200
  cmark_strbuf_puts(html, "<!-- raw HTML omitted -->");
201
+ } else if (renderer->filter_extensions) {
202
+ filter_html_block(renderer, node->as.literal.data, node->as.literal.len);
175
203
  } else {
176
204
  cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
177
205
  }
178
- cr(html);
206
+ cmark_html_render_cr(html);
179
207
  break;
180
208
 
181
209
  case CMARK_NODE_CUSTOM_BLOCK:
182
- cr(html);
210
+ cmark_html_render_cr(html);
183
211
  if (entering) {
184
212
  cmark_strbuf_put(html, node->as.custom.on_enter.data,
185
213
  node->as.custom.on_enter.len);
@@ -187,13 +215,13 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
187
215
  cmark_strbuf_put(html, node->as.custom.on_exit.data,
188
216
  node->as.custom.on_exit.len);
189
217
  }
190
- cr(html);
218
+ cmark_html_render_cr(html);
191
219
  break;
192
220
 
193
221
  case CMARK_NODE_THEMATIC_BREAK:
194
- cr(html);
222
+ cmark_html_render_cr(html);
195
223
  cmark_strbuf_puts(html, "<hr");
196
- S_render_sourcepos(node, html, options);
224
+ cmark_html_render_sourcepos(node, html, options);
197
225
  cmark_strbuf_puts(html, " />\n");
198
226
  break;
199
227
 
@@ -207,9 +235,9 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
207
235
  }
208
236
  if (!tight) {
209
237
  if (entering) {
210
- cr(html);
238
+ cmark_html_render_cr(html);
211
239
  cmark_strbuf_puts(html, "<p");
212
- S_render_sourcepos(node, html, options);
240
+ cmark_html_render_sourcepos(node, html, options);
213
241
  cmark_strbuf_putc(html, '>');
214
242
  } else {
215
243
  cmark_strbuf_puts(html, "</p>\n");
@@ -245,7 +273,20 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
245
273
  if (options & CMARK_OPT_SAFE) {
246
274
  cmark_strbuf_puts(html, "<!-- raw HTML omitted -->");
247
275
  } else {
248
- cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
276
+ filtered = false;
277
+ for (it = renderer->filter_extensions; it; it = it->next) {
278
+ ext = (cmark_syntax_extension *) it->data;
279
+ if (!ext->html_filter_func(ext, node->as.literal.data, node->as.literal.len)) {
280
+ filtered = true;
281
+ break;
282
+ }
283
+ }
284
+ if (!filtered) {
285
+ cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);
286
+ } else {
287
+ cmark_strbuf_puts(html, "&lt;");
288
+ cmark_strbuf_put(html, node->as.literal.data + 1, node->as.literal.len - 1);
289
+ }
249
290
  }
250
291
  break;
251
292
 
@@ -302,7 +343,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
302
343
  node->as.link.url.len);
303
344
  }
304
345
  cmark_strbuf_puts(html, "\" alt=\"");
305
- state->plain = node;
346
+ renderer->plain = node;
306
347
  } else {
307
348
  if (node->as.link.title.len) {
308
349
  cmark_strbuf_puts(html, "\" title=\"");
@@ -318,24 +359,31 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
318
359
  break;
319
360
  }
320
361
 
321
- // cmark_strbuf_putc(html, 'x');
322
362
  return 1;
323
363
  }
324
364
 
325
- char *cmark_render_html(cmark_node *root, int options) {
365
+ char *cmark_render_html(cmark_node *root, int options, cmark_llist *extensions) {
326
366
  char *result;
327
367
  cmark_strbuf html = CMARK_BUF_INIT(cmark_node_mem(root));
328
368
  cmark_event_type ev_type;
329
369
  cmark_node *cur;
330
- struct render_state state = {&html, NULL};
370
+ cmark_html_renderer renderer = {&html, NULL, NULL, NULL};
331
371
  cmark_iter *iter = cmark_iter_new(root);
332
372
 
373
+ for (; extensions; extensions = extensions->next)
374
+ if (((cmark_syntax_extension *) extensions->data)->html_filter_func)
375
+ renderer.filter_extensions = cmark_llist_append(
376
+ renderer.filter_extensions,
377
+ (cmark_syntax_extension *) extensions->data);
378
+
333
379
  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
334
380
  cur = cmark_iter_get_node(iter);
335
- S_render_node(cur, ev_type, &state, options);
381
+ S_render_node(&renderer, cur, ev_type, options);
336
382
  }
337
383
  result = (char *)cmark_strbuf_detach(&html);
338
384
 
385
+ cmark_llist_free(renderer.filter_extensions);
386
+
339
387
  cmark_iter_free(iter);
340
388
  return result;
341
389
  }
@@ -0,0 +1,27 @@
1
+ #ifndef CMARK_HTML_H
2
+ #define CMARK_HTML_H
3
+
4
+ #include "buffer.h"
5
+ #include "node.h"
6
+
7
+ CMARK_INLINE
8
+ static void cmark_html_render_cr(cmark_strbuf *html) {
9
+ if (html->size && html->ptr[html->size - 1] != '\n')
10
+ cmark_strbuf_putc(html, '\n');
11
+ }
12
+
13
+ #define BUFFER_SIZE 100
14
+
15
+ CMARK_INLINE
16
+ static void cmark_html_render_sourcepos(cmark_node *node, cmark_strbuf *html, int options) {
17
+ char buffer[BUFFER_SIZE];
18
+ if (CMARK_OPT_SOURCEPOS & options) {
19
+ snprintf(buffer, BUFFER_SIZE, " data-sourcepos=\"%d:%d-%d:%d\"",
20
+ cmark_node_get_start_line(node), cmark_node_get_start_column(node),
21
+ cmark_node_get_end_line(node), cmark_node_get_end_column(node));
22
+ cmark_strbuf_puts(html, buffer);
23
+ }
24
+ }
25
+
26
+
27
+ #endif
@@ -12,6 +12,7 @@
12
12
  #include "utf8.h"
13
13
  #include "scanners.h"
14
14
  #include "inlines.h"
15
+ #include "syntax_extension.h"
15
16
 
16
17
  static const char *EMDASH = "\xE2\x80\x94";
17
18
  static const char *ENDASH = "\xE2\x80\x93";
@@ -30,15 +31,6 @@ static const char *RIGHTSINGLEQUOTE = "\xE2\x80\x99";
30
31
  #define make_emph(mem) make_simple(mem, CMARK_NODE_EMPH)
31
32
  #define make_strong(mem) make_simple(mem, CMARK_NODE_STRONG)
32
33
 
33
- typedef struct delimiter {
34
- struct delimiter *previous;
35
- struct delimiter *next;
36
- cmark_node *inl_text;
37
- unsigned char delim_char;
38
- bool can_open;
39
- bool can_close;
40
- } delimiter;
41
-
42
34
  typedef struct bracket {
43
35
  struct bracket *previous;
44
36
  struct delimiter *previous_delimiter;
@@ -49,7 +41,7 @@ typedef struct bracket {
49
41
  bool bracket_after;
50
42
  } bracket;
51
43
 
52
- typedef struct {
44
+ typedef struct subject{
53
45
  cmark_mem *mem;
54
46
  cmark_chunk input;
55
47
  bufsize_t pos;
@@ -65,7 +57,7 @@ static CMARK_INLINE bool S_is_line_end_char(char c) {
65
57
  static delimiter *S_insert_emph(subject *subj, delimiter *opener,
66
58
  delimiter *closer);
67
59
 
68
- static int parse_inline(subject *subj, cmark_node *parent, int options);
60
+ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent, int options);
69
61
 
70
62
  static void subject_from_buf(cmark_mem *mem, subject *e, cmark_strbuf *buffer,
71
63
  cmark_reference_map *refmap);
@@ -481,7 +473,40 @@ static cmark_node *handle_period(subject *subj, bool smart) {
481
473
  }
482
474
  }
483
475
 
484
- static void process_emphasis(subject *subj, delimiter *stack_bottom) {
476
+ static void add_extensions_openers_bottom(cmark_parser *parser,
477
+ delimiter **openers_bottom, delimiter *stack_bottom) {
478
+ cmark_llist *tmp_ext;
479
+
480
+ for (tmp_ext = parser->inline_syntax_extensions; tmp_ext; tmp_ext=tmp_ext->next) {
481
+ cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp_ext->data;
482
+ cmark_llist *tmp_char;
483
+ for (tmp_char = ext->special_inline_chars; tmp_char; tmp_char=tmp_char->next) {
484
+ unsigned char c = (unsigned char) (unsigned long) tmp_char->data;
485
+
486
+ openers_bottom[c] = stack_bottom;
487
+ }
488
+ }
489
+ }
490
+
491
+ static cmark_syntax_extension *get_extension_for_special_char(cmark_parser *parser, unsigned char c) {
492
+ cmark_llist *tmp_ext;
493
+
494
+ for (tmp_ext = parser->inline_syntax_extensions; tmp_ext; tmp_ext=tmp_ext->next) {
495
+ cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp_ext->data;
496
+ cmark_llist *tmp_char;
497
+ for (tmp_char = ext->special_inline_chars; tmp_char; tmp_char=tmp_char->next) {
498
+ unsigned char tmp_c = (unsigned char) (unsigned long) tmp_char->data;
499
+
500
+ if (tmp_c == c) {
501
+ return ext;
502
+ }
503
+ }
504
+ }
505
+
506
+ return NULL;
507
+ }
508
+
509
+ static void process_emphasis(cmark_parser *parser, subject *subj, delimiter *stack_bottom) {
485
510
  delimiter *closer = subj->last_delim;
486
511
  delimiter *opener;
487
512
  delimiter *old_closer;
@@ -494,6 +519,7 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {
494
519
  openers_bottom['_'] = stack_bottom;
495
520
  openers_bottom['\''] = stack_bottom;
496
521
  openers_bottom['"'] = stack_bottom;
522
+ add_extensions_openers_bottom(parser, openers_bottom, stack_bottom);
497
523
 
498
524
  // move back to first relevant delim.
499
525
  while (closer != NULL && closer->previous != stack_bottom) {
@@ -502,6 +528,7 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {
502
528
 
503
529
  // now move forward, looking for closers, and handling each
504
530
  while (closer != NULL) {
531
+ cmark_syntax_extension *extension = get_extension_for_special_char(parser, closer->delim_char);
505
532
  if (closer->can_close) {
506
533
  // Now look backwards for first matching opener:
507
534
  opener = closer->previous;
@@ -524,7 +551,13 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {
524
551
  opener = opener->previous;
525
552
  }
526
553
  old_closer = closer;
527
- if (closer->delim_char == '*' || closer->delim_char == '_') {
554
+
555
+ if (extension) {
556
+ if (opener_found)
557
+ closer = extension->insert_inline_from_delim(extension, parser, subj, opener, closer);
558
+ else
559
+ closer = closer->next;
560
+ } else if (closer->delim_char == '*' || closer->delim_char == '_') {
528
561
  if (opener_found) {
529
562
  closer = S_insert_emph(subj, opener, closer);
530
563
  } else {
@@ -796,9 +829,7 @@ noMatch:
796
829
  subj->pos = startpos; // rewind
797
830
  return 0;
798
831
  }
799
-
800
- // Return a link, an image, or a literal close bracket.
801
- static cmark_node *handle_close_bracket(subject *subj) {
832
+ static cmark_node *handle_close_bracket(cmark_parser *parser, subject *subj) {
802
833
  bufsize_t initial_pos;
803
834
  bufsize_t starturl, endurl, starttitle, endtitle, endall;
804
835
  bufsize_t n;
@@ -919,7 +950,7 @@ match:
919
950
  // Free the bracket [:
920
951
  cmark_node_free(opener->inl_text);
921
952
 
922
- process_emphasis(subj, opener->previous_delimiter);
953
+ process_emphasis(parser, subj, opener->previous_delimiter);
923
954
  pop_bracket(subj);
924
955
 
925
956
  // Now, if we have a link, we also want to deactivate earlier link
@@ -963,36 +994,36 @@ static cmark_node *handle_newline(subject *subj) {
963
994
  }
964
995
  }
965
996
 
966
- static bufsize_t subject_find_special_char(subject *subj, int options) {
967
- // "\r\n\\`&_*[]<!"
968
- static const int8_t SPECIAL_CHARS[256] = {
969
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
970
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
971
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
972
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,
973
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
974
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
975
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
976
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
977
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
978
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
979
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
980
-
981
- // " ' . -
982
- static const char SMART_PUNCT_CHARS[] = {
983
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
984
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,
985
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
986
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
987
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
988
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
989
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
990
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
991
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
992
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
993
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
994
- };
997
+ // "\r\n\\`&_*[]<!"
998
+ static int8_t SPECIAL_CHARS[256] = {
999
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1000
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
1001
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1002
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,
1003
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1004
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1005
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1006
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1007
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1008
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1009
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1010
+
1011
+ // " ' . -
1012
+ static char SMART_PUNCT_CHARS[] = {
1013
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1014
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,
1015
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1016
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1017
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1018
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1019
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1020
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1021
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1022
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1023
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1024
+ };
995
1025
 
1026
+ static bufsize_t subject_find_special_char(subject *subj, int options) {
996
1027
  bufsize_t n = subj->pos + 1;
997
1028
 
998
1029
  while (n < subj->input.len) {
@@ -1006,9 +1037,35 @@ static bufsize_t subject_find_special_char(subject *subj, int options) {
1006
1037
  return subj->input.len;
1007
1038
  }
1008
1039
 
1040
+ void cmark_inlines_add_special_character(unsigned char c) {
1041
+ SPECIAL_CHARS[c] = 1;
1042
+ }
1043
+
1044
+ void cmark_inlines_remove_special_character(unsigned char c) {
1045
+ SPECIAL_CHARS[c] = 0;
1046
+ }
1047
+
1048
+ static cmark_node *try_extensions(cmark_parser *parser,
1049
+ cmark_node *parent,
1050
+ unsigned char c,
1051
+ subject *subj) {
1052
+ cmark_node *res = NULL;
1053
+ cmark_llist *tmp;
1054
+
1055
+ for (tmp = parser->inline_syntax_extensions; tmp; tmp = tmp->next) {
1056
+ cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;
1057
+ res = ext->match_inline(ext, parser, parent, c, subj);
1058
+
1059
+ if (res)
1060
+ break;
1061
+ }
1062
+
1063
+ return res;
1064
+ }
1065
+
1009
1066
  // Parse an inline, advancing subject, and add it as a child of parent.
1010
1067
  // Return 0 if no inline can be parsed, 1 otherwise.
1011
- static int parse_inline(subject *subj, cmark_node *parent, int options) {
1068
+ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent, int options) {
1012
1069
  cmark_node *new_inl = NULL;
1013
1070
  cmark_chunk contents;
1014
1071
  unsigned char c;
@@ -1052,7 +1109,7 @@ static int parse_inline(subject *subj, cmark_node *parent, int options) {
1052
1109
  push_bracket(subj, false, new_inl);
1053
1110
  break;
1054
1111
  case ']':
1055
- new_inl = handle_close_bracket(subj);
1112
+ new_inl = handle_close_bracket(parser, subj);
1056
1113
  break;
1057
1114
  case '!':
1058
1115
  advance(subj);
@@ -1065,6 +1122,10 @@ static int parse_inline(subject *subj, cmark_node *parent, int options) {
1065
1122
  }
1066
1123
  break;
1067
1124
  default:
1125
+ new_inl = try_extensions(parser, parent, c, subj);
1126
+ if (new_inl != NULL)
1127
+ break;
1128
+
1068
1129
  endpos = subject_find_special_char(subj, options);
1069
1130
  contents = cmark_chunk_dup(&subj->input, subj->pos, endpos - subj->pos);
1070
1131
  subj->pos = endpos;
@@ -1084,16 +1145,18 @@ static int parse_inline(subject *subj, cmark_node *parent, int options) {
1084
1145
  }
1085
1146
 
1086
1147
  // Parse inlines from parent's string_content, adding as children of parent.
1087
- extern void cmark_parse_inlines(cmark_mem *mem, cmark_node *parent,
1088
- cmark_reference_map *refmap, int options) {
1148
+ void cmark_parse_inlines(cmark_parser *parser,
1149
+ cmark_node *parent,
1150
+ cmark_reference_map *refmap,
1151
+ int options) {
1089
1152
  subject subj;
1090
- subject_from_buf(mem, &subj, &parent->content, refmap);
1153
+ subject_from_buf(parser->mem, &subj, &parent->content, refmap);
1091
1154
  cmark_chunk_rtrim(&subj.input);
1092
1155
 
1093
- while (!is_eof(&subj) && parse_inline(&subj, parent, options))
1156
+ while (!is_eof(&subj) && parse_inline(parser, &subj, parent, options))
1094
1157
  ;
1095
1158
 
1096
- process_emphasis(&subj, NULL);
1159
+ process_emphasis(parser, &subj, NULL);
1097
1160
  // free bracket stack
1098
1161
  while (subj.last_bracket) {
1099
1162
  pop_bracket(&subj);
@@ -1175,3 +1238,148 @@ bufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_strbuf *input,
1175
1238
  cmark_reference_create(refmap, &lab, &url, &title);
1176
1239
  return subj.pos;
1177
1240
  }
1241
+
1242
+ unsigned char cmark_inline_parser_peek_char(cmark_inline_parser *parser) {
1243
+ return peek_char(parser);
1244
+ }
1245
+
1246
+ unsigned char cmark_inline_parser_peek_at(cmark_inline_parser *parser, bufsize_t pos) {
1247
+ return peek_at(parser, pos);
1248
+ }
1249
+
1250
+ int cmark_inline_parser_is_eof(cmark_inline_parser *parser) {
1251
+ return is_eof(parser);
1252
+ }
1253
+
1254
+ static char *
1255
+ my_strndup (const char *s, size_t n)
1256
+ {
1257
+ char *result;
1258
+ size_t len = strlen (s);
1259
+
1260
+ if (n < len)
1261
+ len = n;
1262
+
1263
+ result = (char *) malloc (len + 1);
1264
+ if (!result)
1265
+ return 0;
1266
+
1267
+ result[len] = '\0';
1268
+ return (char *) memcpy (result, s, len);
1269
+ }
1270
+
1271
+ char *cmark_inline_parser_take_while(cmark_inline_parser *parser, cmark_inline_predicate pred) {
1272
+ unsigned char c;
1273
+ bufsize_t startpos = parser->pos;
1274
+ bufsize_t len = 0;
1275
+
1276
+ while ((c = peek_char(parser)) && (*pred)(c)) {
1277
+ advance(parser);
1278
+ len++;
1279
+ }
1280
+
1281
+ return my_strndup((const char *) parser->input.data + startpos, len);
1282
+ }
1283
+
1284
+ void cmark_inline_parser_push_delimiter(cmark_inline_parser *parser,
1285
+ unsigned char c,
1286
+ int can_open,
1287
+ int can_close,
1288
+ cmark_node *inl_text) {
1289
+ push_delimiter(parser, c, can_open, can_close, inl_text);
1290
+ }
1291
+
1292
+ void cmark_inline_parser_remove_delimiter(cmark_inline_parser *parser, delimiter *delim) {
1293
+ remove_delimiter(parser, delim);
1294
+ }
1295
+
1296
+ int cmark_inline_parser_scan_delimiters(cmark_inline_parser *parser,
1297
+ int max_delims,
1298
+ unsigned char c,
1299
+ int *left_flanking,
1300
+ int *right_flanking,
1301
+ int *punct_before,
1302
+ int *punct_after) {
1303
+ int numdelims = 0;
1304
+ bufsize_t before_char_pos;
1305
+ int32_t after_char = 0;
1306
+ int32_t before_char = 0;
1307
+ int len;
1308
+ bool space_before, space_after;
1309
+
1310
+ if (parser->pos == 0) {
1311
+ before_char = 10;
1312
+ } else {
1313
+ before_char_pos = parser->pos - 1;
1314
+ // walk back to the beginning of the UTF_8 sequence:
1315
+ while (peek_at(parser, before_char_pos) >> 6 == 2 && before_char_pos > 0) {
1316
+ before_char_pos -= 1;
1317
+ }
1318
+ len = cmark_utf8proc_iterate(parser->input.data + before_char_pos,
1319
+ parser->pos - before_char_pos, &before_char);
1320
+ if (len == -1) {
1321
+ before_char = 10;
1322
+ }
1323
+ }
1324
+
1325
+ while (peek_char(parser) == c && numdelims <= max_delims) {
1326
+ numdelims++;
1327
+ advance(parser);
1328
+ }
1329
+
1330
+ len = cmark_utf8proc_iterate(parser->input.data + parser->pos,
1331
+ parser->input.len - parser->pos, &after_char);
1332
+ if (len == -1) {
1333
+ after_char = 10;
1334
+ }
1335
+
1336
+ *punct_before = cmark_utf8proc_is_punctuation(before_char);
1337
+ *punct_after = cmark_utf8proc_is_punctuation(after_char);
1338
+ space_before = cmark_utf8proc_is_space(before_char);
1339
+ space_after = cmark_utf8proc_is_space(after_char);
1340
+
1341
+ *left_flanking = numdelims > 0 && !cmark_utf8proc_is_space(after_char) &&
1342
+ !(*punct_after && !space_before && !*punct_before);
1343
+ *right_flanking = numdelims > 0 && !cmark_utf8proc_is_space(before_char) &&
1344
+ !(*punct_before && !space_after && !*punct_after);
1345
+
1346
+ return numdelims;
1347
+ }
1348
+
1349
+ void cmark_inline_parser_advance_offset(cmark_inline_parser *parser) {
1350
+ advance(parser);
1351
+ }
1352
+
1353
+ int cmark_inline_parser_get_offset(cmark_inline_parser *parser) {
1354
+ return parser->pos;
1355
+ }
1356
+
1357
+ void cmark_inline_parser_set_offset(cmark_inline_parser *parser, int offset) {
1358
+ parser->pos = offset;
1359
+ }
1360
+
1361
+ cmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser) {
1362
+ return &parser->input;
1363
+ }
1364
+
1365
+ int cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int image) {
1366
+ for (bracket *b = parser->last_bracket; b; b = b->previous)
1367
+ if (b->active && b->image == image)
1368
+ return 1;
1369
+ return 0;
1370
+ }
1371
+
1372
+ void cmark_node_unput(cmark_node *node, int n) {
1373
+ if (!node->last_child)
1374
+ return;
1375
+ if (node->last_child->type != CMARK_NODE_TEXT)
1376
+ return;
1377
+ if (node->last_child->as.literal.len < n)
1378
+ node->last_child->as.literal.len = 0;
1379
+ else
1380
+ node->last_child->as.literal.len -= n;
1381
+ }
1382
+
1383
+ delimiter *cmark_inline_parser_get_last_delimiter(cmark_inline_parser *parser) {
1384
+ return parser->last_delim;
1385
+ }