markly 0.15.3 → 0.17.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
- checksums.yaml.gz.sig +0 -0
- data/context/getting-started.md +36 -0
- data/context/index.yaml +3 -3
- data/ext/markly/blocks.c +24 -6
- data/ext/markly/cmark-gfm.h +24 -0
- data/ext/markly/cmark-gfm_export.h +1 -0
- data/ext/markly/cmark-gfm_version.h +2 -2
- data/ext/markly/cmark.c +1 -1
- data/ext/markly/cmark_ctype.c +9 -0
- data/ext/markly/cmark_ctype.h +5 -0
- data/ext/markly/commonmark.c +21 -1
- data/ext/markly/config.h +0 -4
- data/ext/markly/extconf.rb +6 -1
- data/ext/markly/{table.c → extensions/table.c} +91 -46
- data/ext/markly/front_matter.c +141 -0
- data/ext/markly/front_matter.h +24 -0
- data/ext/markly/html.c +47 -23
- data/ext/markly/inlines.c +85 -3
- data/ext/markly/iterator.c +6 -1
- data/ext/markly/latex.c +3 -0
- data/ext/markly/man.c +3 -0
- data/ext/markly/markly.c +288 -201
- data/ext/markly/node.c +65 -5
- data/ext/markly/node.h +1 -0
- data/ext/markly/parser.h +19 -0
- data/ext/markly/plaintext.c +3 -0
- data/ext/markly/xml.c +19 -1
- data/lib/markly/flags.rb +10 -1
- data/lib/markly/node/inspect.rb +10 -3
- data/lib/markly/node.rb +53 -28
- data/lib/markly/renderer/generic.rb +42 -12
- data/lib/markly/renderer/headings.rb +24 -19
- data/lib/markly/renderer/html.rb +111 -10
- data/lib/markly/version.rb +4 -2
- data/lib/markly.rb +14 -13
- data/readme.md +22 -6
- data/releases.md +16 -0
- data.tar.gz.sig +0 -0
- metadata +23 -21
- metadata.gz.sig +0 -0
- /data/ext/markly/{autolink.c → extensions/autolink.c} +0 -0
- /data/ext/markly/{autolink.h → extensions/autolink.h} +0 -0
- /data/ext/markly/{cmark-gfm-core-extensions.h → extensions/cmark-gfm-core-extensions.h} +0 -0
- /data/ext/markly/{cmark-gfm-extensions_export.h → extensions/cmark-gfm-extensions_export.h} +0 -0
- /data/ext/markly/{core-extensions.c → extensions/core-extensions.c} +0 -0
- /data/ext/markly/{ext_scanners.c → extensions/ext_scanners.c} +0 -0
- /data/ext/markly/{ext_scanners.h → extensions/ext_scanners.h} +0 -0
- /data/ext/markly/{strikethrough.c → extensions/strikethrough.c} +0 -0
- /data/ext/markly/{strikethrough.h → extensions/strikethrough.h} +0 -0
- /data/ext/markly/{table.h → extensions/table.h} +0 -0
- /data/ext/markly/{tagfilter.c → extensions/tagfilter.c} +0 -0
- /data/ext/markly/{tagfilter.h → extensions/tagfilter.h} +0 -0
- /data/ext/markly/{tasklist.c → extensions/tasklist.c} +0 -0
- /data/ext/markly/{tasklist.h → extensions/tasklist.h} +0 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#include "front_matter.h"
|
|
2
|
+
#include "cmark-gfm.h"
|
|
3
|
+
|
|
4
|
+
#include <string.h>
|
|
5
|
+
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Delimiter and info string parsing
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
// Return true if `input` is an opening front matter delimiter: "---" followed
|
|
11
|
+
// by an optional info string and a newline. No leading whitespace before
|
|
12
|
+
// "---" is permitted.
|
|
13
|
+
//
|
|
14
|
+
// Note: some tools (e.g. Jekyll) also accept "..." as a closing delimiter,
|
|
15
|
+
// derived from the YAML document-end marker. We intentionally do not support
|
|
16
|
+
// it here because this implementation is format-agnostic — the content between
|
|
17
|
+
// the delimiters may be YAML, TOML, JSON, or anything else. "..." has no
|
|
18
|
+
// meaning outside of YAML, so "---" is the only unambiguous delimiter.
|
|
19
|
+
static bool is_opening_delimiter(cmark_chunk *input) {
|
|
20
|
+
const unsigned char *p = input->data;
|
|
21
|
+
if (input->len < 3 || !(p[0] == '-' && p[1] == '-' && p[2] == '-'))
|
|
22
|
+
return false;
|
|
23
|
+
// A fourth consecutive dash produces a longer thematic break, not a
|
|
24
|
+
// front matter delimiter.
|
|
25
|
+
if (input->len > 3 && p[3] == '-')
|
|
26
|
+
return false;
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Return true if `input` is a closing front matter delimiter: exactly "---"
|
|
31
|
+
// with optional trailing whitespace then a newline. An info string is not
|
|
32
|
+
// permitted on the closing delimiter.
|
|
33
|
+
static bool is_closing_delimiter(cmark_chunk *input) {
|
|
34
|
+
const unsigned char *p = input->data;
|
|
35
|
+
int len = input->len;
|
|
36
|
+
|
|
37
|
+
if (len < 3 || !(p[0] == '-' && p[1] == '-' && p[2] == '-'))
|
|
38
|
+
return false;
|
|
39
|
+
|
|
40
|
+
for (int i = 3; i < len; i++) {
|
|
41
|
+
if (p[i] == '\n' || p[i] == '\r')
|
|
42
|
+
return true;
|
|
43
|
+
if (p[i] != ' ' && p[i] != '\t')
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Extract the optional info string from an opening delimiter line, e.g.
|
|
50
|
+
// "--- yaml\n" yields "yaml". Returns a zero-length chunk if absent.
|
|
51
|
+
static cmark_chunk parse_info(cmark_chunk *input) {
|
|
52
|
+
const unsigned char *p = input->data + 3;
|
|
53
|
+
int len = input->len - 3;
|
|
54
|
+
|
|
55
|
+
while (len > 0 && (*p == ' ' || *p == '\t')) { p++; len--; }
|
|
56
|
+
while (len > 0 && (p[len-1] == '\n' || p[len-1] == '\r' ||
|
|
57
|
+
p[len-1] == ' ' || p[len-1] == '\t'))
|
|
58
|
+
len--;
|
|
59
|
+
|
|
60
|
+
return (cmark_chunk){ .data = (unsigned char *)p,
|
|
61
|
+
.len = (bufsize_t)len,
|
|
62
|
+
.alloc = 0 };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Node creation
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
static void create_front_matter_node(cmark_parser *parser) {
|
|
70
|
+
cmark_node *node =
|
|
71
|
+
cmark_node_new_with_mem(CMARK_NODE_FRONT_MATTER, parser->mem);
|
|
72
|
+
|
|
73
|
+
// Store identically to a code block: info string + literal content.
|
|
74
|
+
cmark_node_set_fence_info(node,
|
|
75
|
+
parser->front_matter_info.size > 0
|
|
76
|
+
? (const char *)parser->front_matter_info.ptr
|
|
77
|
+
: "");
|
|
78
|
+
|
|
79
|
+
cmark_node_set_literal(node,
|
|
80
|
+
parser->front_matter_buf.size > 0
|
|
81
|
+
? (const char *)parser->front_matter_buf.ptr
|
|
82
|
+
: "");
|
|
83
|
+
|
|
84
|
+
node->start_line = 1;
|
|
85
|
+
node->start_column = 1;
|
|
86
|
+
node->end_line = parser->line_number;
|
|
87
|
+
node->end_column = 3;
|
|
88
|
+
|
|
89
|
+
cmark_node *first = cmark_node_first_child(parser->root);
|
|
90
|
+
if (first)
|
|
91
|
+
cmark_node_insert_before(first, node);
|
|
92
|
+
else
|
|
93
|
+
cmark_node_append_child(parser->root, node);
|
|
94
|
+
|
|
95
|
+
parser->front_matter_scanning = false;
|
|
96
|
+
cmark_strbuf_clear(&parser->front_matter_buf);
|
|
97
|
+
cmark_strbuf_clear(&parser->front_matter_info);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
// State machine — called from S_process_line in blocks.c
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
|
|
104
|
+
bool cmark_front_matter_process_line(cmark_parser *parser, cmark_chunk *input) {
|
|
105
|
+
// NULL signals end-of-document: the whole document is the front matter.
|
|
106
|
+
if (input == NULL) {
|
|
107
|
+
create_front_matter_node(parser);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Adjust for any offset already consumed (e.g. a UTF-8 BOM on line 1).
|
|
112
|
+
cmark_chunk adjusted = {
|
|
113
|
+
.data = input->data + parser->offset,
|
|
114
|
+
.len = input->len - parser->offset,
|
|
115
|
+
.alloc = 0,
|
|
116
|
+
};
|
|
117
|
+
input = &adjusted;
|
|
118
|
+
|
|
119
|
+
if (parser->line_number == 1) {
|
|
120
|
+
if (is_opening_delimiter(input)) {
|
|
121
|
+
parser->front_matter_scanning = true;
|
|
122
|
+
// Capture optional info string (e.g. "yaml" from "--- yaml\n").
|
|
123
|
+
cmark_chunk info = parse_info(input);
|
|
124
|
+
if (info.len > 0)
|
|
125
|
+
cmark_strbuf_put(&parser->front_matter_info, info.data, info.len);
|
|
126
|
+
}
|
|
127
|
+
return parser->front_matter_scanning;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (!parser->front_matter_scanning)
|
|
131
|
+
return false;
|
|
132
|
+
|
|
133
|
+
if (is_closing_delimiter(input)) {
|
|
134
|
+
create_front_matter_node(parser);
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Accumulate this content line.
|
|
139
|
+
cmark_strbuf_put(&parser->front_matter_buf, input->data, input->len);
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#ifndef CMARK_FRONT_MATTER_H
|
|
2
|
+
#define CMARK_FRONT_MATTER_H
|
|
3
|
+
|
|
4
|
+
#ifdef __cplusplus
|
|
5
|
+
extern "C" {
|
|
6
|
+
#endif
|
|
7
|
+
|
|
8
|
+
#include "cmark-gfm.h"
|
|
9
|
+
#include "parser.h"
|
|
10
|
+
#include "chunk.h"
|
|
11
|
+
|
|
12
|
+
// Called from S_process_line in blocks.c for every line when
|
|
13
|
+
// CMARK_OPT_FRONT_MATTER is set. Drives the front matter state machine
|
|
14
|
+
// stored directly on the parser (front_matter_scanning / front_matter_buf).
|
|
15
|
+
//
|
|
16
|
+
// Returns true if the line was consumed by the front matter scanner and
|
|
17
|
+
// should not be passed to the normal block parser.
|
|
18
|
+
bool cmark_front_matter_process_line(cmark_parser *parser, cmark_chunk *input);
|
|
19
|
+
|
|
20
|
+
#ifdef __cplusplus
|
|
21
|
+
}
|
|
22
|
+
#endif
|
|
23
|
+
|
|
24
|
+
#endif
|
data/ext/markly/html.c
CHANGED
|
@@ -18,6 +18,34 @@ static void escape_html(cmark_strbuf *dest, const unsigned char *source,
|
|
|
18
18
|
houdini_escape_html0(dest, source, length, 0);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
static bufsize_t first_code_info_tag(cmark_chunk *info) {
|
|
22
|
+
bufsize_t first_tag = 0;
|
|
23
|
+
while (first_tag < info->len && !cmark_isspace(info->data[first_tag])) {
|
|
24
|
+
first_tag += 1;
|
|
25
|
+
}
|
|
26
|
+
return first_tag;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static void render_code_info_attrs(cmark_strbuf *html, cmark_chunk *info,
|
|
30
|
+
int options, bool pre_lang) {
|
|
31
|
+
bufsize_t first_tag = first_code_info_tag(info);
|
|
32
|
+
|
|
33
|
+
if (pre_lang) {
|
|
34
|
+
cmark_strbuf_puts(html, " lang=\"");
|
|
35
|
+
} else {
|
|
36
|
+
cmark_strbuf_puts(html, " class=\"language-");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
escape_html(html, info->data, first_tag);
|
|
40
|
+
|
|
41
|
+
if (first_tag < info->len && (options & CMARK_OPT_FULL_INFO_STRING)) {
|
|
42
|
+
cmark_strbuf_puts(html, "\" data-meta=\"");
|
|
43
|
+
escape_html(html, info->data + first_tag + 1, info->len - first_tag - 1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
cmark_strbuf_putc(html, '"');
|
|
47
|
+
}
|
|
48
|
+
|
|
21
49
|
static void filter_html_block(cmark_html_renderer *renderer, uint8_t *data, size_t len) {
|
|
22
50
|
cmark_strbuf *html = renderer->html;
|
|
23
51
|
cmark_llist *it;
|
|
@@ -125,7 +153,11 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
|
|
|
125
153
|
case CMARK_NODE_TEXT:
|
|
126
154
|
case CMARK_NODE_CODE:
|
|
127
155
|
case CMARK_NODE_HTML_INLINE:
|
|
128
|
-
|
|
156
|
+
if (node->type == CMARK_NODE_CODE) {
|
|
157
|
+
escape_html(html, node->as.code.literal.data, node->as.code.literal.len);
|
|
158
|
+
} else {
|
|
159
|
+
escape_html(html, node->as.literal.data, node->as.literal.len);
|
|
160
|
+
}
|
|
129
161
|
break;
|
|
130
162
|
|
|
131
163
|
case CMARK_NODE_LINEBREAK:
|
|
@@ -220,32 +252,17 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
|
|
|
220
252
|
cmark_html_render_sourcepos(node, html, options);
|
|
221
253
|
cmark_strbuf_puts(html, "><code>");
|
|
222
254
|
} else {
|
|
223
|
-
bufsize_t first_tag = 0;
|
|
224
|
-
while (first_tag < node->as.code.info.len &&
|
|
225
|
-
!cmark_isspace(node->as.code.info.data[first_tag])) {
|
|
226
|
-
first_tag += 1;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
255
|
if (options & CMARK_OPT_GITHUB_PRE_LANG) {
|
|
230
256
|
cmark_strbuf_puts(html, "<pre");
|
|
231
257
|
cmark_html_render_sourcepos(node, html, options);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if (first_tag < node->as.code.info.len && (options & CMARK_OPT_FULL_INFO_STRING)) {
|
|
235
|
-
cmark_strbuf_puts(html, "\" data-meta=\"");
|
|
236
|
-
escape_html(html, node->as.code.info.data + first_tag + 1, node->as.code.info.len - first_tag - 1);
|
|
237
|
-
}
|
|
238
|
-
cmark_strbuf_puts(html, "\"><code>");
|
|
258
|
+
render_code_info_attrs(html, &node->as.code.info, options, true);
|
|
259
|
+
cmark_strbuf_puts(html, "><code>");
|
|
239
260
|
} else {
|
|
240
261
|
cmark_strbuf_puts(html, "<pre");
|
|
241
262
|
cmark_html_render_sourcepos(node, html, options);
|
|
242
|
-
cmark_strbuf_puts(html, "><code
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
cmark_strbuf_puts(html, "\" data-meta=\"");
|
|
246
|
-
escape_html(html, node->as.code.info.data + first_tag + 1, node->as.code.info.len - first_tag - 1);
|
|
247
|
-
}
|
|
248
|
-
cmark_strbuf_puts(html, "\">");
|
|
263
|
+
cmark_strbuf_puts(html, "><code");
|
|
264
|
+
render_code_info_attrs(html, &node->as.code.info, options, false);
|
|
265
|
+
cmark_strbuf_putc(html, '>');
|
|
249
266
|
}
|
|
250
267
|
}
|
|
251
268
|
|
|
@@ -327,8 +344,12 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
|
|
|
327
344
|
break;
|
|
328
345
|
|
|
329
346
|
case CMARK_NODE_CODE:
|
|
330
|
-
cmark_strbuf_puts(html, "<code
|
|
331
|
-
|
|
347
|
+
cmark_strbuf_puts(html, "<code");
|
|
348
|
+
if (node->as.code.info.len > 0) {
|
|
349
|
+
render_code_info_attrs(html, &node->as.code.info, options, false);
|
|
350
|
+
}
|
|
351
|
+
cmark_strbuf_putc(html, '>');
|
|
352
|
+
escape_html(html, node->as.code.literal.data, node->as.code.literal.len);
|
|
332
353
|
cmark_strbuf_puts(html, "</code>");
|
|
333
354
|
break;
|
|
334
355
|
|
|
@@ -457,6 +478,9 @@ static int S_render_node(cmark_html_renderer *renderer, cmark_node *node,
|
|
|
457
478
|
}
|
|
458
479
|
break;
|
|
459
480
|
|
|
481
|
+
case CMARK_NODE_FRONT_MATTER:
|
|
482
|
+
break;
|
|
483
|
+
|
|
460
484
|
default:
|
|
461
485
|
assert(false);
|
|
462
486
|
break;
|
data/ext/markly/inlines.c
CHANGED
|
@@ -24,7 +24,6 @@ static const char *RIGHTSINGLEQUOTE = "\xE2\x80\x99";
|
|
|
24
24
|
|
|
25
25
|
// Macros for creating various kinds of simple.
|
|
26
26
|
#define make_str(subj, sc, ec, s) make_literal(subj, CMARK_NODE_TEXT, sc, ec, s)
|
|
27
|
-
#define make_code(subj, sc, ec, s) make_literal(subj, CMARK_NODE_CODE, sc, ec, s)
|
|
28
27
|
#define make_raw_html(subj, sc, ec, s) make_literal(subj, CMARK_NODE_HTML_INLINE, sc, ec, s)
|
|
29
28
|
#define make_linebreak(mem) make_simple(mem, CMARK_NODE_LINEBREAK)
|
|
30
29
|
#define make_softbreak(mem) make_simple(mem, CMARK_NODE_SOFTBREAK)
|
|
@@ -104,6 +103,18 @@ static CMARK_INLINE cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) {
|
|
|
104
103
|
return e;
|
|
105
104
|
}
|
|
106
105
|
|
|
106
|
+
static CMARK_INLINE cmark_node *make_code(subject *subj, int start_column,
|
|
107
|
+
int end_column, cmark_chunk literal) {
|
|
108
|
+
cmark_node *e = (cmark_node *)subj->mem->calloc(1, sizeof(*e));
|
|
109
|
+
cmark_strbuf_init(subj->mem, &e->content, 0);
|
|
110
|
+
e->type = CMARK_NODE_CODE;
|
|
111
|
+
e->as.code.literal = literal;
|
|
112
|
+
e->start_line = e->end_line = subj->line;
|
|
113
|
+
e->start_column = start_column + 1 + subj->column_offset + subj->block_offset;
|
|
114
|
+
e->end_column = end_column + 1 + subj->column_offset + subj->block_offset;
|
|
115
|
+
return e;
|
|
116
|
+
}
|
|
117
|
+
|
|
107
118
|
// Like make_str, but parses entities.
|
|
108
119
|
static cmark_node *make_str_with_entities(subject *subj,
|
|
109
120
|
int start_column, int end_column,
|
|
@@ -385,6 +396,39 @@ static void S_normalize_code(cmark_strbuf *s) {
|
|
|
385
396
|
|
|
386
397
|
}
|
|
387
398
|
|
|
399
|
+
static bufsize_t scan_inline_code_info_prefix(subject *subj, bufsize_t start) {
|
|
400
|
+
if (start >= subj->input.len ||
|
|
401
|
+
!cmark_is_inline_code_info_start_char((char)subj->input.data[start]) ||
|
|
402
|
+
(start > 0 && cmark_is_inline_code_info_char(
|
|
403
|
+
(char)subj->input.data[start - 1]))) {
|
|
404
|
+
return 0;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
bufsize_t pos = start + 1;
|
|
408
|
+
while (pos < subj->input.len && cmark_is_inline_code_info_char(
|
|
409
|
+
(char)subj->input.data[pos])) {
|
|
410
|
+
pos++;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (pos + 1 < subj->input.len && subj->input.data[pos] == ':' &&
|
|
414
|
+
subj->input.data[pos + 1] == '`') {
|
|
415
|
+
return pos;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return 0;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
static bufsize_t find_inline_code_info_prefix(subject *subj, bufsize_t start,
|
|
422
|
+
bufsize_t limit) {
|
|
423
|
+
while (start < limit) {
|
|
424
|
+
if (scan_inline_code_info_prefix(subj, start)) {
|
|
425
|
+
return start;
|
|
426
|
+
}
|
|
427
|
+
start++;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
return 0;
|
|
431
|
+
}
|
|
388
432
|
|
|
389
433
|
// Parse backtick code section or raw backticks, return an inline.
|
|
390
434
|
// Assumes that the subject has a backtick at the current position.
|
|
@@ -403,12 +447,35 @@ static cmark_node *handle_backticks(subject *subj, int options) {
|
|
|
403
447
|
endpos - startpos - openticks.len);
|
|
404
448
|
S_normalize_code(&buf);
|
|
405
449
|
|
|
406
|
-
cmark_node *node = make_code(subj, startpos, endpos - openticks.len - 1,
|
|
407
|
-
|
|
450
|
+
cmark_node *node = make_code(subj, startpos, endpos - openticks.len - 1,
|
|
451
|
+
cmark_chunk_buf_detach(&buf));
|
|
452
|
+
adjust_subj_node_newlines(subj, node, endpos - startpos, openticks.len,
|
|
453
|
+
options);
|
|
408
454
|
return node;
|
|
409
455
|
}
|
|
410
456
|
}
|
|
411
457
|
|
|
458
|
+
static cmark_node *handle_inline_code_info(subject *subj, int options) {
|
|
459
|
+
bufsize_t startpos = subj->pos;
|
|
460
|
+
bufsize_t colonpos = scan_inline_code_info_prefix(subj, startpos);
|
|
461
|
+
if (colonpos == 0) {
|
|
462
|
+
return NULL;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
cmark_chunk info =
|
|
466
|
+
cmark_chunk_dup(&subj->input, startpos, colonpos - startpos);
|
|
467
|
+
subj->pos = colonpos + 1;
|
|
468
|
+
|
|
469
|
+
cmark_node *node = handle_backticks(subj, options);
|
|
470
|
+
if (node->type != CMARK_NODE_CODE) {
|
|
471
|
+
cmark_node_free(node);
|
|
472
|
+
subj->pos = startpos;
|
|
473
|
+
return NULL;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
node->as.code.info = chunk_clone(subj->mem, &info);
|
|
477
|
+
return node;
|
|
478
|
+
}
|
|
412
479
|
|
|
413
480
|
// Scan ***, **, or * and return number scanned, or 0.
|
|
414
481
|
// Advances position.
|
|
@@ -1458,6 +1525,14 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
|
|
|
1458
1525
|
if (c == 0) {
|
|
1459
1526
|
return 0;
|
|
1460
1527
|
}
|
|
1528
|
+
if (options & CMARK_OPT_INLINE_CODE_INFO) {
|
|
1529
|
+
new_inl = handle_inline_code_info(subj, options);
|
|
1530
|
+
}
|
|
1531
|
+
if (new_inl != NULL) {
|
|
1532
|
+
append_child(parent, new_inl);
|
|
1533
|
+
return 1;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1461
1536
|
switch (c) {
|
|
1462
1537
|
case '\r':
|
|
1463
1538
|
case '\n':
|
|
@@ -1511,6 +1586,13 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
|
|
|
1511
1586
|
break;
|
|
1512
1587
|
|
|
1513
1588
|
endpos = subject_find_special_char(subj, options);
|
|
1589
|
+
if (options & CMARK_OPT_INLINE_CODE_INFO) {
|
|
1590
|
+
bufsize_t info_start =
|
|
1591
|
+
find_inline_code_info_prefix(subj, subj->pos + 1, endpos);
|
|
1592
|
+
if (info_start > 0 && info_start < endpos) {
|
|
1593
|
+
endpos = info_start;
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1514
1596
|
contents = cmark_chunk_dup(&subj->input, subj->pos, endpos - subj->pos);
|
|
1515
1597
|
startpos = subj->pos;
|
|
1516
1598
|
subj->pos = endpos;
|
data/ext/markly/iterator.c
CHANGED
|
@@ -139,10 +139,15 @@ void cmark_node_own(cmark_node *root) {
|
|
|
139
139
|
switch (cur->type) {
|
|
140
140
|
case CMARK_NODE_TEXT:
|
|
141
141
|
case CMARK_NODE_HTML_INLINE:
|
|
142
|
-
case CMARK_NODE_CODE:
|
|
143
142
|
case CMARK_NODE_HTML_BLOCK:
|
|
144
143
|
cmark_chunk_to_cstr(iter->mem, &cur->as.literal);
|
|
145
144
|
break;
|
|
145
|
+
case CMARK_NODE_CODE:
|
|
146
|
+
cmark_chunk_to_cstr(iter->mem, &cur->as.code.literal);
|
|
147
|
+
if (cur->as.code.info.len > 0) {
|
|
148
|
+
cmark_chunk_to_cstr(iter->mem, &cur->as.code.info);
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
146
151
|
case CMARK_NODE_LINK:
|
|
147
152
|
cmark_chunk_to_cstr(iter->mem, &cur->as.link.url);
|
|
148
153
|
cmark_chunk_to_cstr(iter->mem, &cur->as.link.title);
|
data/ext/markly/latex.c
CHANGED