markly 0.16.0 → 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/ext/markly/cmark-gfm.h +16 -0
- data/ext/markly/cmark-gfm_export.h +1 -0
- data/ext/markly/cmark-gfm_version.h +2 -2
- data/ext/markly/cmark_ctype.c +9 -0
- data/ext/markly/cmark_ctype.h +5 -0
- data/ext/markly/commonmark.c +10 -3
- data/ext/markly/config.h +0 -4
- data/ext/markly/html.c +44 -23
- data/ext/markly/inlines.c +85 -3
- data/ext/markly/iterator.c +6 -1
- data/ext/markly/markly.c +282 -201
- data/ext/markly/node.c +56 -3
- data/ext/markly/xml.c +12 -1
- data/lib/markly/flags.rb +4 -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 +3 -1
- data/lib/markly.rb +14 -13
- data/readme.md +11 -1
- data/releases.md +11 -1
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b86cb2d3095458e69fe2d6fc2b9d6eb7dbee37b15edf5cc7064104ef12b5cb98
|
|
4
|
+
data.tar.gz: 1ddb2cac9ff79ee9fd2012e67949ddd5886930f6c5ecb28b54edf2eeffbbf110
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fbc478782839f1c5d20abd6f9697da6e870f4620873d1b1450b96e7f8e21c31f345d0461fbc6536da9f3a0b33b19ef7dd69a70c5f1edd40bc7e08b42cab66ac1
|
|
7
|
+
data.tar.gz: ef38f140dd12fbd5788e17f124f280fe25cb1a3af67963d0b8e1780b851adf75609f9da6f38e682ca4ff2a6f59d7d756dc5a7469ffaf76e99c9ea6a9f03b115f
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/context/getting-started.md
CHANGED
|
@@ -42,7 +42,9 @@ Markly accepts integer flags which control how the Markdown is parsed and render
|
|
|
42
42
|
| ------------------------------------ | -----------
|
|
43
43
|
| `Markly::DEFAULT` | The default parsing system.
|
|
44
44
|
| `Markly::UNSAFE` | Allow raw/custom HTML and unsafe links.
|
|
45
|
+
| `Markly::FRONT_MATTER` | Parse front matter at the start of the document.
|
|
45
46
|
| `Markly::FOOTNOTES` | Parse footnotes.
|
|
47
|
+
| `Markly::INLINE_CODE_INFO` | Parse language prefixes such as `ruby:` on inline code spans.
|
|
46
48
|
| `Markly::LIBERAL_HTML_TAG` | Support liberal parsing of inline HTML tags.
|
|
47
49
|
| `Markly::SMART` | Use smart punctuation (curly quotes, etc.).
|
|
48
50
|
| `Markly::STRIKETHROUGH_DOUBLE_TILDE` | Parse strikethroughs by double tildes (compatibility with [redcarpet](https://github.com/vmg/redcarpet))
|
|
@@ -76,6 +78,40 @@ To have multiple options applied, `|` (or) the flags together:
|
|
|
76
78
|
Markly.render_html("\"'Shelob' is my name.\"", flags: Markly::HARD_BREAKS|Markly::SOURCE_POSITION)
|
|
77
79
|
```
|
|
78
80
|
|
|
81
|
+
Inline code language prefixes are opt-in. The language is available through
|
|
82
|
+
`Node#code_info` and is rendered as a `language-...` class:
|
|
83
|
+
|
|
84
|
+
``` ruby
|
|
85
|
+
document = Markly.parse("ruby:`Object.new`", flags: Markly::INLINE_CODE_INFO)
|
|
86
|
+
code = document.first_child.first_child
|
|
87
|
+
|
|
88
|
+
code.code_info
|
|
89
|
+
# => "ruby"
|
|
90
|
+
|
|
91
|
+
code.code_language
|
|
92
|
+
# => "ruby"
|
|
93
|
+
|
|
94
|
+
document.to_html
|
|
95
|
+
# => <p><code class="language-ruby">Object.new</code></p>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`Node#code_info` is also the general info-string accessor for fenced code
|
|
99
|
+
blocks and front matter. `Node#code_language` returns the first token of that
|
|
100
|
+
info string, while `Node#fence_info` remains available for compatibility on
|
|
101
|
+
those block nodes.
|
|
102
|
+
|
|
103
|
+
For a fenced code block, `Node#fence` returns a `Node::Fence` structure with
|
|
104
|
+
the fence character, length, and indentation:
|
|
105
|
+
|
|
106
|
+
``` ruby
|
|
107
|
+
block = Markly.parse(" ~~~~ ruby\n Object.new\n ~~~~").first_child
|
|
108
|
+
|
|
109
|
+
block.fence
|
|
110
|
+
# => #<struct Markly::Node::Fence character="~", length=4, indent=2>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Indented code blocks and other node types return `nil`.
|
|
114
|
+
|
|
79
115
|
## Extensions
|
|
80
116
|
|
|
81
117
|
Both `render_html` and `parse` take an optional `extensions:` argument defining the extensions you want enabled as your CommonMark document is being processed:
|
data/ext/markly/cmark-gfm.h
CHANGED
|
@@ -425,6 +425,18 @@ CMARK_GFM_EXPORT int cmark_node_get_item_index(cmark_node *node);
|
|
|
425
425
|
*/
|
|
426
426
|
CMARK_GFM_EXPORT int cmark_node_set_item_index(cmark_node *node, int idx);
|
|
427
427
|
|
|
428
|
+
/** Returns the info string from a code block or the language identifier from
|
|
429
|
+
* an inline code span.
|
|
430
|
+
*/
|
|
431
|
+
CMARK_GFM_EXPORT const char *cmark_node_get_code_info(cmark_node *node);
|
|
432
|
+
|
|
433
|
+
/** Sets the info string in a code block or the language identifier on an
|
|
434
|
+
* inline code span, returning 1 on success and 0 on failure. Inline code
|
|
435
|
+
* language identifiers must begin with an alphanumeric character and may
|
|
436
|
+
* additionally contain '_', '-', '+', '#', and '.'.
|
|
437
|
+
*/
|
|
438
|
+
CMARK_GFM_EXPORT int cmark_node_set_code_info(cmark_node *node, const char *info);
|
|
439
|
+
|
|
428
440
|
/** Returns the info string from a fenced code block.
|
|
429
441
|
*/
|
|
430
442
|
CMARK_GFM_EXPORT const char *cmark_node_get_fence_info(cmark_node *node);
|
|
@@ -776,6 +788,10 @@ char *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmar
|
|
|
776
788
|
*/
|
|
777
789
|
#define CMARK_OPT_FRONT_MATTER (1 << 18)
|
|
778
790
|
|
|
791
|
+
/** Parse inline code language prefixes, e.g. ruby:`code`.
|
|
792
|
+
*/
|
|
793
|
+
#define CMARK_OPT_INLINE_CODE_INFO (1 << 19)
|
|
794
|
+
|
|
779
795
|
/**
|
|
780
796
|
* ## Version information
|
|
781
797
|
*/
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
# define CMARK_GFM_DEPRECATED_NO_EXPORT CMARK_GFM_NO_EXPORT CMARK_GFM_DEPRECATED
|
|
34
34
|
#endif
|
|
35
35
|
|
|
36
|
+
/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
|
|
36
37
|
#if 0 /* DEFINE_NO_DEPRECATED */
|
|
37
38
|
# ifndef CMARK_GFM_NO_DEPRECATED
|
|
38
39
|
# define CMARK_GFM_NO_DEPRECATED
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#ifndef CMARK_GFM_VERSION_H
|
|
2
2
|
#define CMARK_GFM_VERSION_H
|
|
3
3
|
|
|
4
|
-
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) |
|
|
5
|
-
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.
|
|
4
|
+
#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 13)
|
|
5
|
+
#define CMARK_GFM_VERSION_STRING "0.29.0.gfm.13"
|
|
6
6
|
|
|
7
7
|
#endif
|
data/ext/markly/cmark_ctype.c
CHANGED
|
@@ -42,3 +42,12 @@ int cmark_isalnum(char c) {
|
|
|
42
42
|
int cmark_isdigit(char c) { return cmark_ctype_class[(uint8_t)c] == 3; }
|
|
43
43
|
|
|
44
44
|
int cmark_isalpha(char c) { return cmark_ctype_class[(uint8_t)c] == 4; }
|
|
45
|
+
|
|
46
|
+
int cmark_is_inline_code_info_start_char(char c) {
|
|
47
|
+
return cmark_isalnum(c);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
int cmark_is_inline_code_info_char(char c) {
|
|
51
|
+
return cmark_is_inline_code_info_start_char(c) || c == '_' || c == '-' ||
|
|
52
|
+
c == '+' || c == '#' || c == '.';
|
|
53
|
+
}
|
data/ext/markly/cmark_ctype.h
CHANGED
|
@@ -26,6 +26,11 @@ int cmark_isdigit(char c);
|
|
|
26
26
|
CMARK_GFM_EXPORT
|
|
27
27
|
int cmark_isalpha(char c);
|
|
28
28
|
|
|
29
|
+
/* Character classes for inline code info identifiers. */
|
|
30
|
+
int cmark_is_inline_code_info_start_char(char c);
|
|
31
|
+
|
|
32
|
+
int cmark_is_inline_code_info_char(char c);
|
|
33
|
+
|
|
29
34
|
#ifdef __cplusplus
|
|
30
35
|
}
|
|
31
36
|
#endif
|
data/ext/markly/commonmark.c
CHANGED
|
@@ -271,7 +271,7 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
271
271
|
if (!first_in_list_item) {
|
|
272
272
|
BLANKLINE();
|
|
273
273
|
}
|
|
274
|
-
info =
|
|
274
|
+
info = cmark_node_get_code_info(node);
|
|
275
275
|
info_len = strlen(info);
|
|
276
276
|
fencechar[0] = strchr(info, '`') == NULL ? '`' : '~';
|
|
277
277
|
code = cmark_node_get_literal(node);
|
|
@@ -363,6 +363,10 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
363
363
|
extra_spaces = code_len == 0 ||
|
|
364
364
|
code[0] == '`' || code[code_len - 1] == '`' ||
|
|
365
365
|
code[0] == ' ' || code[code_len - 1] == ' ';
|
|
366
|
+
if (node->as.code.info.len > 0) {
|
|
367
|
+
OUT(cmark_node_get_code_info(node), false, LITERAL);
|
|
368
|
+
LIT(":");
|
|
369
|
+
}
|
|
366
370
|
for (i = 0; i < numticks; i++) {
|
|
367
371
|
LIT("`");
|
|
368
372
|
}
|
|
@@ -494,10 +498,13 @@ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
|
|
|
494
498
|
|
|
495
499
|
case CMARK_NODE_FRONT_MATTER:
|
|
496
500
|
if (entering) {
|
|
497
|
-
const char *
|
|
501
|
+
const char *front_matter_info = cmark_node_get_fence_info(node);
|
|
498
502
|
BLANKLINE();
|
|
499
503
|
LIT("---");
|
|
500
|
-
if (
|
|
504
|
+
if (front_matter_info && *front_matter_info) {
|
|
505
|
+
LIT(" ");
|
|
506
|
+
OUT(front_matter_info, false, LITERAL);
|
|
507
|
+
}
|
|
501
508
|
LIT("\n");
|
|
502
509
|
OUT(cmark_node_get_literal(node), false, LITERAL);
|
|
503
510
|
LIT("---\n");
|
data/ext/markly/config.h
CHANGED
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
extern "C" {
|
|
6
6
|
#endif
|
|
7
7
|
|
|
8
|
-
#ifndef HAVE_STDBOOL_H
|
|
9
8
|
#define HAVE_STDBOOL_H
|
|
10
|
-
#endif
|
|
11
9
|
|
|
12
10
|
#ifdef HAVE_STDBOOL_H
|
|
13
11
|
#include <stdbool.h>
|
|
@@ -71,8 +69,6 @@ CMARK_INLINE int c99_snprintf(char *outBuf, size_t size, const char *format, ...
|
|
|
71
69
|
|
|
72
70
|
#endif
|
|
73
71
|
|
|
74
|
-
#define CMARK_DEBUG_NODES 0
|
|
75
|
-
|
|
76
72
|
#ifdef __cplusplus
|
|
77
73
|
}
|
|
78
74
|
#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
|
|
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);
|