Skip to content

Commit 4cee305

Browse files
cmark_parser: implement and expose reentrant feed function.
This can be useful for transclusion extensions for example, http://talk.commonmark.org/t/transclusion-or-including-sub-documents-for-reuse/270
1 parent 51f76f3 commit 4cee305

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

src/blocks.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,18 @@ void cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len) {
566566
S_parser_feed(parser, (const unsigned char *)buffer, len, false);
567567
}
568568

569+
void cmark_parser_feed_reentrant(cmark_parser *parser, const char *buffer, size_t len) {
570+
cmark_strbuf *saved_linebuf = parser->linebuf;
571+
cmark_strbuf *buf = (cmark_strbuf *)malloc(sizeof(cmark_strbuf));
572+
cmark_strbuf_init(buf, 0);
573+
574+
parser->linebuf = buf;
575+
S_parser_feed(parser, (const unsigned char *)buffer, len, true);
576+
cmark_strbuf_free(buf);
577+
578+
parser->linebuf = saved_linebuf;
579+
}
580+
569581
static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
570582
size_t len, bool eof) {
571583
const unsigned char *end = buffer + len;
@@ -1211,6 +1223,9 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
12111223
bool all_matched = true;
12121224
cmark_node *container;
12131225
cmark_chunk input;
1226+
cmark_node *current;
1227+
1228+
cmark_strbuf_clear(parser->curline);
12141229

12151230
if (parser->options & CMARK_OPT_VALIDATE_UTF8)
12161231
cmark_utf8proc_check(parser->curline, buffer, bytes);
@@ -1242,9 +1257,13 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
12421257
if (parser->blank && container->last_line_blank)
12431258
break_out_of_lists(parser, &container);
12441259

1260+
current = parser->current;
1261+
12451262
open_new_blocks(parser, &container, &input, all_matched);
12461263

1247-
add_text_to_container(parser, container, last_matched_container, &input);
1264+
/* parser->current might have changed if feed_reentrant was called */
1265+
if (current == parser->current)
1266+
add_text_to_container(parser, container, last_matched_container, &input);
12481267

12491268
finished:
12501269
parser->last_line_length = input.len;

src/cmark_extension_api.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,10 @@ void cmark_parser_advance_offset(cmark_parser *parser,
416416
int count,
417417
int columns);
418418

419+
420+
CMARK_EXPORT
421+
void cmark_parser_feed_reentrant(cmark_parser *parser, const char *buffer, size_t len);
422+
419423
/** Attach the syntax 'extension' to the 'parser', to provide extra syntax
420424
* rules.
421425
* See the documentation for cmark_syntax_extension for more information.

0 commit comments

Comments
 (0)