Cutdown Ambiguity Matrix
Rules Under Test
- Escapes resolve before token matching.
- Brace-family tie-break uses same priority + longest opener (
{{before{) + left-to-right. - In
[text][...]target slot, leading@means citation-link classification; mention parser does not run there. - Invalid openers are emitted as literal text unless a rule says otherwise.
Canonical Cases
1) Escape precedence
Input:
\{{name}}
Expected AST:
Paragraph
└── Text("{{name}}")
Input:
\@alice
Expected AST:
Paragraph
└── Text("@alice")
Input:
\[a][@c1]
Expected AST:
Paragraph
└── Text("[a][@c1]")
2) Variable vs attributes
Input:
{{customer}}{.v}
Expected AST:
Paragraph
└── Variable(key="customer", attributes={class:["v"]})
Input:
{{}}
Expected AST:
Paragraph
└── Text("{{}}")
Input:
{{name}
Expected AST:
Paragraph
└── Text("{{name}")
3) Citation-link context vs mention
Input:
[paper][@smith2025]
Expected AST:
Paragraph
└── Link(kind="cite", text=[Text("paper")], target="@smith2025")
Input:
[][@a.b-c_d]
Expected AST:
Paragraph
└── Link(kind="cite", text=[], target="@a.b-c_d")
Input:
[@smith2025]
Expected AST:
Paragraph
└── Text("[@smith2025]")
4) Inline boundary crossing (CDN-0014)
Greedy left-to-right parse is unchanged. CDN-0014 is emitted at the span of the crossing closer.
Input:
** a __ b ** c __
Expected AST:
Paragraph
├── Emphasis([Text("a __ b")])
└── Text(" c __")
Expected diagnostics:
CDN-0014 warning span: the closing "**" (col 9)
message: Crossed inline boundaries: "**" closes while "__" (col 5) is still open
Input:
"" q start [link "" q end][/path]
Expected AST:
Paragraph
├── QuoteInline([Text("q start [link")])
└── Text(" q end][/path]")
Expected diagnostics:
CDN-0014 warning span: the closing '""' (col 16)
message: Crossed inline boundaries: '""' closes while "[" (col 10) is still open
Input (valid nesting — no diagnostic):
** __ text __ **
Expected AST:
Paragraph
└── Emphasis([Strong([Text("text")])])
Expected diagnostics: none
Input (triple crossing — two CDN-0014 emitted):
** __ ~~ text ** __ ~~
Expected AST:
Paragraph
├── Emphasis([Text("__ ~~ text")])
└── Text(" __ ~~")
Expected diagnostics:
CDN-0014 warning span: closing "**" (col 15) — closes while "__" (col 4) is open
CDN-0014 warning span: closing "**" (col 15) — closes while "~~" (col 7) is open
5) Spoiler ^^ opener
Input:
\^^secret^^
Expected AST:
Paragraph
└── Text("^^secret^^")
Input:
^^{{var}}^^
Expected AST:
Paragraph
└── Spoiler([Variable(key="var")])
Input:
^^ open
Expected AST:
Paragraph
├── Text("^^")
└── Text(" open")
Input:
**^^x^^**
Expected AST:
Paragraph
└── Emphasis([Spoiler([Text("x")])])
Input:
^^^x^^^
Expected AST:
Paragraph
├── Spoiler([Text("^x")])
└── Text("^^")
Input (boundary crossing — CDN-0014):
^^ a ** b ^^ c **
Expected AST:
Paragraph
├── Spoiler([Text("a ** b")])
└── Text(" c **")
Expected diagnostics:
CDN-0014 warning span: the closing "^^" (col 11)
message: Crossed inline boundaries: "^^" closes while "**" (col 6) is still open
6) CodeInline escape (\` only)
Input:
``\`x``
Expected AST:
Paragraph
└── CodeInline(value="`x")
Input (double backslash stays literal — \\ is NOT an escape inside CodeInline):
``a\\b``
Expected AST:
Paragraph
└── CodeInline(value="a\\b")
Input (unknown \X stays literal):
``\nb``
Expected AST:
Paragraph
└── CodeInline(value="\nb")
Note: the value above contains the two literal characters \ and n, not a newline.
Input (escape lets multi-backtick embed — the motivating case):
``\`\`\`x``
Expected AST:
Paragraph
└── CodeInline(value="```x")
Input (interaction with run-of-3 opener collapse):
```\`x```
Expected AST:
Paragraph
└── CodeInline(value="``x")
The opener ``` collapses via run-of-3 to (double opener) + literal `` (in content). Then `` \ inside contributes another literal ` for a value of x .
Change Checklist
For every new inline token:
- Add at least one escape case.
- Add at least one opener conflict case.
- Add at least one malformed/unclosed case.
- Add one interaction case with each neighboring precedence tier.
- Add expected AST snapshots.