@@ -411,7 +411,7 @@ static int scan_delims(cmark_parser *parser, subject *subj, unsigned char c,
411411 before_char = 10 ;
412412 } else {
413413 before_char_pos = subj -> pos - 1 ;
414-
414+
415415 // walk back to the beginning of the UTF_8 sequence:
416416 while ((peek_at (subj , before_char_pos ) >> 6 == 2 || parser -> skip_chars [peek_at (subj , before_char_pos )]) && before_char_pos > 0 ) {
417417 before_char_pos -= 1 ;
@@ -437,7 +437,7 @@ static int scan_delims(cmark_parser *parser, subject *subj, unsigned char c,
437437 after_char = 10 ;
438438 } else {
439439 after_char_pos = subj -> pos ;
440-
440+
441441 while (parser -> skip_chars [peek_at (subj , after_char_pos )] && after_char_pos < subj -> input .len ) {
442442 after_char_pos += 1 ;
443443 }
@@ -944,7 +944,7 @@ static int link_label(subject *subj, cmark_chunk *raw_label, bool parse_attribut
944944 bufsize_t startpos = subj -> pos ;
945945 int length = 0 ;
946946 unsigned char c ;
947-
947+
948948 // If we are parsing attribute label, advance past ^
949949 if (parse_attribute_label ) {
950950 if (peek_char (subj ) == '^' ) {
@@ -1130,14 +1130,14 @@ static cmark_node *handle_close_bracket_attribute(cmark_parser *parser, subject
11301130 }
11311131 }
11321132 }
1133-
1133+
11341134 // If we can't match direct link, look for [link label] that matches in refmap
11351135 raw_label = cmark_chunk_literal ("" );
11361136 found_label = link_label (subj , & raw_label , false);
11371137 if (found_label ) {
11381138 ref = (cmark_reference * )cmark_map_lookup (subj -> refmap , & raw_label );
11391139 cmark_chunk_free (subj -> mem , & raw_label );
1140-
1140+
11411141 if (ref && ref -> is_attributes_reference ) {
11421142 isAttributesNode = true;
11431143 attributes = chunk_clone (subj -> mem , & ref -> attributes );
@@ -1149,7 +1149,7 @@ static cmark_node *handle_close_bracket_attribute(cmark_parser *parser, subject
11491149 pop_bracket (subj );
11501150 return make_str (subj , subj -> pos - 1 , subj -> pos - 1 , cmark_chunk_literal ("]" ));
11511151 }
1152-
1152+
11531153 inl = make_simple (subj -> mem , CMARK_NODE_ATTRIBUTE );
11541154 inl -> as .attribute .attributes = attributes ;
11551155 inl -> start_line = inl -> end_line = subj -> line ;
@@ -1516,6 +1516,7 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
15161516 cmark_chunk contents ;
15171517 unsigned char c ;
15181518 bufsize_t startpos , endpos ;
1519+ bufsize_t initpos = subj -> pos ;
15191520 c = peek_char (subj );
15201521 if (c == 0 ) {
15211522 return 0 ;
@@ -1563,43 +1564,50 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
15631564 new_inl = handle_close_bracket (parser , subj );
15641565 break ;
15651566 case '!' :
1566- advance (subj );
1567- if (peek_char (subj ) == '[' && peek_char_n (subj , 1 ) != '^' ) {
1567+ // specifically check for '![' not followed by '^'
1568+ if (peek_char_n (subj , 1 ) == '[' && peek_char_n (subj , 2 ) != '^' ) {
1569+ advance (subj );
15681570 advance (subj );
15691571 new_inl = make_str (subj , subj -> pos - 2 , subj -> pos - 1 , cmark_chunk_literal ("![" ));
15701572 push_bracket (subj , IMAGE , new_inl );
1571- } else {
1572- new_inl = make_str (subj , subj -> pos - 1 , subj -> pos - 1 , cmark_chunk_literal ("!" ));
15731573 }
15741574 break ;
15751575 case '^' :
1576- advance (subj );
15771576 // TODO: Support a name between ^ and [
1578- if (peek_char (subj ) == '[' ) {
1577+ // specifically check for '^['
1578+ if (peek_char_n (subj , 1 ) == '[' ) {
1579+ advance (subj );
15791580 advance (subj );
15801581 new_inl = make_str (subj , subj -> pos - 2 , subj -> pos - 1 , cmark_chunk_literal ("^[" ));
15811582 push_bracket (subj , ATTRIBUTE , new_inl );
1582- } else {
1583- new_inl = make_str (subj , subj -> pos - 1 , subj -> pos - 1 , cmark_chunk_literal ("^" ));
15841583 }
15851584 break ;
1586- default :
1587- new_inl = try_extensions (parser , parent , c , subj );
1588- if (new_inl != NULL )
1589- break ;
1585+ }
15901586
1591- endpos = subject_find_special_char (parser , subj , options );
1592- contents = cmark_chunk_dup (& subj -> input , subj -> pos , endpos - subj -> pos );
1593- startpos = subj -> pos ;
1594- subj -> pos = endpos ;
1587+ if (subj -> pos == initpos ) {
1588+ if (!new_inl )
1589+ new_inl = try_extensions (parser , parent , c , subj );
15951590
1596- // if we're at a newline, strip trailing spaces.
1597- if ((options & CMARK_OPT_PRESERVE_WHITESPACE ) == 0 && S_is_line_end_char (peek_char (subj ))) {
1598- cmark_chunk_rtrim (& contents );
1599- }
1591+ if (!new_inl ) {
1592+ endpos = subject_find_special_char (parser , subj , options );
1593+ if (endpos == subj -> pos ) {
1594+ advance (subj );
1595+ new_inl = make_str (subj , subj -> pos - 1 , subj -> pos - 1 , cmark_chunk_dup (& subj -> input , subj -> pos - 1 , 1 ));
1596+ } else {
1597+ contents = cmark_chunk_dup (& subj -> input , subj -> pos , endpos - subj -> pos );
1598+ startpos = subj -> pos ;
1599+ subj -> pos = endpos ;
1600+
1601+ // if we're at a newline, strip trailing spaces.
1602+ if ((options & CMARK_OPT_PRESERVE_WHITESPACE ) == 0 && S_is_line_end_char (peek_char (subj ))) {
1603+ cmark_chunk_rtrim (& contents );
1604+ }
16001605
1601- new_inl = make_str (subj , startpos , endpos - 1 , contents );
1606+ new_inl = make_str (subj , startpos , endpos - 1 , contents );
1607+ }
1608+ }
16021609 }
1610+
16031611 if (new_inl != NULL ) {
16041612 cmark_node_append_child (parent , new_inl );
16051613 }
@@ -1708,27 +1716,27 @@ bufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_chunk *input,
17081716bufsize_t cmark_parse_reference_attributes_inline (cmark_mem * mem , cmark_chunk * input ,
17091717 cmark_map * refmap ) {
17101718 subject subj ;
1711-
1719+
17121720 cmark_chunk lab ;
17131721 cmark_chunk attributes ;
1714-
1722+
17151723 bufsize_t matchlen = 0 ;
17161724 unsigned char c ;
1717-
1725+
17181726 subject_from_buf (mem , -1 , 0 , & subj , input , NULL );
1719-
1727+
17201728 // parse attribute label:
17211729 if (!link_label (& subj , & lab , true) || lab .len == 0 ) {
17221730 return 0 ;
17231731 }
1724-
1732+
17251733 // Colon:
17261734 if (peek_char (& subj ) == ':' ) {
17271735 advance (& subj );
17281736 } else {
17291737 return 0 ;
17301738 }
1731-
1739+
17321740 // parse attributes
17331741 spnl (& subj );
17341742 // read until next newline
@@ -1737,19 +1745,19 @@ bufsize_t cmark_parse_reference_attributes_inline(cmark_mem *mem, cmark_chunk *i
17371745 advance (& subj );
17381746 matchlen ++ ;
17391747 }
1740-
1748+
17411749 if (matchlen == 0 ) {
17421750 return 0 ;
17431751 }
1744-
1752+
17451753 attributes = cmark_chunk_dup (& subj .input , startpos , matchlen );
1746-
1754+
17471755 // parse final spaces and newline:
17481756 skip_spaces (& subj );
17491757 if (!skip_line_end (& subj )) {
17501758 return 0 ;
17511759 }
1752-
1760+
17531761 // insert reference into refmap
17541762 cmark_reference_create_attributes (refmap , & lab , & attributes );
17551763 return subj .pos ;
0 commit comments