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.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/Rakefile +9 -9
  4. data/ext/commonmarker/cmark/api_test/main.c +5 -0
  5. data/ext/commonmarker/cmark/build/CMakeCache.txt +459 -0
  6. data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CMakeCCompiler.cmake +67 -0
  7. data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CMakeCXXCompiler.cmake +68 -0
  8. data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CMakeDetermineCompilerABI_C.bin +0 -0
  9. data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CMakeDetermineCompilerABI_CXX.bin +0 -0
  10. data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CMakeSystem.cmake +15 -0
  11. data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CompilerIdC/CMakeCCompilerId.c +544 -0
  12. data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CompilerIdC/a.out +0 -0
  13. data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CompilerIdCXX/CMakeCXXCompilerId.cpp +533 -0
  14. data/ext/commonmarker/cmark/build/CMakeFiles/3.5.2/CompilerIdCXX/a.out +0 -0
  15. data/ext/commonmarker/cmark/build/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
  16. data/ext/commonmarker/cmark/build/CMakeFiles/CMakeError.log +14 -0
  17. data/ext/commonmarker/cmark/build/CMakeFiles/CMakeOutput.log +562 -0
  18. data/ext/commonmarker/cmark/build/CMakeFiles/Makefile.cmake +150 -0
  19. data/ext/commonmarker/cmark/build/CMakeFiles/Makefile2 +295 -0
  20. data/ext/commonmarker/cmark/build/CMakeFiles/TargetDirectories.txt +39 -0
  21. data/ext/commonmarker/cmark/build/CMakeFiles/cmake.check_cache +1 -0
  22. data/ext/commonmarker/cmark/build/CMakeFiles/feature_tests.bin +0 -0
  23. data/ext/commonmarker/cmark/build/CMakeFiles/feature_tests.c +34 -0
  24. data/ext/commonmarker/cmark/build/CMakeFiles/feature_tests.cxx +405 -0
  25. data/ext/commonmarker/cmark/build/CMakeFiles/progress.marks +1 -0
  26. data/ext/commonmarker/cmark/build/CTestTestfile.cmake +10 -0
  27. data/ext/commonmarker/cmark/build/Makefile +250 -0
  28. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
  29. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/DependInfo.cmake +35 -0
  30. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/build.make +168 -0
  31. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/cmake_clean.cmake +12 -0
  32. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/depend.make +2 -0
  33. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/flags.make +17 -0
  34. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/link.txt +1 -0
  35. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/api_test.dir/progress.make +5 -0
  36. data/ext/commonmarker/cmark/build/api_test/CMakeFiles/progress.marks +1 -0
  37. data/ext/commonmarker/cmark/build/api_test/Makefile +300 -0
  38. data/ext/commonmarker/cmark/build/api_test/cmake_install.cmake +29 -0
  39. data/ext/commonmarker/cmark/build/cmake_install.cmake +48 -0
  40. data/ext/commonmarker/cmark/build/man/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
  41. data/ext/commonmarker/cmark/build/man/CMakeFiles/progress.marks +1 -0
  42. data/ext/commonmarker/cmark/build/man/Makefile +194 -0
  43. data/ext/commonmarker/cmark/build/man/cmake_install.cmake +37 -0
  44. data/ext/commonmarker/cmark/build/src/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
  45. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/DependInfo.cmake +41 -0
  46. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/build.make +626 -0
  47. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/cmake_clean.cmake +29 -0
  48. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/depend.make +2 -0
  49. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/flags.make +10 -0
  50. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/link.txt +1 -0
  51. data/ext/commonmarker/cmark/build/src/CMakeFiles/cmark.dir/progress.make +22 -0
  52. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/DependInfo.cmake +46 -0
  53. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/build.make +603 -0
  54. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/cmake_clean.cmake +29 -0
  55. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/depend.make +2 -0
  56. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/flags.make +10 -0
  57. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/link.txt +1 -0
  58. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark.dir/progress.make +21 -0
  59. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/C.includecache +468 -0
  60. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/DependInfo.cmake +40 -0
  61. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/blocks.c.o +0 -0
  62. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/buffer.c.o +0 -0
  63. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/build.make +600 -0
  64. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmake_clean.cmake +28 -0
  65. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmake_clean_target.cmake +3 -0
  66. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmark.c.o +0 -0
  67. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/cmark_ctype.c.o +0 -0
  68. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/commonmark.c.o +0 -0
  69. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/depend.internal +211 -0
  70. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/depend.make +211 -0
  71. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/flags.make +10 -0
  72. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_href_e.c.o +0 -0
  73. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_e.c.o +0 -0
  74. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/houdini_html_u.c.o +0 -0
  75. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/html.c.o +0 -0
  76. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/inlines.c.o +0 -0
  77. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/iterator.c.o +0 -0
  78. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/latex.c.o +0 -0
  79. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/link.txt +2 -0
  80. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/man.c.o +0 -0
  81. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/node.c.o +0 -0
  82. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/progress.make +21 -0
  83. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/references.c.o +0 -0
  84. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/render.c.o +0 -0
  85. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/scanners.c.o +0 -0
  86. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/utf8.c.o +0 -0
  87. data/ext/commonmarker/cmark/build/src/CMakeFiles/libcmark_static.dir/xml.c.o +0 -0
  88. data/ext/commonmarker/cmark/build/src/CMakeFiles/progress.marks +1 -0
  89. data/ext/commonmarker/cmark/build/src/Makefile +956 -0
  90. data/ext/commonmarker/cmark/build/src/cmake_install.cmake +77 -0
  91. data/ext/commonmarker/cmark/build/src/cmark_export.h +41 -0
  92. data/ext/commonmarker/cmark/build/src/cmark_version.h +7 -0
  93. data/ext/commonmarker/cmark/build/src/config.h +84 -0
  94. data/ext/commonmarker/cmark/build/src/libcmark.a +0 -0
  95. data/ext/commonmarker/cmark/build/src/libcmark.pc +10 -0
  96. data/ext/commonmarker/cmark/build/testdir/CMakeFiles/CMakeDirectoryInformation.cmake +16 -0
  97. data/ext/commonmarker/cmark/build/testdir/CMakeFiles/progress.marks +1 -0
  98. data/ext/commonmarker/cmark/build/testdir/CTestTestfile.cmake +14 -0
  99. data/ext/commonmarker/cmark/build/testdir/Makefile +194 -0
  100. data/ext/commonmarker/cmark/build/testdir/cmake_install.cmake +29 -0
  101. data/ext/commonmarker/cmark/man/man1/cmark.1 +11 -4
  102. data/ext/commonmarker/cmark/man/man3/cmark.3 +66 -11
  103. data/ext/commonmarker/cmark/src/blocks.c +232 -235
  104. data/ext/commonmarker/cmark/src/buffer.c +19 -56
  105. data/ext/commonmarker/cmark/src/buffer.h +7 -20
  106. data/ext/commonmarker/cmark/src/chunk.h +19 -19
  107. data/ext/commonmarker/cmark/src/cmark.c +14 -0
  108. data/ext/commonmarker/cmark/src/cmark.h +45 -6
  109. data/ext/commonmarker/cmark/src/cmark_ctype.c +2 -0
  110. data/ext/commonmarker/cmark/src/cmark_ctype.h +2 -0
  111. data/ext/commonmarker/cmark/src/commonmark.c +42 -29
  112. data/ext/commonmarker/cmark/src/config.h.in +8 -0
  113. data/ext/commonmarker/cmark/src/html.c +3 -1
  114. data/ext/commonmarker/cmark/src/inlines.c +111 -150
  115. data/ext/commonmarker/cmark/src/inlines.h +4 -4
  116. data/ext/commonmarker/cmark/src/iterator.c +6 -7
  117. data/ext/commonmarker/cmark/src/iterator.h +2 -0
  118. data/ext/commonmarker/cmark/src/latex.c +10 -8
  119. data/ext/commonmarker/cmark/src/main.c +6 -2
  120. data/ext/commonmarker/cmark/src/man.c +9 -5
  121. data/ext/commonmarker/cmark/src/node.c +38 -29
  122. data/ext/commonmarker/cmark/src/node.h +15 -11
  123. data/ext/commonmarker/cmark/src/parser.h +4 -2
  124. data/ext/commonmarker/cmark/src/references.c +23 -22
  125. data/ext/commonmarker/cmark/src/references.h +3 -1
  126. data/ext/commonmarker/cmark/src/render.c +9 -7
  127. data/ext/commonmarker/cmark/src/render.h +3 -1
  128. data/ext/commonmarker/cmark/src/scanners.c +30 -22
  129. data/ext/commonmarker/cmark/src/xml.c +1 -1
  130. data/ext/commonmarker/cmark/test/CMakeLists.txt +8 -8
  131. data/ext/commonmarker/cmark/test/cmark.py +34 -14
  132. data/ext/commonmarker/cmark/test/roundtrip_tests.py +47 -0
  133. data/ext/commonmarker/cmark/test/spec.txt +96 -6
  134. data/ext/commonmarker/cmark/test/spec_tests.py +5 -8
  135. data/ext/commonmarker/commonmarker.c +14 -8
  136. data/lib/commonmarker/config.rb +2 -2
  137. data/lib/commonmarker/renderer.rb +17 -7
  138. data/lib/commonmarker/renderer/html_renderer.rb +16 -21
  139. data/lib/commonmarker/version.rb +1 -1
  140. data/test/test_pathological_inputs.rb +11 -11
  141. metadata +99 -4
  142. data/ext/commonmarker/cmark/test/roundtrip.bat +0 -1
  143. data/ext/commonmarker/cmark/test/roundtrip.sh +0 -2
