@@ -67,7 +67,7 @@ static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
6767 size_t len , bool eof );
6868
6969static void S_process_line (cmark_parser * parser , const unsigned char * buffer ,
70- bufsize_t bytes );
70+ bufsize_t bytes , bool ensureEndsInNewline );
7171
7272static cmark_node * make_block (cmark_mem * mem , cmark_node_type tag ,
7373 int start_line , int start_column ) {
@@ -687,6 +687,7 @@ static void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,
687687 size_t len , bool eof ) {
688688 const unsigned char * end = buffer + len ;
689689 static const uint8_t repl [] = {239 , 191 , 189 };
690+ bool preserveWhitespace = parser -> options & CMARK_OPT_PRESERVE_WHITESPACE ;
690691
691692 if (parser -> last_buffer_ended_with_cr && * buffer == '\n' ) {
692693 // 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,
714715 if (process ) {
715716 if (parser -> linebuf .size > 0 ) {
716717 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 );
718719 cmark_strbuf_clear (& parser -> linebuf );
719720 } else {
720- S_process_line (parser , buffer , chunk_len );
721+ S_process_line (parser , buffer , chunk_len , ! preserveWhitespace || ! eof || eol < end );
721722 }
722723 } else {
723724 if (eol < end && * eol == '\0' ) {
@@ -1023,6 +1024,8 @@ static cmark_node *check_open_blocks(cmark_parser *parser, cmark_chunk *input,
10231024 * all_matched = false;
10241025 cmark_node * container = parser -> root ;
10251026 cmark_node_type cont_type ;
1027+
1028+
10261029
10271030 while (S_last_child_is_open (container )) {
10281031 container = container -> last_child ;
@@ -1337,7 +1340,7 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
13371340 // then treat this as a "lazy continuation line" and add it to
13381341 // the open paragraph.
13391342 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 )) &&
13411344 S_type (parser -> current ) == CMARK_NODE_PARAGRAPH ) {
13421345 add_line (parser -> current , input , parser );
13431346 } else { // not a lazy continuation
@@ -1395,15 +1398,21 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
13951398 container -> as .heading .setext == false) {
13961399 chop_trailing_hashtags (input );
13971400 }
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 ,
13991403 false);
14001404 add_line (container , input , parser );
14011405 } else {
14021406 // 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+ }
14071416 add_line (container , input , parser );
14081417 }
14091418
@@ -1413,7 +1422,7 @@ static void add_text_to_container(cmark_parser *parser, cmark_node *container,
14131422
14141423/* See http://spec.commonmark.org/0.24/#phase-1-block-structure */
14151424static void S_process_line (cmark_parser * parser , const unsigned char * buffer ,
1416- bufsize_t bytes ) {
1425+ bufsize_t bytes , bool ensureEndsInNewline ) {
14171426 cmark_node * last_matched_container ;
14181427 bool all_matched = true;
14191428 cmark_node * container ;
@@ -1430,7 +1439,7 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
14301439 bytes = parser -> curline .size ;
14311440
14321441 // 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 ]) ))
14341443 cmark_strbuf_putc (& parser -> curline , '\n' );
14351444
14361445 parser -> offset = 0 ;
@@ -1463,7 +1472,9 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
14631472
14641473 current = parser -> current ;
14651474
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 );
14671478
14681479 /* parser->current might have changed if feed_reentrant was called */
14691480 if (current == parser -> current )
@@ -1490,7 +1501,7 @@ cmark_node *cmark_parser_finish(cmark_parser *parser) {
14901501 return NULL ;
14911502
14921503 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 );
14941505 cmark_strbuf_clear (& parser -> linebuf );
14951506 }
14961507
0 commit comments