Skip to content

Commit c816eae

Browse files
allow extensions to use ! and ^ as special characters (#30)
* allow extensions to use `!` and `^` as special characters * update Makefile with new include dir
1 parent ef4622f commit c816eae

File tree

2 files changed

+46
-38
lines changed

2 files changed

+46
-38
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ mingw:
101101
cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchain-mingw32.cmake -DCMAKE_INSTALL_PREFIX=$(MINGW_INSTALLDIR) ;\
102102
$(MAKE) && $(MAKE) install
103103

104-
man/man3/cmark-gfm.3: src/cmark-gfm.h | $(CMARK)
104+
man/man3/cmark-gfm.3: src/include/cmark-gfm.h | $(CMARK)
105105
python man/make_man_page.py $< > $@ \
106106

107107
archive:

src/inlines.c

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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,
17081716
bufsize_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

Comments
 (0)