commonmarker 0.23.10 → 1.0.0

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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1049 -0
  3. data/Cargo.toml +6 -0
  4. data/README.md +144 -203
  5. data/ext/commonmarker/Cargo.toml +13 -0
  6. data/ext/commonmarker/extconf.rb +3 -6
  7. data/ext/commonmarker/src/lib.rs +153 -0
  8. data/ext/commonmarker/src/options.rs +140 -0
  9. data/ext/commonmarker/src/plugins/syntax_highlighting.rs +74 -0
  10. data/ext/commonmarker/src/plugins.rs +3 -0
  11. data/ext/commonmarker/src/utils.rs +8 -0
  12. data/lib/commonmarker/config.rb +84 -40
  13. data/lib/commonmarker/constants.rb +7 -0
  14. data/lib/commonmarker/extension.rb +14 -0
  15. data/lib/commonmarker/renderer.rb +1 -127
  16. data/lib/commonmarker/utils.rb +22 -0
  17. data/lib/commonmarker/version.rb +2 -2
  18. data/lib/commonmarker.rb +14 -29
  19. metadata +36 -188
  20. data/Rakefile +0 -109
  21. data/bin/commonmarker +0 -118
  22. data/commonmarker.gemspec +0 -38
  23. data/ext/commonmarker/arena.c +0 -104
  24. data/ext/commonmarker/autolink.c +0 -508
  25. data/ext/commonmarker/autolink.h +0 -8
  26. data/ext/commonmarker/blocks.c +0 -1622
  27. data/ext/commonmarker/buffer.c +0 -278
  28. data/ext/commonmarker/buffer.h +0 -116
  29. data/ext/commonmarker/case_fold_switch.inc +0 -4327
  30. data/ext/commonmarker/chunk.h +0 -135
  31. data/ext/commonmarker/cmark-gfm-core-extensions.h +0 -54
  32. data/ext/commonmarker/cmark-gfm-extension_api.h +0 -737
  33. data/ext/commonmarker/cmark-gfm-extensions_export.h +0 -42
  34. data/ext/commonmarker/cmark-gfm.h +0 -833
  35. data/ext/commonmarker/cmark-gfm_export.h +0 -42
  36. data/ext/commonmarker/cmark-gfm_version.h +0 -7
  37. data/ext/commonmarker/cmark.c +0 -55
  38. data/ext/commonmarker/cmark_ctype.c +0 -44
  39. data/ext/commonmarker/cmark_ctype.h +0 -33
  40. data/ext/commonmarker/commonmark.c +0 -514
  41. data/ext/commonmarker/commonmarker.c +0 -1308
  42. data/ext/commonmarker/commonmarker.h +0 -16
  43. data/ext/commonmarker/config.h +0 -76
  44. data/ext/commonmarker/core-extensions.c +0 -27
  45. data/ext/commonmarker/entities.inc +0 -2138
  46. data/ext/commonmarker/ext_scanners.c +0 -879
  47. data/ext/commonmarker/ext_scanners.h +0 -24
  48. data/ext/commonmarker/footnotes.c +0 -63
  49. data/ext/commonmarker/footnotes.h +0 -27
  50. data/ext/commonmarker/houdini.h +0 -57
  51. data/ext/commonmarker/houdini_href_e.c +0 -100
  52. data/ext/commonmarker/houdini_html_e.c +0 -66
  53. data/ext/commonmarker/houdini_html_u.c +0 -149
  54. data/ext/commonmarker/html.c +0 -502
  55. data/ext/commonmarker/html.h +0 -27
  56. data/ext/commonmarker/inlines.c +0 -1788
  57. data/ext/commonmarker/inlines.h +0 -29
  58. data/ext/commonmarker/iterator.c +0 -159
  59. data/ext/commonmarker/iterator.h +0 -26
  60. data/ext/commonmarker/latex.c +0 -468
  61. data/ext/commonmarker/linked_list.c +0 -37
  62. data/ext/commonmarker/man.c +0 -274
  63. data/ext/commonmarker/map.c +0 -129
  64. data/ext/commonmarker/map.h +0 -44
  65. data/ext/commonmarker/node.c +0 -1045
  66. data/ext/commonmarker/node.h +0 -167
  67. data/ext/commonmarker/parser.h +0 -59
  68. data/ext/commonmarker/plaintext.c +0 -218
  69. data/ext/commonmarker/plugin.c +0 -36
  70. data/ext/commonmarker/plugin.h +0 -34
  71. data/ext/commonmarker/references.c +0 -43
  72. data/ext/commonmarker/references.h +0 -26
  73. data/ext/commonmarker/registry.c +0 -63
  74. data/ext/commonmarker/registry.h +0 -24
  75. data/ext/commonmarker/render.c +0 -213
  76. data/ext/commonmarker/render.h +0 -62
  77. data/ext/commonmarker/scanners.c +0 -14056
  78. data/ext/commonmarker/scanners.h +0 -70
  79. data/ext/commonmarker/scanners.re +0 -341
  80. data/ext/commonmarker/strikethrough.c +0 -167
  81. data/ext/commonmarker/strikethrough.h +0 -9
  82. data/ext/commonmarker/syntax_extension.c +0 -149
  83. data/ext/commonmarker/syntax_extension.h +0 -34
  84. data/ext/commonmarker/table.c +0 -917
  85. data/ext/commonmarker/table.h +0 -12
  86. data/ext/commonmarker/tagfilter.c +0 -60
  87. data/ext/commonmarker/tagfilter.h +0 -8
  88. data/ext/commonmarker/tasklist.c +0 -156
  89. data/ext/commonmarker/tasklist.h +0 -8
  90. data/ext/commonmarker/utf8.c +0 -317
  91. data/ext/commonmarker/utf8.h +0 -35
  92. data/ext/commonmarker/xml.c +0 -182
  93. data/lib/commonmarker/node/inspect.rb +0 -47
  94. data/lib/commonmarker/node.rb +0 -83
  95. data/lib/commonmarker/renderer/html_renderer.rb +0 -256
