commonmarker 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/Rakefile +9 -9
- data/ext/commonmarker/cmark/api_test/main.c +5 -0
- data/ext/commonmarker/cmark/build/CMakeCache.txt +459 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CMakeCCompiler.cmake +67 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CMakeCXXCompiler.cmake +68 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CMakeDetermineCompilerABI_C.bin +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CMakeDetermineCompilerABI_CXX.bin +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CMakeSystem.cmake +15 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CompilerIdC/CMakeCCompilerId.c +544 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CompilerIdC/a.out +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CompilerIdCXX/CMakeCXXCompilerId.cpp +533 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CompilerIdCXX/a.out +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeError.log +14 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/CMakeOutput.log +562 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/Makefile.cmake +150 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/Makefile2 +295 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/TargetDirectories.txt +39 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/cmake.check_cache +1 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/feature_tests.bin +0 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/feature_tests.c +34 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/feature_tests.cxx +405 -0
- data/ext/commonmarker/cmark/build/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark/build/CTestTestfile.cmake +10 -0
- data/ext/commonmarker/cmark/build/Makefile +250 -0
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/DependInfo.cmake +35 -0
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/build.make +168 -0
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/cmake_clean.cmake +12 -0
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/depend.make +2 -0
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/flags.make +17 -0
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/link.txt +1 -0
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/progress.make +5 -0
- data/ext/commonmarker/cmark/build/api_test/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark/build/api_test/Makefile +300 -0
- data/ext/commonmarker/cmark/build/api_test/cmake_install.cmake +29 -0
- data/ext/commonmarker/cmark/build/cmake_install.cmake +48 -0
- data/ext/commonmarker/cmark/build/man/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark/build/man/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark/build/man/Makefile +194 -0
- data/ext/commonmarker/cmark/build/man/cmake_install.cmake +37 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/DependInfo.cmake +41 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/build.make +626 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/cmake_clean.cmake +29 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/depend.make +2 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/flags.make +10 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/link.txt +1 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/progress.make +22 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/DependInfo.cmake +46 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/build.make +603 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/cmake_clean.cmake +29 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/depend.make +2 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/flags.make +10 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/link.txt +1 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/progress.make +21 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/C.includecache +468 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/DependInfo.cmake +40 -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/buffer.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/build.make +600 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmake_clean.cmake +28 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmake_clean_target.cmake +3 -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/cmark_ctype.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 +211 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/depend.make +211 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/flags.make +10 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_href_e.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_e.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_u.c.o +0 -0
- 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 +2 -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/progress.make +21 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/references.c.o +0 -0
- data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/render.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/utf8.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 -0
- data/ext/commonmarker/cmark/build/src/Makefile +956 -0
- data/ext/commonmarker/cmark/build/src/cmake_install.cmake +77 -0
- data/ext/commonmarker/cmark/build/src/cmark_export.h +41 -0
- data/ext/commonmarker/cmark/build/src/cmark_version.h +7 -0
- data/ext/commonmarker/cmark/build/src/config.h +84 -0
- data/ext/commonmarker/cmark/build/src/libcmark.a +0 -0
- data/ext/commonmarker/cmark/build/src/libcmark.pc +10 -0
- data/ext/commonmarker/cmark/build/testdir/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
- data/ext/commonmarker/cmark/build/testdir/CMakeFiles/progress.marks +1 -0
- data/ext/commonmarker/cmark/build/testdir/CTestTestfile.cmake +14 -0
- data/ext/commonmarker/cmark/build/testdir/Makefile +194 -0
- data/ext/commonmarker/cmark/build/testdir/cmake_install.cmake +29 -0
- data/ext/commonmarker/cmark/man/man1/cmark.1 +11 -4
- data/ext/commonmarker/cmark/man/man3/cmark.3 +66 -11
- data/ext/commonmarker/cmark/src/blocks.c +232 -235
- data/ext/commonmarker/cmark/src/buffer.c +19 -56
- data/ext/commonmarker/cmark/src/buffer.h +7 -20
- data/ext/commonmarker/cmark/src/chunk.h +19 -19
- data/ext/commonmarker/cmark/src/cmark.c +14 -0
- data/ext/commonmarker/cmark/src/cmark.h +45 -6
- data/ext/commonmarker/cmark/src/cmark_ctype.c +2 -0
- data/ext/commonmarker/cmark/src/cmark_ctype.h +2 -0
- data/ext/commonmarker/cmark/src/commonmark.c +42 -29
- data/ext/commonmarker/cmark/src/config.h.in +8 -0
- data/ext/commonmarker/cmark/src/html.c +3 -1
- data/ext/commonmarker/cmark/src/inlines.c +111 -150
- data/ext/commonmarker/cmark/src/inlines.h +4 -4
- data/ext/commonmarker/cmark/src/iterator.c +6 -7
- data/ext/commonmarker/cmark/src/iterator.h +2 -0
- data/ext/commonmarker/cmark/src/latex.c +10 -8
- data/ext/commonmarker/cmark/src/main.c +6 -2
- data/ext/commonmarker/cmark/src/man.c +9 -5
- data/ext/commonmarker/cmark/src/node.c +38 -29
- data/ext/commonmarker/cmark/src/node.h +15 -11
- data/ext/commonmarker/cmark/src/parser.h +4 -2
- data/ext/commonmarker/cmark/src/references.c +23 -22
- data/ext/commonmarker/cmark/src/references.h +3 -1
- data/ext/commonmarker/cmark/src/render.c +9 -7
- data/ext/commonmarker/cmark/src/render.h +3 -1
- data/ext/commonmarker/cmark/src/scanners.c +30 -22
- data/ext/commonmarker/cmark/src/xml.c +1 -1
- data/ext/commonmarker/cmark/test/CMakeLists.txt +8 -8
- data/ext/commonmarker/cmark/test/cmark.py +34 -14
- data/ext/commonmarker/cmark/test/roundtrip_tests.py +47 -0
- data/ext/commonmarker/cmark/test/spec.txt +96 -6
- data/ext/commonmarker/cmark/test/spec_tests.py +5 -8
- data/ext/commonmarker/commonmarker.c +14 -8
- data/lib/commonmarker/config.rb +2 -2
- data/lib/commonmarker/renderer.rb +17 -7
- data/lib/commonmarker/renderer/html_renderer.rb +16 -21
- data/lib/commonmarker/version.rb +1 -1
- data/test/test_pathological_inputs.rb +11 -11
- metadata +99 -4
- data/ext/commonmarker/cmark/test/roundtrip.bat +0 -1
- data/ext/commonmarker/cmark/test/roundtrip.sh +0 -2
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
#include <stdio.h>
|
|
3
3
|
#include <string.h>
|
|
4
4
|
#include <assert.h>
|
|
5
|
-
#include <ctype.h>
|
|
6
5
|
|
|
7
6
|
#include "config.h"
|
|
8
7
|
#include "cmark.h"
|
|
@@ -12,7 +11,6 @@
|
|
|
12
11
|
#include "scanners.h"
|
|
13
12
|
#include "render.h"
|
|
14
13
|
|
|
15
|
-
#define safe_strlen(s) cmark_strbuf_safe_strlen(s)
|
|
16
14
|
#define OUT(s, wrap, escaping) renderer->out(renderer, s, wrap, escaping)
|
|
17
15
|
#define LIT(s) renderer->out(renderer, s, false, LITERAL)
|
|
18
16
|
#define CR() renderer->cr(renderer)
|
|
@@ -23,7 +21,7 @@
|
|
|
23
21
|
// Functions to convert cmark_nodes to commonmark strings.
|
|
24
22
|
|
|
25
23
|
static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
|
|
26
|
-
|
|
24
|
+
int32_t c, unsigned char nextc) {
|
|
27
25
|
bool needs_escaping = false;
|
|
28
26
|
bool follows_digit =
|
|
29
27
|
renderer->buffer->size > 0 &&
|
|
@@ -31,24 +29,26 @@ static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_escaping escape,
|
|
|
31
29
|
char encoded[ENCODED_SIZE];
|
|
32
30
|
|
|
33
31
|
needs_escaping =
|
|
32
|
+
c < 0x80 &&
|
|
34
33
|
escape != LITERAL &&
|
|
35
34
|
((escape == NORMAL &&
|
|
36
35
|
(c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
|
|
37
36
|
c == '>' || c == '\\' || c == '`' || c == '!' ||
|
|
38
|
-
(c == '&' &&
|
|
37
|
+
(c == '&' && cmark_isalpha(nextc)) || (c == '!' && nextc == '[') ||
|
|
39
38
|
(renderer->begin_content && (c == '-' || c == '+' || c == '=') &&
|
|
40
39
|
// begin_content doesn't get set to false til we've passed digits
|
|
41
40
|
// at the beginning of line, so...
|
|
42
41
|
!follows_digit) ||
|
|
43
42
|
(renderer->begin_content && (c == '.' || c == ')') && follows_digit &&
|
|
44
43
|
(nextc == 0 || cmark_isspace(nextc))))) ||
|
|
45
|
-
(escape == URL && (c == '`' || c == '<' || c == '>' ||
|
|
46
|
-
c
|
|
44
|
+
(escape == URL && (c == '`' || c == '<' || c == '>' ||
|
|
45
|
+
cmark_isspace(c) || c == '\\' || c == ')' ||
|
|
46
|
+
c == '(')) ||
|
|
47
47
|
(escape == TITLE &&
|
|
48
48
|
(c == '`' || c == '<' || c == '>' || c == '"' || c == '\\')));
|
|
49
49
|
|
|
50
50
|
if (needs_escaping) {
|
|
51
|
-
if (
|
|
51
|
+
if (cmark_isspace(c)) {
|
|
52
52
|
// use percent encoding for spaces
|
|
53
53
|
snprintf(encoded, ENCODED_SIZE, "%%%2x", c);
|
|
54
54
|
cmark_strbuf_puts(renderer->buffer, encoded);
|
|
@@ -66,7 +66,7 @@ static int longest_backtick_sequence(const char *code) {
|
|
|
66
66
|
int longest = 0;
|
|
67
67
|
int current = 0;
|
|
68
68
|
size_t i = 0;
|
|
69
|
-
size_t code_len =
|
|
69
|
+
size_t code_len = strlen(code);
|
|
70
70
|
while (i <= code_len) {
|
|
71
71
|
if (code[i] == '`') {
|
|
72
72
|
current++;
|
|
@@ -85,7 +85,7 @@ static int shortest_unused_backtick_sequence(const char *code) {
|
|
|
85
85
|
int32_t used = 1;
|
|
86
86
|
int current = 0;
|
|
87
87
|
size_t i = 0;
|
|
88
|
-
size_t code_len =
|
|
88
|
+
size_t code_len = strlen(code);
|
|
89
89
|
while (i <= code_len) {
|
|
90
90
|
if (code[i] == '`') {
|
|
91
91
|
current++;
|
|
@@ -171,7 +171,10 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
171
171
|
size_t info_len, code_len;
|
|
172
172
|
char listmarker[LISTMARKER_SIZE];
|
|
173
173
|
char *emph_delim;
|
|
174
|
+
bool first_in_list_item;
|
|
174
175
|
bufsize_t marker_width;
|
|
176
|
+
bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) &&
|
|
177
|
+
!(CMARK_OPT_HARDBREAKS & options);
|
|
175
178
|
|
|
176
179
|
// Don't adjust tight list status til we've started the list.
|
|
177
180
|
// Otherwise we loose the blank line between a paragraph and
|
|
@@ -204,7 +207,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
204
207
|
case CMARK_NODE_LIST:
|
|
205
208
|
if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||
|
|
206
209
|
node->next->type == CMARK_NODE_LIST)) {
|
|
207
|
-
// this ensures that a following code block or list will be
|
|
210
|
+
// this ensures that a following indented code block or list will be
|
|
208
211
|
// inteprereted correctly.
|
|
209
212
|
CR();
|
|
210
213
|
LIT("<!-- end list -->");
|
|
@@ -229,7 +232,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
229
232
|
snprintf(listmarker, LISTMARKER_SIZE, "%d%s%s", list_number,
|
|
230
233
|
list_delim == CMARK_PAREN_DELIM ? ")" : ".",
|
|
231
234
|
list_number < 10 ? " " : " ");
|
|
232
|
-
marker_width =
|
|
235
|
+
marker_width = strlen(listmarker);
|
|
233
236
|
}
|
|
234
237
|
if (entering) {
|
|
235
238
|
if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
|
|
@@ -256,27 +259,31 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
256
259
|
}
|
|
257
260
|
LIT(" ");
|
|
258
261
|
renderer->begin_content = true;
|
|
259
|
-
renderer->
|
|
262
|
+
renderer->no_linebreaks = true;
|
|
260
263
|
} else {
|
|
261
|
-
renderer->
|
|
264
|
+
renderer->no_linebreaks = false;
|
|
262
265
|
BLANKLINE();
|
|
263
266
|
}
|
|
264
267
|
break;
|
|
265
268
|
|
|
266
269
|
case CMARK_NODE_CODE_BLOCK:
|
|
267
|
-
|
|
270
|
+
first_in_list_item = node->prev == NULL && node->parent &&
|
|
271
|
+
node->parent->type == CMARK_NODE_ITEM;
|
|
272
|
+
|
|
273
|
+
if (!first_in_list_item) {
|
|
274
|
+
BLANKLINE();
|
|
275
|
+
}
|
|
268
276
|
info = cmark_node_get_fence_info(node);
|
|
269
|
-
info_len =
|
|
277
|
+
info_len = strlen(info);
|
|
270
278
|
code = cmark_node_get_literal(node);
|
|
271
|
-
code_len =
|
|
279
|
+
code_len = strlen(code);
|
|
272
280
|
// use indented form if no info, and code doesn't
|
|
273
281
|
// begin or end with a blank line, and code isn't
|
|
274
282
|
// first thing in a list item
|
|
275
|
-
if (info_len == 0 &&
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
!
|
|
279
|
-
node->parent->type == CMARK_NODE_ITEM)) {
|
|
283
|
+
if (info_len == 0 && (code_len > 2 && !cmark_isspace(code[0]) &&
|
|
284
|
+
!(cmark_isspace(code[code_len - 1]) &&
|
|
285
|
+
cmark_isspace(code[code_len - 2]))) &&
|
|
286
|
+
!first_in_list_item) {
|
|
280
287
|
LIT(" ");
|
|
281
288
|
cmark_strbuf_puts(renderer->prefix, " ");
|
|
282
289
|
OUT(cmark_node_get_literal(node), false, LITERAL);
|
|
@@ -327,7 +334,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
327
334
|
break;
|
|
328
335
|
|
|
329
336
|
case CMARK_NODE_TEXT:
|
|
330
|
-
OUT(cmark_node_get_literal(node),
|
|
337
|
+
OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
|
|
331
338
|
break;
|
|
332
339
|
|
|
333
340
|
case CMARK_NODE_LINEBREAK:
|
|
@@ -338,16 +345,22 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
338
345
|
break;
|
|
339
346
|
|
|
340
347
|
case CMARK_NODE_SOFTBREAK:
|
|
341
|
-
if (
|
|
348
|
+
if (CMARK_OPT_HARDBREAKS & options) {
|
|
349
|
+
LIT(" ");
|
|
350
|
+
CR();
|
|
351
|
+
} else if (!renderer->no_linebreaks &&
|
|
352
|
+
renderer->width == 0 &&
|
|
353
|
+
!(CMARK_OPT_HARDBREAKS & options) &&
|
|
354
|
+
!(CMARK_OPT_NOBREAKS & options)) {
|
|
342
355
|
CR();
|
|
343
356
|
} else {
|
|
344
|
-
OUT(" ",
|
|
357
|
+
OUT(" ", allow_wrap, LITERAL);
|
|
345
358
|
}
|
|
346
359
|
break;
|
|
347
360
|
|
|
348
361
|
case CMARK_NODE_CODE:
|
|
349
362
|
code = cmark_node_get_literal(node);
|
|
350
|
-
code_len =
|
|
363
|
+
code_len = strlen(code);
|
|
351
364
|
numticks = shortest_unused_backtick_sequence(code);
|
|
352
365
|
for (i = 0; i < numticks; i++) {
|
|
353
366
|
LIT("`");
|
|
@@ -355,7 +368,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
355
368
|
if (code_len == 0 || code[0] == '`') {
|
|
356
369
|
LIT(" ");
|
|
357
370
|
}
|
|
358
|
-
OUT(cmark_node_get_literal(node),
|
|
371
|
+
OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);
|
|
359
372
|
if (code_len == 0 || code[code_len - 1] == '`') {
|
|
360
373
|
LIT(" ");
|
|
361
374
|
}
|
|
@@ -417,7 +430,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
417
430
|
LIT("](");
|
|
418
431
|
OUT(cmark_node_get_url(node), false, URL);
|
|
419
432
|
title = cmark_node_get_title(node);
|
|
420
|
-
if (
|
|
433
|
+
if (strlen(title) > 0) {
|
|
421
434
|
LIT(" \"");
|
|
422
435
|
OUT(title, false, TITLE);
|
|
423
436
|
LIT("\"");
|
|
@@ -434,8 +447,8 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
434
447
|
LIT("](");
|
|
435
448
|
OUT(cmark_node_get_url(node), false, URL);
|
|
436
449
|
title = cmark_node_get_title(node);
|
|
437
|
-
if (
|
|
438
|
-
OUT(" \"",
|
|
450
|
+
if (strlen(title) > 0) {
|
|
451
|
+
OUT(" \"", allow_wrap, LITERAL);
|
|
439
452
|
OUT(title, false, TITLE);
|
|
440
453
|
LIT("\"");
|
|
441
454
|
}
|
|
@@ -69,6 +69,14 @@ CMARK_INLINE int c99_snprintf(char *outBuf, size_t size, const char *format, ...
|
|
|
69
69
|
|
|
70
70
|
#endif
|
|
71
71
|
|
|
72
|
+
#ifdef _WIN32
|
|
73
|
+
# include <BaseTsd.h>
|
|
74
|
+
typedef SSIZE_T ssize_t;
|
|
75
|
+
typedef SIZE_T size_t;
|
|
76
|
+
#else
|
|
77
|
+
# include <sys/types.h>
|
|
78
|
+
#endif
|
|
79
|
+
|
|
72
80
|
#ifdef __cplusplus
|
|
73
81
|
}
|
|
74
82
|
#endif
|
|
@@ -228,6 +228,8 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
|
|
|
228
228
|
case CMARK_NODE_SOFTBREAK:
|
|
229
229
|
if (options & CMARK_OPT_HARDBREAKS) {
|
|
230
230
|
cmark_strbuf_puts(html, "<br />\n");
|
|
231
|
+
} else if (options & CMARK_OPT_NOBREAKS) {
|
|
232
|
+
cmark_strbuf_putc(html, ' ');
|
|
231
233
|
} else {
|
|
232
234
|
cmark_strbuf_putc(html, '\n');
|
|
233
235
|
}
|
|
@@ -322,7 +324,7 @@ static int S_render_node(cmark_node *node, cmark_event_type ev_type,
|
|
|
322
324
|
|
|
323
325
|
char *cmark_render_html(cmark_node *root, int options) {
|
|
324
326
|
char *result;
|
|
325
|
-
cmark_strbuf html =
|
|
327
|
+
cmark_strbuf html = CMARK_BUF_INIT(cmark_node_mem(root));
|
|
326
328
|
cmark_event_type ev_type;
|
|
327
329
|
cmark_node *cur;
|
|
328
330
|
struct render_state state = {&html, NULL};
|
|
@@ -22,13 +22,13 @@ static const char *LEFTSINGLEQUOTE = "\xE2\x80\x98";
|
|
|
22
22
|
static const char *RIGHTSINGLEQUOTE = "\xE2\x80\x99";
|
|
23
23
|
|
|
24
24
|
// Macros for creating various kinds of simple.
|
|
25
|
-
#define make_str(s) make_literal(CMARK_NODE_TEXT, s)
|
|
26
|
-
#define make_code(s) make_literal(CMARK_NODE_CODE, s)
|
|
27
|
-
#define make_raw_html(s) make_literal(CMARK_NODE_HTML_INLINE, s)
|
|
28
|
-
#define make_linebreak() make_simple(CMARK_NODE_LINEBREAK)
|
|
29
|
-
#define make_softbreak() make_simple(CMARK_NODE_SOFTBREAK)
|
|
30
|
-
#define make_emph() make_simple(CMARK_NODE_EMPH)
|
|
31
|
-
#define make_strong() make_simple(CMARK_NODE_STRONG)
|
|
25
|
+
#define make_str(mem, s) make_literal(mem, CMARK_NODE_TEXT, s)
|
|
26
|
+
#define make_code(mem, s) make_literal(mem, CMARK_NODE_CODE, s)
|
|
27
|
+
#define make_raw_html(mem, s) make_literal(mem, CMARK_NODE_HTML_INLINE, s)
|
|
28
|
+
#define make_linebreak(mem) make_simple(mem, CMARK_NODE_LINEBREAK)
|
|
29
|
+
#define make_softbreak(mem) make_simple(mem, CMARK_NODE_SOFTBREAK)
|
|
30
|
+
#define make_emph(mem) make_simple(mem, CMARK_NODE_EMPH)
|
|
31
|
+
#define make_strong(mem) make_simple(mem, CMARK_NODE_STRONG)
|
|
32
32
|
|
|
33
33
|
typedef struct delimiter {
|
|
34
34
|
struct delimiter *previous;
|
|
@@ -42,6 +42,7 @@ typedef struct delimiter {
|
|
|
42
42
|
} delimiter;
|
|
43
43
|
|
|
44
44
|
typedef struct {
|
|
45
|
+
cmark_mem *mem;
|
|
45
46
|
cmark_chunk input;
|
|
46
47
|
bufsize_t pos;
|
|
47
48
|
cmark_reference_map *refmap;
|
|
@@ -57,66 +58,46 @@ static delimiter *S_insert_emph(subject *subj, delimiter *opener,
|
|
|
57
58
|
|
|
58
59
|
static int parse_inline(subject *subj, cmark_node *parent, int options);
|
|
59
60
|
|
|
60
|
-
static void subject_from_buf(subject *e, cmark_strbuf *buffer,
|
|
61
|
+
static void subject_from_buf(cmark_mem *mem, subject *e, cmark_strbuf *buffer,
|
|
61
62
|
cmark_reference_map *refmap);
|
|
62
63
|
static bufsize_t subject_find_special_char(subject *subj, int options);
|
|
63
64
|
|
|
64
65
|
// Create an inline with a literal string value.
|
|
65
|
-
static CMARK_INLINE cmark_node *make_literal(cmark_node_type t, cmark_chunk s) {
|
|
66
|
-
cmark_node *e = (cmark_node *)calloc(1, sizeof(*e));
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
e->next = NULL;
|
|
71
|
-
e->prev = NULL;
|
|
72
|
-
e->parent = NULL;
|
|
73
|
-
e->first_child = NULL;
|
|
74
|
-
e->last_child = NULL;
|
|
75
|
-
// These fields aren't used for inlines:
|
|
76
|
-
e->start_line = 0;
|
|
77
|
-
e->start_column = 0;
|
|
78
|
-
e->end_line = 0;
|
|
79
|
-
}
|
|
66
|
+
static CMARK_INLINE cmark_node *make_literal(cmark_mem *mem, cmark_node_type t, cmark_chunk s) {
|
|
67
|
+
cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e));
|
|
68
|
+
cmark_strbuf_init(mem, &e->content, 0);
|
|
69
|
+
e->type = t;
|
|
70
|
+
e->as.literal = s;
|
|
80
71
|
return e;
|
|
81
72
|
}
|
|
82
73
|
|
|
83
74
|
// Create an inline with no value.
|
|
84
|
-
static CMARK_INLINE cmark_node *make_simple(cmark_node_type t) {
|
|
85
|
-
cmark_node *e = (cmark_node *)calloc(1, sizeof(*e));
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
e->next = NULL;
|
|
89
|
-
e->prev = NULL;
|
|
90
|
-
e->parent = NULL;
|
|
91
|
-
e->first_child = NULL;
|
|
92
|
-
e->last_child = NULL;
|
|
93
|
-
// These fields aren't used for inlines:
|
|
94
|
-
e->start_line = 0;
|
|
95
|
-
e->start_column = 0;
|
|
96
|
-
e->end_line = 0;
|
|
97
|
-
}
|
|
75
|
+
static CMARK_INLINE cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) {
|
|
76
|
+
cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e));
|
|
77
|
+
cmark_strbuf_init(mem, &e->content, 0);
|
|
78
|
+
e->type = t;
|
|
98
79
|
return e;
|
|
99
80
|
}
|
|
100
81
|
|
|
101
82
|
// Like make_str, but parses entities.
|
|
102
|
-
static cmark_node *make_str_with_entities(cmark_chunk *content) {
|
|
103
|
-
cmark_strbuf unescaped =
|
|
83
|
+
static cmark_node *make_str_with_entities(cmark_mem *mem, cmark_chunk *content) {
|
|
84
|
+
cmark_strbuf unescaped = CMARK_BUF_INIT(mem);
|
|
104
85
|
|
|
105
86
|
if (houdini_unescape_html(&unescaped, content->data, content->len)) {
|
|
106
|
-
return make_str(cmark_chunk_buf_detach(&unescaped));
|
|
87
|
+
return make_str(mem, cmark_chunk_buf_detach(&unescaped));
|
|
107
88
|
} else {
|
|
108
|
-
return make_str(*content);
|
|
89
|
+
return make_str(mem, *content);
|
|
109
90
|
}
|
|
110
91
|
}
|
|
111
92
|
|
|
112
93
|
// Duplicate a chunk by creating a copy of the buffer not by reusing the
|
|
113
94
|
// buffer like cmark_chunk_dup does.
|
|
114
|
-
static cmark_chunk chunk_clone(cmark_chunk *src) {
|
|
95
|
+
static cmark_chunk chunk_clone(cmark_mem *mem, cmark_chunk *src) {
|
|
115
96
|
cmark_chunk c;
|
|
116
97
|
bufsize_t len = src->len;
|
|
117
98
|
|
|
118
99
|
c.len = len;
|
|
119
|
-
c.data = (unsigned char *)
|
|
100
|
+
c.data = (unsigned char *)mem->calloc(len + 1, 1);
|
|
120
101
|
c.alloc = 1;
|
|
121
102
|
memcpy(c.data, src->data, len);
|
|
122
103
|
c.data[len] = '\0';
|
|
@@ -124,8 +105,8 @@ static cmark_chunk chunk_clone(cmark_chunk *src) {
|
|
|
124
105
|
return c;
|
|
125
106
|
}
|
|
126
107
|
|
|
127
|
-
static cmark_chunk cmark_clean_autolink(cmark_chunk *url, int is_email) {
|
|
128
|
-
cmark_strbuf buf =
|
|
108
|
+
static cmark_chunk cmark_clean_autolink(cmark_mem *mem, cmark_chunk *url, int is_email) {
|
|
109
|
+
cmark_strbuf buf = CMARK_BUF_INIT(mem);
|
|
129
110
|
|
|
130
111
|
cmark_chunk_trim(url);
|
|
131
112
|
|
|
@@ -141,16 +122,17 @@ static cmark_chunk cmark_clean_autolink(cmark_chunk *url, int is_email) {
|
|
|
141
122
|
return cmark_chunk_buf_detach(&buf);
|
|
142
123
|
}
|
|
143
124
|
|
|
144
|
-
static CMARK_INLINE cmark_node *make_autolink(cmark_chunk url, int is_email) {
|
|
145
|
-
cmark_node *link = make_simple(CMARK_NODE_LINK);
|
|
146
|
-
link->as.link.url = cmark_clean_autolink(&url, is_email);
|
|
125
|
+
static CMARK_INLINE cmark_node *make_autolink(cmark_mem *mem, cmark_chunk url, int is_email) {
|
|
126
|
+
cmark_node *link = make_simple(mem, CMARK_NODE_LINK);
|
|
127
|
+
link->as.link.url = cmark_clean_autolink(mem, &url, is_email);
|
|
147
128
|
link->as.link.title = cmark_chunk_literal("");
|
|
148
|
-
cmark_node_append_child(link, make_str_with_entities(&url));
|
|
129
|
+
cmark_node_append_child(link, make_str_with_entities(mem, &url));
|
|
149
130
|
return link;
|
|
150
131
|
}
|
|
151
132
|
|
|
152
|
-
static void subject_from_buf(subject *e, cmark_strbuf *buffer,
|
|
133
|
+
static void subject_from_buf(cmark_mem *mem, subject *e, cmark_strbuf *buffer,
|
|
153
134
|
cmark_reference_map *refmap) {
|
|
135
|
+
e->mem = mem;
|
|
154
136
|
e->input.data = buffer->ptr;
|
|
155
137
|
e->input.len = buffer->size;
|
|
156
138
|
e->input.alloc = 0;
|
|
@@ -251,16 +233,16 @@ static cmark_node *handle_backticks(subject *subj) {
|
|
|
251
233
|
|
|
252
234
|
if (endpos == 0) { // not found
|
|
253
235
|
subj->pos = startpos; // rewind
|
|
254
|
-
return make_str(openticks);
|
|
236
|
+
return make_str(subj->mem, openticks);
|
|
255
237
|
} else {
|
|
256
|
-
cmark_strbuf buf =
|
|
238
|
+
cmark_strbuf buf = CMARK_BUF_INIT(subj->mem);
|
|
257
239
|
|
|
258
240
|
cmark_strbuf_set(&buf, subj->input.data + startpos,
|
|
259
241
|
endpos - startpos - openticks.len);
|
|
260
242
|
cmark_strbuf_trim(&buf);
|
|
261
243
|
cmark_strbuf_normalize_whitespace(&buf);
|
|
262
244
|
|
|
263
|
-
return make_code(cmark_chunk_buf_detach(&buf));
|
|
245
|
+
return make_code(subj->mem, cmark_chunk_buf_detach(&buf));
|
|
264
246
|
}
|
|
265
247
|
}
|
|
266
248
|
|
|
@@ -362,10 +344,7 @@ static void remove_delimiter(subject *subj, delimiter *delim) {
|
|
|
362
344
|
|
|
363
345
|
static void push_delimiter(subject *subj, unsigned char c, bool can_open,
|
|
364
346
|
bool can_close, cmark_node *inl_text) {
|
|
365
|
-
delimiter *delim = (delimiter *)
|
|
366
|
-
if (delim == NULL) {
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
347
|
+
delimiter *delim = (delimiter *)subj->mem->calloc(1, sizeof(delimiter));
|
|
369
348
|
delim->delim_char = c;
|
|
370
349
|
delim->can_open = can_open;
|
|
371
350
|
delim->can_close = can_close;
|
|
@@ -398,7 +377,7 @@ static cmark_node *handle_delim(subject *subj, unsigned char c, bool smart) {
|
|
|
398
377
|
contents = cmark_chunk_dup(&subj->input, subj->pos - numdelims, numdelims);
|
|
399
378
|
}
|
|
400
379
|
|
|
401
|
-
inl_text = make_str(contents);
|
|
380
|
+
inl_text = make_str(subj->mem, contents);
|
|
402
381
|
|
|
403
382
|
if ((can_open || can_close) && (!(c == '\'' || c == '"') || smart)) {
|
|
404
383
|
push_delimiter(subj, c, can_open, can_close, inl_text);
|
|
@@ -414,7 +393,7 @@ static cmark_node *handle_hyphen(subject *subj, bool smart) {
|
|
|
414
393
|
advance(subj);
|
|
415
394
|
|
|
416
395
|
if (!smart || peek_char(subj) != '-') {
|
|
417
|
-
return make_str(cmark_chunk_literal("-"));
|
|
396
|
+
return make_str(subj->mem, cmark_chunk_literal("-"));
|
|
418
397
|
}
|
|
419
398
|
|
|
420
399
|
while (smart && peek_char(subj) == '-') {
|
|
@@ -425,7 +404,7 @@ static cmark_node *handle_hyphen(subject *subj, bool smart) {
|
|
|
425
404
|
int en_count = 0;
|
|
426
405
|
int em_count = 0;
|
|
427
406
|
int i;
|
|
428
|
-
cmark_strbuf buf =
|
|
407
|
+
cmark_strbuf buf = CMARK_BUF_INIT(subj->mem);
|
|
429
408
|
|
|
430
409
|
if (numhyphens % 3 == 0) { // if divisible by 3, use all em dashes
|
|
431
410
|
em_count = numhyphens / 3;
|
|
@@ -447,7 +426,7 @@ static cmark_node *handle_hyphen(subject *subj, bool smart) {
|
|
|
447
426
|
cmark_strbuf_puts(&buf, ENDASH);
|
|
448
427
|
}
|
|
449
428
|
|
|
450
|
-
return make_str(cmark_chunk_buf_detach(&buf));
|
|
429
|
+
return make_str(subj->mem, cmark_chunk_buf_detach(&buf));
|
|
451
430
|
}
|
|
452
431
|
|
|
453
432
|
// Assumes we have a period at the current position.
|
|
@@ -457,12 +436,12 @@ static cmark_node *handle_period(subject *subj, bool smart) {
|
|
|
457
436
|
advance(subj);
|
|
458
437
|
if (peek_char(subj) == '.') {
|
|
459
438
|
advance(subj);
|
|
460
|
-
return make_str(cmark_chunk_literal(ELLIPSES));
|
|
439
|
+
return make_str(subj->mem, cmark_chunk_literal(ELLIPSES));
|
|
461
440
|
} else {
|
|
462
|
-
return make_str(cmark_chunk_literal(".."));
|
|
441
|
+
return make_str(subj->mem, cmark_chunk_literal(".."));
|
|
463
442
|
}
|
|
464
443
|
} else {
|
|
465
|
-
return make_str(cmark_chunk_literal("."));
|
|
444
|
+
return make_str(subj->mem, cmark_chunk_literal("."));
|
|
466
445
|
}
|
|
467
446
|
}
|
|
468
447
|
|
|
@@ -508,18 +487,18 @@ static void process_emphasis(subject *subj, delimiter *stack_bottom) {
|
|
|
508
487
|
closer = closer->next;
|
|
509
488
|
}
|
|
510
489
|
} else if (closer->delim_char == '\'') {
|
|
511
|
-
cmark_chunk_free(&closer->inl_text->as.literal);
|
|
490
|
+
cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
|
|
512
491
|
closer->inl_text->as.literal = cmark_chunk_literal(RIGHTSINGLEQUOTE);
|
|
513
492
|
if (opener_found) {
|
|
514
|
-
cmark_chunk_free(&opener->inl_text->as.literal);
|
|
493
|
+
cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
|
|
515
494
|
opener->inl_text->as.literal = cmark_chunk_literal(LEFTSINGLEQUOTE);
|
|
516
495
|
}
|
|
517
496
|
closer = closer->next;
|
|
518
497
|
} else if (closer->delim_char == '"') {
|
|
519
|
-
cmark_chunk_free(&closer->inl_text->as.literal);
|
|
498
|
+
cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);
|
|
520
499
|
closer->inl_text->as.literal = cmark_chunk_literal(RIGHTDOUBLEQUOTE);
|
|
521
500
|
if (opener_found) {
|
|
522
|
-
cmark_chunk_free(&opener->inl_text->as.literal);
|
|
501
|
+
cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);
|
|
523
502
|
opener->inl_text->as.literal = cmark_chunk_literal(LEFTDOUBLEQUOTE);
|
|
524
503
|
}
|
|
525
504
|
closer = closer->next;
|
|
@@ -552,7 +531,7 @@ static delimiter *S_insert_emph(subject *subj, delimiter *opener,
|
|
|
552
531
|
cmark_node *closer_inl = closer->inl_text;
|
|
553
532
|
bufsize_t opener_num_chars = opener_inl->as.literal.len;
|
|
554
533
|
bufsize_t closer_num_chars = closer_inl->as.literal.len;
|
|
555
|
-
cmark_node *tmp, *
|
|
534
|
+
cmark_node *tmp, *tmpnext, *emph;
|
|
556
535
|
|
|
557
536
|
// calculate the actual number of characters used from this closer
|
|
558
537
|
if (closer_num_chars < 3 || opener_num_chars < 3) {
|
|
@@ -576,37 +555,22 @@ static delimiter *S_insert_emph(subject *subj, delimiter *opener,
|
|
|
576
555
|
delim = tmp_delim;
|
|
577
556
|
}
|
|
578
557
|
|
|
579
|
-
|
|
580
|
-
|
|
558
|
+
// create new emph or strong, and splice it in to our inlines
|
|
559
|
+
// between the opener and closer
|
|
560
|
+
emph = use_delims == 1 ? make_emph(subj->mem) : make_strong(subj->mem);
|
|
561
|
+
|
|
562
|
+
tmp = opener_inl->next;
|
|
563
|
+
while (tmp && tmp != closer_inl) {
|
|
564
|
+
tmpnext = tmp->next;
|
|
565
|
+
cmark_node_append_child(emph, tmp);
|
|
566
|
+
tmp = tmpnext;
|
|
567
|
+
}
|
|
568
|
+
cmark_node_insert_after(opener_inl, emph);
|
|
581
569
|
|
|
582
570
|
// if opener has 0 characters, remove it and its associated inline
|
|
583
571
|
if (opener_num_chars == 0) {
|
|
584
|
-
|
|
585
|
-
cmark_chunk_free(&(opener_inl->as.literal));
|
|
586
|
-
emph = opener_inl;
|
|
587
|
-
emph->type = use_delims == 1 ? CMARK_NODE_EMPH : CMARK_NODE_STRONG;
|
|
588
|
-
// remove opener from list
|
|
572
|
+
cmark_node_free(opener_inl);
|
|
589
573
|
remove_delimiter(subj, opener);
|
|
590
|
-
} else {
|
|
591
|
-
// create new emph or strong, and splice it in to our inlines
|
|
592
|
-
// between the opener and closer
|
|
593
|
-
emph = use_delims == 1 ? make_emph() : make_strong();
|
|
594
|
-
emph->parent = opener_inl->parent;
|
|
595
|
-
emph->prev = opener_inl;
|
|
596
|
-
opener_inl->next = emph;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
// push children below emph
|
|
600
|
-
emph->next = closer_inl;
|
|
601
|
-
closer_inl->prev = emph;
|
|
602
|
-
emph->first_child = first_child;
|
|
603
|
-
emph->last_child = last_child;
|
|
604
|
-
|
|
605
|
-
// fix children pointers
|
|
606
|
-
first_child->prev = NULL;
|
|
607
|
-
last_child->next = NULL;
|
|
608
|
-
for (tmp = first_child; tmp != NULL; tmp = tmp->next) {
|
|
609
|
-
tmp->parent = emph;
|
|
610
574
|
}
|
|
611
575
|
|
|
612
576
|
// if closer has 0 characters, remove it and its associated inline
|
|
@@ -629,18 +593,18 @@ static cmark_node *handle_backslash(subject *subj) {
|
|
|
629
593
|
if (cmark_ispunct(
|
|
630
594
|
nextchar)) { // only ascii symbols and newline can be escaped
|
|
631
595
|
advance(subj);
|
|
632
|
-
return make_str(cmark_chunk_dup(&subj->input, subj->pos - 1, 1));
|
|
596
|
+
return make_str(subj->mem, cmark_chunk_dup(&subj->input, subj->pos - 1, 1));
|
|
633
597
|
} else if (!is_eof(subj) && skip_line_end(subj)) {
|
|
634
|
-
return make_linebreak();
|
|
598
|
+
return make_linebreak(subj->mem);
|
|
635
599
|
} else {
|
|
636
|
-
return make_str(cmark_chunk_literal("\\"));
|
|
600
|
+
return make_str(subj->mem, cmark_chunk_literal("\\"));
|
|
637
601
|
}
|
|
638
602
|
}
|
|
639
603
|
|
|
640
604
|
// Parse an entity or a regular "&" string.
|
|
641
605
|
// Assumes the subject has an '&' character at the current position.
|
|
642
606
|
static cmark_node *handle_entity(subject *subj) {
|
|
643
|
-
cmark_strbuf ent =
|
|
607
|
+
cmark_strbuf ent = CMARK_BUF_INIT(subj->mem);
|
|
644
608
|
bufsize_t len;
|
|
645
609
|
|
|
646
610
|
advance(subj);
|
|
@@ -649,16 +613,16 @@ static cmark_node *handle_entity(subject *subj) {
|
|
|
649
613
|
subj->input.len - subj->pos);
|
|
650
614
|
|
|
651
615
|
if (len == 0)
|
|
652
|
-
return make_str(cmark_chunk_literal("&"));
|
|
616
|
+
return make_str(subj->mem, cmark_chunk_literal("&"));
|
|
653
617
|
|
|
654
618
|
subj->pos += len;
|
|
655
|
-
return make_str(cmark_chunk_buf_detach(&ent));
|
|
619
|
+
return make_str(subj->mem, cmark_chunk_buf_detach(&ent));
|
|
656
620
|
}
|
|
657
621
|
|
|
658
622
|
// Clean a URL: remove surrounding whitespace and surrounding <>,
|
|
659
623
|
// and remove \ that escape punctuation.
|
|
660
|
-
cmark_chunk cmark_clean_url(cmark_chunk *url) {
|
|
661
|
-
cmark_strbuf buf =
|
|
624
|
+
cmark_chunk cmark_clean_url(cmark_mem *mem, cmark_chunk *url) {
|
|
625
|
+
cmark_strbuf buf = CMARK_BUF_INIT(mem);
|
|
662
626
|
|
|
663
627
|
cmark_chunk_trim(url);
|
|
664
628
|
|
|
@@ -677,8 +641,8 @@ cmark_chunk cmark_clean_url(cmark_chunk *url) {
|
|
|
677
641
|
return cmark_chunk_buf_detach(&buf);
|
|
678
642
|
}
|
|
679
643
|
|
|
680
|
-
cmark_chunk cmark_clean_title(cmark_chunk *title) {
|
|
681
|
-
cmark_strbuf buf =
|
|
644
|
+
cmark_chunk cmark_clean_title(cmark_mem *mem, cmark_chunk *title) {
|
|
645
|
+
cmark_strbuf buf = CMARK_BUF_INIT(mem);
|
|
682
646
|
unsigned char first, last;
|
|
683
647
|
|
|
684
648
|
if (title->len == 0) {
|
|
@@ -715,7 +679,7 @@ static cmark_node *handle_pointy_brace(subject *subj) {
|
|
|
715
679
|
contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);
|
|
716
680
|
subj->pos += matchlen;
|
|
717
681
|
|
|
718
|
-
return make_autolink(contents, 0);
|
|
682
|
+
return make_autolink(subj->mem, contents, 0);
|
|
719
683
|
}
|
|
720
684
|
|
|
721
685
|
// next try to match an email autolink
|
|
@@ -724,7 +688,7 @@ static cmark_node *handle_pointy_brace(subject *subj) {
|
|
|
724
688
|
contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);
|
|
725
689
|
subj->pos += matchlen;
|
|
726
690
|
|
|
727
|
-
return make_autolink(contents, 1);
|
|
691
|
+
return make_autolink(subj->mem, contents, 1);
|
|
728
692
|
}
|
|
729
693
|
|
|
730
694
|
// finally, try to match an html tag
|
|
@@ -732,11 +696,11 @@ static cmark_node *handle_pointy_brace(subject *subj) {
|
|
|
732
696
|
if (matchlen > 0) {
|
|
733
697
|
contents = cmark_chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);
|
|
734
698
|
subj->pos += matchlen;
|
|
735
|
-
return make_raw_html(contents);
|
|
699
|
+
return make_raw_html(subj->mem, contents);
|
|
736
700
|
}
|
|
737
701
|
|
|
738
702
|
// if nothing matches, just return the opening <:
|
|
739
|
-
return make_str(cmark_chunk_literal("<"));
|
|
703
|
+
return make_str(subj->mem, cmark_chunk_literal("<"));
|
|
740
704
|
}
|
|
741
705
|
|
|
742
706
|
// Parse a link label. Returns 1 if successful.
|
|
@@ -786,7 +750,7 @@ noMatch:
|
|
|
786
750
|
}
|
|
787
751
|
|
|
788
752
|
// Return a link, an image, or a literal close bracket.
|
|
789
|
-
static cmark_node *handle_close_bracket(subject *subj
|
|
753
|
+
static cmark_node *handle_close_bracket(subject *subj) {
|
|
790
754
|
bufsize_t initial_pos;
|
|
791
755
|
bufsize_t starturl, endurl, starttitle, endtitle, endall;
|
|
792
756
|
bufsize_t n;
|
|
@@ -796,10 +760,10 @@ static cmark_node *handle_close_bracket(subject *subj, cmark_node *parent) {
|
|
|
796
760
|
cmark_chunk url_chunk, title_chunk;
|
|
797
761
|
cmark_chunk url, title;
|
|
798
762
|
delimiter *opener;
|
|
799
|
-
cmark_node *link_text;
|
|
800
763
|
cmark_node *inl;
|
|
801
764
|
cmark_chunk raw_label;
|
|
802
765
|
int found_label;
|
|
766
|
+
cmark_node *tmp, *tmpnext;
|
|
803
767
|
|
|
804
768
|
advance(subj); // advance past ]
|
|
805
769
|
initial_pos = subj->pos;
|
|
@@ -814,18 +778,17 @@ static cmark_node *handle_close_bracket(subject *subj, cmark_node *parent) {
|
|
|
814
778
|
}
|
|
815
779
|
|
|
816
780
|
if (opener == NULL) {
|
|
817
|
-
return make_str(cmark_chunk_literal("]"));
|
|
781
|
+
return make_str(subj->mem, cmark_chunk_literal("]"));
|
|
818
782
|
}
|
|
819
783
|
|
|
820
784
|
if (!opener->active) {
|
|
821
785
|
// take delimiter off stack
|
|
822
786
|
remove_delimiter(subj, opener);
|
|
823
|
-
return make_str(cmark_chunk_literal("]"));
|
|
787
|
+
return make_str(subj->mem, cmark_chunk_literal("]"));
|
|
824
788
|
}
|
|
825
789
|
|
|
826
790
|
// If we got here, we matched a potential link/image text.
|
|
827
791
|
is_image = opener->delim_char == '!';
|
|
828
|
-
link_text = opener->inl_text->next;
|
|
829
792
|
|
|
830
793
|
// Now we check to see if it's a link/image.
|
|
831
794
|
|
|
@@ -852,10 +815,10 @@ static cmark_node *handle_close_bracket(subject *subj, cmark_node *parent) {
|
|
|
852
815
|
url_chunk = cmark_chunk_dup(&subj->input, starturl, endurl - starturl);
|
|
853
816
|
title_chunk =
|
|
854
817
|
cmark_chunk_dup(&subj->input, starttitle, endtitle - starttitle);
|
|
855
|
-
url = cmark_clean_url(&url_chunk);
|
|
856
|
-
title = cmark_clean_title(&title_chunk);
|
|
857
|
-
cmark_chunk_free(&url_chunk);
|
|
858
|
-
cmark_chunk_free(&title_chunk);
|
|
818
|
+
url = cmark_clean_url(subj->mem, &url_chunk);
|
|
819
|
+
title = cmark_clean_title(subj->mem, &title_chunk);
|
|
820
|
+
cmark_chunk_free(subj->mem, &url_chunk);
|
|
821
|
+
cmark_chunk_free(subj->mem, &title_chunk);
|
|
859
822
|
goto match;
|
|
860
823
|
|
|
861
824
|
} else {
|
|
@@ -868,7 +831,7 @@ static cmark_node *handle_close_bracket(subject *subj, cmark_node *parent) {
|
|
|
868
831
|
raw_label = cmark_chunk_literal("");
|
|
869
832
|
found_label = link_label(subj, &raw_label);
|
|
870
833
|
if (!found_label || raw_label.len == 0) {
|
|
871
|
-
cmark_chunk_free(&raw_label);
|
|
834
|
+
cmark_chunk_free(subj->mem, &raw_label);
|
|
872
835
|
raw_label = cmark_chunk_dup(&subj->input, opener->position,
|
|
873
836
|
initial_pos - opener->position - 1);
|
|
874
837
|
}
|
|
@@ -880,11 +843,11 @@ static cmark_node *handle_close_bracket(subject *subj, cmark_node *parent) {
|
|
|
880
843
|
}
|
|
881
844
|
|
|
882
845
|
ref = cmark_reference_lookup(subj->refmap, &raw_label);
|
|
883
|
-
cmark_chunk_free(&raw_label);
|
|
846
|
+
cmark_chunk_free(subj->mem, &raw_label);
|
|
884
847
|
|
|
885
848
|
if (ref != NULL) { // found
|
|
886
|
-
url = chunk_clone(&ref->url);
|
|
887
|
-
title = chunk_clone(&ref->title);
|
|
849
|
+
url = chunk_clone(subj->mem, &ref->url);
|
|
850
|
+
title = chunk_clone(subj->mem, &ref->title);
|
|
888
851
|
goto match;
|
|
889
852
|
} else {
|
|
890
853
|
goto noMatch;
|
|
@@ -894,27 +857,25 @@ noMatch:
|
|
|
894
857
|
// If we fall through to here, it means we didn't match a link:
|
|
895
858
|
remove_delimiter(subj, opener); // remove this opener from delimiter list
|
|
896
859
|
subj->pos = initial_pos;
|
|
897
|
-
return make_str(cmark_chunk_literal("]"));
|
|
860
|
+
return make_str(subj->mem, cmark_chunk_literal("]"));
|
|
898
861
|
|
|
899
862
|
match:
|
|
900
|
-
inl =
|
|
901
|
-
inl->type = is_image ? CMARK_NODE_IMAGE : CMARK_NODE_LINK;
|
|
902
|
-
cmark_chunk_free(&inl->as.literal);
|
|
903
|
-
inl->first_child = link_text;
|
|
904
|
-
process_emphasis(subj, opener);
|
|
863
|
+
inl = make_simple(subj->mem, is_image ? CMARK_NODE_IMAGE : CMARK_NODE_LINK);
|
|
905
864
|
inl->as.link.url = url;
|
|
906
865
|
inl->as.link.title = title;
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
tmp->parent = inl;
|
|
915
|
-
inl->last_child = tmp;
|
|
866
|
+
cmark_node_insert_before(opener->inl_text, inl);
|
|
867
|
+
// Add link text:
|
|
868
|
+
tmp = opener->inl_text->next;
|
|
869
|
+
while (tmp) {
|
|
870
|
+
tmpnext = tmp->next;
|
|
871
|
+
cmark_node_append_child(inl, tmp);
|
|
872
|
+
tmp = tmpnext;
|
|
916
873
|
}
|
|
917
|
-
|
|
874
|
+
|
|
875
|
+
// Free the bracket [:
|
|
876
|
+
cmark_node_free(opener->inl_text);
|
|
877
|
+
|
|
878
|
+
process_emphasis(subj, opener);
|
|
918
879
|
|
|
919
880
|
// Now, if we have a link, we also want to deactivate earlier link
|
|
920
881
|
// delimiters. (This code can be removed if we decide to allow links
|
|
@@ -952,9 +913,9 @@ static cmark_node *handle_newline(subject *subj) {
|
|
|
952
913
|
skip_spaces(subj);
|
|
953
914
|
if (nlpos > 1 && peek_at(subj, nlpos - 1) == ' ' &&
|
|
954
915
|
peek_at(subj, nlpos - 2) == ' ') {
|
|
955
|
-
return make_linebreak();
|
|
916
|
+
return make_linebreak(subj->mem);
|
|
956
917
|
} else {
|
|
957
|
-
return make_softbreak();
|
|
918
|
+
return make_softbreak(subj->mem);
|
|
958
919
|
}
|
|
959
920
|
}
|
|
960
921
|
|
|
@@ -1043,20 +1004,20 @@ static int parse_inline(subject *subj, cmark_node *parent, int options) {
|
|
|
1043
1004
|
break;
|
|
1044
1005
|
case '[':
|
|
1045
1006
|
advance(subj);
|
|
1046
|
-
new_inl = make_str(cmark_chunk_literal("["));
|
|
1007
|
+
new_inl = make_str(subj->mem, cmark_chunk_literal("["));
|
|
1047
1008
|
push_delimiter(subj, '[', true, false, new_inl);
|
|
1048
1009
|
break;
|
|
1049
1010
|
case ']':
|
|
1050
|
-
new_inl = handle_close_bracket(subj
|
|
1011
|
+
new_inl = handle_close_bracket(subj);
|
|
1051
1012
|
break;
|
|
1052
1013
|
case '!':
|
|
1053
1014
|
advance(subj);
|
|
1054
1015
|
if (peek_char(subj) == '[') {
|
|
1055
1016
|
advance(subj);
|
|
1056
|
-
new_inl = make_str(cmark_chunk_literal("!["));
|
|
1017
|
+
new_inl = make_str(subj->mem, cmark_chunk_literal("!["));
|
|
1057
1018
|
push_delimiter(subj, '!', false, true, new_inl);
|
|
1058
1019
|
} else {
|
|
1059
|
-
new_inl = make_str(cmark_chunk_literal("!"));
|
|
1020
|
+
new_inl = make_str(subj->mem, cmark_chunk_literal("!"));
|
|
1060
1021
|
}
|
|
1061
1022
|
break;
|
|
1062
1023
|
default:
|
|
@@ -1069,7 +1030,7 @@ static int parse_inline(subject *subj, cmark_node *parent, int options) {
|
|
|
1069
1030
|
cmark_chunk_rtrim(&contents);
|
|
1070
1031
|
}
|
|
1071
1032
|
|
|
1072
|
-
new_inl = make_str(contents);
|
|
1033
|
+
new_inl = make_str(subj->mem, contents);
|
|
1073
1034
|
}
|
|
1074
1035
|
if (new_inl != NULL) {
|
|
1075
1036
|
cmark_node_append_child(parent, new_inl);
|
|
@@ -1079,10 +1040,10 @@ static int parse_inline(subject *subj, cmark_node *parent, int options) {
|
|
|
1079
1040
|
}
|
|
1080
1041
|
|
|
1081
1042
|
// Parse inlines from parent's string_content, adding as children of parent.
|
|
1082
|
-
extern void cmark_parse_inlines(cmark_node *parent, cmark_reference_map *refmap,
|
|
1043
|
+
extern void cmark_parse_inlines(cmark_mem *mem, cmark_node *parent, cmark_reference_map *refmap,
|
|
1083
1044
|
int options) {
|
|
1084
1045
|
subject subj;
|
|
1085
|
-
subject_from_buf(&subj, &parent->
|
|
1046
|
+
subject_from_buf(mem, &subj, &parent->content, refmap);
|
|
1086
1047
|
cmark_chunk_rtrim(&subj.input);
|
|
1087
1048
|
|
|
1088
1049
|
while (!is_eof(&subj) && parse_inline(&subj, parent, options))
|
|
@@ -1103,7 +1064,7 @@ static void spnl(subject *subj) {
|
|
|
1103
1064
|
// Modify refmap if a reference is encountered.
|
|
1104
1065
|
// Return 0 if no reference found, otherwise position of subject
|
|
1105
1066
|
// after reference is parsed.
|
|
1106
|
-
bufsize_t cmark_parse_reference_inline(cmark_strbuf *input,
|
|
1067
|
+
bufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_strbuf *input,
|
|
1107
1068
|
cmark_reference_map *refmap) {
|
|
1108
1069
|
subject subj;
|
|
1109
1070
|
|
|
@@ -1114,7 +1075,7 @@ bufsize_t cmark_parse_reference_inline(cmark_strbuf *input,
|
|
|
1114
1075
|
bufsize_t matchlen = 0;
|
|
1115
1076
|
bufsize_t beforetitle;
|
|
1116
1077
|
|
|
1117
|
-
subject_from_buf(&subj, input, NULL);
|
|
1078
|
+
subject_from_buf(mem, &subj, input, NULL);
|
|
1118
1079
|
|
|
1119
1080
|
// parse label:
|
|
1120
1081
|
if (!link_label(&subj, &lab) || lab.len == 0)
|