@@ -17,6 +17,8 @@ int cmark_isalnum(char c);
17
17
 
18
18
  int cmark_isdigit(char c);
19
19
 
20
+ int cmark_isalpha(char c);
21
+
20
22
  #ifdef __cplusplus
21
23
  }
22
24
  #endif
@@ -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
- int32_t c, unsigned char nextc) {
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 == '&' && isalpha(nextc)) || (c == '!' && nextc == '[') ||
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 == '>' || isspace(c) ||
46
- c == '\\' || c == ')' || 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 (isspace(c)) {
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 = safe_strlen(code);
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 = safe_strlen(code);
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 = safe_strlen(listmarker);
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->no_wrap = true;
262
+ renderer->no_linebreaks = true;
260
263
  } else {
261
- renderer->no_wrap = false;
264
+ renderer->no_linebreaks = false;
262
265
  BLANKLINE();
263
266
  }
264
267
  break;
265
268
 
266
269
  case CMARK_NODE_CODE_BLOCK:
267
- BLANKLINE();
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 = safe_strlen(info);
277
+ info_len = strlen(info);
270
278
  code = cmark_node_get_literal(node);
271
- code_len = safe_strlen(code);
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
- (code_len > 2 && !isspace((unsigned char)code[0]) &&
277
- !(isspace((unsigned char)code[code_len - 1]) && isspace((unsigned char)code[code_len - 2]))) &&
278
- !(node->prev == NULL && node->parent &&
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), true, NORMAL);
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 (renderer->width == 0 && !(CMARK_OPT_HARDBREAKS & options)) {
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(" ", true, LITERAL);
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 = safe_strlen(code);
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), true, LITERAL);
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 (safe_strlen(title) > 0) {
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 (safe_strlen(title) > 0) {
438
- OUT(" \"", true, LITERAL);
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 = GH_BUF_INIT;
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
- if (e != NULL) {
68
- e->type = t;
69
- e->as.literal = s;
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
- if (e != NULL) {
87
- e->type = t;
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 = GH_BUF_INIT;
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 *)malloc(len + 1);
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 = GH_BUF_INIT;
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 = GH_BUF_INIT;
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 *)malloc(sizeof(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 = GH_BUF_INIT;
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, *emph, *first_child, *last_child;
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
- first_child = opener_inl->next;
580
- last_child = closer_inl->prev;
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
- // replace empty opener inline with emph
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 = GH_BUF_INIT;
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 = GH_BUF_INIT;
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 = GH_BUF_INIT;
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, cmark_node *parent) {
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 = opener->inl_text;
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
- inl->next = NULL;
908
- if (link_text) {
909
- cmark_node *tmp;
910
- link_text->prev = NULL;
911
- for (tmp = link_text; tmp->next != NULL; tmp = tmp->next) {
912
- tmp->parent = inl;
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
- parent->last_child = inl;
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, parent);
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->string_content, refmap);
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)