commonmarker 0.23.10 → 2.2.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.
- checksums.yaml +4 -4
- data/Cargo.lock +1156 -0
- data/Cargo.toml +7 -0
- data/README.md +237 -172
- data/ext/commonmarker/Cargo.toml +20 -0
- data/ext/commonmarker/extconf.rb +3 -6
- data/ext/commonmarker/src/lib.rs +103 -0
- data/ext/commonmarker/src/node.rs +1221 -0
- data/ext/commonmarker/src/options.rs +220 -0
- data/ext/commonmarker/src/plugins/syntax_highlighting.rs +166 -0
- data/ext/commonmarker/src/plugins.rs +6 -0
- data/ext/commonmarker/src/utils.rs +8 -0
- data/lib/commonmarker/config.rb +92 -40
- data/lib/commonmarker/constants.rb +7 -0
- data/lib/commonmarker/extension.rb +14 -0
- data/lib/commonmarker/node/ast.rb +8 -0
- data/lib/commonmarker/node/inspect.rb +14 -4
- data/lib/commonmarker/node.rb +29 -47
- data/lib/commonmarker/renderer.rb +1 -127
- data/lib/commonmarker/utils.rb +22 -0
- data/lib/commonmarker/version.rb +2 -2
- data/lib/commonmarker.rb +27 -25
- metadata +38 -191
- data/Rakefile +0 -109
- data/bin/commonmarker +0 -118
- data/commonmarker.gemspec +0 -38
- data/ext/commonmarker/arena.c +0 -104
- data/ext/commonmarker/autolink.c +0 -508
- data/ext/commonmarker/autolink.h +0 -8
- data/ext/commonmarker/blocks.c +0 -1622
- data/ext/commonmarker/buffer.c +0 -278
- data/ext/commonmarker/buffer.h +0 -116
- data/ext/commonmarker/case_fold_switch.inc +0 -4327
- data/ext/commonmarker/chunk.h +0 -135
- data/ext/commonmarker/cmark-gfm-core-extensions.h +0 -54
- data/ext/commonmarker/cmark-gfm-extension_api.h +0 -737
- data/ext/commonmarker/cmark-gfm-extensions_export.h +0 -42
- data/ext/commonmarker/cmark-gfm.h +0 -833
- data/ext/commonmarker/cmark-gfm_export.h +0 -42
- data/ext/commonmarker/cmark-gfm_version.h +0 -7
- data/ext/commonmarker/cmark.c +0 -55
- data/ext/commonmarker/cmark_ctype.c +0 -44
- data/ext/commonmarker/cmark_ctype.h +0 -33
- data/ext/commonmarker/commonmark.c +0 -514
- data/ext/commonmarker/commonmarker.c +0 -1308
- data/ext/commonmarker/commonmarker.h +0 -16
- data/ext/commonmarker/config.h +0 -76
- data/ext/commonmarker/core-extensions.c +0 -27
- data/ext/commonmarker/entities.inc +0 -2138
- data/ext/commonmarker/ext_scanners.c +0 -879
- data/ext/commonmarker/ext_scanners.h +0 -24
- data/ext/commonmarker/footnotes.c +0 -63
- data/ext/commonmarker/footnotes.h +0 -27
- data/ext/commonmarker/houdini.h +0 -57
- data/ext/commonmarker/houdini_href_e.c +0 -100
- data/ext/commonmarker/houdini_html_e.c +0 -66
- data/ext/commonmarker/houdini_html_u.c +0 -149
- data/ext/commonmarker/html.c +0 -502
- data/ext/commonmarker/html.h +0 -27
- data/ext/commonmarker/inlines.c +0 -1788
- data/ext/commonmarker/inlines.h +0 -29
- data/ext/commonmarker/iterator.c +0 -159
- data/ext/commonmarker/iterator.h +0 -26
- data/ext/commonmarker/latex.c +0 -468
- data/ext/commonmarker/linked_list.c +0 -37
- data/ext/commonmarker/man.c +0 -274
- data/ext/commonmarker/map.c +0 -129
- data/ext/commonmarker/map.h +0 -44
- data/ext/commonmarker/node.c +0 -1045
- data/ext/commonmarker/node.h +0 -167
- data/ext/commonmarker/parser.h +0 -59
- data/ext/commonmarker/plaintext.c +0 -218
- data/ext/commonmarker/plugin.c +0 -36
- data/ext/commonmarker/plugin.h +0 -34
- data/ext/commonmarker/references.c +0 -43
- data/ext/commonmarker/references.h +0 -26
- data/ext/commonmarker/registry.c +0 -63
- data/ext/commonmarker/registry.h +0 -24
- data/ext/commonmarker/render.c +0 -213
- data/ext/commonmarker/render.h +0 -62
- data/ext/commonmarker/scanners.c +0 -14056
- data/ext/commonmarker/scanners.h +0 -70
- data/ext/commonmarker/scanners.re +0 -341
- data/ext/commonmarker/strikethrough.c +0 -167
- data/ext/commonmarker/strikethrough.h +0 -9
- data/ext/commonmarker/syntax_extension.c +0 -149
- data/ext/commonmarker/syntax_extension.h +0 -34
- data/ext/commonmarker/table.c +0 -917
- data/ext/commonmarker/table.h +0 -12
- data/ext/commonmarker/tagfilter.c +0 -60
- data/ext/commonmarker/tagfilter.h +0 -8
- data/ext/commonmarker/tasklist.c +0 -156
- data/ext/commonmarker/tasklist.h +0 -8
- data/ext/commonmarker/utf8.c +0 -317
- data/ext/commonmarker/utf8.h +0 -35
- data/ext/commonmarker/xml.c +0 -182
- 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 */
|
data/ext/commonmarker/cmark.c
DELETED
@@ -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(";
|
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
|
-
}
|