@@ -67,7 +67,7 @@ static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
67
67
size_t len , bool eof );
68
68
69
69
static void S_process_line (cmark_parser * parser , const unsigned char * buffer ,
70
- bufsize_t bytes );
70
+ bufsize_t bytes , bool ensureEndsInNewline );
71
71
72
72
static cmark_node * make_block (cmark_mem * mem , cmark_node_type tag ,
73
73
int start_line , int start_column ) {
@@ -687,6 +687,7 @@ static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
687
687
size_t len , bool eof ) {
688
688
const unsigned char * end = buffer + len ;
689
689
static const uint8_t repl [] = {239 , 191 , 189 };
690
+ bool preserveWhitespace = parser -> options & CMARK_OPT_PRESERVE_WHITESPACE ;
690
691
691
692
if (parser -> last_buffer_ended_with_cr && * buffer == '\n' ) {
692
693
// skip NL if last buffer ended with CR ; see #117
@@ -714,10 +715,10 @@ static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
714
715
if (process ) {
715
716
if (parser -> linebuf .size > 0 ) {
716
717
cmark_strbuf_put (& parser -> linebuf , buffer , chunk_len );
717
- S_process_line (parser , parser -> linebuf .ptr , parser -> linebuf .size );
718
+ S_process_line (parser , parser -> linebuf .ptr , parser -> linebuf .size , ! preserveWhitespace || ! eof || eol < end );
718
719
cmark_strbuf_clear (& parser -> linebuf );
719
720
} else {
720
- S_process_line (parser , buffer , chunk_len );
721
+ S_process_line (parser , buffer , chunk_len , ! preserveWhitespace || ! eof || eol < end );
721
722
}
722
723
} else {
723
724
if (eol < end && * eol == '\0' ) {
@@ -1023,6 +1024,8 @@ static cmark_node *check_open_blocks(cmark_parser *parser, cmark_chunk *input,
1023
1024
* all_matched = false;
1024
1025
cmark_node * container = parser -> root ;
1025
1026
cmark_node_type cont_type ;
1027
+
1028
+
1026
1029
1027
1030
while (S_last_child_is_open (container )) {
1028
1031
container = container -> last_child ;
@@ -1337,7 +1340,7 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
1337
1340
// then treat this as a "lazy continuation line" and add it to
1338
1341
// the open paragraph.
1339
1342
if (parser -> current != last_matched_container &&
1340
- container == last_matched_container && !parser -> blank &&
1343
+ container == last_matched_container && ( !parser -> blank || ( parser -> options & CMARK_OPT_PRESERVE_WHITESPACE )) &&
1341
1344
S_type (parser -> current ) == CMARK_NODE_PARAGRAPH ) {
1342
1345
add_line (parser -> current , input , parser );
1343
1346
} else { // not a lazy continuation
@@ -1395,15 +1398,21 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
1395
1398
container -> as .heading .setext == false) {
1396
1399
chop_trailing_hashtags (input );
1397
1400
}
1398
- S_advance_offset (parser , input , parser -> first_nonspace - parser -> offset ,
1401
+ if ((parser -> options & CMARK_OPT_PRESERVE_WHITESPACE ) == 0 )
1402
+ S_advance_offset (parser , input , parser -> first_nonspace - parser -> offset ,
1399
1403
false);
1400
1404
add_line (container , input , parser );
1401
1405
} else {
1402
1406
// create paragraph container for line
1403
- container = add_child (parser , container , CMARK_NODE_PARAGRAPH ,
1404
- parser -> first_nonspace + 1 );
1405
- S_advance_offset (parser , input , parser -> first_nonspace - parser -> offset ,
1406
- false);
1407
+ if (parser -> options & CMARK_OPT_PRESERVE_WHITESPACE ) {
1408
+ container = add_child (parser , container , CMARK_NODE_PARAGRAPH ,
1409
+ parser -> offset + 1 );
1410
+ } else {
1411
+ container = add_child (parser , container , CMARK_NODE_PARAGRAPH ,
1412
+ parser -> first_nonspace + 1 );
1413
+ S_advance_offset (parser , input , parser -> first_nonspace - parser -> offset ,
1414
+ false);
1415
+ }
1407
1416
add_line (container , input , parser );
1408
1417
}
1409
1418
@@ -1413,7 +1422,7 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
1413
1422
1414
1423
/* See http://spec.commonmark.org/0.24/#phase-1-block-structure */
1415
1424
static void S_process_line (cmark_parser * parser , const unsigned char * buffer ,
1416
- bufsize_t bytes ) {
1425
+ bufsize_t bytes , bool ensureEndsInNewline ) {
1417
1426
cmark_node * last_matched_container ;
1418
1427
bool all_matched = true;
1419
1428
cmark_node * container ;
@@ -1430,7 +1439,7 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
1430
1439
bytes = parser -> curline .size ;
1431
1440
1432
1441
// ensure line ends with a newline:
1433
- if (bytes == 0 || !S_is_line_end_char (parser -> curline .ptr [bytes - 1 ]))
1442
+ if (ensureEndsInNewline && ( bytes == 0 || !S_is_line_end_char (parser -> curline .ptr [bytes - 1 ]) ))
1434
1443
cmark_strbuf_putc (& parser -> curline , '\n' );
1435
1444
1436
1445
parser -> offset = 0 ;
@@ -1463,7 +1472,9 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
1463
1472
1464
1473
current = parser -> current ;
1465
1474
1466
- open_new_blocks (parser , & container , & input , all_matched );
1475
+ // Only open new blocks if we're not limited to inline
1476
+ if ((parser -> options & CMARK_OPT_INLINE_ONLY ) == 0 )
1477
+ open_new_blocks (parser , & container , & input , all_matched );
1467
1478
1468
1479
/* parser->current might have changed if feed_reentrant was called */
1469
1480
if (current == parser -> current )
@@ -1490,7 +1501,7 @@ cmark_node *cmark_parser_finish(cmark_parser *parser) {
1490
1501
return NULL ;
1491
1502
1492
1503
if (parser -> linebuf .size ) {
1493
- S_process_line (parser , parser -> linebuf .ptr , parser -> linebuf .size );
1504
+ S_process_line (parser , parser -> linebuf .ptr , parser -> linebuf .size , ( parser -> options & CMARK_OPT_PRESERVE_WHITESPACE ) == 0 );
1494
1505
cmark_strbuf_clear (& parser -> linebuf );
1495
1506
}
1496
1507
0 commit comments