Skip to content

Commit cadb630

Browse files
authored
Merge pull request #90 from MDeiml/code-span-parse-ahead
Avoid conflicts for code spans by parsing ahead
2 parents 10b9b5a + 5fb1552 commit cadb630

File tree

5 files changed

+23612
-23707
lines changed

5 files changed

+23612
-23707
lines changed

tree-sitter-markdown-inline/corpus/issues.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,19 @@ foo `<!--comment-->`
8888
(code_span
8989
(code_span_delimiter)
9090
(code_span_delimiter)))
91+
92+
================================================================================
93+
#75 - code spans with `[x][]`
94+
================================================================================
95+
`some code`
96+
normal text (or even nothing) `[index][]`
97+
98+
--------------------------------------------------------------------------------
99+
100+
(inline
101+
(code_span
102+
(code_span_delimiter)
103+
(code_span_delimiter))
104+
(code_span
105+
(code_span_delimiter)
106+
(code_span_delimiter)))

tree-sitter-markdown-inline/grammar.js

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ const common = require('../common/grammar.js');
99
const PRECEDENCE_LEVEL_EMPHASIS = 1;
1010
const PRECEDENCE_LEVEL_LINK = 10;
1111
const PRECEDENCE_LEVEL_HTML = 100;
12-
const PRECEDENCE_LEVEL_CODE_SPAN = 100;
13-
const PRECEDENCE_LEVEL_LATEX = 100;
1412

