Skip to content

Commit 3843151

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 3c2f4f2 commit 3843151

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;
@@ -1216,6 +1228,9 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
12161228
bool all_matched = true;
12171229
cmark_node *container;
12181230
cmark_chunk input;
1231+
cmark_node *current;
1232+
1233+
cmark_strbuf_clear(parser->curline);
12191234

12201235
if (parser->options & CMARK_OPT_VALIDATE_UTF8)
12211236
cmark_utf8proc_check(parser->curline, buffer, bytes);
@@ -1248,9 +1263,13 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
12481263
if (parser->blank && container->last_line_blank)
12491264
break_out_of_lists(parser, &container);
12501265

1266+
current = parser->current;
1267+
12511268
open_new_blocks(parser, &container, &input, all_matched);
12521269

1253-
add_text_to_container(parser, container, last_matched_container, &input);
1270+
/* parser->current might have changed if feed_reentrant was called */
1271+
if (current == parser->current)
1272+
add_text_to_container(parser, container, last_matched_container, &input);
12541273

12551274
finished:
12561275
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
@@ -414,6 +414,10 @@ void cmark_parser_advance_offset(cmark_parser *parser,
414414
int count,
415415
int columns);
416416

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

0 commit comments

Comments
 (0)