@@ -411,7 +411,7 @@ static int scan_delims(cmark_parser *parser, subject *subj, unsigned char c,
411
411
before_char = 10 ;
412
412
} else {
413
413
before_char_pos = subj -> pos - 1 ;
414
-
414
+
415
415
// walk back to the beginning of the UTF_8 sequence:
416
416
while ((peek_at (subj , before_char_pos ) >> 6 == 2 || parser -> skip_chars [peek_at (subj , before_char_pos )]) && before_char_pos > 0 ) {
417
417
before_char_pos -= 1 ;
@@ -437,7 +437,7 @@ static int scan_delims(cmark_parser *parser, subject *subj, unsigned char c,
437
437
after_char = 10 ;
438
438
} else {
439
439
after_char_pos = subj -> pos ;
440
-
440
+
441
441
while (parser -> skip_chars [peek_at (subj , after_char_pos )] && after_char_pos < subj -> input .len ) {
442
442
after_char_pos += 1 ;
443
443
}
@@ -944,7 +944,7 @@ static int link_label(subject *subj, cmark_chunk *raw_label, bool parse_attribut
944
944
bufsize_t startpos = subj -> pos ;
945
945
int length = 0 ;
946
946
unsigned char c ;
947
-
947
+
948
948
// If we are parsing attribute label, advance past ^
949
949
if (parse_attribute_label ) {
950
950
if (peek_char (subj ) == '^' ) {
@@ -1130,14 +1130,14 @@ static cmark_node *handle_close_bracket_attribute(cmark_parser *parser, subject
1130
1130
}
1131
1131
}
1132
1132
}
1133
-
1133
+
1134
1134
// If we can't match direct link, look for [link label] that matches in refmap
1135
1135
raw_label = cmark_chunk_literal ("" );
1136
1136
found_label = link_label (subj , & raw_label , false);
1137
1137
if (found_label ) {
1138
1138
ref = (cmark_reference * )cmark_map_lookup (subj -> refmap , & raw_label );
1139
1139
cmark_chunk_free (subj -> mem , & raw_label );
1140
-
1140
+
1141
1141
if (ref && ref -> is_attributes_reference ) {
1142
1142
isAttributesNode = true;
1143
1143
attributes = chunk_clone (subj -> mem , & ref -> attributes );
@@ -1149,7 +1149,7 @@ static cmark_node *handle_close_bracket_attribute(cmark_parser *parser, subject
1149
1149
pop_bracket (subj );
1150
1150
return make_str (subj , subj -> pos - 1 , subj -> pos - 1 , cmark_chunk_literal ("]" ));
1151
1151
}
1152
-
1152
+
1153
1153
inl = make_simple (subj -> mem , CMARK_NODE_ATTRIBUTE );
1154
1154
inl -> as .attribute .attributes = attributes ;
1155
1155
inl -> start_line = inl -> end_line = subj -> line ;
@@ -1516,6 +1516,7 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
1516
1516
cmark_chunk contents ;
1517
1517
unsigned char c ;
1518
1518
bufsize_t startpos , endpos ;
1519
+ bufsize_t initpos = subj -> pos ;
1519
1520
c = peek_char (subj );
1520
1521
if (c == 0 ) {
1521
1522
return 0 ;
@@ -1563,43 +1564,50 @@ static int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent,
1563
1564
new_inl = handle_close_bracket (parser , subj );
1564
1565
break ;
1565
1566
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 );
1568
1570
advance (subj );
1569
1571
new_inl = make_str (subj , subj -> pos - 2 , subj -> pos - 1 , cmark_chunk_literal ("![" ));
1570
1572
push_bracket (subj , IMAGE , new_inl );
1571
- } else {
1572
- new_inl = make_str (subj , subj -> pos - 1 , subj -> pos - 1 , cmark_chunk_literal ("!" ));
1573
1573
}
1574
1574
break ;
1575
1575
case '^' :
1576
- advance (subj );
1577
1576
// 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 );
1579
1580
advance (subj );
1580
1581
new_inl = make_str (subj , subj -> pos - 2 , subj -> pos - 1 , cmark_chunk_literal ("^[" ));
1581
1582
push_bracket (subj , ATTRIBUTE , new_inl );
1582
- } else {
1583
- new_inl = make_str (subj , subj -> pos - 1 , subj -> pos - 1 , cmark_chunk_literal ("^" ));
1584
1583
}
1585
1584
break ;
1586
- default :
1587
- new_inl = try_extensions (parser , parent , c , subj );
1588
- if (new_inl != NULL )
1589
- break ;
1585
+ }
1590
1586
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 );
1595
1590
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
+ }
1600
1605
1601
- new_inl = make_str (subj , startpos , endpos - 1 , contents );
1606
+ new_inl = make_str (subj , startpos , endpos - 1 , contents );
1607
+ }
1608
+ }
1602
1609
}
1610
+
1603
1611
if (new_inl != NULL ) {
1604
1612
cmark_node_append_child (parent , new_inl );
1605
1613
}
@@ -1708,27 +1716,27 @@ bufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_chunk *input,
1708
1716
bufsize_t cmark_parse_reference_attributes_inline (cmark_mem * mem , cmark_chunk * input ,
1709
1717
cmark_map * refmap ) {
1710
1718
subject subj ;
1711
-
1719
+
1712
1720
cmark_chunk lab ;
1713
1721
cmark_chunk attributes ;
1714
-
1722
+
1715
1723
bufsize_t matchlen = 0 ;
1716
1724
unsigned char c ;
1717
-
1725
+
1718
1726
subject_from_buf (mem , -1 , 0 , & subj , input , NULL );
1719
-
1727
+
1720
1728
// parse attribute label:
1721
1729
if (!link_label (& subj , & lab , true) || lab .len == 0 ) {
1722
1730
return 0 ;
1723
1731
}
1724
-
1732
+
1725
1733
// Colon:
1726
1734
if (peek_char (& subj ) == ':' ) {
1727
1735
advance (& subj );
1728
1736
} else {
1729
1737
return 0 ;
1730
1738
}
1731
-
1739
+
1732
1740
// parse attributes
1733
1741
spnl (& subj );
1734
1742
// read until next newline
@@ -1737,19 +1745,19 @@ bufsize_t cmark_parse_reference_attributes_inline(cmark_mem *mem, cmark_chunk *i
1737
1745
advance (& subj );
1738
1746
matchlen ++ ;
1739
1747
}
1740
-
1748
+
1741
1749
if (matchlen == 0 ) {
1742
1750
return 0 ;
1743
1751
}
1744
-
1752
+
1745
1753
attributes = cmark_chunk_dup (& subj .input , startpos , matchlen );
1746
-
1754
+
1747
1755
// parse final spaces and newline:
1748
1756
skip_spaces (& subj );
1749
1757
if (!skip_line_end (& subj )) {
1750
1758
return 0 ;
1751
1759
}
1752
-
1760
+
1753
1761
// insert reference into refmap
1754
1762
cmark_reference_create_attributes (refmap , & lab , & attributes );
1755
1763
return subj .pos ;
0 commit comments