1513
// Punctuation characters as specified in
1614
// https://github.github.com/gfm/#ascii-punctuation-character
@@ -70,6 +68,10 @@ module.exports = grammar(add_inline_rules({
7068
// An opening token does not mean the text after has to be latex if there is no closing token
7169
$._latex_span_start,
7270
$._latex_span_close,
71+
72+
// Token emmited when encountering opening delimiters for a leaf span
73+
// e.g. a code span, that does not have a matching closing span
74+
$._unclosed_span
7375
],
7476
precedences: $ => [
7577
// [$._strong_emphasis_star, $._inline_element_no_star],
@@ -81,8 +83,6 @@ module.exports = grammar(add_inline_rules({
8183
],
8284
// More conflicts are defined in `add_inline_rules`
8385
conflicts: $ => [
84-
[$.code_span, $._inline_base],
85-
[$.latex_block, $._inline_base],
8686

8787
[$._closing_tag, $._text_base],
8888
[$._open_tag, $._text_base],
@@ -121,25 +121,23 @@ module.exports = grammar(add_inline_rules({
121121
// A lot of inlines are defined in `add_inline_rules`, including:
122122
//
123123
// * collections of inlines
124-
// * code spans
125-
// * latex spans
126124
// * emphasis
127125
// * textual content
128126
//
129127
// This is done to reduce code duplication, as some inlines need to be parsed differently
130128
// depending on the context. For example inlines in ATX headings may not contain newlines.
131129

132-
code_span: $ => prec.dynamic(PRECEDENCE_LEVEL_CODE_SPAN, seq(
130+
code_span: $ => seq(
133131
alias($._code_span_start, $.code_span_delimiter),
134132
repeat(choice($._text_base, '[', ']', $._soft_line_break, $._html_tag)),
135133
alias($._code_span_close, $.code_span_delimiter)
136-
)),
134+
),
137135

138-
latex_block: $ => prec.dynamic(PRECEDENCE_LEVEL_LATEX, seq(
136+
latex_block: $ => seq(
139137
alias($._latex_span_start, $.latex_span_delimiter),
140138
repeat(choice($._text_base, '[', ']', $._soft_line_break, $._html_tag)),
141139
alias($._latex_span_close, $.latex_span_delimiter),
142-
)),
140+
),
143141

144142
// Different kinds of links:
145143
// * inline links (https://github.github.com/gfm/#inline-link)
@@ -346,9 +344,8 @@ module.exports = grammar(add_inline_rules({
346344
$.code_span,
347345
alias($._html_tag, $.html_tag),
348346
$._text_base,
349-
$._code_span_start,
350347
common.EXTENSION_TAGS ? $.tag : choice(),
351-
(common.EXTENSION_LATEX ? $._latex_span_start : choice()),
348+
$._unclosed_span,
352349
))),
353350
_text_base: $ => choice(
354351
$._word,
@@ -361,10 +358,9 @@ module.exports = grammar(add_inline_rules({
361358
),
362359
_text_inline_no_link: $ => choice(
363360
$._text_base,
364-
$._code_span_start,
365-
$._latex_span_start,
366361
$._emphasis_open_star,
367362
$._emphasis_open_underscore,
363+
$._unclosed_span,
368364
),
369365

370366
...(common.EXTENSION_TAGS ? {

tree-sitter-markdown-inline/src/grammar.json

Lines changed: 102 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,114 +1458,106 @@
14581458
"value": "\\n|\\r\\n?"
14591459
},
14601460
"code_span": {
1461-
"type": "PREC_DYNAMIC",
1462-
"value": 100,
1463-
"content": {
1464-
"type": "SEQ",
1465-
"members": [
1466-
{
1467-
"type": "ALIAS",
1468-
"content": {
1469-
"type": "SYMBOL",
1470-
"name": "_code_span_start"
1471-
},
1472-
"named": true,
1473-
"value": "code_span_delimiter"
1474-
},
1475-
{
1476-
"type": "REPEAT",
1477-
"content": {
1478-
"type": "CHOICE",
1479-
"members": [
1480-
{
1481-
"type": "SYMBOL",
1482-
"name": "_text_base"
1483-
},
1484-
{
1485-
"type": "STRING",
1486-
"value": "["
1487-
},
1488-
{
1489-
"type": "STRING",
1490-
"value": "]"
1491-
},
1492-
{
1493-
"type": "SYMBOL",
1494-
"name": "_soft_line_break"
1495-
},
1496-
{
1497-
"type": "SYMBOL",
1498-
"name": "_html_tag"
1499-
}
1500-
]
1501-
}
1461+
"type": "SEQ",
1462+
"members": [
1463+
{
1464+
"type": "ALIAS",
1465+
"content": {
1466+
"type": "SYMBOL",
1467+
"name": "_code_span_start"
15021468
},
1503-
{
1504-
"type": "ALIAS",
1505-
"content": {
1506-
"type": "SYMBOL",
1507-
"name": "_code_span_close"
1508-
},
1509-
"named": true,
1510-
"value": "code_span_delimiter"
1469+
"named": true,
1470+
"value": "code_span_delimiter"
1471+
},
1472+
{
1473+
"type": "REPEAT",
1474+
"content": {
1475+
"type": "CHOICE",
1476+
"members": [
1477+
{
1478+
"type": "SYMBOL",
1479+
"name": "_text_base"
1480+
},
1481+
{
1482+
"type": "STRING",
1483+
"value": "["
1484+
},
1485+
{
1486+
"type": "STRING",
1487+
"value": "]"
1488+
},
1489+
{
1490+
"type": "SYMBOL",
1491+
"name": "_soft_line_break"
1492+
},
1493+
{
1494+
"type": "SYMBOL",
1495+
"name": "_html_tag"
1496+
}
1497+
]
15111498
}
1512-
]
1513-
}
1499+
},
1500+
{
1501+
"type": "ALIAS",
1502+
"content": {
1503+
"type": "SYMBOL",
1504+
"name": "_code_span_close"
1505+
},
1506+
"named": true,
1507+
"value": "code_span_delimiter"
1508+
}
1509+
]
15141510
},
15151511
"latex_block": {
1516-
"type": "PREC_DYNAMIC",
1517-
"value": 100,
1518-
"content": {
1519-
"type": "SEQ",
1520-
"members": [
1521-
{
1522-
"type": "ALIAS",
1523-
"content": {
1524-
"type": "SYMBOL",
1525-
"name": "_latex_span_start"
1526-
},
1527-
"named": true,
1528-
"value": "latex_span_delimiter"
1529-
},
1530-
{
1531-
"type": "REPEAT",
1532-
"content": {
1533-
"type": "CHOICE",
1534-
"members": [
1535-
{
1536-
"type": "SYMBOL",
1537-
"name": "_text_base"
1538-
},
1539-
{
1540-
"type": "STRING",
1541-
"value": "["
1542-
},
1543-
{
1544-
"type": "STRING",
1545-
"value": "]"
1546-
},
1547-
{
1548-
"type": "SYMBOL",
1549-
"name": "_soft_line_break"
1550-
},
1551-
{
1552-
"type": "SYMBOL",
1553-
"name": "_html_tag"
1554-
}
1555-
]
1556-
}
1512+
"type": "SEQ",
1513+
"members": [
1514+
{
1515+
"type": "ALIAS",
1516+
"content": {
1517+
"type": "SYMBOL",
1518+
"name": "_latex_span_start"
15571519
},
1558-
{
1559-
"type": "ALIAS",
1560-
"content": {
1561-
"type": "SYMBOL",
1562-
"name": "_latex_span_close"
1563-
},
1564-
"named": true,
1565-
"value": "latex_span_delimiter"
1520+
"named": true,
1521+
"value": "latex_span_delimiter"
1522+
},
1523+
{
1524+
"type": "REPEAT",
1525+
"content": {
1526+
"type": "CHOICE",
1527+
"members": [
1528+
{
1529+
"type": "SYMBOL",
1530+
"name": "_text_base"
1531+
},
1532+
{
1533+
"type": "STRING",
1534+
"value": "["
1535+
},
1536+
{
1537+
"type": "STRING",
1538+
"value": "]"
1539+
},
1540+
{
1541+
"type": "SYMBOL",
1542+
"name": "_soft_line_break"
1543+
},
1544+
{
1545+
"type": "SYMBOL",
1546+
"name": "_html_tag"
1547+
}
1548+
]
15661549
}
1567-
]
1568-
}
1550+
},
1551+
{
1552+
"type": "ALIAS",
1553+
"content": {
1554+
"type": "SYMBOL",
1555+
"name": "_latex_span_close"
1556+
},
1557+
"named": true,
1558+
"value": "latex_span_delimiter"
1559+
}
1560+
]
15691561
},
15701562
"_link_text": {
15711563
"type": "PREC_DYNAMIC",
@@ -4215,17 +4207,13 @@
42154207
"type": "SYMBOL",
42164208
"name": "_text_base"
42174209
},
4218-
{
4219-
"type": "SYMBOL",
4220-
"name": "_code_span_start"
4221-
},
42224210
{
42234211
"type": "CHOICE",
42244212
"members": []
42254213
},
42264214
{
42274215
"type": "SYMBOL",
4228-
"name": "_latex_span_start"
4216+
"name": "_unclosed_span"
42294217
}
42304218
]
42314219
}
@@ -4411,19 +4399,15 @@
44114399
},
44124400
{
44134401
"type": "SYMBOL",
4414-
"name": "_code_span_start"
4415-
},
4416-
{
4417-
"type": "SYMBOL",
4418-
"name": "_latex_span_start"
4402+
"name": "_emphasis_open_star"
44194403
},
44204404
{
44214405
"type": "SYMBOL",
4422-
"name": "_emphasis_open_star"
4406+
"name": "_emphasis_open_underscore"
44234407
},
44244408
{
44254409
"type": "SYMBOL",
4426-
"name": "_emphasis_open_underscore"
4410+
"name": "_unclosed_span"
44274411
}
44284412
]
44294413
},
@@ -5556,14 +5540,6 @@
55565540
},
55575541
"extras": [],
55585542
"conflicts": [
5559-
[
5560-
"code_span",
5561-
"_inline_base"
5562-
],
5563-
[
5564-
"latex_block",
5565-
"_inline_base"
5566-
],
55675543
[
55685544
"_closing_tag",
55695545
"_text_base"
@@ -5888,6 +5864,10 @@
58885864
{
58895865
"type": "SYMBOL",
58905866
"name": "_latex_span_close"
5867+
},
5868+
{
5869+
"type": "SYMBOL",
5870+
"name": "_unclosed_span"
58915871
}
58925872
],
58935873
"inline": [],

0 commit comments

Comments
 (0)