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.
- checksums.yaml +4 -4
- data/Rakefile +3 -0
- data/bin/commonmarker +19 -3
- data/ext/commonmarker/cmark/CMakeLists.txt +1 -0
- data/ext/commonmarker/cmark/COPYING +2 -24
- data/ext/commonmarker/cmark/Makefile +25 -5
- data/ext/commonmarker/cmark/README.md +1 -1
- data/ext/commonmarker/cmark/api_test/CMakeLists.txt +1 -1
- data/ext/commonmarker/cmark/api_test/main.c +25 -27
- data/ext/commonmarker/cmark/build/CMakeCache.txt +12 -9
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CMakeCCompiler.cmake +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CMakeCXXCompiler.cmake +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CMakeDetermineCompilerABI_C.bin +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CMakeDetermineCompilerABI_CXX.bin +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CMakeSystem.cmake +4 -4
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CompilerIdC/CMakeCCompilerId.c +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CompilerIdC/a.out +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CompilerIdCXX/CMakeCXXCompilerId.cpp +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/{3.6.0 → 3.6.1}/CompilerIdCXX/a.out +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeError.log +6 -6
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeOutput.log +148 -148
- data/ext/commonmarker/cmark/build/CMakeFiles/Makefile.cmake +41 -109
- data/ext/commonmarker/cmark/build/CMakeFiles/Makefile2 +66 -10
- data/ext/commonmarker/cmark/build/CMakeFiles/TargetDirectories.txt +8 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/progress.marks +1 -1
- data/ext/commonmarker/cmark/build/CTestTestfile.cmake +1 -0
- data/ext/commonmarker/cmark/build/Makefile +23 -9
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/build.make +2 -2
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/progress.marks +1 -1
- data/ext/commonmarker/cmark/build/api_test/Makefile +9 -9
- data/ext/commonmarker/cmark/build/cmake_install.cmake +1 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/C.includecache +190 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/DependInfo.cmake +29 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/autolink.c.o +0 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/build.make +249 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/cmake_clean.cmake +15 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/cmake_clean_target.cmake +3 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/core-extensions.c.o +0 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/depend.internal +92 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/depend.make +92 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/ext_scanners.c.o +0 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/flags.make +10 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/link.txt +2 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/progress.make +8 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/strikethrough.c.o +0 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/table.c.o +0 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/libcmarkextensions_static.dir/whitelist.c.o +0 -0
- data/ext/commonmarker/cmark/build/extensions/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark/build/extensions/Makefile +390 -0
- data/ext/commonmarker/cmark/build/extensions/cmake_install.cmake +29 -0
- data/ext/commonmarker/cmark/build/extensions/libcmarkextensions.a +0 -0
- data/ext/commonmarker/cmark/build/man/Makefile +9 -9
- data/ext/commonmarker/cmark/build/src/CMakeFiles/Export/lib/cmake/cmark.cmake +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/DependInfo.cmake +7 -19
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/build.make +6 -517
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/cmake_clean.cmake +0 -19
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/flags.make +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/link.txt +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/progress.make +0 -19
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/DependInfo.cmake +9 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/build.make +112 -4
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/cmake_clean.cmake +4 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/flags.make +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/link.txt +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/progress.make +24 -20
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/C.includecache +144 -10
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/DependInfo.cmake +9 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/blocks.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/build.make +112 -4
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmake_clean.cmake +4 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmark.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/commonmark.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/depend.internal +74 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/depend.make +74 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/flags.make +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/html.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/inlines.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/iterator.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/latex.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/link.txt +1 -1
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/linked_list.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/man.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/node.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/plugin.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/progress.make +24 -20
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/registry.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/scanners.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/syntax_extension.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/xml.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/progress.marks +1 -1
- data/ext/commonmarker/cmark/build/src/Makefile +141 -66
- data/ext/commonmarker/cmark/build/src/cmake_install.cmake +4 -0
- data/ext/commonmarker/cmark/build/src/libcmark.a +0 -0
- data/ext/commonmarker/cmark/build/testdir/CTestTestfile.cmake +3 -1
- data/ext/commonmarker/cmark/build/testdir/Makefile +9 -9
- data/ext/commonmarker/cmark/extensions/CMakeLists.txt +82 -0
- data/ext/commonmarker/cmark/extensions/autolink.c +338 -0
- data/ext/commonmarker/cmark/extensions/autolink.h +8 -0
- data/ext/commonmarker/cmark/extensions/core-extensions.c +16 -0
- data/ext/commonmarker/cmark/extensions/core-extensions.h +16 -0
- data/ext/commonmarker/cmark/extensions/ext_scanners.c +585 -0
- data/ext/commonmarker/cmark/extensions/ext_scanners.h +20 -0
- data/ext/commonmarker/cmark/extensions/ext_scanners.re +65 -0
- data/ext/commonmarker/cmark/extensions/strikethrough.c +142 -0
- data/ext/commonmarker/cmark/extensions/strikethrough.h +9 -0
- data/ext/commonmarker/cmark/extensions/table.c +493 -0
- data/ext/commonmarker/cmark/extensions/table.h +8 -0
- data/ext/commonmarker/cmark/extensions/whitelist.c +59 -0
- data/ext/commonmarker/cmark/extensions/whitelist.h +8 -0
- data/ext/commonmarker/cmark/man/man3/cmark.3 +98 -34
- data/ext/commonmarker/cmark/src/CMakeLists.txt +16 -1
- data/ext/commonmarker/cmark/src/blocks.c +219 -40
- data/ext/commonmarker/cmark/src/buffer.h +36 -0
- data/ext/commonmarker/cmark/src/cmark.c +5 -1
- data/ext/commonmarker/cmark/src/cmark.h +91 -34
- data/ext/commonmarker/cmark/src/cmark_ctype.h +7 -0
- data/ext/commonmarker/cmark/src/cmark_extension_api.h +655 -0
- data/ext/commonmarker/cmark/src/commonmark.c +7 -2
- data/ext/commonmarker/cmark/src/houdini.h +12 -6
- data/ext/commonmarker/cmark/src/houdini_html_e.c +1 -1
- data/ext/commonmarker/cmark/src/html.c +102 -54
- data/ext/commonmarker/cmark/src/html.h +27 -0
- data/ext/commonmarker/cmark/src/inlines.c +261 -53
- data/ext/commonmarker/cmark/src/inlines.h +7 -2
- data/ext/commonmarker/cmark/src/iterator.c +12 -7
- data/ext/commonmarker/cmark/src/latex.c +5 -2
- data/ext/commonmarker/cmark/src/linked_list.c +37 -0
- data/ext/commonmarker/cmark/src/main.c +91 -27
- data/ext/commonmarker/cmark/src/man.c +18 -2
- data/ext/commonmarker/cmark/src/node.c +157 -58
- data/ext/commonmarker/cmark/src/node.h +23 -0
- data/ext/commonmarker/cmark/src/parser.h +19 -2
- data/ext/commonmarker/cmark/src/plugin.c +33 -0
- data/ext/commonmarker/cmark/src/plugin.h +34 -0
- data/ext/commonmarker/cmark/src/registry.c +60 -0
- data/ext/commonmarker/cmark/src/registry.h +24 -0
- data/ext/commonmarker/cmark/src/render.h +9 -0
- data/ext/commonmarker/cmark/src/scanners.c +265 -391
- data/ext/commonmarker/cmark/src/scanners.h +5 -0
- data/ext/commonmarker/cmark/src/scanners.re +2 -2
- data/ext/commonmarker/cmark/src/syntax_extension.c +110 -0
- data/ext/commonmarker/cmark/src/syntax_extension.h +27 -0
- data/ext/commonmarker/cmark/suppressions +28 -0
- data/ext/commonmarker/cmark/test/CMakeLists.txt +12 -1
- data/ext/commonmarker/cmark/test/extensions.txt +173 -0
- data/ext/commonmarker/cmark/test/regression.txt +24 -0
- data/ext/commonmarker/cmark/test/spec.txt +27 -26
- data/ext/commonmarker/cmark/toolchain-mingw32.cmake +1 -1
- data/ext/commonmarker/commonmarker.c +132 -15
- data/ext/commonmarker/commonmarker.h +4 -0
- data/ext/commonmarker/extconf.rb +12 -5
- data/lib/commonmarker.rb +8 -6
- data/lib/commonmarker/node.rb +13 -2
- data/lib/commonmarker/renderer.rb +1 -1
- data/lib/commonmarker/version.rb +1 -1
- data/test/test_commonmark.rb +34 -0
- data/test/test_encoding.rb +2 -1
- data/test/test_extensions.rb +50 -0
- data/test/test_helper.rb +2 -1
- 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
|
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
|
-
|
34
|
+
CMARK_EXPORT
|
35
|
+
bufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src,
|
35
36
|
bufsize_t size);
|
36
|
-
|
37
|
+
CMARK_EXPORT
|
38
|
+
int houdini_escape_html(cmark_strbuf *ob, const uint8_t *src,
|
37
39
|
bufsize_t size);
|
38
|
-
|
40
|
+
CMARK_EXPORT
|
41
|
+
int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src,
|
39
42
|
bufsize_t size, int secure);
|
40
|
-
|
43
|
+
CMARK_EXPORT
|
44
|
+
int houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src,
|
41
45
|
bufsize_t size);
|
42
|
-
|
46
|
+
CMARK_EXPORT
|
47
|
+
void houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src,
|
43
48
|
bufsize_t size);
|
44
|
-
|
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
|
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
|
-
#
|
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
|
23
|
-
|
24
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
if (match != data) {
|
33
|
+
cmark_strbuf_put(html, data, match - data);
|
34
|
+
len -= (match - data);
|
35
|
+
data = match;
|
36
|
+
}
|
31
37
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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, "<");
|
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(
|
44
|
-
|
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 =
|
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 (
|
56
|
-
|
76
|
+
if (renderer->plain == node) { // back at original node
|
77
|
+
renderer->plain = NULL;
|
57
78
|
}
|
58
79
|
|
59
|
-
if (
|
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
|
-
|
110
|
+
cmark_html_render_cr(html);
|
85
111
|
cmark_strbuf_puts(html, "<blockquote");
|
86
|
-
|
112
|
+
cmark_html_render_sourcepos(node, html, options);
|
87
113
|
cmark_strbuf_puts(html, ">\n");
|
88
114
|
} else {
|
89
|
-
|
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
|
-
|
125
|
+
cmark_html_render_cr(html);
|
100
126
|
if (list_type == CMARK_BULLET_LIST) {
|
101
127
|
cmark_strbuf_puts(html, "<ul");
|
102
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
149
|
+
cmark_html_render_cr(html);
|
124
150
|
cmark_strbuf_puts(html, "<li");
|
125
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
206
|
+
cmark_html_render_cr(html);
|
179
207
|
break;
|
180
208
|
|
181
209
|
case CMARK_NODE_CUSTOM_BLOCK:
|
182
|
-
|
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
|
-
|
218
|
+
cmark_html_render_cr(html);
|
191
219
|
break;
|
192
220
|
|
193
221
|
case CMARK_NODE_THEMATIC_BREAK:
|
194
|
-
|
222
|
+
cmark_html_render_cr(html);
|
195
223
|
cmark_strbuf_puts(html, "<hr");
|
196
|
-
|
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
|
-
|
238
|
+
cmark_html_render_cr(html);
|
211
239
|
cmark_strbuf_puts(html, "<p");
|
212
|
-
|
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
|
-
|
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, "<");
|
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
|
-
|
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
|
-
|
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,
|
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
|
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
|
-
|
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
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
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
|
-
|
1088
|
-
|
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
|
+
}
|