Skip to content

Commit 6df1faa

Browse files
iCharlesHuQuietMisdreavus
authored andcommitted
Don't emit an attribute node if it doesn't have parentheses
rdar://77476197
1 parent 471d20c commit 6df1faa

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

api_test/main.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,37 @@ static void preserve_whitespace_opt(test_batch_runner *runner) {
12031203
check_markdown_plaintext(runner, " hello \n \n world ");
12041204
}
12051205

1206+
static void check_markdown_attributes_node(test_batch_runner *runner, char *markdown, cmark_node_type expectedType, char *expectedAttributes) {
1207+
cmark_node *doc = cmark_parse_document(markdown, strlen(markdown), CMARK_OPT_DEFAULT);
1208+
cmark_node *pg = cmark_node_first_child(doc);
1209+
INT_EQ(runner, cmark_node_get_type(pg), CMARK_NODE_PARAGRAPH, "markdown '%s' did not produce a paragraph node", markdown);
1210+
cmark_node *attributeNode = cmark_node_first_child(pg);
1211+
cmark_node_type nodeType = cmark_node_get_type(attributeNode);
1212+
INT_EQ(runner, nodeType, expectedType, "markdown '%s' did not produce the correct node type: got %d, expecting %d", markdown, nodeType, expectedType);
1213+
const char *attributeContent = cmark_node_get_attributes(attributeNode);
1214+
if (attributeContent == NULL) {
1215+
OK(runner, expectedAttributes == NULL, "markdown '%s' produced an unexpected NULL attribute", markdown);
1216+
} else if (expectedAttributes == NULL) {
1217+
OK(runner, attributeContent == NULL, "markdown '%s' produced an unexpected NULL attribute", markdown);
1218+
} else {
1219+
STR_EQ(runner, attributeContent, expectedAttributes, "markdown '%s' did not produce the correct attributes: got %s, expecting: %s", markdown, attributeContent, expectedAttributes);
1220+
}
1221+
1222+
cmark_node_free(doc);
1223+
}
1224+
1225+
static void verify_custome_attributes_node(test_batch_runner *runner) {
1226+
// Should produce a TEXT node since there's no `()` to signify attributes
1227+
check_markdown_attributes_node(runner, "^[]", CMARK_NODE_TEXT, NULL);
1228+
check_markdown_attributes_node(runner, "^[](", CMARK_NODE_TEXT, NULL);
1229+
check_markdown_attributes_node(runner, "^[])", CMARK_NODE_TEXT, NULL);
1230+
check_markdown_attributes_node(runner, "^[])(", CMARK_NODE_TEXT, NULL);
1231+
// Should produce an ATTRIBUTE node with no attributes
1232+
check_markdown_attributes_node(runner, "^[]()", CMARK_NODE_ATTRIBUTE, "");
1233+
// Should produce an ATTRIBUTE node with attributes
1234+
check_markdown_attributes_node(runner, "^[](rainbow: 'extreme')", CMARK_NODE_ATTRIBUTE, "rainbow: 'extreme'");
1235+
}
1236+
12061237
int main() {
12071238
int retval;
12081239
test_batch_runner *runner = test_batch_runner_new();
@@ -1235,6 +1266,7 @@ int main() {
12351266
ref_source_pos(runner);
12361267
inline_only_opt(runner);
12371268
preserve_whitespace_opt(runner);
1269+
verify_custome_attributes_node(runner);
12381270

12391271
test_print_summary(runner);
12401272
retval = test_ok(runner) ? 0 : 1;

src/inlines.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,7 @@ static cmark_node *handle_close_bracket_attribute(cmark_parser *parser, subject
10941094
cmark_chunk raw_label;
10951095
int found_label;
10961096
cmark_node *tmp, *tmpnext;
1097+
bool isAttributesNode = false;
10971098

10981099
// ^name[content](attributes)
10991100
// TODO: support name. we will not even enter this with a name because we fail the match first
@@ -1108,9 +1109,20 @@ static cmark_node *handle_close_bracket_attribute(cmark_parser *parser, subject
11081109

11091110
if (peek_at(subj, endattributes) == ')') {
11101111
subj->pos = endattributes + 1;
1111-
attributes = cmark_chunk_dup(&subj->input, startattributes, endattributes - startattributes);
1112+
isAttributesNode = true;
1113+
if (endattributes - startattributes == 0) {
1114+
attributes = cmark_chunk_literal(NULL);
1115+
} else {
1116+
attributes = cmark_chunk_dup(&subj->input, startattributes, endattributes - startattributes);
1117+
}
11121118
}
11131119
}
1120+
1121+
if (!isAttributesNode) {
1122+
// The current node can't be parsed as attribute node, turn it to a TEXT node instead.
1123+
pop_bracket(subj);
1124+
return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal("]"));
1125+
}
11141126

11151127
inl = make_simple(subj->mem, CMARK_NODE_ATTRIBUTE);
11161128
inl->as.attribute.attributes = attributes;

0 commit comments

Comments
 (0)