@@ -1,42 +0,0 @@
1
-
2
- #ifndef CMARK_GFM_EXPORT_H
3
- #define CMARK_GFM_EXPORT_H
4
-
5
- #ifdef CMARK_GFM_STATIC_DEFINE
6
- # define CMARK_GFM_EXPORT
7
- # define CMARK_GFM_NO_EXPORT
8
- #else
9
- # ifndef CMARK_GFM_EXPORT
10
- # ifdef libcmark_gfm_EXPORTS
11
- /* We are building this library */
12
- # define CMARK_GFM_EXPORT __attribute__((visibility("default")))
13
- # else
14
- /* We are using this library */
15
- # define CMARK_GFM_EXPORT __attribute__((visibility("default")))
16
- # endif
17
- # endif
18
-
19
- # ifndef CMARK_GFM_NO_EXPORT
20
- # define CMARK_GFM_NO_EXPORT __attribute__((visibility("hidden")))
21
- # endif
22
- #endif
23
-
24
- #ifndef CMARK_GFM_DEPRECATED
25
- # define CMARK_GFM_DEPRECATED __attribute__ ((__deprecated__))
26
- #endif
27
-
28
- #ifndef CMARK_GFM_DEPRECATED_EXPORT
29
- # define CMARK_GFM_DEPRECATED_EXPORT CMARK_GFM_EXPORT CMARK_GFM_DEPRECATED
30
- #endif
31
-
32
- #ifndef CMARK_GFM_DEPRECATED_NO_EXPORT
33
- # define CMARK_GFM_DEPRECATED_NO_EXPORT CMARK_GFM_NO_EXPORT CMARK_GFM_DEPRECATED
34
- #endif
35
-
36
- #if 0 /* DEFINE_NO_DEPRECATED */
37
- # ifndef CMARK_GFM_NO_DEPRECATED
38
- # define CMARK_GFM_NO_DEPRECATED
39
- # endif
40
- #endif
41
-
42
- #endif /* CMARK_GFM_EXPORT_H */
@@ -1,7 +0,0 @@
1
- #ifndef CMARK_GFM_VERSION_H
2
- #define CMARK_GFM_VERSION_H
3
-
4
- #define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 11)
5
- #define CMARK_GFM_VERSION_STRING "0.29.0.gfm.11"
6
-
7
- #endif
@@ -1,55 +0,0 @@
1
- #include <stdlib.h>
2
- #include <assert.h>
3
- #include <stdio.h>
4
- #include "registry.h"
5
- #include "node.h"
6
- #include "houdini.h"
7
- #include "cmark-gfm.h"
8
- #include "buffer.h"
9
-
10
- cmark_node_type CMARK_NODE_LAST_BLOCK = CMARK_NODE_FOOTNOTE_DEFINITION;
11
- cmark_node_type CMARK_NODE_LAST_INLINE = CMARK_NODE_FOOTNOTE_REFERENCE;
12
-
13
- int cmark_version(void) { return CMARK_GFM_VERSION; }
14
-
15
- const char *cmark_version_string(void) { return CMARK_GFM_VERSION_STRING; }
16
-
17
- static void *xcalloc(size_t nmem, size_t size) {
18
- void *ptr = calloc(nmem, size);
19
- if (!ptr) {
20
- fprintf(stderr, "[cmark] calloc returned null pointer, aborting\n");
21
- abort();
22
- }
23
- return ptr;
24
- }
25
-
26
- static void *xrealloc(void *ptr, size_t size) {
27
- void *new_ptr = realloc(ptr, size);
28
- if (!new_ptr) {
29
- fprintf(stderr, "[cmark] realloc returned null pointer, aborting\n");
30
- abort();
31
- }
32
- return new_ptr;
33
- }
34
-
35
- static void xfree(void *ptr) {
36
- free(ptr);
37
- }
38
-
39
- cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR = {xcalloc, xrealloc, xfree};
40
-
41
- cmark_mem *cmark_get_default_mem_allocator(void) {
42
- return &CMARK_DEFAULT_MEM_ALLOCATOR;
43
- }
44
-
45
- char *cmark_markdown_to_html(const char *text, size_t len, int options) {
46
- cmark_node *doc;
47
- char *result;
48
-
49
- doc = cmark_parse_document(text, len, options);
50
-
51
- result = cmark_render_html(doc, options, NULL);
52
- cmark_node_free(doc);
53
-
54
- return result;
55
- }
@@ -1,44 +0,0 @@
1
- #include <stdint.h>
2
-
3
- #include "cmark_ctype.h"
4
-
5
- /** 1 = space, 2 = punct, 3 = digit, 4 = alpha, 0 = other
6
- */
7
- static const uint8_t cmark_ctype_class[256] = {
8
- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
9
- /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
10
- /* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11
- /* 2 */ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
12
- /* 3 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2,
13
- /* 4 */ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
14
- /* 5 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2,
15
- /* 6 */ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
16
- /* 7 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0,
17
- /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
18
- /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19
- /* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20
- /* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
21
- /* c */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22
- /* d */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23
- /* e */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
24
- /* f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
25
-
26
- /**
27
- * Returns 1 if c is a "whitespace" character as defined by the spec.
28
- */
29
- int cmark_isspace(char c) { return cmark_ctype_class[(uint8_t)c] == 1; }
30
-
31
- /**
32
- * Returns 1 if c is an ascii punctuation character.
33
- */
34
- int cmark_ispunct(char c) { return cmark_ctype_class[(uint8_t)c] == 2; }
35
-
36
- int cmark_isalnum(char c) {
37
- uint8_t result;
38
- result = cmark_ctype_class[(uint8_t)c];
39
- return (result == 3 || result == 4);
40
- }
41
-
42
- int cmark_isdigit(char c) { return cmark_ctype_class[(uint8_t)c] == 3; }
43
-
44
- int cmark_isalpha(char c) { return cmark_ctype_class[(uint8_t)c] == 4; }
@@ -1,33 +0,0 @@
1
- #ifndef CMARK_CMARK_CTYPE_H
2
- #define CMARK_CMARK_CTYPE_H
3
-
4
- #ifdef __cplusplus
5
- extern "C" {
6
- #endif
7
-
8
- #include "cmark-gfm_export.h"
9
-
10
- /** Locale-independent versions of functions from ctype.h.
11
- * We want cmark to behave the same no matter what the system locale.
12
- */
13
-
14
- CMARK_GFM_EXPORT
15
- int cmark_isspace(char c);
16
-
17
- CMARK_GFM_EXPORT
18
- int cmark_ispunct(char c);
19
-
20
- CMARK_GFM_EXPORT
21
- int cmark_isalnum(char c);
22
-
23
- CMARK_GFM_EXPORT
24
- int cmark_isdigit(char c);
25
-
26
- CMARK_GFM_EXPORT
27
- int cmark_isalpha(char c);
28
-
29
- #ifdef __cplusplus
30
- }
31
- #endif
32
-
33
- #endif
@@ -1,514 +0,0 @@
1
- #include <stdlib.h>
2
- #include <stdio.h>
3
- #include <string.h>
4
- #include <stdint.h>
5
- #include <assert.h>
6
-
7
- #include "config.h"
8
- #include "cmark-gfm.h"
9
- #include "node.h"
10
- #include "buffer.h"
11
- #include "utf8.h"
12
- #include "scanners.h"
13
- #include "render.h"
14
- #include "syntax_extension.h"
15
-
16
- #define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)
17
- #define LIT(s) renderer->out(renderer, node, s, false, LITERAL)
18
- #define CR() renderer->cr(renderer)
19
- #define BLANKLINE() renderer->blankline(renderer)
20
- #define ENCODED_SIZE 20
21
- #define LISTMARKER_SIZE 20
22
-
23
- // Functions to convert cmark_nodes to commonmark strings.
24
-
25
- static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node,
26
- cmark_escaping escape,
27
- int32_t c, unsigned char nextc) {
28
- bool needs_escaping = false;
29
- bool follows_digit =
30
- renderer->buffer->size > 0 &&
31
- cmark_isdigit(renderer->buffer->ptr[renderer->buffer->size - 1]);
32
- char encoded[ENCODED_SIZE];
33
-
34
- needs_escaping =
35
- c < 0x80 && escape != LITERAL &&
36
- ((escape == NORMAL &&
37
- (c < 0x20 ||
38
- c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||
39
- c == '>' || c == '\\' || c == '`' || c == '~' || c == '!' ||
40
- (c == '&' && cmark_isalpha(nextc)) || (c == '!' && nextc == '[') ||
41
- (renderer->begin_content && (c == '-' || c == '+' || c == '=') &&
42
- // begin_content doesn't get set to false til we've passed digits
43
- // at the beginning of line, so...
44
- !follows_digit) ||
45
- (renderer->begin_content && (c == '.' || c == ')') && follows_digit &&
46
- (nextc == 0 || cmark_isspace(nextc))))) ||
47
- (escape == URL &&
48
- (c == '`' || c == '<' || c == '>' || cmark_isspace((char)c) || c == '\\' ||
49
- c == ')' || c == '(')) ||
50
- (escape == TITLE &&
51
- (c == '`' || c == '<' || c == '>' || c == '"' || c == '\\')));
52
-
53
- if (needs_escaping) {
54
- if (escape == URL && cmark_isspace((char)c)) {
55
- // use percent encoding for spaces
56
- snprintf(encoded, ENCODED_SIZE, "%%%2X", c);
57
- cmark_strbuf_puts(renderer->buffer, encoded);
58
- renderer->column += 3;
59
- } else if (cmark_ispunct((char)c)) {
60
- cmark_render_ascii(renderer, "\\");
61
- cmark_render_code_point(renderer, c);
62
- } else { // render as entity
63
- snprintf(encoded, ENCODED_SIZE, "&#%d;", c);
64
- cmark_strbuf_puts(renderer->buffer, encoded);
65
- renderer->column += (int)strlen(encoded);
66
- }
67
- } else {
68
- cmark_render_code_point(renderer, c);
69
- }
70
- }
71
-
72
- static int longest_backtick_sequence(const char *code) {
73
- int longest = 0;
74
- int current = 0;
75
- size_t i = 0;
76
- size_t code_len = strlen(code);
77
- while (i <= code_len) {
78
- if (code[i] == '`') {
79
- current++;
80
- } else {
81
- if (current > longest) {
82
- longest = current;
83
- }
84
- current = 0;
85
- }
86
- i++;
87
- }
88
- return longest;
89
- }
90
-
91
- static int shortest_unused_backtick_sequence(const char *code) {
92
- // note: if the shortest sequence is >= 32, this returns 32
93
- // so as not to overflow the bit array.
94
- uint32_t used = 1;
95
- int current = 0;
96
- size_t i = 0;
97
- size_t code_len = strlen(code);
98
- while (i <= code_len) {
99
- if (code[i] == '`') {
100
- current++;
101
- } else {
102
- if (current > 0 && current < 32) {
103
- used |= (1U << current);
104
- }
105
- current = 0;
106
- }
107
- i++;
108
- }
109
- // return number of first bit that is 0:
110
- i = 0;
111
- while (i < 32 && used & 1) {
112
- used = used >> 1;
113
- i++;
114
- }
115
- return (int)i;
116
- }
117
-
118
- static bool is_autolink(cmark_node *node) {
119
- cmark_chunk *title;
120
- cmark_chunk *url;
121
- cmark_node *link_text;
122
- char *realurl;
123
- int realurllen;
124
-
125
- if (node->type != CMARK_NODE_LINK) {
126
- return false;
127
- }
128
-
129
- url = &node->as.link.url;
130
- if (url->len == 0 || scan_scheme(url, 0) == 0) {
131
- return false;
132
- }
133
-
134
- title = &node->as.link.title;
135
- // if it has a title, we can't treat it as an autolink:
136
- if (title->len > 0) {
137
- return false;
138
- }
139
-
140
- link_text = node->first_child;
141
- if (link_text == NULL) {
142
- return false;
143
- }
144
- cmark_consolidate_text_nodes(link_text);
145
- realurl = (char *)url->data;
146
- realurllen = url->len;
147
- if (strncmp(realurl, "mailto:", 7) == 0) {
148
- realurl += 7;
149
- realurllen -= 7;
150
- }
151
- return (realurllen == link_text->as.literal.len &&
152
- strncmp(realurl, (char *)link_text->as.literal.data,
153
- link_text->as.literal.len) == 0);
154
- }
155
-
156
- static int S_render_node(cmark_renderer *renderer, cmark_node *node,
157
- cmark_event_type ev_type, int options) {
158
- int list_number;
159
- cmark_delim_type list_delim;
160
- int numticks;
161
- bool extra_spaces;
162
- int i;
163
- bool entering = (ev_type == CMARK_EVENT_ENTER);
164
- const char *info, *code, *title;
165
- char fencechar[2] = {'\0', '\0'};
166
- size_t info_len, code_len;
167
- char listmarker[LISTMARKER_SIZE];
168
- const char *emph_delim;
169
- bool first_in_list_item;
170
- bufsize_t marker_width;
171
- bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) &&
172
- !(CMARK_OPT_HARDBREAKS & options);
173
-
174
- // Don't adjust tight list status til we've started the list.
175
- // Otherwise we loose the blank line between a paragraph and
176
- // a following list.
177
- if (entering) {
178
- if (node->parent && node->parent->type == CMARK_NODE_ITEM) {
179
- renderer->in_tight_list_item = node->parent->parent->as.list.tight;
180
- }
181
- } else {
182
- if (node->type == CMARK_NODE_LIST) {
183
- renderer->in_tight_list_item =
184
- node->parent &&
185
- node->parent->type == CMARK_NODE_ITEM &&
186
- node->parent->parent->as.list.tight;
187
- }
188
- }
189
-
190
- if (node->extension && node->extension->commonmark_render_func) {
191
- node->extension->commonmark_render_func(node->extension, renderer, node, ev_type, options);
192
- return 1;
193
- }
194
-
195
- switch (node->type) {
196
- case CMARK_NODE_DOCUMENT:
197
- break;
198
-
199
- case CMARK_NODE_BLOCK_QUOTE:
200
- if (entering) {
201
- LIT("> ");
202
- renderer->begin_content = true;
203
- cmark_strbuf_puts(renderer->prefix, "> ");
204
- } else {
205
- cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 2);
206
- BLANKLINE();
207
- }
208
- break;
209
-
210
- case CMARK_NODE_LIST:
211
- if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||
212
- node->next->type == CMARK_NODE_LIST)) {
213
- // this ensures that a following indented code block or list will be
214
- // inteprereted correctly.
215
- CR();
216
- LIT("<!-- end list -->");
217
- BLANKLINE();
218
- }
219
- break;
220
-
221
- case CMARK_NODE_ITEM:
222
- if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
223
- marker_width = 4;
224
- } else {
225
- list_number = cmark_node_get_item_index(node);
226
- list_delim = cmark_node_get_list_delim(node->parent);
227
- // we ensure a width of at least 4 so
228
- // we get nice transition from single digits
229
- // to double
230
- snprintf(listmarker, LISTMARKER_SIZE, "%d%s%s", list_number,
231
- list_delim == CMARK_PAREN_DELIM ? ")" : ".",
232
- list_number < 10 ? " " : " ");
233
- marker_width = (bufsize_t)strlen(listmarker);
234
- }
235
- if (entering) {
236
- if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
237
- LIT(" - ");
238
- renderer->begin_content = true;
239
- } else {
240
- LIT(listmarker);
241
- renderer->begin_content = true;
242
- }
243
- for (i = marker_width; i--;) {
244
- cmark_strbuf_putc(renderer->prefix, ' ');
245
- }
246
- } else {
247
- cmark_strbuf_truncate(renderer->prefix,
248
- renderer->prefix->size - marker_width);
249
- CR();
250
- }
251
- break;
252
-
253
- case CMARK_NODE_HEADING:
254
- if (entering) {
255
- for (i = cmark_node_get_heading_level(node); i > 0; i--) {
256
- LIT("#");
257
- }
258
- LIT(" ");
259
- renderer->begin_content = true;
260
- renderer->no_linebreaks = true;
261
- } else {
262
- renderer->no_linebreaks = false;
263
- BLANKLINE();
264
- }
265
- break;
266
-
267
- case CMARK_NODE_CODE_BLOCK:
268
- first_in_list_item = node->prev == NULL && node->parent &&
269
- node->parent->type == CMARK_NODE_ITEM;
270
-
271
- if (!first_in_list_item) {
272
- BLANKLINE();
273
- }
274
- info = cmark_node_get_fence_info(node);
275
- info_len = strlen(info);
276
- fencechar[0] = strchr(info, '`') == NULL ? '`' : '~';
277
- code = cmark_node_get_literal(node);
278
- code_len = strlen(code);
279
- // use indented form if no info, and code doesn't
280
- // begin or end with a blank line, and code isn't
281
- // first thing in a list item
282
- if (info_len == 0 && (code_len > 2 && !cmark_isspace(code[0]) &&
283
- !(cmark_isspace(code[code_len - 1]) &&
284
- cmark_isspace(code[code_len - 2]))) &&
285
- !first_in_list_item) {
286
- LIT(" ");
287
- cmark_strbuf_puts(renderer->prefix, " ");
288
- OUT(cmark_node_get_literal(node), false, LITERAL);
289
- cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);
290
- } else {
291
- numticks = longest_backtick_sequence(code) + 1;
292
- if (numticks < 3) {
293
- numticks = 3;
294
- }
295
- for (i = 0; i < numticks; i++) {
296
- LIT(fencechar);
297
- }
298
- LIT(" ");
299
- OUT(info, false, LITERAL);
300
- CR();
301
- OUT(cmark_node_get_literal(node), false, LITERAL);
302
- CR();
303
- for (i = 0; i < numticks; i++) {
304
- LIT(fencechar);
305
- }
306
- }
307
- BLANKLINE();
308
- break;
309
-
310
- case CMARK_NODE_HTML_BLOCK:
311
- BLANKLINE();
312
- OUT(cmark_node_get_literal(node), false, LITERAL);
313
- BLANKLINE();
314
- break;
315
-
316
- case CMARK_NODE_CUSTOM_BLOCK:
317
- BLANKLINE();
318
- OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
319
- false, LITERAL);
320
- BLANKLINE();
321
- break;
322
-
323
- case CMARK_NODE_THEMATIC_BREAK:
324
- BLANKLINE();
325
- LIT("-----");
326
- BLANKLINE();
327
- break;
328
-
329
- case CMARK_NODE_PARAGRAPH:
330
- if (!entering) {
331
- BLANKLINE();
332
- }
333
- break;
334
-
335
- case CMARK_NODE_TEXT:
336
- OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
337
- break;
338
-
339
- case CMARK_NODE_LINEBREAK:
340
- if (!(CMARK_OPT_HARDBREAKS & options)) {
341
- LIT(" ");
342
- }
343
- CR();
344
- break;
345
-
346
- case CMARK_NODE_SOFTBREAK:
347
- if (CMARK_OPT_HARDBREAKS & options) {
348
- LIT(" ");
349
- CR();
350
- } else if (!renderer->no_linebreaks && renderer->width == 0 &&
351
- !(CMARK_OPT_HARDBREAKS & options) &&
352
- !(CMARK_OPT_NOBREAKS & options)) {
353
- CR();
354
- } else {
355
- OUT(" ", allow_wrap, LITERAL);
356
- }
357
- break;
358
-
359
- case CMARK_NODE_CODE:
360
- code = cmark_node_get_literal(node);
361
- code_len = strlen(code);
362
- numticks = shortest_unused_backtick_sequence(code);
363
- extra_spaces = code_len == 0 ||
364
- code[0] == '`' || code[code_len - 1] == '`' ||
365
- code[0] == ' ' || code[code_len - 1] == ' ';
366
- for (i = 0; i < numticks; i++) {
367
- LIT("`");
368
- }
369
- if (extra_spaces) {
370
- LIT(" ");
371
- }
372
- OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);
373
- if (extra_spaces) {
374
- LIT(" ");
375
- }
376
- for (i = 0; i < numticks; i++) {
377
- LIT("`");
378
- }
379
- break;
380
-
381
- case CMARK_NODE_HTML_INLINE:
382
- OUT(cmark_node_get_literal(node), false, LITERAL);
383
- break;
384
-
385
- case CMARK_NODE_CUSTOM_INLINE:
386
- OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),
387
- false, LITERAL);
388
- break;
389
-
390
- case CMARK_NODE_STRONG:
391
- if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {
392
- if (entering) {
393
- LIT("**");
394
- } else {
395
- LIT("**");
396
- }
397
- }
398
- break;
399
-
400
- case CMARK_NODE_EMPH:
401
- // If we have EMPH(EMPH(x)), we need to use *_x_*
402
- // because **x** is STRONG(x):
403
- if (node->parent && node->parent->type == CMARK_NODE_EMPH &&
404
- node->next == NULL && node->prev == NULL) {
405
- emph_delim = "_";
406
- } else {
407
- emph_delim = "*";
408
- }
409
- if (entering) {
410
- LIT(emph_delim);
411
- } else {
412
- LIT(emph_delim);
413
- }
414
- break;
415
-
416
- case CMARK_NODE_LINK:
417
- if (is_autolink(node)) {
418
- if (entering) {
419
- LIT("<");
420
- if (strncmp(cmark_node_get_url(node), "mailto:", 7) == 0) {
421
- LIT((const char *)cmark_node_get_url(node) + 7);
422
- } else {
423
- LIT((const char *)cmark_node_get_url(node));
424
- }
425
- LIT(">");
426
- // return signal to skip contents of node...
427
- return 0;
428
- }
429
- } else {
430
- if (entering) {
431
- LIT("[");
432
- } else {
433
- LIT("](");
434
- OUT(cmark_node_get_url(node), false, URL);
435
- title = cmark_node_get_title(node);
436
- if (strlen(title) > 0) {
437
- LIT(" \"");
438
- OUT(title, false, TITLE);
439
- LIT("\"");
440
- }
441
- LIT(")");
442
- }
443
- }
444
- break;
445
-
446
- case CMARK_NODE_IMAGE:
447
- if (entering) {
448
- LIT("![");
449
- } else {
450
- LIT("](");
451
- OUT(cmark_node_get_url(node), false, URL);
452
- title = cmark_node_get_title(node);
453
- if (strlen(title) > 0) {
454
- OUT(" \"", allow_wrap, LITERAL);
455
- OUT(title, false, TITLE);
456
- LIT("\"");
457
- }
458
- LIT(")");
459
- }
460
- break;
461
-
462
- case CMARK_NODE_FOOTNOTE_REFERENCE:
463
- if (entering) {
464
- LIT("[^");
465
-
466
- char *footnote_label = renderer->mem->calloc(node->parent_footnote_def->as.literal.len + 1, sizeof(char));
467
- memmove(footnote_label, node->parent_footnote_def->as.literal.data, node->parent_footnote_def->as.literal.len);
468
-
469
- OUT(footnote_label, false, LITERAL);
470
- renderer->mem->free(footnote_label);
471
-
472
- LIT("]");
473
- }
474
- break;
475
-
476
- case CMARK_NODE_FOOTNOTE_DEFINITION:
477
- if (entering) {
478
- renderer->footnote_ix += 1;
479
- LIT("[^");
480
-
481
- char *footnote_label = renderer->mem->calloc(node->as.literal.len + 1, sizeof(char));
482
- memmove(footnote_label, node->as.literal.data, node->as.literal.len);
483
-
484
- OUT(footnote_label, false, LITERAL);
485
- renderer->mem->free(footnote_label);
486
-
487
- LIT("]:\n");
488
-
489
- cmark_strbuf_puts(renderer->prefix, " ");
490
- } else {
491
- cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);
492
- }
493
- break;
494
-
495
- default:
496
- assert(false);
497
- break;
498
- }
499
-
500
- return 1;
501
- }
502
-
503
- char *cmark_render_commonmark(cmark_node *root, int options, int width) {
504
- return cmark_render_commonmark_with_mem(root, options, width, cmark_node_mem(root));
505
- }
506
-
507
- char *cmark_render_commonmark_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {
508
- if (options & CMARK_OPT_HARDBREAKS) {
509
- // disable breaking on width, since it has
510
- // a different meaning with OPT_HARDBREAKS
511
- width = 0;
512
- }
513
- return cmark_render(mem, root, options, width, outc, S_render_node);
514
- }