should be text.
+
+## Invalid Comments
+Invalid start should be text.
+Double dash should be text maybe.
+Starts with arrow should be text.
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdHeader {
+ before: MdHashList [
+ MdHash {
+ hash_token: HASH@0..1 "#" [] [],
+ },
+ ],
+ content: MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@1..27 " Invalid Inline HTML Cases" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ after: MdHashList [],
+ },
+ MdNewline {
+ value_token: NEWLINE@27..28 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@28..29 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@29..84 "These should all be parsed as text, NOT as inline HTML." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@84..85 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@85..86 "\n" [] [],
+ },
+ MdHeader {
+ before: MdHashList [
+ MdHash {
+ hash_token: HASH@86..88 "##" [] [],
+ },
+ ],
+ content: MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@88..107 " Period in Tag Name" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ after: MdHashList [],
+ },
+ MdNewline {
+ value_token: NEWLINE@107..108 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@108..116 "The URL " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@116..117 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@117..128 "example.com" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@128..129 ">" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@129..149 " should remain text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@149..150 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@150..157 "Domain " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@157..158 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@158..174 "test.example.com" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@174..175 ">" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@175..195 " should remain text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@195..196 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@196..197 "\n" [] [],
+ },
+ MdHeader {
+ before: MdHashList [
+ MdHash {
+ hash_token: HASH@197..199 "##" [] [],
+ },
+ ],
+ content: MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@199..213 " Unclosed Tags" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ after: MdHashList [],
+ },
+ MdNewline {
+ value_token: NEWLINE@213..214 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@214..227 "Open bracket " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@227..228 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@228..246 " followed by text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@246..247 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@247..259 "Partial tag " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@259..260 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@260..279 "div should be text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@279..280 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@280..292 "Missing end " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@292..293 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@293..325 "div class=\"test\" should be text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@325..326 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@326..339 "Missing name " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@339..340 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@340..348 "div =foo" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@348..349 ">" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@349..365 " should be text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@365..366 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@366..380 "Missing value " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@380..381 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@381..389 "div data" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@389..390 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@390..392 "x=" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@392..393 ">" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@393..409 " should be text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@409..410 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@410..431 "Backtick in unquoted " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@431..432 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@432..440 "div data" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@440..441 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@441..443 "x=" [] [],
+ },
+ MdInlineCode {
+ l_tick_token: BACKTICK@443..444 "`" [] [],
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@444..445 "a" [] [],
+ },
+ ],
+ r_tick_token: BACKTICK@445..446 "`" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@446..447 ">" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@447..463 " should be text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@463..464 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@464..477 "Invalid name " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@477..478 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@478..488 "div 1a=foo" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@488..489 ">" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@489..505 " should be text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@505..506 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@506..507 "\n" [] [],
+ },
+ MdHeader {
+ before: MdHashList [
+ MdHash {
+ hash_token: HASH@507..509 "##" [] [],
+ },
+ ],
+ content: MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@509..526 " Invalid Comments" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ after: MdHashList [],
+ },
+ MdNewline {
+ value_token: NEWLINE@526..527 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@527..541 "Invalid start " [] [],
+ },
+ MdInlineHtml {
+ value: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@541..542 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@542..543 "!" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@543..544 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@544..545 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@545..546 ">" [] [],
+ },
+ ],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@546..562 " should be text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@562..563 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@563..575 "Double dash " [] [],
+ },
+ MdInlineHtml {
+ value: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@575..576 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@576..577 "!" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@577..578 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@578..579 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@579..584 " foo " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@584..585 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@585..586 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@586..591 " bar " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@591..592 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@592..593 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@593..594 ">" [] [],
+ },
+ ],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@594..616 " should be text maybe." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@616..617 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@617..635 "Starts with arrow " [] [],
+ },
+ MdInlineHtml {
+ value: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@635..636 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@636..637 "!" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@637..638 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@638..639 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@639..640 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@640..641 ">" [] [],
+ },
+ ],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@641..657 " should be text." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@657..658 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@658..658 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..658
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..658
+ 0: MD_HEADER@0..27
+ 0: MD_HASH_LIST@0..1
+ 0: MD_HASH@0..1
+ 0: HASH@0..1 "#" [] []
+ 1: MD_PARAGRAPH@1..27
+ 0: MD_INLINE_ITEM_LIST@1..27
+ 0: MD_TEXTUAL@1..27
+ 0: MD_TEXTUAL_LITERAL@1..27 " Invalid Inline HTML Cases" [] []
+ 1: (empty)
+ 2: MD_HASH_LIST@27..27
+ 1: MD_NEWLINE@27..28
+ 0: NEWLINE@27..28 "\n" [] []
+ 2: MD_NEWLINE@28..29
+ 0: NEWLINE@28..29 "\n" [] []
+ 3: MD_PARAGRAPH@29..85
+ 0: MD_INLINE_ITEM_LIST@29..85
+ 0: MD_TEXTUAL@29..84
+ 0: MD_TEXTUAL_LITERAL@29..84 "These should all be parsed as text, NOT as inline HTML." [] []
+ 1: MD_TEXTUAL@84..85
+ 0: MD_TEXTUAL_LITERAL@84..85 "\n" [] []
+ 1: (empty)
+ 4: MD_NEWLINE@85..86
+ 0: NEWLINE@85..86 "\n" [] []
+ 5: MD_HEADER@86..107
+ 0: MD_HASH_LIST@86..88
+ 0: MD_HASH@86..88
+ 0: HASH@86..88 "##" [] []
+ 1: MD_PARAGRAPH@88..107
+ 0: MD_INLINE_ITEM_LIST@88..107
+ 0: MD_TEXTUAL@88..107
+ 0: MD_TEXTUAL_LITERAL@88..107 " Period in Tag Name" [] []
+ 1: (empty)
+ 2: MD_HASH_LIST@107..107
+ 6: MD_NEWLINE@107..108
+ 0: NEWLINE@107..108 "\n" [] []
+ 7: MD_PARAGRAPH@108..196
+ 0: MD_INLINE_ITEM_LIST@108..196
+ 0: MD_TEXTUAL@108..116
+ 0: MD_TEXTUAL_LITERAL@108..116 "The URL " [] []
+ 1: MD_TEXTUAL@116..117
+ 0: MD_TEXTUAL_LITERAL@116..117 "<" [] []
+ 2: MD_TEXTUAL@117..128
+ 0: MD_TEXTUAL_LITERAL@117..128 "example.com" [] []
+ 3: MD_TEXTUAL@128..129
+ 0: MD_TEXTUAL_LITERAL@128..129 ">" [] []
+ 4: MD_TEXTUAL@129..149
+ 0: MD_TEXTUAL_LITERAL@129..149 " should remain text." [] []
+ 5: MD_TEXTUAL@149..150
+ 0: MD_TEXTUAL_LITERAL@149..150 "\n" [] []
+ 6: MD_TEXTUAL@150..157
+ 0: MD_TEXTUAL_LITERAL@150..157 "Domain " [] []
+ 7: MD_TEXTUAL@157..158
+ 0: MD_TEXTUAL_LITERAL@157..158 "<" [] []
+ 8: MD_TEXTUAL@158..174
+ 0: MD_TEXTUAL_LITERAL@158..174 "test.example.com" [] []
+ 9: MD_TEXTUAL@174..175
+ 0: MD_TEXTUAL_LITERAL@174..175 ">" [] []
+ 10: MD_TEXTUAL@175..195
+ 0: MD_TEXTUAL_LITERAL@175..195 " should remain text." [] []
+ 11: MD_TEXTUAL@195..196
+ 0: MD_TEXTUAL_LITERAL@195..196 "\n" [] []
+ 1: (empty)
+ 8: MD_NEWLINE@196..197
+ 0: NEWLINE@196..197 "\n" [] []
+ 9: MD_HEADER@197..213
+ 0: MD_HASH_LIST@197..199
+ 0: MD_HASH@197..199
+ 0: HASH@197..199 "##" [] []
+ 1: MD_PARAGRAPH@199..213
+ 0: MD_INLINE_ITEM_LIST@199..213
+ 0: MD_TEXTUAL@199..213
+ 0: MD_TEXTUAL_LITERAL@199..213 " Unclosed Tags" [] []
+ 1: (empty)
+ 2: MD_HASH_LIST@213..213
+ 10: MD_NEWLINE@213..214
+ 0: NEWLINE@213..214 "\n" [] []
+ 11: MD_PARAGRAPH@214..506
+ 0: MD_INLINE_ITEM_LIST@214..506
+ 0: MD_TEXTUAL@214..227
+ 0: MD_TEXTUAL_LITERAL@214..227 "Open bracket " [] []
+ 1: MD_TEXTUAL@227..228
+ 0: MD_TEXTUAL_LITERAL@227..228 "<" [] []
+ 2: MD_TEXTUAL@228..246
+ 0: MD_TEXTUAL_LITERAL@228..246 " followed by text." [] []
+ 3: MD_TEXTUAL@246..247
+ 0: MD_TEXTUAL_LITERAL@246..247 "\n" [] []
+ 4: MD_TEXTUAL@247..259
+ 0: MD_TEXTUAL_LITERAL@247..259 "Partial tag " [] []
+ 5: MD_TEXTUAL@259..260
+ 0: MD_TEXTUAL_LITERAL@259..260 "<" [] []
+ 6: MD_TEXTUAL@260..279
+ 0: MD_TEXTUAL_LITERAL@260..279 "div should be text." [] []
+ 7: MD_TEXTUAL@279..280
+ 0: MD_TEXTUAL_LITERAL@279..280 "\n" [] []
+ 8: MD_TEXTUAL@280..292
+ 0: MD_TEXTUAL_LITERAL@280..292 "Missing end " [] []
+ 9: MD_TEXTUAL@292..293
+ 0: MD_TEXTUAL_LITERAL@292..293 "<" [] []
+ 10: MD_TEXTUAL@293..325
+ 0: MD_TEXTUAL_LITERAL@293..325 "div class=\"test\" should be text." [] []
+ 11: MD_TEXTUAL@325..326
+ 0: MD_TEXTUAL_LITERAL@325..326 "\n" [] []
+ 12: MD_TEXTUAL@326..339
+ 0: MD_TEXTUAL_LITERAL@326..339 "Missing name " [] []
+ 13: MD_TEXTUAL@339..340
+ 0: MD_TEXTUAL_LITERAL@339..340 "<" [] []
+ 14: MD_TEXTUAL@340..348
+ 0: MD_TEXTUAL_LITERAL@340..348 "div =foo" [] []
+ 15: MD_TEXTUAL@348..349
+ 0: MD_TEXTUAL_LITERAL@348..349 ">" [] []
+ 16: MD_TEXTUAL@349..365
+ 0: MD_TEXTUAL_LITERAL@349..365 " should be text." [] []
+ 17: MD_TEXTUAL@365..366
+ 0: MD_TEXTUAL_LITERAL@365..366 "\n" [] []
+ 18: MD_TEXTUAL@366..380
+ 0: MD_TEXTUAL_LITERAL@366..380 "Missing value " [] []
+ 19: MD_TEXTUAL@380..381
+ 0: MD_TEXTUAL_LITERAL@380..381 "<" [] []
+ 20: MD_TEXTUAL@381..389
+ 0: MD_TEXTUAL_LITERAL@381..389 "div data" [] []
+ 21: MD_TEXTUAL@389..390
+ 0: MD_TEXTUAL_LITERAL@389..390 "-" [] []
+ 22: MD_TEXTUAL@390..392
+ 0: MD_TEXTUAL_LITERAL@390..392 "x=" [] []
+ 23: MD_TEXTUAL@392..393
+ 0: MD_TEXTUAL_LITERAL@392..393 ">" [] []
+ 24: MD_TEXTUAL@393..409
+ 0: MD_TEXTUAL_LITERAL@393..409 " should be text." [] []
+ 25: MD_TEXTUAL@409..410
+ 0: MD_TEXTUAL_LITERAL@409..410 "\n" [] []
+ 26: MD_TEXTUAL@410..431
+ 0: MD_TEXTUAL_LITERAL@410..431 "Backtick in unquoted " [] []
+ 27: MD_TEXTUAL@431..432
+ 0: MD_TEXTUAL_LITERAL@431..432 "<" [] []
+ 28: MD_TEXTUAL@432..440
+ 0: MD_TEXTUAL_LITERAL@432..440 "div data" [] []
+ 29: MD_TEXTUAL@440..441
+ 0: MD_TEXTUAL_LITERAL@440..441 "-" [] []
+ 30: MD_TEXTUAL@441..443
+ 0: MD_TEXTUAL_LITERAL@441..443 "x=" [] []
+ 31: MD_INLINE_CODE@443..446
+ 0: BACKTICK@443..444 "`" [] []
+ 1: MD_INLINE_ITEM_LIST@444..445
+ 0: MD_TEXTUAL@444..445
+ 0: MD_TEXTUAL_LITERAL@444..445 "a" [] []
+ 2: BACKTICK@445..446 "`" [] []
+ 32: MD_TEXTUAL@446..447
+ 0: MD_TEXTUAL_LITERAL@446..447 ">" [] []
+ 33: MD_TEXTUAL@447..463
+ 0: MD_TEXTUAL_LITERAL@447..463 " should be text." [] []
+ 34: MD_TEXTUAL@463..464
+ 0: MD_TEXTUAL_LITERAL@463..464 "\n" [] []
+ 35: MD_TEXTUAL@464..477
+ 0: MD_TEXTUAL_LITERAL@464..477 "Invalid name " [] []
+ 36: MD_TEXTUAL@477..478
+ 0: MD_TEXTUAL_LITERAL@477..478 "<" [] []
+ 37: MD_TEXTUAL@478..488
+ 0: MD_TEXTUAL_LITERAL@478..488 "div 1a=foo" [] []
+ 38: MD_TEXTUAL@488..489
+ 0: MD_TEXTUAL_LITERAL@488..489 ">" [] []
+ 39: MD_TEXTUAL@489..505
+ 0: MD_TEXTUAL_LITERAL@489..505 " should be text." [] []
+ 40: MD_TEXTUAL@505..506
+ 0: MD_TEXTUAL_LITERAL@505..506 "\n" [] []
+ 1: (empty)
+ 12: MD_NEWLINE@506..507
+ 0: NEWLINE@506..507 "\n" [] []
+ 13: MD_HEADER@507..526
+ 0: MD_HASH_LIST@507..509
+ 0: MD_HASH@507..509
+ 0: HASH@507..509 "##" [] []
+ 1: MD_PARAGRAPH@509..526
+ 0: MD_INLINE_ITEM_LIST@509..526
+ 0: MD_TEXTUAL@509..526
+ 0: MD_TEXTUAL_LITERAL@509..526 " Invalid Comments" [] []
+ 1: (empty)
+ 2: MD_HASH_LIST@526..526
+ 14: MD_NEWLINE@526..527
+ 0: NEWLINE@526..527 "\n" [] []
+ 15: MD_PARAGRAPH@527..658
+ 0: MD_INLINE_ITEM_LIST@527..658
+ 0: MD_TEXTUAL@527..541
+ 0: MD_TEXTUAL_LITERAL@527..541 "Invalid start " [] []
+ 1: MD_INLINE_HTML@541..546
+ 0: MD_INLINE_ITEM_LIST@541..546
+ 0: MD_TEXTUAL@541..542
+ 0: MD_TEXTUAL_LITERAL@541..542 "<" [] []
+ 1: MD_TEXTUAL@542..543
+ 0: MD_TEXTUAL_LITERAL@542..543 "!" [] []
+ 2: MD_TEXTUAL@543..544
+ 0: MD_TEXTUAL_LITERAL@543..544 "-" [] []
+ 3: MD_TEXTUAL@544..545
+ 0: MD_TEXTUAL_LITERAL@544..545 "-" [] []
+ 4: MD_TEXTUAL@545..546
+ 0: MD_TEXTUAL_LITERAL@545..546 ">" [] []
+ 2: MD_TEXTUAL@546..562
+ 0: MD_TEXTUAL_LITERAL@546..562 " should be text." [] []
+ 3: MD_TEXTUAL@562..563
+ 0: MD_TEXTUAL_LITERAL@562..563 "\n" [] []
+ 4: MD_TEXTUAL@563..575
+ 0: MD_TEXTUAL_LITERAL@563..575 "Double dash " [] []
+ 5: MD_INLINE_HTML@575..594
+ 0: MD_INLINE_ITEM_LIST@575..594
+ 0: MD_TEXTUAL@575..576
+ 0: MD_TEXTUAL_LITERAL@575..576 "<" [] []
+ 1: MD_TEXTUAL@576..577
+ 0: MD_TEXTUAL_LITERAL@576..577 "!" [] []
+ 2: MD_TEXTUAL@577..578
+ 0: MD_TEXTUAL_LITERAL@577..578 "-" [] []
+ 3: MD_TEXTUAL@578..579
+ 0: MD_TEXTUAL_LITERAL@578..579 "-" [] []
+ 4: MD_TEXTUAL@579..584
+ 0: MD_TEXTUAL_LITERAL@579..584 " foo " [] []
+ 5: MD_TEXTUAL@584..585
+ 0: MD_TEXTUAL_LITERAL@584..585 "-" [] []
+ 6: MD_TEXTUAL@585..586
+ 0: MD_TEXTUAL_LITERAL@585..586 "-" [] []
+ 7: MD_TEXTUAL@586..591
+ 0: MD_TEXTUAL_LITERAL@586..591 " bar " [] []
+ 8: MD_TEXTUAL@591..592
+ 0: MD_TEXTUAL_LITERAL@591..592 "-" [] []
+ 9: MD_TEXTUAL@592..593
+ 0: MD_TEXTUAL_LITERAL@592..593 "-" [] []
+ 10: MD_TEXTUAL@593..594
+ 0: MD_TEXTUAL_LITERAL@593..594 ">" [] []
+ 6: MD_TEXTUAL@594..616
+ 0: MD_TEXTUAL_LITERAL@594..616 " should be text maybe." [] []
+ 7: MD_TEXTUAL@616..617
+ 0: MD_TEXTUAL_LITERAL@616..617 "\n" [] []
+ 8: MD_TEXTUAL@617..635
+ 0: MD_TEXTUAL_LITERAL@617..635 "Starts with arrow " [] []
+ 9: MD_INLINE_HTML@635..641
+ 0: MD_INLINE_ITEM_LIST@635..641
+ 0: MD_TEXTUAL@635..636
+ 0: MD_TEXTUAL_LITERAL@635..636 "<" [] []
+ 1: MD_TEXTUAL@636..637
+ 0: MD_TEXTUAL_LITERAL@636..637 "!" [] []
+ 2: MD_TEXTUAL@637..638
+ 0: MD_TEXTUAL_LITERAL@637..638 "-" [] []
+ 3: MD_TEXTUAL@638..639
+ 0: MD_TEXTUAL_LITERAL@638..639 "-" [] []
+ 4: MD_TEXTUAL@639..640
+ 0: MD_TEXTUAL_LITERAL@639..640 "-" [] []
+ 5: MD_TEXTUAL@640..641
+ 0: MD_TEXTUAL_LITERAL@640..641 ">" [] []
+ 10: MD_TEXTUAL@641..657
+ 0: MD_TEXTUAL_LITERAL@641..657 " should be text." [] []
+ 11: MD_TEXTUAL@657..658
+ 0: MD_TEXTUAL_LITERAL@657..658 "\n" [] []
+ 1: (empty)
+ 2: EOF@658..658 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_destination_title.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_destination_title.md
new file mode 100644
index 000000000000..0f4293b8ad7c
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_destination_title.md
@@ -0,0 +1,11 @@
+Paren destination: [a](b(c)d)
+
+Angle destination: [a](
)
+
+Title double: [a](u "t")
+
+Title single: [a](u 't')
+
+Title paren: [a](u (t))
+
+Image title: 
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_destination_title.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_destination_title.md.snap
new file mode 100644
index 000000000000..f173cc8fd0dc
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_destination_title.md.snap
@@ -0,0 +1,468 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+Paren destination: [a](b(c)d)
+
+Angle destination: [a]()
+
+Title double: [a](u "t")
+
+Title single: [a](u 't')
+
+Title paren: [a](u (t))
+
+Image title: 
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..19 "Paren destination: " [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@19..20 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@20..21 "a" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@21..22 "]" [] [],
+ l_paren_token: L_PAREN@22..23 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@23..24 "b" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@24..25 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@25..26 "c" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@26..27 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@27..28 "d" [] [],
+ },
+ ],
+ title: missing (optional),
+ r_paren_token: R_PAREN@28..29 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@29..30 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@30..31 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@31..50 "Angle destination: " [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@50..51 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@51..52 "a" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@52..53 "]" [] [],
+ l_paren_token: L_PAREN@53..54 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@54..55 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@55..56 "b" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@56..57 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@57..58 "c" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@58..59 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@59..60 "d" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@60..61 ">" [] [],
+ },
+ ],
+ title: missing (optional),
+ r_paren_token: R_PAREN@61..62 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@62..63 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@63..64 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@64..78 "Title double: " [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@78..79 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@79..80 "a" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@80..81 "]" [] [],
+ l_paren_token: L_PAREN@81..82 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@82..83 "u" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@83..84 " " [] [],
+ },
+ ],
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@84..87 "\"t\"" [] [],
+ },
+ ],
+ },
+ r_paren_token: R_PAREN@87..88 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@88..89 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@89..90 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@90..104 "Title single: " [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@104..105 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@105..106 "a" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@106..107 "]" [] [],
+ l_paren_token: L_PAREN@107..108 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@108..109 "u" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@109..110 " " [] [],
+ },
+ ],
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@110..113 "'t'" [] [],
+ },
+ ],
+ },
+ r_paren_token: R_PAREN@113..114 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@114..115 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@115..116 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@116..129 "Title paren: " [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@129..130 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@130..131 "a" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@131..132 "]" [] [],
+ l_paren_token: L_PAREN@132..133 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@133..134 "u" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@134..135 " " [] [],
+ },
+ ],
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@135..136 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@136..137 "t" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@137..138 ")" [] [],
+ },
+ ],
+ },
+ r_paren_token: R_PAREN@138..139 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@139..140 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@140..141 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@141..154 "Image title: " [] [],
+ },
+ MdInlineImage {
+ excl_token: BANG@154..155 "!" [] [],
+ l_brack_token: L_BRACK@155..156 "[" [] [],
+ alt: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@156..159 "alt" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@159..160 "]" [] [],
+ l_paren_token: L_PAREN@160..161 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@161..162 "u" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@162..163 " " [] [],
+ },
+ ],
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@163..166 "\"t\"" [] [],
+ },
+ ],
+ },
+ r_paren_token: R_PAREN@166..167 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@167..168 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@168..168 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..168
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..168
+ 0: MD_PARAGRAPH@0..30
+ 0: MD_INLINE_ITEM_LIST@0..30
+ 0: MD_TEXTUAL@0..19
+ 0: MD_TEXTUAL_LITERAL@0..19 "Paren destination: " [] []
+ 1: MD_INLINE_LINK@19..29
+ 0: L_BRACK@19..20 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@20..21
+ 0: MD_TEXTUAL@20..21
+ 0: MD_TEXTUAL_LITERAL@20..21 "a" [] []
+ 2: R_BRACK@21..22 "]" [] []
+ 3: L_PAREN@22..23 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@23..28
+ 0: MD_TEXTUAL@23..24
+ 0: MD_TEXTUAL_LITERAL@23..24 "b" [] []
+ 1: MD_TEXTUAL@24..25
+ 0: MD_TEXTUAL_LITERAL@24..25 "(" [] []
+ 2: MD_TEXTUAL@25..26
+ 0: MD_TEXTUAL_LITERAL@25..26 "c" [] []
+ 3: MD_TEXTUAL@26..27
+ 0: MD_TEXTUAL_LITERAL@26..27 ")" [] []
+ 4: MD_TEXTUAL@27..28
+ 0: MD_TEXTUAL_LITERAL@27..28 "d" [] []
+ 5: (empty)
+ 6: R_PAREN@28..29 ")" [] []
+ 2: MD_TEXTUAL@29..30
+ 0: MD_TEXTUAL_LITERAL@29..30 "\n" [] []
+ 1: (empty)
+ 1: MD_NEWLINE@30..31
+ 0: NEWLINE@30..31 "\n" [] []
+ 2: MD_PARAGRAPH@31..63
+ 0: MD_INLINE_ITEM_LIST@31..63
+ 0: MD_TEXTUAL@31..50
+ 0: MD_TEXTUAL_LITERAL@31..50 "Angle destination: " [] []
+ 1: MD_INLINE_LINK@50..62
+ 0: L_BRACK@50..51 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@51..52
+ 0: MD_TEXTUAL@51..52
+ 0: MD_TEXTUAL_LITERAL@51..52 "a" [] []
+ 2: R_BRACK@52..53 "]" [] []
+ 3: L_PAREN@53..54 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@54..61
+ 0: MD_TEXTUAL@54..55
+ 0: MD_TEXTUAL_LITERAL@54..55 "<" [] []
+ 1: MD_TEXTUAL@55..56
+ 0: MD_TEXTUAL_LITERAL@55..56 "b" [] []
+ 2: MD_TEXTUAL@56..57
+ 0: MD_TEXTUAL_LITERAL@56..57 "(" [] []
+ 3: MD_TEXTUAL@57..58
+ 0: MD_TEXTUAL_LITERAL@57..58 "c" [] []
+ 4: MD_TEXTUAL@58..59
+ 0: MD_TEXTUAL_LITERAL@58..59 ")" [] []
+ 5: MD_TEXTUAL@59..60
+ 0: MD_TEXTUAL_LITERAL@59..60 "d" [] []
+ 6: MD_TEXTUAL@60..61
+ 0: MD_TEXTUAL_LITERAL@60..61 ">" [] []
+ 5: (empty)
+ 6: R_PAREN@61..62 ")" [] []
+ 2: MD_TEXTUAL@62..63
+ 0: MD_TEXTUAL_LITERAL@62..63 "\n" [] []
+ 1: (empty)
+ 3: MD_NEWLINE@63..64
+ 0: NEWLINE@63..64 "\n" [] []
+ 4: MD_PARAGRAPH@64..89
+ 0: MD_INLINE_ITEM_LIST@64..89
+ 0: MD_TEXTUAL@64..78
+ 0: MD_TEXTUAL_LITERAL@64..78 "Title double: " [] []
+ 1: MD_INLINE_LINK@78..88
+ 0: L_BRACK@78..79 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@79..80
+ 0: MD_TEXTUAL@79..80
+ 0: MD_TEXTUAL_LITERAL@79..80 "a" [] []
+ 2: R_BRACK@80..81 "]" [] []
+ 3: L_PAREN@81..82 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@82..84
+ 0: MD_TEXTUAL@82..83
+ 0: MD_TEXTUAL_LITERAL@82..83 "u" [] []
+ 1: MD_TEXTUAL@83..84
+ 0: MD_TEXTUAL_LITERAL@83..84 " " [] []
+ 5: MD_LINK_TITLE@84..87
+ 0: MD_INLINE_ITEM_LIST@84..87
+ 0: MD_TEXTUAL@84..87
+ 0: MD_TEXTUAL_LITERAL@84..87 "\"t\"" [] []
+ 6: R_PAREN@87..88 ")" [] []
+ 2: MD_TEXTUAL@88..89
+ 0: MD_TEXTUAL_LITERAL@88..89 "\n" [] []
+ 1: (empty)
+ 5: MD_NEWLINE@89..90
+ 0: NEWLINE@89..90 "\n" [] []
+ 6: MD_PARAGRAPH@90..115
+ 0: MD_INLINE_ITEM_LIST@90..115
+ 0: MD_TEXTUAL@90..104
+ 0: MD_TEXTUAL_LITERAL@90..104 "Title single: " [] []
+ 1: MD_INLINE_LINK@104..114
+ 0: L_BRACK@104..105 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@105..106
+ 0: MD_TEXTUAL@105..106
+ 0: MD_TEXTUAL_LITERAL@105..106 "a" [] []
+ 2: R_BRACK@106..107 "]" [] []
+ 3: L_PAREN@107..108 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@108..110
+ 0: MD_TEXTUAL@108..109
+ 0: MD_TEXTUAL_LITERAL@108..109 "u" [] []
+ 1: MD_TEXTUAL@109..110
+ 0: MD_TEXTUAL_LITERAL@109..110 " " [] []
+ 5: MD_LINK_TITLE@110..113
+ 0: MD_INLINE_ITEM_LIST@110..113
+ 0: MD_TEXTUAL@110..113
+ 0: MD_TEXTUAL_LITERAL@110..113 "'t'" [] []
+ 6: R_PAREN@113..114 ")" [] []
+ 2: MD_TEXTUAL@114..115
+ 0: MD_TEXTUAL_LITERAL@114..115 "\n" [] []
+ 1: (empty)
+ 7: MD_NEWLINE@115..116
+ 0: NEWLINE@115..116 "\n" [] []
+ 8: MD_PARAGRAPH@116..140
+ 0: MD_INLINE_ITEM_LIST@116..140
+ 0: MD_TEXTUAL@116..129
+ 0: MD_TEXTUAL_LITERAL@116..129 "Title paren: " [] []
+ 1: MD_INLINE_LINK@129..139
+ 0: L_BRACK@129..130 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@130..131
+ 0: MD_TEXTUAL@130..131
+ 0: MD_TEXTUAL_LITERAL@130..131 "a" [] []
+ 2: R_BRACK@131..132 "]" [] []
+ 3: L_PAREN@132..133 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@133..135
+ 0: MD_TEXTUAL@133..134
+ 0: MD_TEXTUAL_LITERAL@133..134 "u" [] []
+ 1: MD_TEXTUAL@134..135
+ 0: MD_TEXTUAL_LITERAL@134..135 " " [] []
+ 5: MD_LINK_TITLE@135..138
+ 0: MD_INLINE_ITEM_LIST@135..138
+ 0: MD_TEXTUAL@135..136
+ 0: MD_TEXTUAL_LITERAL@135..136 "(" [] []
+ 1: MD_TEXTUAL@136..137
+ 0: MD_TEXTUAL_LITERAL@136..137 "t" [] []
+ 2: MD_TEXTUAL@137..138
+ 0: MD_TEXTUAL_LITERAL@137..138 ")" [] []
+ 6: R_PAREN@138..139 ")" [] []
+ 2: MD_TEXTUAL@139..140
+ 0: MD_TEXTUAL_LITERAL@139..140 "\n" [] []
+ 1: (empty)
+ 9: MD_NEWLINE@140..141
+ 0: NEWLINE@140..141 "\n" [] []
+ 10: MD_PARAGRAPH@141..168
+ 0: MD_INLINE_ITEM_LIST@141..168
+ 0: MD_TEXTUAL@141..154
+ 0: MD_TEXTUAL_LITERAL@141..154 "Image title: " [] []
+ 1: MD_INLINE_IMAGE@154..167
+ 0: BANG@154..155 "!" [] []
+ 1: L_BRACK@155..156 "[" [] []
+ 2: MD_INLINE_ITEM_LIST@156..159
+ 0: MD_TEXTUAL@156..159
+ 0: MD_TEXTUAL_LITERAL@156..159 "alt" [] []
+ 3: R_BRACK@159..160 "]" [] []
+ 4: L_PAREN@160..161 "(" [] []
+ 5: MD_INLINE_ITEM_LIST@161..163
+ 0: MD_TEXTUAL@161..162
+ 0: MD_TEXTUAL_LITERAL@161..162 "u" [] []
+ 1: MD_TEXTUAL@162..163
+ 0: MD_TEXTUAL_LITERAL@162..163 " " [] []
+ 6: MD_LINK_TITLE@163..166
+ 0: MD_INLINE_ITEM_LIST@163..166
+ 0: MD_TEXTUAL@163..166
+ 0: MD_TEXTUAL_LITERAL@163..166 "\"t\"" [] []
+ 7: R_PAREN@166..167 ")" [] []
+ 2: MD_TEXTUAL@167..168
+ 0: MD_TEXTUAL_LITERAL@167..168 "\n" [] []
+ 1: (empty)
+ 2: EOF@168..168 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_whitespace.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_whitespace.md
new file mode 100644
index 000000000000..502a1004733e
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_whitespace.md
@@ -0,0 +1,17 @@
+Whitespace around destination and title:
+[link]( /uri
+ "title" )
+
+Title spanning lines:
+[link](/url "title
+continued")
+
+Line break between destination and title:
+[link](/uri
+"title")
+
+Leading whitespace before destination:
+[link]( /url)
+
+Trailing whitespace before close paren:
+[link](/url )
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_whitespace.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_whitespace.md.snap
new file mode 100644
index 000000000000..d984449d3f4a
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/inline_link_whitespace.md.snap
@@ -0,0 +1,406 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+Whitespace around destination and title:
+[link]( /uri
+ "title" )
+
+Title spanning lines:
+[link](/url "title
+continued")
+
+Line break between destination and title:
+[link](/uri
+"title")
+
+Leading whitespace before destination:
+[link]( /url)
+
+Trailing whitespace before close paren:
+[link](/url )
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..40 "Whitespace around destination and title:" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@40..41 "\n" [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@41..42 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@42..46 "link" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@46..47 "]" [] [],
+ l_paren_token: L_PAREN@47..48 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@48..51 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@51..55 "/uri" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@55..56 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@56..57 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@57..58 " " [] [],
+ },
+ ],
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@58..65 "\"title\"" [] [],
+ },
+ ],
+ },
+ r_paren_token: R_PAREN@65..68 " )" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@68..69 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@69..70 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@70..91 "Title spanning lines:" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@91..92 "\n" [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@92..93 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@93..97 "link" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@97..98 "]" [] [],
+ l_paren_token: L_PAREN@98..99 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@99..103 "/url" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@103..104 " " [] [],
+ },
+ ],
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@104..110 "\"title" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@110..111 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@111..121 "continued\"" [] [],
+ },
+ ],
+ },
+ r_paren_token: R_PAREN@121..122 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@122..123 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@123..124 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@124..165 "Line break between destination and title:" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@165..166 "\n" [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@166..167 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@167..171 "link" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@171..172 "]" [] [],
+ l_paren_token: L_PAREN@172..173 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@173..177 "/uri" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@177..178 "\n" [] [],
+ },
+ ],
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@178..185 "\"title\"" [] [],
+ },
+ ],
+ },
+ r_paren_token: R_PAREN@185..186 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@186..187 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@187..188 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@188..226 "Leading whitespace before destination:" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@226..227 "\n" [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@227..228 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@228..232 "link" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@232..233 "]" [] [],
+ l_paren_token: L_PAREN@233..234 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@234..237 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@237..241 "/url" [] [],
+ },
+ ],
+ title: missing (optional),
+ r_paren_token: R_PAREN@241..242 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@242..243 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@243..244 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@244..283 "Trailing whitespace before close paren:" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@283..284 "\n" [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@284..285 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@285..289 "link" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@289..290 "]" [] [],
+ l_paren_token: L_PAREN@290..291 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@291..295 "/url" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@295..298 " " [] [],
+ },
+ ],
+ title: missing (optional),
+ r_paren_token: R_PAREN@298..299 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@299..300 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@300..300 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..300
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..300
+ 0: MD_PARAGRAPH@0..69
+ 0: MD_INLINE_ITEM_LIST@0..69
+ 0: MD_TEXTUAL@0..40
+ 0: MD_TEXTUAL_LITERAL@0..40 "Whitespace around destination and title:" [] []
+ 1: MD_TEXTUAL@40..41
+ 0: MD_TEXTUAL_LITERAL@40..41 "\n" [] []
+ 2: MD_INLINE_LINK@41..68
+ 0: L_BRACK@41..42 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@42..46
+ 0: MD_TEXTUAL@42..46
+ 0: MD_TEXTUAL_LITERAL@42..46 "link" [] []
+ 2: R_BRACK@46..47 "]" [] []
+ 3: L_PAREN@47..48 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@48..58
+ 0: MD_TEXTUAL@48..51
+ 0: MD_TEXTUAL_LITERAL@48..51 " " [] []
+ 1: MD_TEXTUAL@51..55
+ 0: MD_TEXTUAL_LITERAL@51..55 "/uri" [] []
+ 2: MD_TEXTUAL@55..56
+ 0: MD_TEXTUAL_LITERAL@55..56 "\n" [] []
+ 3: MD_TEXTUAL@56..57
+ 0: MD_TEXTUAL_LITERAL@56..57 " " [] []
+ 4: MD_TEXTUAL@57..58
+ 0: MD_TEXTUAL_LITERAL@57..58 " " [] []
+ 5: MD_LINK_TITLE@58..65
+ 0: MD_INLINE_ITEM_LIST@58..65
+ 0: MD_TEXTUAL@58..65
+ 0: MD_TEXTUAL_LITERAL@58..65 "\"title\"" [] []
+ 6: R_PAREN@65..68 " )" [] []
+ 3: MD_TEXTUAL@68..69
+ 0: MD_TEXTUAL_LITERAL@68..69 "\n" [] []
+ 1: (empty)
+ 1: MD_NEWLINE@69..70
+ 0: NEWLINE@69..70 "\n" [] []
+ 2: MD_PARAGRAPH@70..123
+ 0: MD_INLINE_ITEM_LIST@70..123
+ 0: MD_TEXTUAL@70..91
+ 0: MD_TEXTUAL_LITERAL@70..91 "Title spanning lines:" [] []
+ 1: MD_TEXTUAL@91..92
+ 0: MD_TEXTUAL_LITERAL@91..92 "\n" [] []
+ 2: MD_INLINE_LINK@92..122
+ 0: L_BRACK@92..93 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@93..97
+ 0: MD_TEXTUAL@93..97
+ 0: MD_TEXTUAL_LITERAL@93..97 "link" [] []
+ 2: R_BRACK@97..98 "]" [] []
+ 3: L_PAREN@98..99 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@99..104
+ 0: MD_TEXTUAL@99..103
+ 0: MD_TEXTUAL_LITERAL@99..103 "/url" [] []
+ 1: MD_TEXTUAL@103..104
+ 0: MD_TEXTUAL_LITERAL@103..104 " " [] []
+ 5: MD_LINK_TITLE@104..121
+ 0: MD_INLINE_ITEM_LIST@104..121
+ 0: MD_TEXTUAL@104..110
+ 0: MD_TEXTUAL_LITERAL@104..110 "\"title" [] []
+ 1: MD_TEXTUAL@110..111
+ 0: MD_TEXTUAL_LITERAL@110..111 "\n" [] []
+ 2: MD_TEXTUAL@111..121
+ 0: MD_TEXTUAL_LITERAL@111..121 "continued\"" [] []
+ 6: R_PAREN@121..122 ")" [] []
+ 3: MD_TEXTUAL@122..123
+ 0: MD_TEXTUAL_LITERAL@122..123 "\n" [] []
+ 1: (empty)
+ 3: MD_NEWLINE@123..124
+ 0: NEWLINE@123..124 "\n" [] []
+ 4: MD_PARAGRAPH@124..187
+ 0: MD_INLINE_ITEM_LIST@124..187
+ 0: MD_TEXTUAL@124..165
+ 0: MD_TEXTUAL_LITERAL@124..165 "Line break between destination and title:" [] []
+ 1: MD_TEXTUAL@165..166
+ 0: MD_TEXTUAL_LITERAL@165..166 "\n" [] []
+ 2: MD_INLINE_LINK@166..186
+ 0: L_BRACK@166..167 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@167..171
+ 0: MD_TEXTUAL@167..171
+ 0: MD_TEXTUAL_LITERAL@167..171 "link" [] []
+ 2: R_BRACK@171..172 "]" [] []
+ 3: L_PAREN@172..173 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@173..178
+ 0: MD_TEXTUAL@173..177
+ 0: MD_TEXTUAL_LITERAL@173..177 "/uri" [] []
+ 1: MD_TEXTUAL@177..178
+ 0: MD_TEXTUAL_LITERAL@177..178 "\n" [] []
+ 5: MD_LINK_TITLE@178..185
+ 0: MD_INLINE_ITEM_LIST@178..185
+ 0: MD_TEXTUAL@178..185
+ 0: MD_TEXTUAL_LITERAL@178..185 "\"title\"" [] []
+ 6: R_PAREN@185..186 ")" [] []
+ 3: MD_TEXTUAL@186..187
+ 0: MD_TEXTUAL_LITERAL@186..187 "\n" [] []
+ 1: (empty)
+ 5: MD_NEWLINE@187..188
+ 0: NEWLINE@187..188 "\n" [] []
+ 6: MD_PARAGRAPH@188..243
+ 0: MD_INLINE_ITEM_LIST@188..243
+ 0: MD_TEXTUAL@188..226
+ 0: MD_TEXTUAL_LITERAL@188..226 "Leading whitespace before destination:" [] []
+ 1: MD_TEXTUAL@226..227
+ 0: MD_TEXTUAL_LITERAL@226..227 "\n" [] []
+ 2: MD_INLINE_LINK@227..242
+ 0: L_BRACK@227..228 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@228..232
+ 0: MD_TEXTUAL@228..232
+ 0: MD_TEXTUAL_LITERAL@228..232 "link" [] []
+ 2: R_BRACK@232..233 "]" [] []
+ 3: L_PAREN@233..234 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@234..241
+ 0: MD_TEXTUAL@234..237
+ 0: MD_TEXTUAL_LITERAL@234..237 " " [] []
+ 1: MD_TEXTUAL@237..241
+ 0: MD_TEXTUAL_LITERAL@237..241 "/url" [] []
+ 5: (empty)
+ 6: R_PAREN@241..242 ")" [] []
+ 3: MD_TEXTUAL@242..243
+ 0: MD_TEXTUAL_LITERAL@242..243 "\n" [] []
+ 1: (empty)
+ 7: MD_NEWLINE@243..244
+ 0: NEWLINE@243..244 "\n" [] []
+ 8: MD_PARAGRAPH@244..300
+ 0: MD_INLINE_ITEM_LIST@244..300
+ 0: MD_TEXTUAL@244..283
+ 0: MD_TEXTUAL_LITERAL@244..283 "Trailing whitespace before close paren:" [] []
+ 1: MD_TEXTUAL@283..284
+ 0: MD_TEXTUAL_LITERAL@283..284 "\n" [] []
+ 2: MD_INLINE_LINK@284..299
+ 0: L_BRACK@284..285 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@285..289
+ 0: MD_TEXTUAL@285..289
+ 0: MD_TEXTUAL_LITERAL@285..289 "link" [] []
+ 2: R_BRACK@289..290 "]" [] []
+ 3: L_PAREN@290..291 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@291..298
+ 0: MD_TEXTUAL@291..295
+ 0: MD_TEXTUAL_LITERAL@291..295 "/url" [] []
+ 1: MD_TEXTUAL@295..298
+ 0: MD_TEXTUAL_LITERAL@295..298 " " [] []
+ 5: (empty)
+ 6: R_PAREN@298..299 ")" [] []
+ 3: MD_TEXTUAL@299..300
+ 0: MD_TEXTUAL_LITERAL@299..300 "\n" [] []
+ 1: (empty)
+ 2: EOF@300..300 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/lazy_continuation.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/lazy_continuation.md
new file mode 100644
index 000000000000..33298e8d5795
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/lazy_continuation.md
@@ -0,0 +1,31 @@
+> This is a quote
+that continues lazily
+
+> Another quote
+with lazy continuation
+> and explicit continuation
+
+> Multi-line quote
+with more lazy content
+and even more content
+
+> Quote interrupted by heading
+# This heading ends the lazy continuation
+
+> Quote interrupted by setext heading
+Setext heading
+---
+
+> Quote interrupted by list
+- This list item ends lazy continuation
+
+> Quote interrupted by fenced code
+```
+code block
+```
+
+> Quote interrupted by thematic break
+---
+
+> Quote interrupted by indented code
+ This is an indented code block
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/lazy_continuation.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/lazy_continuation.md.snap
new file mode 100644
index 000000000000..1b6ba21153b2
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/lazy_continuation.md.snap
@@ -0,0 +1,532 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+> This is a quote
+that continues lazily
+
+> Another quote
+with lazy continuation
+> and explicit continuation
+
+> Multi-line quote
+with more lazy content
+and even more content
+
+> Quote interrupted by heading
+# This heading ends the lazy continuation
+
+> Quote interrupted by setext heading
+Setext heading
+---
+
+> Quote interrupted by list
+- This list item ends lazy continuation
+
+> Quote interrupted by fenced code
+```
+code block
+```
+
+> Quote interrupted by thematic break
+---
+
+> Quote interrupted by indented code
+ This is an indented code block
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdQuote {
+ marker_token: R_ANGLE@0..1 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@1..17 "This is a quote" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@17..18 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@18..39 "that continues lazily" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@39..40 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdNewline {
+ value_token: NEWLINE@40..41 "\n" [] [],
+ },
+ MdQuote {
+ marker_token: R_ANGLE@41..42 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@42..56 "Another quote" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@56..57 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@57..79 "with lazy continuation" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@79..80 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@80..107 "and explicit continuation" [Skipped(">"), Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@107..108 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdNewline {
+ value_token: NEWLINE@108..109 "\n" [] [],
+ },
+ MdQuote {
+ marker_token: R_ANGLE@109..110 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@110..116 "Multi" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@116..117 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@117..127 "line quote" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@127..128 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@128..150 "with more lazy content" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@150..151 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@151..172 "and even more content" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@172..173 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdNewline {
+ value_token: NEWLINE@173..174 "\n" [] [],
+ },
+ MdQuote {
+ marker_token: R_ANGLE@174..175 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@175..204 "Quote interrupted by heading" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@204..205 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdHeader {
+ before: MdHashList [
+ MdHash {
+ hash_token: HASH@205..206 "#" [] [],
+ },
+ ],
+ content: MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@206..246 " This heading ends the lazy continuation" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ after: MdHashList [],
+ },
+ MdNewline {
+ value_token: NEWLINE@246..247 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@247..248 "\n" [] [],
+ },
+ MdQuote {
+ marker_token: R_ANGLE@248..249 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@249..285 "Quote interrupted by setext heading" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@285..286 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@286..300 "Setext heading" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@300..301 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdThematicBreakBlock {
+ value_token: MD_THEMATIC_BREAK_LITERAL@301..304 "---" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@304..305 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@305..306 "\n" [] [],
+ },
+ MdQuote {
+ marker_token: R_ANGLE@306..307 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@307..333 "Quote interrupted by list" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@333..334 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdBulletListItem {
+ md_bullet_list: MdBulletList [
+ MdBullet {
+ bullet: MINUS@334..335 "-" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@335..373 " This list item ends lazy continuation" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@373..374 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ ],
+ },
+ MdNewline {
+ value_token: NEWLINE@374..375 "\n" [] [],
+ },
+ MdQuote {
+ marker_token: R_ANGLE@375..376 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@376..409 "Quote interrupted by fenced code" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@409..410 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdFencedCodeBlock {
+ l_fence: TRIPLE_BACKTICK@410..413 "```" [] [],
+ code_list: MdCodeNameList [],
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@413..414 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@414..424 "code block" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@424..425 "\n" [] [],
+ },
+ ],
+ r_fence: TRIPLE_BACKTICK@425..428 "```" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@428..429 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@429..430 "\n" [] [],
+ },
+ MdQuote {
+ marker_token: R_ANGLE@430..431 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@431..467 "Quote interrupted by thematic break" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@467..468 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdThematicBreakBlock {
+ value_token: MD_THEMATIC_BREAK_LITERAL@468..471 "---" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@471..472 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@472..473 "\n" [] [],
+ },
+ MdQuote {
+ marker_token: R_ANGLE@473..474 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@474..509 "Quote interrupted by indented code" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@509..510 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@510..544 "This is an indented code block" [Skipped(" "), Skipped(" "), Skipped(" "), Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@544..545 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ ],
+ eof_token: EOF@545..545 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..545
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..545
+ 0: MD_QUOTE@0..40
+ 0: R_ANGLE@0..1 ">" [] []
+ 1: MD_BLOCK_LIST@1..40
+ 0: MD_PARAGRAPH@1..40
+ 0: MD_INLINE_ITEM_LIST@1..40
+ 0: MD_TEXTUAL@1..17
+ 0: MD_TEXTUAL_LITERAL@1..17 "This is a quote" [Skipped(" ")] []
+ 1: MD_TEXTUAL@17..18
+ 0: MD_TEXTUAL_LITERAL@17..18 "\n" [] []
+ 2: MD_TEXTUAL@18..39
+ 0: MD_TEXTUAL_LITERAL@18..39 "that continues lazily" [] []
+ 3: MD_TEXTUAL@39..40
+ 0: MD_TEXTUAL_LITERAL@39..40 "\n" [] []
+ 1: (empty)
+ 1: MD_NEWLINE@40..41
+ 0: NEWLINE@40..41 "\n" [] []
+ 2: MD_QUOTE@41..108
+ 0: R_ANGLE@41..42 ">" [] []
+ 1: MD_BLOCK_LIST@42..108
+ 0: MD_PARAGRAPH@42..108
+ 0: MD_INLINE_ITEM_LIST@42..108
+ 0: MD_TEXTUAL@42..56
+ 0: MD_TEXTUAL_LITERAL@42..56 "Another quote" [Skipped(" ")] []
+ 1: MD_TEXTUAL@56..57
+ 0: MD_TEXTUAL_LITERAL@56..57 "\n" [] []
+ 2: MD_TEXTUAL@57..79
+ 0: MD_TEXTUAL_LITERAL@57..79 "with lazy continuation" [] []
+ 3: MD_TEXTUAL@79..80
+ 0: MD_TEXTUAL_LITERAL@79..80 "\n" [] []
+ 4: MD_TEXTUAL@80..107
+ 0: MD_TEXTUAL_LITERAL@80..107 "and explicit continuation" [Skipped(">"), Skipped(" ")] []
+ 5: MD_TEXTUAL@107..108
+ 0: MD_TEXTUAL_LITERAL@107..108 "\n" [] []
+ 1: (empty)
+ 3: MD_NEWLINE@108..109
+ 0: NEWLINE@108..109 "\n" [] []
+ 4: MD_QUOTE@109..173
+ 0: R_ANGLE@109..110 ">" [] []
+ 1: MD_BLOCK_LIST@110..173
+ 0: MD_PARAGRAPH@110..173
+ 0: MD_INLINE_ITEM_LIST@110..173
+ 0: MD_TEXTUAL@110..116
+ 0: MD_TEXTUAL_LITERAL@110..116 "Multi" [Skipped(" ")] []
+ 1: MD_TEXTUAL@116..117
+ 0: MD_TEXTUAL_LITERAL@116..117 "-" [] []
+ 2: MD_TEXTUAL@117..127
+ 0: MD_TEXTUAL_LITERAL@117..127 "line quote" [] []
+ 3: MD_TEXTUAL@127..128
+ 0: MD_TEXTUAL_LITERAL@127..128 "\n" [] []
+ 4: MD_TEXTUAL@128..150
+ 0: MD_TEXTUAL_LITERAL@128..150 "with more lazy content" [] []
+ 5: MD_TEXTUAL@150..151
+ 0: MD_TEXTUAL_LITERAL@150..151 "\n" [] []
+ 6: MD_TEXTUAL@151..172
+ 0: MD_TEXTUAL_LITERAL@151..172 "and even more content" [] []
+ 7: MD_TEXTUAL@172..173
+ 0: MD_TEXTUAL_LITERAL@172..173 "\n" [] []
+ 1: (empty)
+ 5: MD_NEWLINE@173..174
+ 0: NEWLINE@173..174 "\n" [] []
+ 6: MD_QUOTE@174..205
+ 0: R_ANGLE@174..175 ">" [] []
+ 1: MD_BLOCK_LIST@175..205
+ 0: MD_PARAGRAPH@175..205
+ 0: MD_INLINE_ITEM_LIST@175..205
+ 0: MD_TEXTUAL@175..204
+ 0: MD_TEXTUAL_LITERAL@175..204 "Quote interrupted by heading" [Skipped(" ")] []
+ 1: MD_TEXTUAL@204..205
+ 0: MD_TEXTUAL_LITERAL@204..205 "\n" [] []
+ 1: (empty)
+ 7: MD_HEADER@205..246
+ 0: MD_HASH_LIST@205..206
+ 0: MD_HASH@205..206
+ 0: HASH@205..206 "#" [] []
+ 1: MD_PARAGRAPH@206..246
+ 0: MD_INLINE_ITEM_LIST@206..246
+ 0: MD_TEXTUAL@206..246
+ 0: MD_TEXTUAL_LITERAL@206..246 " This heading ends the lazy continuation" [] []
+ 1: (empty)
+ 2: MD_HASH_LIST@246..246
+ 8: MD_NEWLINE@246..247
+ 0: NEWLINE@246..247 "\n" [] []
+ 9: MD_NEWLINE@247..248
+ 0: NEWLINE@247..248 "\n" [] []
+ 10: MD_QUOTE@248..301
+ 0: R_ANGLE@248..249 ">" [] []
+ 1: MD_BLOCK_LIST@249..301
+ 0: MD_PARAGRAPH@249..301
+ 0: MD_INLINE_ITEM_LIST@249..301
+ 0: MD_TEXTUAL@249..285
+ 0: MD_TEXTUAL_LITERAL@249..285 "Quote interrupted by setext heading" [Skipped(" ")] []
+ 1: MD_TEXTUAL@285..286
+ 0: MD_TEXTUAL_LITERAL@285..286 "\n" [] []
+ 2: MD_TEXTUAL@286..300
+ 0: MD_TEXTUAL_LITERAL@286..300 "Setext heading" [] []
+ 3: MD_TEXTUAL@300..301
+ 0: MD_TEXTUAL_LITERAL@300..301 "\n" [] []
+ 1: (empty)
+ 11: MD_THEMATIC_BREAK_BLOCK@301..304
+ 0: MD_THEMATIC_BREAK_LITERAL@301..304 "---" [] []
+ 12: MD_NEWLINE@304..305
+ 0: NEWLINE@304..305 "\n" [] []
+ 13: MD_NEWLINE@305..306
+ 0: NEWLINE@305..306 "\n" [] []
+ 14: MD_QUOTE@306..334
+ 0: R_ANGLE@306..307 ">" [] []
+ 1: MD_BLOCK_LIST@307..334
+ 0: MD_PARAGRAPH@307..334
+ 0: MD_INLINE_ITEM_LIST@307..334
+ 0: MD_TEXTUAL@307..333
+ 0: MD_TEXTUAL_LITERAL@307..333 "Quote interrupted by list" [Skipped(" ")] []
+ 1: MD_TEXTUAL@333..334
+ 0: MD_TEXTUAL_LITERAL@333..334 "\n" [] []
+ 1: (empty)
+ 15: MD_BULLET_LIST_ITEM@334..374
+ 0: MD_BULLET_LIST@334..374
+ 0: MD_BULLET@334..374
+ 0: MINUS@334..335 "-" [] []
+ 1: MD_BLOCK_LIST@335..374
+ 0: MD_PARAGRAPH@335..374
+ 0: MD_INLINE_ITEM_LIST@335..374
+ 0: MD_TEXTUAL@335..373
+ 0: MD_TEXTUAL_LITERAL@335..373 " This list item ends lazy continuation" [] []
+ 1: MD_TEXTUAL@373..374
+ 0: MD_TEXTUAL_LITERAL@373..374 "\n" [] []
+ 1: (empty)
+ 16: MD_NEWLINE@374..375
+ 0: NEWLINE@374..375 "\n" [] []
+ 17: MD_QUOTE@375..410
+ 0: R_ANGLE@375..376 ">" [] []
+ 1: MD_BLOCK_LIST@376..410
+ 0: MD_PARAGRAPH@376..410
+ 0: MD_INLINE_ITEM_LIST@376..410
+ 0: MD_TEXTUAL@376..409
+ 0: MD_TEXTUAL_LITERAL@376..409 "Quote interrupted by fenced code" [Skipped(" ")] []
+ 1: MD_TEXTUAL@409..410
+ 0: MD_TEXTUAL_LITERAL@409..410 "\n" [] []
+ 1: (empty)
+ 18: MD_FENCED_CODE_BLOCK@410..428
+ 0: TRIPLE_BACKTICK@410..413 "```" [] []
+ 1: MD_CODE_NAME_LIST@413..413
+ 2: MD_INLINE_ITEM_LIST@413..425
+ 0: MD_TEXTUAL@413..414
+ 0: MD_TEXTUAL_LITERAL@413..414 "\n" [] []
+ 1: MD_TEXTUAL@414..424
+ 0: MD_TEXTUAL_LITERAL@414..424 "code block" [] []
+ 2: MD_TEXTUAL@424..425
+ 0: MD_TEXTUAL_LITERAL@424..425 "\n" [] []
+ 3: TRIPLE_BACKTICK@425..428 "```" [] []
+ 19: MD_NEWLINE@428..429
+ 0: NEWLINE@428..429 "\n" [] []
+ 20: MD_NEWLINE@429..430
+ 0: NEWLINE@429..430 "\n" [] []
+ 21: MD_QUOTE@430..468
+ 0: R_ANGLE@430..431 ">" [] []
+ 1: MD_BLOCK_LIST@431..468
+ 0: MD_PARAGRAPH@431..468
+ 0: MD_INLINE_ITEM_LIST@431..468
+ 0: MD_TEXTUAL@431..467
+ 0: MD_TEXTUAL_LITERAL@431..467 "Quote interrupted by thematic break" [Skipped(" ")] []
+ 1: MD_TEXTUAL@467..468
+ 0: MD_TEXTUAL_LITERAL@467..468 "\n" [] []
+ 1: (empty)
+ 22: MD_THEMATIC_BREAK_BLOCK@468..471
+ 0: MD_THEMATIC_BREAK_LITERAL@468..471 "---" [] []
+ 23: MD_NEWLINE@471..472
+ 0: NEWLINE@471..472 "\n" [] []
+ 24: MD_NEWLINE@472..473
+ 0: NEWLINE@472..473 "\n" [] []
+ 25: MD_QUOTE@473..545
+ 0: R_ANGLE@473..474 ">" [] []
+ 1: MD_BLOCK_LIST@474..545
+ 0: MD_PARAGRAPH@474..545
+ 0: MD_INLINE_ITEM_LIST@474..545
+ 0: MD_TEXTUAL@474..509
+ 0: MD_TEXTUAL_LITERAL@474..509 "Quote interrupted by indented code" [Skipped(" ")] []
+ 1: MD_TEXTUAL@509..510
+ 0: MD_TEXTUAL_LITERAL@509..510 "\n" [] []
+ 2: MD_TEXTUAL@510..544
+ 0: MD_TEXTUAL_LITERAL@510..544 "This is an indented code block" [Skipped(" "), Skipped(" "), Skipped(" "), Skipped(" ")] []
+ 3: MD_TEXTUAL@544..545
+ 0: MD_TEXTUAL_LITERAL@544..545 "\n" [] []
+ 1: (empty)
+ 2: EOF@545..545 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition.md
new file mode 100644
index 000000000000..49f729678fdb
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition.md
@@ -0,0 +1,9 @@
+[example]: https://example.com
+
+[foo]: /url
+
+ [one-space]: /url
+
+ [two-spaces]: /url
+
+ [three-spaces]: /url
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition.md.snap
new file mode 100644
index 000000000000..2cc6a441b2a8
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition.md.snap
@@ -0,0 +1,306 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+[example]: https://example.com
+
+[foo]: /url
+
+ [one-space]: /url
+
+ [two-spaces]: /url
+
+ [three-spaces]: /url
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@0..1 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@1..8 "example" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@8..9 "]" [] [],
+ colon_token: COLON@9..10 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@10..11 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@11..30 "https://example.com" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@30..31 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@31..32 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@32..33 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@33..36 "foo" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@36..37 "]" [] [],
+ colon_token: COLON@37..38 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@38..39 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@39..43 "/url" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@43..44 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@44..45 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@45..47 "[" [Skipped(" ")] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@47..50 "one" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@50..51 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@51..56 "space" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@56..57 "]" [] [],
+ colon_token: COLON@57..58 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@58..59 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@59..63 "/url" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@63..64 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@64..65 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@65..68 "[" [Skipped(" "), Skipped(" ")] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@68..71 "two" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@71..72 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@72..78 "spaces" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@78..79 "]" [] [],
+ colon_token: COLON@79..80 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@80..81 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@81..85 "/url" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@85..86 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@86..87 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@87..91 "[" [Skipped(" "), Skipped(" "), Skipped(" ")] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@91..96 "three" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@96..97 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@97..103 "spaces" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@103..104 "]" [] [],
+ colon_token: COLON@104..105 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@105..106 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@106..110 "/url" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@110..111 "\n" [] [],
+ },
+ ],
+ eof_token: EOF@111..111 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..111
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..111
+ 0: MD_LINK_REFERENCE_DEFINITION@0..30
+ 0: L_BRACK@0..1 "[" [] []
+ 1: MD_LINK_LABEL@1..8
+ 0: MD_INLINE_ITEM_LIST@1..8
+ 0: MD_TEXTUAL@1..8
+ 0: MD_TEXTUAL_LITERAL@1..8 "example" [] []
+ 2: R_BRACK@8..9 "]" [] []
+ 3: COLON@9..10 ":" [] []
+ 4: MD_LINK_DESTINATION@10..30
+ 0: MD_INLINE_ITEM_LIST@10..30
+ 0: MD_TEXTUAL@10..11
+ 0: MD_TEXTUAL_LITERAL@10..11 " " [] []
+ 1: MD_TEXTUAL@11..30
+ 0: MD_TEXTUAL_LITERAL@11..30 "https://example.com" [] []
+ 5: (empty)
+ 1: MD_NEWLINE@30..31
+ 0: NEWLINE@30..31 "\n" [] []
+ 2: MD_NEWLINE@31..32
+ 0: NEWLINE@31..32 "\n" [] []
+ 3: MD_LINK_REFERENCE_DEFINITION@32..43
+ 0: L_BRACK@32..33 "[" [] []
+ 1: MD_LINK_LABEL@33..36
+ 0: MD_INLINE_ITEM_LIST@33..36
+ 0: MD_TEXTUAL@33..36
+ 0: MD_TEXTUAL_LITERAL@33..36 "foo" [] []
+ 2: R_BRACK@36..37 "]" [] []
+ 3: COLON@37..38 ":" [] []
+ 4: MD_LINK_DESTINATION@38..43
+ 0: MD_INLINE_ITEM_LIST@38..43
+ 0: MD_TEXTUAL@38..39
+ 0: MD_TEXTUAL_LITERAL@38..39 " " [] []
+ 1: MD_TEXTUAL@39..43
+ 0: MD_TEXTUAL_LITERAL@39..43 "/url" [] []
+ 5: (empty)
+ 4: MD_NEWLINE@43..44
+ 0: NEWLINE@43..44 "\n" [] []
+ 5: MD_NEWLINE@44..45
+ 0: NEWLINE@44..45 "\n" [] []
+ 6: MD_LINK_REFERENCE_DEFINITION@45..63
+ 0: L_BRACK@45..47 "[" [Skipped(" ")] []
+ 1: MD_LINK_LABEL@47..56
+ 0: MD_INLINE_ITEM_LIST@47..56
+ 0: MD_TEXTUAL@47..50
+ 0: MD_TEXTUAL_LITERAL@47..50 "one" [] []
+ 1: MD_TEXTUAL@50..51
+ 0: MD_TEXTUAL_LITERAL@50..51 "-" [] []
+ 2: MD_TEXTUAL@51..56
+ 0: MD_TEXTUAL_LITERAL@51..56 "space" [] []
+ 2: R_BRACK@56..57 "]" [] []
+ 3: COLON@57..58 ":" [] []
+ 4: MD_LINK_DESTINATION@58..63
+ 0: MD_INLINE_ITEM_LIST@58..63
+ 0: MD_TEXTUAL@58..59
+ 0: MD_TEXTUAL_LITERAL@58..59 " " [] []
+ 1: MD_TEXTUAL@59..63
+ 0: MD_TEXTUAL_LITERAL@59..63 "/url" [] []
+ 5: (empty)
+ 7: MD_NEWLINE@63..64
+ 0: NEWLINE@63..64 "\n" [] []
+ 8: MD_NEWLINE@64..65
+ 0: NEWLINE@64..65 "\n" [] []
+ 9: MD_LINK_REFERENCE_DEFINITION@65..85
+ 0: L_BRACK@65..68 "[" [Skipped(" "), Skipped(" ")] []
+ 1: MD_LINK_LABEL@68..78
+ 0: MD_INLINE_ITEM_LIST@68..78
+ 0: MD_TEXTUAL@68..71
+ 0: MD_TEXTUAL_LITERAL@68..71 "two" [] []
+ 1: MD_TEXTUAL@71..72
+ 0: MD_TEXTUAL_LITERAL@71..72 "-" [] []
+ 2: MD_TEXTUAL@72..78
+ 0: MD_TEXTUAL_LITERAL@72..78 "spaces" [] []
+ 2: R_BRACK@78..79 "]" [] []
+ 3: COLON@79..80 ":" [] []
+ 4: MD_LINK_DESTINATION@80..85
+ 0: MD_INLINE_ITEM_LIST@80..85
+ 0: MD_TEXTUAL@80..81
+ 0: MD_TEXTUAL_LITERAL@80..81 " " [] []
+ 1: MD_TEXTUAL@81..85
+ 0: MD_TEXTUAL_LITERAL@81..85 "/url" [] []
+ 5: (empty)
+ 10: MD_NEWLINE@85..86
+ 0: NEWLINE@85..86 "\n" [] []
+ 11: MD_NEWLINE@86..87
+ 0: NEWLINE@86..87 "\n" [] []
+ 12: MD_LINK_REFERENCE_DEFINITION@87..110
+ 0: L_BRACK@87..91 "[" [Skipped(" "), Skipped(" "), Skipped(" ")] []
+ 1: MD_LINK_LABEL@91..103
+ 0: MD_INLINE_ITEM_LIST@91..103
+ 0: MD_TEXTUAL@91..96
+ 0: MD_TEXTUAL_LITERAL@91..96 "three" [] []
+ 1: MD_TEXTUAL@96..97
+ 0: MD_TEXTUAL_LITERAL@96..97 "-" [] []
+ 2: MD_TEXTUAL@97..103
+ 0: MD_TEXTUAL_LITERAL@97..103 "spaces" [] []
+ 2: R_BRACK@103..104 "]" [] []
+ 3: COLON@104..105 ":" [] []
+ 4: MD_LINK_DESTINATION@105..110
+ 0: MD_INLINE_ITEM_LIST@105..110
+ 0: MD_TEXTUAL@105..106
+ 0: MD_TEXTUAL_LITERAL@105..106 " " [] []
+ 1: MD_TEXTUAL@106..110
+ 0: MD_TEXTUAL_LITERAL@106..110 "/url" [] []
+ 5: (empty)
+ 13: MD_NEWLINE@110..111
+ 0: NEWLINE@110..111 "\n" [] []
+ 2: EOF@111..111 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition_edge_cases.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition_edge_cases.md
new file mode 100644
index 000000000000..b8c72626c468
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition_edge_cases.md
@@ -0,0 +1,32 @@
+Some text with trailing spaces
+
+ [after-trailing]: /url
+
+Another paragraph
+
+ [normal-indent]: /url
+
+[lambda]: /url
+
+[nihongo]: /url "Japanese label"
+
+[title-next-line]: /url
+ "title on next line"
+
+[single-quote-next]: /url
+ 'single quoted'
+
+[paren-next]: /url
+ (parenthesized)
+
+[balanced-parens]: http://example.com/path(with)parens
+
+[nested-parens]: http://example.com/a(b(c)d)e
+
+[escaped\]bracket]: /url
+
+[trailing-spaces]: /url
+
+[invalid-trailing]: /url invalid
+
+[angle-trailing]: invalid
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition_edge_cases.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition_edge_cases.md.snap
new file mode 100644
index 000000000000..c1d0f90e6c95
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition_edge_cases.md.snap
@@ -0,0 +1,1052 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+Some text with trailing spaces
+
+ [after-trailing]: /url
+
+Another paragraph
+
+ [normal-indent]: /url
+
+[lambda]: /url
+
+[nihongo]: /url "Japanese label"
+
+[title-next-line]: /url
+ "title on next line"
+
+[single-quote-next]: /url
+ 'single quoted'
+
+[paren-next]: /url
+ (parenthesized)
+
+[balanced-parens]: http://example.com/path(with)parens
+
+[nested-parens]: http://example.com/a(b(c)d)e
+
+[escaped\]bracket]: /url
+
+[trailing-spaces]: /url
+
+[invalid-trailing]: /url invalid
+
+[angle-trailing]: invalid
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..30 "Some text with trailing spaces" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@30..31 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@31..32 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@32..35 "[" [Skipped(" "), Skipped(" ")] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@35..40 "after" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@40..41 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@41..49 "trailing" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@49..50 "]" [] [],
+ colon_token: COLON@50..51 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@51..52 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@52..56 "/url" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@56..57 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@57..58 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@58..75 "Another paragraph" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@75..76 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@76..77 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@77..80 "[" [Skipped(" "), Skipped(" ")] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@80..86 "normal" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@86..87 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@87..93 "indent" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@93..94 "]" [] [],
+ colon_token: COLON@94..95 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@95..96 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@96..100 "/url" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@100..101 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@101..102 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@102..103 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@103..109 "lambda" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@109..110 "]" [] [],
+ colon_token: COLON@110..111 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@111..112 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@112..116 "/url" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@116..117 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@117..118 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@118..119 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@119..126 "nihongo" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@126..127 "]" [] [],
+ colon_token: COLON@127..128 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@128..129 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@129..133 "/url" [] [],
+ },
+ ],
+ },
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@133..134 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@134..150 "\"Japanese label\"" [] [],
+ },
+ ],
+ },
+ },
+ MdNewline {
+ value_token: NEWLINE@150..151 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@151..152 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@152..153 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@153..158 "title" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@158..159 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@159..163 "next" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@163..164 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@164..168 "line" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@168..169 "]" [] [],
+ colon_token: COLON@169..170 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@170..171 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@171..175 "/url" [] [],
+ },
+ ],
+ },
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@175..176 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@176..178 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@178..198 "\"title on next line\"" [] [],
+ },
+ ],
+ },
+ },
+ MdNewline {
+ value_token: NEWLINE@198..199 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@199..200 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@200..201 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@201..207 "single" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@207..208 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@208..213 "quote" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@213..214 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@214..218 "next" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@218..219 "]" [] [],
+ colon_token: COLON@219..220 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@220..221 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@221..225 "/url" [] [],
+ },
+ ],
+ },
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@225..226 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@226..228 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@228..243 "'single quoted'" [] [],
+ },
+ ],
+ },
+ },
+ MdNewline {
+ value_token: NEWLINE@243..244 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@244..245 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@245..246 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@246..251 "paren" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@251..252 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@252..256 "next" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@256..257 "]" [] [],
+ colon_token: COLON@257..258 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@258..259 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@259..263 "/url" [] [],
+ },
+ ],
+ },
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@263..264 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@264..266 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@266..267 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@267..280 "parenthesized" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@280..281 ")" [] [],
+ },
+ ],
+ },
+ },
+ MdNewline {
+ value_token: NEWLINE@281..282 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@282..283 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@283..284 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@284..292 "balanced" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@292..293 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@293..299 "parens" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@299..300 "]" [] [],
+ colon_token: COLON@300..301 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@301..302 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@302..325 "http://example.com/path" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@325..326 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@326..330 "with" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@330..331 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@331..337 "parens" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@337..338 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@338..339 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@339..340 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@340..346 "nested" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@346..347 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@347..353 "parens" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@353..354 "]" [] [],
+ colon_token: COLON@354..355 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@355..356 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@356..376 "http://example.com/a" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@376..377 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@377..378 "b" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@378..379 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@379..380 "c" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@380..381 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@381..382 "d" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@382..383 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@383..384 "e" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@384..385 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@385..386 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@386..387 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@387..394 "escaped" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@394..396 "\\]" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@396..403 "bracket" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@403..404 "]" [] [],
+ colon_token: COLON@404..405 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@405..406 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@406..410 "/url" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@410..411 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@411..412 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@412..413 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@413..421 "trailing" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@421..422 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@422..428 "spaces" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@428..429 "]" [] [],
+ colon_token: COLON@429..430 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@430..431 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@431..435 "/url" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@435..438 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@438..439 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@439..440 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@440..441 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@441..448 "invalid" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@448..449 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@449..457 "trailing" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@457..458 "]" [] [],
+ colon_token: COLON@458..459 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@459..460 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@460..464 "/url" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@464..465 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@465..472 "invalid" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@472..473 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@473..474 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@474..475 "[" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@475..480 "angle" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@480..481 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@481..489 "trailing" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@489..490 "]" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@490..491 ":" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@491..492 " " [] [],
+ },
+ MdInlineHtml {
+ value: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@492..493 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@493..497 "/url" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@497..498 ">" [] [],
+ },
+ ],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@498..506 " invalid" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@506..507 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@507..507 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..507
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..507
+ 0: MD_PARAGRAPH@0..31
+ 0: MD_INLINE_ITEM_LIST@0..31
+ 0: MD_TEXTUAL@0..30
+ 0: MD_TEXTUAL_LITERAL@0..30 "Some text with trailing spaces" [] []
+ 1: MD_TEXTUAL@30..31
+ 0: MD_TEXTUAL_LITERAL@30..31 "\n" [] []
+ 1: (empty)
+ 1: MD_NEWLINE@31..32
+ 0: NEWLINE@31..32 "\n" [] []
+ 2: MD_LINK_REFERENCE_DEFINITION@32..56
+ 0: L_BRACK@32..35 "[" [Skipped(" "), Skipped(" ")] []
+ 1: MD_LINK_LABEL@35..49
+ 0: MD_INLINE_ITEM_LIST@35..49
+ 0: MD_TEXTUAL@35..40
+ 0: MD_TEXTUAL_LITERAL@35..40 "after" [] []
+ 1: MD_TEXTUAL@40..41
+ 0: MD_TEXTUAL_LITERAL@40..41 "-" [] []
+ 2: MD_TEXTUAL@41..49
+ 0: MD_TEXTUAL_LITERAL@41..49 "trailing" [] []
+ 2: R_BRACK@49..50 "]" [] []
+ 3: COLON@50..51 ":" [] []
+ 4: MD_LINK_DESTINATION@51..56
+ 0: MD_INLINE_ITEM_LIST@51..56
+ 0: MD_TEXTUAL@51..52
+ 0: MD_TEXTUAL_LITERAL@51..52 " " [] []
+ 1: MD_TEXTUAL@52..56
+ 0: MD_TEXTUAL_LITERAL@52..56 "/url" [] []
+ 5: (empty)
+ 3: MD_NEWLINE@56..57
+ 0: NEWLINE@56..57 "\n" [] []
+ 4: MD_NEWLINE@57..58
+ 0: NEWLINE@57..58 "\n" [] []
+ 5: MD_PARAGRAPH@58..76
+ 0: MD_INLINE_ITEM_LIST@58..76
+ 0: MD_TEXTUAL@58..75
+ 0: MD_TEXTUAL_LITERAL@58..75 "Another paragraph" [] []
+ 1: MD_TEXTUAL@75..76
+ 0: MD_TEXTUAL_LITERAL@75..76 "\n" [] []
+ 1: (empty)
+ 6: MD_NEWLINE@76..77
+ 0: NEWLINE@76..77 "\n" [] []
+ 7: MD_LINK_REFERENCE_DEFINITION@77..100
+ 0: L_BRACK@77..80 "[" [Skipped(" "), Skipped(" ")] []
+ 1: MD_LINK_LABEL@80..93
+ 0: MD_INLINE_ITEM_LIST@80..93
+ 0: MD_TEXTUAL@80..86
+ 0: MD_TEXTUAL_LITERAL@80..86 "normal" [] []
+ 1: MD_TEXTUAL@86..87
+ 0: MD_TEXTUAL_LITERAL@86..87 "-" [] []
+ 2: MD_TEXTUAL@87..93
+ 0: MD_TEXTUAL_LITERAL@87..93 "indent" [] []
+ 2: R_BRACK@93..94 "]" [] []
+ 3: COLON@94..95 ":" [] []
+ 4: MD_LINK_DESTINATION@95..100
+ 0: MD_INLINE_ITEM_LIST@95..100
+ 0: MD_TEXTUAL@95..96
+ 0: MD_TEXTUAL_LITERAL@95..96 " " [] []
+ 1: MD_TEXTUAL@96..100
+ 0: MD_TEXTUAL_LITERAL@96..100 "/url" [] []
+ 5: (empty)
+ 8: MD_NEWLINE@100..101
+ 0: NEWLINE@100..101 "\n" [] []
+ 9: MD_NEWLINE@101..102
+ 0: NEWLINE@101..102 "\n" [] []
+ 10: MD_LINK_REFERENCE_DEFINITION@102..116
+ 0: L_BRACK@102..103 "[" [] []
+ 1: MD_LINK_LABEL@103..109
+ 0: MD_INLINE_ITEM_LIST@103..109
+ 0: MD_TEXTUAL@103..109
+ 0: MD_TEXTUAL_LITERAL@103..109 "lambda" [] []
+ 2: R_BRACK@109..110 "]" [] []
+ 3: COLON@110..111 ":" [] []
+ 4: MD_LINK_DESTINATION@111..116
+ 0: MD_INLINE_ITEM_LIST@111..116
+ 0: MD_TEXTUAL@111..112
+ 0: MD_TEXTUAL_LITERAL@111..112 " " [] []
+ 1: MD_TEXTUAL@112..116
+ 0: MD_TEXTUAL_LITERAL@112..116 "/url" [] []
+ 5: (empty)
+ 11: MD_NEWLINE@116..117
+ 0: NEWLINE@116..117 "\n" [] []
+ 12: MD_NEWLINE@117..118
+ 0: NEWLINE@117..118 "\n" [] []
+ 13: MD_LINK_REFERENCE_DEFINITION@118..150
+ 0: L_BRACK@118..119 "[" [] []
+ 1: MD_LINK_LABEL@119..126
+ 0: MD_INLINE_ITEM_LIST@119..126
+ 0: MD_TEXTUAL@119..126
+ 0: MD_TEXTUAL_LITERAL@119..126 "nihongo" [] []
+ 2: R_BRACK@126..127 "]" [] []
+ 3: COLON@127..128 ":" [] []
+ 4: MD_LINK_DESTINATION@128..133
+ 0: MD_INLINE_ITEM_LIST@128..133
+ 0: MD_TEXTUAL@128..129
+ 0: MD_TEXTUAL_LITERAL@128..129 " " [] []
+ 1: MD_TEXTUAL@129..133
+ 0: MD_TEXTUAL_LITERAL@129..133 "/url" [] []
+ 5: MD_LINK_TITLE@133..150
+ 0: MD_INLINE_ITEM_LIST@133..150
+ 0: MD_TEXTUAL@133..134
+ 0: MD_TEXTUAL_LITERAL@133..134 " " [] []
+ 1: MD_TEXTUAL@134..150
+ 0: MD_TEXTUAL_LITERAL@134..150 "\"Japanese label\"" [] []
+ 14: MD_NEWLINE@150..151
+ 0: NEWLINE@150..151 "\n" [] []
+ 15: MD_NEWLINE@151..152
+ 0: NEWLINE@151..152 "\n" [] []
+ 16: MD_LINK_REFERENCE_DEFINITION@152..198
+ 0: L_BRACK@152..153 "[" [] []
+ 1: MD_LINK_LABEL@153..168
+ 0: MD_INLINE_ITEM_LIST@153..168
+ 0: MD_TEXTUAL@153..158
+ 0: MD_TEXTUAL_LITERAL@153..158 "title" [] []
+ 1: MD_TEXTUAL@158..159
+ 0: MD_TEXTUAL_LITERAL@158..159 "-" [] []
+ 2: MD_TEXTUAL@159..163
+ 0: MD_TEXTUAL_LITERAL@159..163 "next" [] []
+ 3: MD_TEXTUAL@163..164
+ 0: MD_TEXTUAL_LITERAL@163..164 "-" [] []
+ 4: MD_TEXTUAL@164..168
+ 0: MD_TEXTUAL_LITERAL@164..168 "line" [] []
+ 2: R_BRACK@168..169 "]" [] []
+ 3: COLON@169..170 ":" [] []
+ 4: MD_LINK_DESTINATION@170..175
+ 0: MD_INLINE_ITEM_LIST@170..175
+ 0: MD_TEXTUAL@170..171
+ 0: MD_TEXTUAL_LITERAL@170..171 " " [] []
+ 1: MD_TEXTUAL@171..175
+ 0: MD_TEXTUAL_LITERAL@171..175 "/url" [] []
+ 5: MD_LINK_TITLE@175..198
+ 0: MD_INLINE_ITEM_LIST@175..198
+ 0: MD_TEXTUAL@175..176
+ 0: MD_TEXTUAL_LITERAL@175..176 "\n" [] []
+ 1: MD_TEXTUAL@176..178
+ 0: MD_TEXTUAL_LITERAL@176..178 " " [] []
+ 2: MD_TEXTUAL@178..198
+ 0: MD_TEXTUAL_LITERAL@178..198 "\"title on next line\"" [] []
+ 17: MD_NEWLINE@198..199
+ 0: NEWLINE@198..199 "\n" [] []
+ 18: MD_NEWLINE@199..200
+ 0: NEWLINE@199..200 "\n" [] []
+ 19: MD_LINK_REFERENCE_DEFINITION@200..243
+ 0: L_BRACK@200..201 "[" [] []
+ 1: MD_LINK_LABEL@201..218
+ 0: MD_INLINE_ITEM_LIST@201..218
+ 0: MD_TEXTUAL@201..207
+ 0: MD_TEXTUAL_LITERAL@201..207 "single" [] []
+ 1: MD_TEXTUAL@207..208
+ 0: MD_TEXTUAL_LITERAL@207..208 "-" [] []
+ 2: MD_TEXTUAL@208..213
+ 0: MD_TEXTUAL_LITERAL@208..213 "quote" [] []
+ 3: MD_TEXTUAL@213..214
+ 0: MD_TEXTUAL_LITERAL@213..214 "-" [] []
+ 4: MD_TEXTUAL@214..218
+ 0: MD_TEXTUAL_LITERAL@214..218 "next" [] []
+ 2: R_BRACK@218..219 "]" [] []
+ 3: COLON@219..220 ":" [] []
+ 4: MD_LINK_DESTINATION@220..225
+ 0: MD_INLINE_ITEM_LIST@220..225
+ 0: MD_TEXTUAL@220..221
+ 0: MD_TEXTUAL_LITERAL@220..221 " " [] []
+ 1: MD_TEXTUAL@221..225
+ 0: MD_TEXTUAL_LITERAL@221..225 "/url" [] []
+ 5: MD_LINK_TITLE@225..243
+ 0: MD_INLINE_ITEM_LIST@225..243
+ 0: MD_TEXTUAL@225..226
+ 0: MD_TEXTUAL_LITERAL@225..226 "\n" [] []
+ 1: MD_TEXTUAL@226..228
+ 0: MD_TEXTUAL_LITERAL@226..228 " " [] []
+ 2: MD_TEXTUAL@228..243
+ 0: MD_TEXTUAL_LITERAL@228..243 "'single quoted'" [] []
+ 20: MD_NEWLINE@243..244
+ 0: NEWLINE@243..244 "\n" [] []
+ 21: MD_NEWLINE@244..245
+ 0: NEWLINE@244..245 "\n" [] []
+ 22: MD_LINK_REFERENCE_DEFINITION@245..281
+ 0: L_BRACK@245..246 "[" [] []
+ 1: MD_LINK_LABEL@246..256
+ 0: MD_INLINE_ITEM_LIST@246..256
+ 0: MD_TEXTUAL@246..251
+ 0: MD_TEXTUAL_LITERAL@246..251 "paren" [] []
+ 1: MD_TEXTUAL@251..252
+ 0: MD_TEXTUAL_LITERAL@251..252 "-" [] []
+ 2: MD_TEXTUAL@252..256
+ 0: MD_TEXTUAL_LITERAL@252..256 "next" [] []
+ 2: R_BRACK@256..257 "]" [] []
+ 3: COLON@257..258 ":" [] []
+ 4: MD_LINK_DESTINATION@258..263
+ 0: MD_INLINE_ITEM_LIST@258..263
+ 0: MD_TEXTUAL@258..259
+ 0: MD_TEXTUAL_LITERAL@258..259 " " [] []
+ 1: MD_TEXTUAL@259..263
+ 0: MD_TEXTUAL_LITERAL@259..263 "/url" [] []
+ 5: MD_LINK_TITLE@263..281
+ 0: MD_INLINE_ITEM_LIST@263..281
+ 0: MD_TEXTUAL@263..264
+ 0: MD_TEXTUAL_LITERAL@263..264 "\n" [] []
+ 1: MD_TEXTUAL@264..266
+ 0: MD_TEXTUAL_LITERAL@264..266 " " [] []
+ 2: MD_TEXTUAL@266..267
+ 0: MD_TEXTUAL_LITERAL@266..267 "(" [] []
+ 3: MD_TEXTUAL@267..280
+ 0: MD_TEXTUAL_LITERAL@267..280 "parenthesized" [] []
+ 4: MD_TEXTUAL@280..281
+ 0: MD_TEXTUAL_LITERAL@280..281 ")" [] []
+ 23: MD_NEWLINE@281..282
+ 0: NEWLINE@281..282 "\n" [] []
+ 24: MD_NEWLINE@282..283
+ 0: NEWLINE@282..283 "\n" [] []
+ 25: MD_LINK_REFERENCE_DEFINITION@283..337
+ 0: L_BRACK@283..284 "[" [] []
+ 1: MD_LINK_LABEL@284..299
+ 0: MD_INLINE_ITEM_LIST@284..299
+ 0: MD_TEXTUAL@284..292
+ 0: MD_TEXTUAL_LITERAL@284..292 "balanced" [] []
+ 1: MD_TEXTUAL@292..293
+ 0: MD_TEXTUAL_LITERAL@292..293 "-" [] []
+ 2: MD_TEXTUAL@293..299
+ 0: MD_TEXTUAL_LITERAL@293..299 "parens" [] []
+ 2: R_BRACK@299..300 "]" [] []
+ 3: COLON@300..301 ":" [] []
+ 4: MD_LINK_DESTINATION@301..337
+ 0: MD_INLINE_ITEM_LIST@301..337
+ 0: MD_TEXTUAL@301..302
+ 0: MD_TEXTUAL_LITERAL@301..302 " " [] []
+ 1: MD_TEXTUAL@302..325
+ 0: MD_TEXTUAL_LITERAL@302..325 "http://example.com/path" [] []
+ 2: MD_TEXTUAL@325..326
+ 0: MD_TEXTUAL_LITERAL@325..326 "(" [] []
+ 3: MD_TEXTUAL@326..330
+ 0: MD_TEXTUAL_LITERAL@326..330 "with" [] []
+ 4: MD_TEXTUAL@330..331
+ 0: MD_TEXTUAL_LITERAL@330..331 ")" [] []
+ 5: MD_TEXTUAL@331..337
+ 0: MD_TEXTUAL_LITERAL@331..337 "parens" [] []
+ 5: (empty)
+ 26: MD_NEWLINE@337..338
+ 0: NEWLINE@337..338 "\n" [] []
+ 27: MD_NEWLINE@338..339
+ 0: NEWLINE@338..339 "\n" [] []
+ 28: MD_LINK_REFERENCE_DEFINITION@339..384
+ 0: L_BRACK@339..340 "[" [] []
+ 1: MD_LINK_LABEL@340..353
+ 0: MD_INLINE_ITEM_LIST@340..353
+ 0: MD_TEXTUAL@340..346
+ 0: MD_TEXTUAL_LITERAL@340..346 "nested" [] []
+ 1: MD_TEXTUAL@346..347
+ 0: MD_TEXTUAL_LITERAL@346..347 "-" [] []
+ 2: MD_TEXTUAL@347..353
+ 0: MD_TEXTUAL_LITERAL@347..353 "parens" [] []
+ 2: R_BRACK@353..354 "]" [] []
+ 3: COLON@354..355 ":" [] []
+ 4: MD_LINK_DESTINATION@355..384
+ 0: MD_INLINE_ITEM_LIST@355..384
+ 0: MD_TEXTUAL@355..356
+ 0: MD_TEXTUAL_LITERAL@355..356 " " [] []
+ 1: MD_TEXTUAL@356..376
+ 0: MD_TEXTUAL_LITERAL@356..376 "http://example.com/a" [] []
+ 2: MD_TEXTUAL@376..377
+ 0: MD_TEXTUAL_LITERAL@376..377 "(" [] []
+ 3: MD_TEXTUAL@377..378
+ 0: MD_TEXTUAL_LITERAL@377..378 "b" [] []
+ 4: MD_TEXTUAL@378..379
+ 0: MD_TEXTUAL_LITERAL@378..379 "(" [] []
+ 5: MD_TEXTUAL@379..380
+ 0: MD_TEXTUAL_LITERAL@379..380 "c" [] []
+ 6: MD_TEXTUAL@380..381
+ 0: MD_TEXTUAL_LITERAL@380..381 ")" [] []
+ 7: MD_TEXTUAL@381..382
+ 0: MD_TEXTUAL_LITERAL@381..382 "d" [] []
+ 8: MD_TEXTUAL@382..383
+ 0: MD_TEXTUAL_LITERAL@382..383 ")" [] []
+ 9: MD_TEXTUAL@383..384
+ 0: MD_TEXTUAL_LITERAL@383..384 "e" [] []
+ 5: (empty)
+ 29: MD_NEWLINE@384..385
+ 0: NEWLINE@384..385 "\n" [] []
+ 30: MD_NEWLINE@385..386
+ 0: NEWLINE@385..386 "\n" [] []
+ 31: MD_LINK_REFERENCE_DEFINITION@386..410
+ 0: L_BRACK@386..387 "[" [] []
+ 1: MD_LINK_LABEL@387..403
+ 0: MD_INLINE_ITEM_LIST@387..403
+ 0: MD_TEXTUAL@387..394
+ 0: MD_TEXTUAL_LITERAL@387..394 "escaped" [] []
+ 1: MD_TEXTUAL@394..396
+ 0: MD_TEXTUAL_LITERAL@394..396 "\\]" [] []
+ 2: MD_TEXTUAL@396..403
+ 0: MD_TEXTUAL_LITERAL@396..403 "bracket" [] []
+ 2: R_BRACK@403..404 "]" [] []
+ 3: COLON@404..405 ":" [] []
+ 4: MD_LINK_DESTINATION@405..410
+ 0: MD_INLINE_ITEM_LIST@405..410
+ 0: MD_TEXTUAL@405..406
+ 0: MD_TEXTUAL_LITERAL@405..406 " " [] []
+ 1: MD_TEXTUAL@406..410
+ 0: MD_TEXTUAL_LITERAL@406..410 "/url" [] []
+ 5: (empty)
+ 32: MD_NEWLINE@410..411
+ 0: NEWLINE@410..411 "\n" [] []
+ 33: MD_NEWLINE@411..412
+ 0: NEWLINE@411..412 "\n" [] []
+ 34: MD_LINK_REFERENCE_DEFINITION@412..435
+ 0: L_BRACK@412..413 "[" [] []
+ 1: MD_LINK_LABEL@413..428
+ 0: MD_INLINE_ITEM_LIST@413..428
+ 0: MD_TEXTUAL@413..421
+ 0: MD_TEXTUAL_LITERAL@413..421 "trailing" [] []
+ 1: MD_TEXTUAL@421..422
+ 0: MD_TEXTUAL_LITERAL@421..422 "-" [] []
+ 2: MD_TEXTUAL@422..428
+ 0: MD_TEXTUAL_LITERAL@422..428 "spaces" [] []
+ 2: R_BRACK@428..429 "]" [] []
+ 3: COLON@429..430 ":" [] []
+ 4: MD_LINK_DESTINATION@430..435
+ 0: MD_INLINE_ITEM_LIST@430..435
+ 0: MD_TEXTUAL@430..431
+ 0: MD_TEXTUAL_LITERAL@430..431 " " [] []
+ 1: MD_TEXTUAL@431..435
+ 0: MD_TEXTUAL_LITERAL@431..435 "/url" [] []
+ 5: (empty)
+ 35: MD_PARAGRAPH@435..439
+ 0: MD_INLINE_ITEM_LIST@435..439
+ 0: MD_TEXTUAL@435..438
+ 0: MD_TEXTUAL_LITERAL@435..438 " " [] []
+ 1: MD_TEXTUAL@438..439
+ 0: MD_TEXTUAL_LITERAL@438..439 "\n" [] []
+ 1: (empty)
+ 36: MD_NEWLINE@439..440
+ 0: NEWLINE@439..440 "\n" [] []
+ 37: MD_LINK_REFERENCE_DEFINITION@440..464
+ 0: L_BRACK@440..441 "[" [] []
+ 1: MD_LINK_LABEL@441..457
+ 0: MD_INLINE_ITEM_LIST@441..457
+ 0: MD_TEXTUAL@441..448
+ 0: MD_TEXTUAL_LITERAL@441..448 "invalid" [] []
+ 1: MD_TEXTUAL@448..449
+ 0: MD_TEXTUAL_LITERAL@448..449 "-" [] []
+ 2: MD_TEXTUAL@449..457
+ 0: MD_TEXTUAL_LITERAL@449..457 "trailing" [] []
+ 2: R_BRACK@457..458 "]" [] []
+ 3: COLON@458..459 ":" [] []
+ 4: MD_LINK_DESTINATION@459..464
+ 0: MD_INLINE_ITEM_LIST@459..464
+ 0: MD_TEXTUAL@459..460
+ 0: MD_TEXTUAL_LITERAL@459..460 " " [] []
+ 1: MD_TEXTUAL@460..464
+ 0: MD_TEXTUAL_LITERAL@460..464 "/url" [] []
+ 5: (empty)
+ 38: MD_PARAGRAPH@464..473
+ 0: MD_INLINE_ITEM_LIST@464..473
+ 0: MD_TEXTUAL@464..465
+ 0: MD_TEXTUAL_LITERAL@464..465 " " [] []
+ 1: MD_TEXTUAL@465..472
+ 0: MD_TEXTUAL_LITERAL@465..472 "invalid" [] []
+ 2: MD_TEXTUAL@472..473
+ 0: MD_TEXTUAL_LITERAL@472..473 "\n" [] []
+ 1: (empty)
+ 39: MD_NEWLINE@473..474
+ 0: NEWLINE@473..474 "\n" [] []
+ 40: MD_PARAGRAPH@474..507
+ 0: MD_INLINE_ITEM_LIST@474..507
+ 0: MD_TEXTUAL@474..475
+ 0: MD_TEXTUAL_LITERAL@474..475 "[" [] []
+ 1: MD_TEXTUAL@475..480
+ 0: MD_TEXTUAL_LITERAL@475..480 "angle" [] []
+ 2: MD_TEXTUAL@480..481
+ 0: MD_TEXTUAL_LITERAL@480..481 "-" [] []
+ 3: MD_TEXTUAL@481..489
+ 0: MD_TEXTUAL_LITERAL@481..489 "trailing" [] []
+ 4: MD_TEXTUAL@489..490
+ 0: MD_TEXTUAL_LITERAL@489..490 "]" [] []
+ 5: MD_TEXTUAL@490..491
+ 0: MD_TEXTUAL_LITERAL@490..491 ":" [] []
+ 6: MD_TEXTUAL@491..492
+ 0: MD_TEXTUAL_LITERAL@491..492 " " [] []
+ 7: MD_INLINE_HTML@492..498
+ 0: MD_INLINE_ITEM_LIST@492..498
+ 0: MD_TEXTUAL@492..493
+ 0: MD_TEXTUAL_LITERAL@492..493 "<" [] []
+ 1: MD_TEXTUAL@493..497
+ 0: MD_TEXTUAL_LITERAL@493..497 "/url" [] []
+ 2: MD_TEXTUAL@497..498
+ 0: MD_TEXTUAL_LITERAL@497..498 ">" [] []
+ 8: MD_TEXTUAL@498..506
+ 0: MD_TEXTUAL_LITERAL@498..506 " invalid" [] []
+ 9: MD_TEXTUAL@506..507
+ 0: MD_TEXTUAL_LITERAL@506..507 "\n" [] []
+ 1: (empty)
+ 2: EOF@507..507 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition_invalid.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition_invalid.md
new file mode 100644
index 000000000000..e62c67e57955
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition_invalid.md
@@ -0,0 +1,14 @@
+These should NOT be parsed as link reference definitions.
+They should fall back to paragraph parsing.
+
+Unterminated angle bracket destination:
+[unterminated-angle]: Outer quote
+>> Nested quote
+>>> Deeply nested
+
+> Back to outer
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/nested_quote.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/nested_quote.md.snap
new file mode 100644
index 000000000000..02e336c24db9
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/nested_quote.md.snap
@@ -0,0 +1,146 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+> Outer quote
+>> Nested quote
+>>> Deeply nested
+
+> Back to outer
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdQuote {
+ marker_token: R_ANGLE@0..1 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@1..13 "Outer quote" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@13..14 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdQuote {
+ marker_token: R_ANGLE@14..16 ">" [Skipped(">")] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@16..29 "Nested quote" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@29..30 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdQuote {
+ marker_token: R_ANGLE@30..33 ">" [Skipped(">"), Skipped(">")] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@33..47 "Deeply nested" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@47..48 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ MdNewline {
+ value_token: NEWLINE@48..49 "\n" [] [],
+ },
+ MdQuote {
+ marker_token: R_ANGLE@49..50 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@50..64 "Back to outer" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@64..65 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ ],
+ eof_token: EOF@65..65 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..65
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..65
+ 0: MD_QUOTE@0..48
+ 0: R_ANGLE@0..1 ">" [] []
+ 1: MD_BLOCK_LIST@1..48
+ 0: MD_PARAGRAPH@1..14
+ 0: MD_INLINE_ITEM_LIST@1..14
+ 0: MD_TEXTUAL@1..13
+ 0: MD_TEXTUAL_LITERAL@1..13 "Outer quote" [Skipped(" ")] []
+ 1: MD_TEXTUAL@13..14
+ 0: MD_TEXTUAL_LITERAL@13..14 "\n" [] []
+ 1: (empty)
+ 1: MD_QUOTE@14..48
+ 0: R_ANGLE@14..16 ">" [Skipped(">")] []
+ 1: MD_BLOCK_LIST@16..48
+ 0: MD_PARAGRAPH@16..30
+ 0: MD_INLINE_ITEM_LIST@16..30
+ 0: MD_TEXTUAL@16..29
+ 0: MD_TEXTUAL_LITERAL@16..29 "Nested quote" [Skipped(" ")] []
+ 1: MD_TEXTUAL@29..30
+ 0: MD_TEXTUAL_LITERAL@29..30 "\n" [] []
+ 1: (empty)
+ 1: MD_QUOTE@30..48
+ 0: R_ANGLE@30..33 ">" [Skipped(">"), Skipped(">")] []
+ 1: MD_BLOCK_LIST@33..48
+ 0: MD_PARAGRAPH@33..48
+ 0: MD_INLINE_ITEM_LIST@33..48
+ 0: MD_TEXTUAL@33..47
+ 0: MD_TEXTUAL_LITERAL@33..47 "Deeply nested" [Skipped(" ")] []
+ 1: MD_TEXTUAL@47..48
+ 0: MD_TEXTUAL_LITERAL@47..48 "\n" [] []
+ 1: (empty)
+ 1: MD_NEWLINE@48..49
+ 0: NEWLINE@48..49 "\n" [] []
+ 2: MD_QUOTE@49..65
+ 0: R_ANGLE@49..50 ">" [] []
+ 1: MD_BLOCK_LIST@50..65
+ 0: MD_PARAGRAPH@50..65
+ 0: MD_INLINE_ITEM_LIST@50..65
+ 0: MD_TEXTUAL@50..64
+ 0: MD_TEXTUAL_LITERAL@50..64 "Back to outer" [Skipped(" ")] []
+ 1: MD_TEXTUAL@64..65
+ 0: MD_TEXTUAL_LITERAL@64..65 "\n" [] []
+ 1: (empty)
+ 2: EOF@65..65 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/ordered_list.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/ordered_list.md
new file mode 100644
index 000000000000..b250e4984978
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/ordered_list.md
@@ -0,0 +1,6 @@
+1. First item
+2. Second item
+3. Third item
+
+1) Using parenthesis
+2) Another item
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/ordered_list.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/ordered_list.md.snap
new file mode 100644
index 000000000000..f1c98f087c14
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/ordered_list.md.snap
@@ -0,0 +1,185 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+1. First item
+2. Second item
+3. Third item
+
+1) Using parenthesis
+2) Another item
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdOrderedListItem {
+ md_bullet_list: MdBulletList [
+ MdBullet {
+ bullet: MD_ORDERED_LIST_MARKER@0..2 "1." [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@2..13 " First item" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@13..14 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdBullet {
+ bullet: MD_ORDERED_LIST_MARKER@14..16 "2." [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@16..28 " Second item" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@28..29 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdBullet {
+ bullet: MD_ORDERED_LIST_MARKER@29..31 "3." [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@31..42 " Third item" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@42..43 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@43..44 "\n" [] [],
+ },
+ ],
+ },
+ ],
+ },
+ MdOrderedListItem {
+ md_bullet_list: MdBulletList [
+ MdBullet {
+ bullet: MD_ORDERED_LIST_MARKER@44..46 "1)" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@46..64 " Using parenthesis" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@64..65 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdBullet {
+ bullet: MD_ORDERED_LIST_MARKER@65..67 "2)" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@67..80 " Another item" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@80..81 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ eof_token: EOF@81..81 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..81
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..81
+ 0: MD_ORDERED_LIST_ITEM@0..44
+ 0: MD_BULLET_LIST@0..44
+ 0: MD_BULLET@0..14
+ 0: MD_ORDERED_LIST_MARKER@0..2 "1." [] []
+ 1: MD_BLOCK_LIST@2..14
+ 0: MD_PARAGRAPH@2..14
+ 0: MD_INLINE_ITEM_LIST@2..14
+ 0: MD_TEXTUAL@2..13
+ 0: MD_TEXTUAL_LITERAL@2..13 " First item" [] []
+ 1: MD_TEXTUAL@13..14
+ 0: MD_TEXTUAL_LITERAL@13..14 "\n" [] []
+ 1: (empty)
+ 1: MD_BULLET@14..29
+ 0: MD_ORDERED_LIST_MARKER@14..16 "2." [] []
+ 1: MD_BLOCK_LIST@16..29
+ 0: MD_PARAGRAPH@16..29
+ 0: MD_INLINE_ITEM_LIST@16..29
+ 0: MD_TEXTUAL@16..28
+ 0: MD_TEXTUAL_LITERAL@16..28 " Second item" [] []
+ 1: MD_TEXTUAL@28..29
+ 0: MD_TEXTUAL_LITERAL@28..29 "\n" [] []
+ 1: (empty)
+ 2: MD_BULLET@29..44
+ 0: MD_ORDERED_LIST_MARKER@29..31 "3." [] []
+ 1: MD_BLOCK_LIST@31..44
+ 0: MD_PARAGRAPH@31..43
+ 0: MD_INLINE_ITEM_LIST@31..43
+ 0: MD_TEXTUAL@31..42
+ 0: MD_TEXTUAL_LITERAL@31..42 " Third item" [] []
+ 1: MD_TEXTUAL@42..43
+ 0: MD_TEXTUAL_LITERAL@42..43 "\n" [] []
+ 1: (empty)
+ 1: MD_NEWLINE@43..44
+ 0: NEWLINE@43..44 "\n" [] []
+ 1: MD_ORDERED_LIST_ITEM@44..81
+ 0: MD_BULLET_LIST@44..81
+ 0: MD_BULLET@44..65
+ 0: MD_ORDERED_LIST_MARKER@44..46 "1)" [] []
+ 1: MD_BLOCK_LIST@46..65
+ 0: MD_PARAGRAPH@46..65
+ 0: MD_INLINE_ITEM_LIST@46..65
+ 0: MD_TEXTUAL@46..64
+ 0: MD_TEXTUAL_LITERAL@46..64 " Using parenthesis" [] []
+ 1: MD_TEXTUAL@64..65
+ 0: MD_TEXTUAL_LITERAL@64..65 "\n" [] []
+ 1: (empty)
+ 1: MD_BULLET@65..81
+ 0: MD_ORDERED_LIST_MARKER@65..67 "2)" [] []
+ 1: MD_BLOCK_LIST@67..81
+ 0: MD_PARAGRAPH@67..81
+ 0: MD_INLINE_ITEM_LIST@67..81
+ 0: MD_TEXTUAL@67..80
+ 0: MD_TEXTUAL_LITERAL@67..80 " Another item" [] []
+ 1: MD_TEXTUAL@80..81
+ 0: MD_TEXTUAL_LITERAL@80..81 "\n" [] []
+ 1: (empty)
+ 2: EOF@81..81 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph.md
new file mode 100644
index 000000000000..b3f891111b93
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph.md
@@ -0,0 +1,3 @@
+This is a simple paragraph.
+
+This is another paragraph.
\ No newline at end of file
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph.md.snap
new file mode 100644
index 000000000000..a6ca100f767f
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph.md.snap
@@ -0,0 +1,70 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+This is a simple paragraph.
+
+This is another paragraph.
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..27 "This is a simple paragraph." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@27..28 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@28..29 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@29..55 "This is another paragraph." [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@55..55 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..55
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..55
+ 0: MD_PARAGRAPH@0..28
+ 0: MD_INLINE_ITEM_LIST@0..28
+ 0: MD_TEXTUAL@0..27
+ 0: MD_TEXTUAL_LITERAL@0..27 "This is a simple paragraph." [] []
+ 1: MD_TEXTUAL@27..28
+ 0: MD_TEXTUAL_LITERAL@27..28 "\n" [] []
+ 1: (empty)
+ 1: MD_NEWLINE@28..29
+ 0: NEWLINE@28..29 "\n" [] []
+ 2: MD_PARAGRAPH@29..55
+ 0: MD_INLINE_ITEM_LIST@29..55
+ 0: MD_TEXTUAL@29..55
+ 0: MD_TEXTUAL_LITERAL@29..55 "This is another paragraph." [] []
+ 1: (empty)
+ 2: EOF@55..55 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph_interruption.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph_interruption.md
new file mode 100644
index 000000000000..48c087618be2
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph_interruption.md
@@ -0,0 +1,16 @@
+Paragraph text
+# Heading interrupts
+
+More text here
+- List interrupts
+
+Another para
+> Quote interrupts
+
+Some text
+```
+Fence interrupts
+```
+
+Final text
+***
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph_interruption.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph_interruption.md.snap
new file mode 100644
index 000000000000..361c97814589
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/paragraph_interruption.md.snap
@@ -0,0 +1,289 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+Paragraph text
+# Heading interrupts
+
+More text here
+- List interrupts
+
+Another para
+> Quote interrupts
+
+Some text
+```
+Fence interrupts
+```
+
+Final text
+***
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..14 "Paragraph text" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@14..15 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdHeader {
+ before: MdHashList [
+ MdHash {
+ hash_token: HASH@15..16 "#" [] [],
+ },
+ ],
+ content: MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@16..35 " Heading interrupts" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ after: MdHashList [],
+ },
+ MdNewline {
+ value_token: NEWLINE@35..36 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@36..37 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@37..51 "More text here" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@51..52 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdBulletListItem {
+ md_bullet_list: MdBulletList [
+ MdBullet {
+ bullet: MINUS@52..53 "-" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@53..69 " List interrupts" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@69..70 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ ],
+ },
+ MdNewline {
+ value_token: NEWLINE@70..71 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@71..83 "Another para" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@83..84 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdQuote {
+ marker_token: R_ANGLE@84..85 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@85..102 "Quote interrupts" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@102..103 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdNewline {
+ value_token: NEWLINE@103..104 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@104..113 "Some text" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@113..114 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdFencedCodeBlock {
+ l_fence: TRIPLE_BACKTICK@114..117 "```" [] [],
+ code_list: MdCodeNameList [],
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@117..118 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@118..134 "Fence interrupts" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@134..135 "\n" [] [],
+ },
+ ],
+ r_fence: TRIPLE_BACKTICK@135..138 "```" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@138..139 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@139..140 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@140..150 "Final text" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@150..151 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdThematicBreakBlock {
+ value_token: MD_THEMATIC_BREAK_LITERAL@151..154 "***" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@154..155 "\n" [] [],
+ },
+ ],
+ eof_token: EOF@155..155 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..155
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..155
+ 0: MD_PARAGRAPH@0..15
+ 0: MD_INLINE_ITEM_LIST@0..15
+ 0: MD_TEXTUAL@0..14
+ 0: MD_TEXTUAL_LITERAL@0..14 "Paragraph text" [] []
+ 1: MD_TEXTUAL@14..15
+ 0: MD_TEXTUAL_LITERAL@14..15 "\n" [] []
+ 1: (empty)
+ 1: MD_HEADER@15..35
+ 0: MD_HASH_LIST@15..16
+ 0: MD_HASH@15..16
+ 0: HASH@15..16 "#" [] []
+ 1: MD_PARAGRAPH@16..35
+ 0: MD_INLINE_ITEM_LIST@16..35
+ 0: MD_TEXTUAL@16..35
+ 0: MD_TEXTUAL_LITERAL@16..35 " Heading interrupts" [] []
+ 1: (empty)
+ 2: MD_HASH_LIST@35..35
+ 2: MD_NEWLINE@35..36
+ 0: NEWLINE@35..36 "\n" [] []
+ 3: MD_NEWLINE@36..37
+ 0: NEWLINE@36..37 "\n" [] []
+ 4: MD_PARAGRAPH@37..52
+ 0: MD_INLINE_ITEM_LIST@37..52
+ 0: MD_TEXTUAL@37..51
+ 0: MD_TEXTUAL_LITERAL@37..51 "More text here" [] []
+ 1: MD_TEXTUAL@51..52
+ 0: MD_TEXTUAL_LITERAL@51..52 "\n" [] []
+ 1: (empty)
+ 5: MD_BULLET_LIST_ITEM@52..70
+ 0: MD_BULLET_LIST@52..70
+ 0: MD_BULLET@52..70
+ 0: MINUS@52..53 "-" [] []
+ 1: MD_BLOCK_LIST@53..70
+ 0: MD_PARAGRAPH@53..70
+ 0: MD_INLINE_ITEM_LIST@53..70
+ 0: MD_TEXTUAL@53..69
+ 0: MD_TEXTUAL_LITERAL@53..69 " List interrupts" [] []
+ 1: MD_TEXTUAL@69..70
+ 0: MD_TEXTUAL_LITERAL@69..70 "\n" [] []
+ 1: (empty)
+ 6: MD_NEWLINE@70..71
+ 0: NEWLINE@70..71 "\n" [] []
+ 7: MD_PARAGRAPH@71..84
+ 0: MD_INLINE_ITEM_LIST@71..84
+ 0: MD_TEXTUAL@71..83
+ 0: MD_TEXTUAL_LITERAL@71..83 "Another para" [] []
+ 1: MD_TEXTUAL@83..84
+ 0: MD_TEXTUAL_LITERAL@83..84 "\n" [] []
+ 1: (empty)
+ 8: MD_QUOTE@84..103
+ 0: R_ANGLE@84..85 ">" [] []
+ 1: MD_BLOCK_LIST@85..103
+ 0: MD_PARAGRAPH@85..103
+ 0: MD_INLINE_ITEM_LIST@85..103
+ 0: MD_TEXTUAL@85..102
+ 0: MD_TEXTUAL_LITERAL@85..102 "Quote interrupts" [Skipped(" ")] []
+ 1: MD_TEXTUAL@102..103
+ 0: MD_TEXTUAL_LITERAL@102..103 "\n" [] []
+ 1: (empty)
+ 9: MD_NEWLINE@103..104
+ 0: NEWLINE@103..104 "\n" [] []
+ 10: MD_PARAGRAPH@104..114
+ 0: MD_INLINE_ITEM_LIST@104..114
+ 0: MD_TEXTUAL@104..113
+ 0: MD_TEXTUAL_LITERAL@104..113 "Some text" [] []
+ 1: MD_TEXTUAL@113..114
+ 0: MD_TEXTUAL_LITERAL@113..114 "\n" [] []
+ 1: (empty)
+ 11: MD_FENCED_CODE_BLOCK@114..138
+ 0: TRIPLE_BACKTICK@114..117 "```" [] []
+ 1: MD_CODE_NAME_LIST@117..117
+ 2: MD_INLINE_ITEM_LIST@117..135
+ 0: MD_TEXTUAL@117..118
+ 0: MD_TEXTUAL_LITERAL@117..118 "\n" [] []
+ 1: MD_TEXTUAL@118..134
+ 0: MD_TEXTUAL_LITERAL@118..134 "Fence interrupts" [] []
+ 2: MD_TEXTUAL@134..135
+ 0: MD_TEXTUAL_LITERAL@134..135 "\n" [] []
+ 3: TRIPLE_BACKTICK@135..138 "```" [] []
+ 12: MD_NEWLINE@138..139
+ 0: NEWLINE@138..139 "\n" [] []
+ 13: MD_NEWLINE@139..140
+ 0: NEWLINE@139..140 "\n" [] []
+ 14: MD_PARAGRAPH@140..151
+ 0: MD_INLINE_ITEM_LIST@140..151
+ 0: MD_TEXTUAL@140..150
+ 0: MD_TEXTUAL_LITERAL@140..150 "Final text" [] []
+ 1: MD_TEXTUAL@150..151
+ 0: MD_TEXTUAL_LITERAL@150..151 "\n" [] []
+ 1: (empty)
+ 15: MD_THEMATIC_BREAK_BLOCK@151..154
+ 0: MD_THEMATIC_BREAK_LITERAL@151..154 "***" [] []
+ 16: MD_NEWLINE@154..155
+ 0: NEWLINE@154..155 "\n" [] []
+ 2: EOF@155..155 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/paren_depth_limit.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/paren_depth_limit.md
new file mode 100644
index 000000000000..3cbf1f91d3e1
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/paren_depth_limit.md
@@ -0,0 +1 @@
+[a](x((((((((((((((((((((((((((((((((y)))))))))))))))))))))))))))))))))
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/paren_depth_limit.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/paren_depth_limit.md.snap
new file mode 100644
index 000000000000..d51a9ea0e1e8
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/paren_depth_limit.md.snap
@@ -0,0 +1,400 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+[a](x((((((((((((((((((((((((((((((((y)))))))))))))))))))))))))))))))))
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdInlineLink {
+ l_brack_token: L_BRACK@0..1 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@1..2 "a" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@2..3 "]" [] [],
+ l_paren_token: L_PAREN@3..4 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@4..5 "x" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@5..6 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@6..7 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@7..8 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@8..9 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@9..10 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@10..11 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@11..12 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@12..13 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@13..14 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@14..15 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@15..16 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@16..17 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@17..18 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@18..19 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@19..20 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@20..21 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@21..22 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@22..23 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@23..24 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@24..25 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@25..26 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@26..27 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@27..28 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@28..29 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@29..30 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@30..31 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@31..32 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@32..33 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@33..34 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@34..35 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@35..36 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@36..37 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@37..38 "y" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@38..39 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@39..40 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@40..41 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@41..42 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@42..43 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@43..44 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@44..45 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@45..46 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@46..47 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@47..48 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@48..49 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@49..50 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@50..51 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@51..52 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@52..53 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@53..54 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@54..55 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@55..56 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@56..57 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@57..58 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@58..59 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@59..60 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@60..61 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@61..62 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@62..63 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@63..64 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@64..65 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@65..66 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@66..67 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@67..68 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@68..69 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@69..70 ")" [] [],
+ },
+ ],
+ title: missing (optional),
+ r_paren_token: R_PAREN@70..71 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@71..72 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@72..72 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..72
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..72
+ 0: MD_PARAGRAPH@0..72
+ 0: MD_INLINE_ITEM_LIST@0..72
+ 0: MD_INLINE_LINK@0..71
+ 0: L_BRACK@0..1 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@1..2
+ 0: MD_TEXTUAL@1..2
+ 0: MD_TEXTUAL_LITERAL@1..2 "a" [] []
+ 2: R_BRACK@2..3 "]" [] []
+ 3: L_PAREN@3..4 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@4..70
+ 0: MD_TEXTUAL@4..5
+ 0: MD_TEXTUAL_LITERAL@4..5 "x" [] []
+ 1: MD_TEXTUAL@5..6
+ 0: MD_TEXTUAL_LITERAL@5..6 "(" [] []
+ 2: MD_TEXTUAL@6..7
+ 0: MD_TEXTUAL_LITERAL@6..7 "(" [] []
+ 3: MD_TEXTUAL@7..8
+ 0: MD_TEXTUAL_LITERAL@7..8 "(" [] []
+ 4: MD_TEXTUAL@8..9
+ 0: MD_TEXTUAL_LITERAL@8..9 "(" [] []
+ 5: MD_TEXTUAL@9..10
+ 0: MD_TEXTUAL_LITERAL@9..10 "(" [] []
+ 6: MD_TEXTUAL@10..11
+ 0: MD_TEXTUAL_LITERAL@10..11 "(" [] []
+ 7: MD_TEXTUAL@11..12
+ 0: MD_TEXTUAL_LITERAL@11..12 "(" [] []
+ 8: MD_TEXTUAL@12..13
+ 0: MD_TEXTUAL_LITERAL@12..13 "(" [] []
+ 9: MD_TEXTUAL@13..14
+ 0: MD_TEXTUAL_LITERAL@13..14 "(" [] []
+ 10: MD_TEXTUAL@14..15
+ 0: MD_TEXTUAL_LITERAL@14..15 "(" [] []
+ 11: MD_TEXTUAL@15..16
+ 0: MD_TEXTUAL_LITERAL@15..16 "(" [] []
+ 12: MD_TEXTUAL@16..17
+ 0: MD_TEXTUAL_LITERAL@16..17 "(" [] []
+ 13: MD_TEXTUAL@17..18
+ 0: MD_TEXTUAL_LITERAL@17..18 "(" [] []
+ 14: MD_TEXTUAL@18..19
+ 0: MD_TEXTUAL_LITERAL@18..19 "(" [] []
+ 15: MD_TEXTUAL@19..20
+ 0: MD_TEXTUAL_LITERAL@19..20 "(" [] []
+ 16: MD_TEXTUAL@20..21
+ 0: MD_TEXTUAL_LITERAL@20..21 "(" [] []
+ 17: MD_TEXTUAL@21..22
+ 0: MD_TEXTUAL_LITERAL@21..22 "(" [] []
+ 18: MD_TEXTUAL@22..23
+ 0: MD_TEXTUAL_LITERAL@22..23 "(" [] []
+ 19: MD_TEXTUAL@23..24
+ 0: MD_TEXTUAL_LITERAL@23..24 "(" [] []
+ 20: MD_TEXTUAL@24..25
+ 0: MD_TEXTUAL_LITERAL@24..25 "(" [] []
+ 21: MD_TEXTUAL@25..26
+ 0: MD_TEXTUAL_LITERAL@25..26 "(" [] []
+ 22: MD_TEXTUAL@26..27
+ 0: MD_TEXTUAL_LITERAL@26..27 "(" [] []
+ 23: MD_TEXTUAL@27..28
+ 0: MD_TEXTUAL_LITERAL@27..28 "(" [] []
+ 24: MD_TEXTUAL@28..29
+ 0: MD_TEXTUAL_LITERAL@28..29 "(" [] []
+ 25: MD_TEXTUAL@29..30
+ 0: MD_TEXTUAL_LITERAL@29..30 "(" [] []
+ 26: MD_TEXTUAL@30..31
+ 0: MD_TEXTUAL_LITERAL@30..31 "(" [] []
+ 27: MD_TEXTUAL@31..32
+ 0: MD_TEXTUAL_LITERAL@31..32 "(" [] []
+ 28: MD_TEXTUAL@32..33
+ 0: MD_TEXTUAL_LITERAL@32..33 "(" [] []
+ 29: MD_TEXTUAL@33..34
+ 0: MD_TEXTUAL_LITERAL@33..34 "(" [] []
+ 30: MD_TEXTUAL@34..35
+ 0: MD_TEXTUAL_LITERAL@34..35 "(" [] []
+ 31: MD_TEXTUAL@35..36
+ 0: MD_TEXTUAL_LITERAL@35..36 "(" [] []
+ 32: MD_TEXTUAL@36..37
+ 0: MD_TEXTUAL_LITERAL@36..37 "(" [] []
+ 33: MD_TEXTUAL@37..38
+ 0: MD_TEXTUAL_LITERAL@37..38 "y" [] []
+ 34: MD_TEXTUAL@38..39
+ 0: MD_TEXTUAL_LITERAL@38..39 ")" [] []
+ 35: MD_TEXTUAL@39..40
+ 0: MD_TEXTUAL_LITERAL@39..40 ")" [] []
+ 36: MD_TEXTUAL@40..41
+ 0: MD_TEXTUAL_LITERAL@40..41 ")" [] []
+ 37: MD_TEXTUAL@41..42
+ 0: MD_TEXTUAL_LITERAL@41..42 ")" [] []
+ 38: MD_TEXTUAL@42..43
+ 0: MD_TEXTUAL_LITERAL@42..43 ")" [] []
+ 39: MD_TEXTUAL@43..44
+ 0: MD_TEXTUAL_LITERAL@43..44 ")" [] []
+ 40: MD_TEXTUAL@44..45
+ 0: MD_TEXTUAL_LITERAL@44..45 ")" [] []
+ 41: MD_TEXTUAL@45..46
+ 0: MD_TEXTUAL_LITERAL@45..46 ")" [] []
+ 42: MD_TEXTUAL@46..47
+ 0: MD_TEXTUAL_LITERAL@46..47 ")" [] []
+ 43: MD_TEXTUAL@47..48
+ 0: MD_TEXTUAL_LITERAL@47..48 ")" [] []
+ 44: MD_TEXTUAL@48..49
+ 0: MD_TEXTUAL_LITERAL@48..49 ")" [] []
+ 45: MD_TEXTUAL@49..50
+ 0: MD_TEXTUAL_LITERAL@49..50 ")" [] []
+ 46: MD_TEXTUAL@50..51
+ 0: MD_TEXTUAL_LITERAL@50..51 ")" [] []
+ 47: MD_TEXTUAL@51..52
+ 0: MD_TEXTUAL_LITERAL@51..52 ")" [] []
+ 48: MD_TEXTUAL@52..53
+ 0: MD_TEXTUAL_LITERAL@52..53 ")" [] []
+ 49: MD_TEXTUAL@53..54
+ 0: MD_TEXTUAL_LITERAL@53..54 ")" [] []
+ 50: MD_TEXTUAL@54..55
+ 0: MD_TEXTUAL_LITERAL@54..55 ")" [] []
+ 51: MD_TEXTUAL@55..56
+ 0: MD_TEXTUAL_LITERAL@55..56 ")" [] []
+ 52: MD_TEXTUAL@56..57
+ 0: MD_TEXTUAL_LITERAL@56..57 ")" [] []
+ 53: MD_TEXTUAL@57..58
+ 0: MD_TEXTUAL_LITERAL@57..58 ")" [] []
+ 54: MD_TEXTUAL@58..59
+ 0: MD_TEXTUAL_LITERAL@58..59 ")" [] []
+ 55: MD_TEXTUAL@59..60
+ 0: MD_TEXTUAL_LITERAL@59..60 ")" [] []
+ 56: MD_TEXTUAL@60..61
+ 0: MD_TEXTUAL_LITERAL@60..61 ")" [] []
+ 57: MD_TEXTUAL@61..62
+ 0: MD_TEXTUAL_LITERAL@61..62 ")" [] []
+ 58: MD_TEXTUAL@62..63
+ 0: MD_TEXTUAL_LITERAL@62..63 ")" [] []
+ 59: MD_TEXTUAL@63..64
+ 0: MD_TEXTUAL_LITERAL@63..64 ")" [] []
+ 60: MD_TEXTUAL@64..65
+ 0: MD_TEXTUAL_LITERAL@64..65 ")" [] []
+ 61: MD_TEXTUAL@65..66
+ 0: MD_TEXTUAL_LITERAL@65..66 ")" [] []
+ 62: MD_TEXTUAL@66..67
+ 0: MD_TEXTUAL_LITERAL@66..67 ")" [] []
+ 63: MD_TEXTUAL@67..68
+ 0: MD_TEXTUAL_LITERAL@67..68 ")" [] []
+ 64: MD_TEXTUAL@68..69
+ 0: MD_TEXTUAL_LITERAL@68..69 ")" [] []
+ 65: MD_TEXTUAL@69..70
+ 0: MD_TEXTUAL_LITERAL@69..70 ")" [] []
+ 5: (empty)
+ 6: R_PAREN@70..71 ")" [] []
+ 1: MD_TEXTUAL@71..72
+ 0: MD_TEXTUAL_LITERAL@71..72 "\n" [] []
+ 1: (empty)
+ 2: EOF@72..72 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_link_not_implemented.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_link_not_implemented.md
new file mode 100644
index 000000000000..0c7df8482598
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_link_not_implemented.md
@@ -0,0 +1 @@
+Reference links without definitions should be parsed as text: [text][label].
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_link_not_implemented.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_link_not_implemented.md.snap
new file mode 100644
index 000000000000..70745a7d274c
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_link_not_implemented.md.snap
@@ -0,0 +1,86 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+Reference links without definitions should be parsed as text: [text][label].
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..62 "Reference links without definitions should be parsed as text: " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@62..63 "[" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@63..67 "text" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@67..68 "]" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@68..69 "[" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@69..74 "label" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@74..75 "]" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@75..76 "." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@76..77 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@77..77 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..77
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..77
+ 0: MD_PARAGRAPH@0..77
+ 0: MD_INLINE_ITEM_LIST@0..77
+ 0: MD_TEXTUAL@0..62
+ 0: MD_TEXTUAL_LITERAL@0..62 "Reference links without definitions should be parsed as text: " [] []
+ 1: MD_TEXTUAL@62..63
+ 0: MD_TEXTUAL_LITERAL@62..63 "[" [] []
+ 2: MD_TEXTUAL@63..67
+ 0: MD_TEXTUAL_LITERAL@63..67 "text" [] []
+ 3: MD_TEXTUAL@67..68
+ 0: MD_TEXTUAL_LITERAL@67..68 "]" [] []
+ 4: MD_TEXTUAL@68..69
+ 0: MD_TEXTUAL_LITERAL@68..69 "[" [] []
+ 5: MD_TEXTUAL@69..74
+ 0: MD_TEXTUAL_LITERAL@69..74 "label" [] []
+ 6: MD_TEXTUAL@74..75
+ 0: MD_TEXTUAL_LITERAL@74..75 "]" [] []
+ 7: MD_TEXTUAL@75..76
+ 0: MD_TEXTUAL_LITERAL@75..76 "." [] []
+ 8: MD_TEXTUAL@76..77
+ 0: MD_TEXTUAL_LITERAL@76..77 "\n" [] []
+ 1: (empty)
+ 2: EOF@77..77 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_links.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_links.md
new file mode 100644
index 000000000000..1fd899443983
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_links.md
@@ -0,0 +1,37 @@
+[example]: https://example.com "Example Title"
+
+Full reference: [click here][example]
+
+Collapsed reference: [example][]
+
+Shortcut reference: [example]
+
+[foo]: https://foo.com
+
+Image full: ![alt text][foo]
+
+Image collapsed: ![foo][]
+
+Image shortcut: ![foo]
+
+Multiple words in text: [click here for more info][example]
+
+Empty label (collapsed): [test][]
+
+[test]: https://test.com
+
+Shortcut that looks like text: [undefined]
+
+Mixed with inline: [inline](https://inline.com) and [ref][example]
+
+Nested in paragraph: This is a paragraph with [a reference][foo] in the middle.
+
+[Case Label]: https://case.example
+
+Case-insensitive: [case label]
+
+Whitespace normalized: [case label]
+
+[label\]]: https://escaped.example
+
+Escaped bracket in label: [text][label\]]
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_links.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_links.md.snap
new file mode 100644
index 000000000000..fce5c5466dec
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/reference_links.md.snap
@@ -0,0 +1,1065 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+[example]: https://example.com "Example Title"
+
+Full reference: [click here][example]
+
+Collapsed reference: [example][]
+
+Shortcut reference: [example]
+
+[foo]: https://foo.com
+
+Image full: ![alt text][foo]
+
+Image collapsed: ![foo][]
+
+Image shortcut: ![foo]
+
+Multiple words in text: [click here for more info][example]
+
+Empty label (collapsed): [test][]
+
+[test]: https://test.com
+
+Shortcut that looks like text: [undefined]
+
+Mixed with inline: [inline](https://inline.com) and [ref][example]
+
+Nested in paragraph: This is a paragraph with [a reference][foo] in the middle.
+
+[Case Label]: https://case.example
+
+Case-insensitive: [case label]
+
+Whitespace normalized: [case label]
+
+[label\]]: https://escaped.example
+
+Escaped bracket in label: [text][label\]]
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@0..1 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@1..8 "example" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@8..9 "]" [] [],
+ colon_token: COLON@9..10 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@10..11 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@11..30 "https://example.com" [] [],
+ },
+ ],
+ },
+ title: MdLinkTitle {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@30..31 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@31..46 "\"Example Title\"" [] [],
+ },
+ ],
+ },
+ },
+ MdNewline {
+ value_token: NEWLINE@46..47 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@47..48 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@48..64 "Full reference: " [] [],
+ },
+ MdReferenceLink {
+ l_brack_token: L_BRACK@64..65 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@65..75 "click here" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@75..76 "]" [] [],
+ label: MdReferenceLinkLabel {
+ l_brack_token: L_BRACK@76..77 "[" [] [],
+ label: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@77..84 "example" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@84..85 "]" [] [],
+ },
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@85..86 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@86..87 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@87..108 "Collapsed reference: " [] [],
+ },
+ MdReferenceLink {
+ l_brack_token: L_BRACK@108..109 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@109..116 "example" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@116..117 "]" [] [],
+ label: MdReferenceLinkLabel {
+ l_brack_token: L_BRACK@117..118 "[" [] [],
+ label: MdInlineItemList [],
+ r_brack_token: R_BRACK@118..119 "]" [] [],
+ },
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@119..120 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@120..121 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@121..141 "Shortcut reference: " [] [],
+ },
+ MdReferenceLink {
+ l_brack_token: L_BRACK@141..142 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@142..149 "example" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@149..150 "]" [] [],
+ label: missing (optional),
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@150..151 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@151..152 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@152..153 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@153..156 "foo" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@156..157 "]" [] [],
+ colon_token: COLON@157..158 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@158..159 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@159..174 "https://foo.com" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@174..175 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@175..176 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@176..188 "Image full: " [] [],
+ },
+ MdReferenceImage {
+ excl_token: BANG@188..189 "!" [] [],
+ l_brack_token: L_BRACK@189..190 "[" [] [],
+ alt: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@190..198 "alt text" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@198..199 "]" [] [],
+ label: MdReferenceLinkLabel {
+ l_brack_token: L_BRACK@199..200 "[" [] [],
+ label: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@200..203 "foo" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@203..204 "]" [] [],
+ },
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@204..205 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@205..206 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@206..223 "Image collapsed: " [] [],
+ },
+ MdReferenceImage {
+ excl_token: BANG@223..224 "!" [] [],
+ l_brack_token: L_BRACK@224..225 "[" [] [],
+ alt: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@225..228 "foo" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@228..229 "]" [] [],
+ label: MdReferenceLinkLabel {
+ l_brack_token: L_BRACK@229..230 "[" [] [],
+ label: MdInlineItemList [],
+ r_brack_token: R_BRACK@230..231 "]" [] [],
+ },
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@231..232 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@232..233 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@233..249 "Image shortcut: " [] [],
+ },
+ MdReferenceImage {
+ excl_token: BANG@249..250 "!" [] [],
+ l_brack_token: L_BRACK@250..251 "[" [] [],
+ alt: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@251..254 "foo" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@254..255 "]" [] [],
+ label: missing (optional),
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@255..256 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@256..257 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@257..281 "Multiple words in text: " [] [],
+ },
+ MdReferenceLink {
+ l_brack_token: L_BRACK@281..282 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@282..306 "click here for more info" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@306..307 "]" [] [],
+ label: MdReferenceLinkLabel {
+ l_brack_token: L_BRACK@307..308 "[" [] [],
+ label: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@308..315 "example" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@315..316 "]" [] [],
+ },
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@316..317 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@317..318 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@318..330 "Empty label " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@330..331 "(" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@331..340 "collapsed" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@340..341 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@341..342 ":" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@342..343 " " [] [],
+ },
+ MdReferenceLink {
+ l_brack_token: L_BRACK@343..344 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@344..348 "test" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@348..349 "]" [] [],
+ label: MdReferenceLinkLabel {
+ l_brack_token: L_BRACK@349..350 "[" [] [],
+ label: MdInlineItemList [],
+ r_brack_token: R_BRACK@350..351 "]" [] [],
+ },
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@351..352 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@352..353 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@353..354 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@354..358 "test" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@358..359 "]" [] [],
+ colon_token: COLON@359..360 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@360..361 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@361..377 "https://test.com" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@377..378 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@378..379 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@379..410 "Shortcut that looks like text: " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@410..411 "[" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@411..420 "undefined" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@420..421 "]" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@421..422 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@422..423 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@423..442 "Mixed with inline: " [] [],
+ },
+ MdInlineLink {
+ l_brack_token: L_BRACK@442..443 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@443..449 "inline" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@449..450 "]" [] [],
+ l_paren_token: L_PAREN@450..451 "(" [] [],
+ destination: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@451..469 "https://inline.com" [] [],
+ },
+ ],
+ title: missing (optional),
+ r_paren_token: R_PAREN@469..470 ")" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@470..475 " and " [] [],
+ },
+ MdReferenceLink {
+ l_brack_token: L_BRACK@475..476 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@476..479 "ref" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@479..480 "]" [] [],
+ label: MdReferenceLinkLabel {
+ l_brack_token: L_BRACK@480..481 "[" [] [],
+ label: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@481..488 "example" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@488..489 "]" [] [],
+ },
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@489..490 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@490..491 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@491..537 "Nested in paragraph: This is a paragraph with " [] [],
+ },
+ MdReferenceLink {
+ l_brack_token: L_BRACK@537..538 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@538..549 "a reference" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@549..550 "]" [] [],
+ label: MdReferenceLinkLabel {
+ l_brack_token: L_BRACK@550..551 "[" [] [],
+ label: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@551..554 "foo" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@554..555 "]" [] [],
+ },
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@555..570 " in the middle." [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@570..571 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@571..572 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@572..573 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@573..583 "Case Label" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@583..584 "]" [] [],
+ colon_token: COLON@584..585 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@585..586 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@586..606 "https://case.example" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@606..607 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@607..608 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@608..612 "Case" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@612..613 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@613..626 "insensitive: " [] [],
+ },
+ MdReferenceLink {
+ l_brack_token: L_BRACK@626..627 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@627..637 "case label" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@637..638 "]" [] [],
+ label: missing (optional),
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@638..639 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@639..640 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@640..663 "Whitespace normalized: " [] [],
+ },
+ MdReferenceLink {
+ l_brack_token: L_BRACK@663..664 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@664..676 "case label" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@676..677 "]" [] [],
+ label: missing (optional),
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@677..678 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@678..679 "\n" [] [],
+ },
+ MdLinkReferenceDefinition {
+ l_brack_token: L_BRACK@679..680 "[" [] [],
+ label: MdLinkLabel {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@680..685 "label" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@685..687 "\\]" [] [],
+ },
+ ],
+ },
+ r_brack_token: R_BRACK@687..688 "]" [] [],
+ colon_token: COLON@688..689 ":" [] [],
+ destination: MdLinkDestination {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@689..690 " " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@690..713 "https://escaped.example" [] [],
+ },
+ ],
+ },
+ title: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@713..714 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@714..715 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@715..741 "Escaped bracket in label: " [] [],
+ },
+ MdReferenceLink {
+ l_brack_token: L_BRACK@741..742 "[" [] [],
+ text: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@742..746 "text" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@746..747 "]" [] [],
+ label: MdReferenceLinkLabel {
+ l_brack_token: L_BRACK@747..748 "[" [] [],
+ label: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@748..753 "label" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@753..755 "\\]" [] [],
+ },
+ ],
+ r_brack_token: R_BRACK@755..756 "]" [] [],
+ },
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@756..757 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@757..757 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..757
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..757
+ 0: MD_LINK_REFERENCE_DEFINITION@0..46
+ 0: L_BRACK@0..1 "[" [] []
+ 1: MD_LINK_LABEL@1..8
+ 0: MD_INLINE_ITEM_LIST@1..8
+ 0: MD_TEXTUAL@1..8
+ 0: MD_TEXTUAL_LITERAL@1..8 "example" [] []
+ 2: R_BRACK@8..9 "]" [] []
+ 3: COLON@9..10 ":" [] []
+ 4: MD_LINK_DESTINATION@10..30
+ 0: MD_INLINE_ITEM_LIST@10..30
+ 0: MD_TEXTUAL@10..11
+ 0: MD_TEXTUAL_LITERAL@10..11 " " [] []
+ 1: MD_TEXTUAL@11..30
+ 0: MD_TEXTUAL_LITERAL@11..30 "https://example.com" [] []
+ 5: MD_LINK_TITLE@30..46
+ 0: MD_INLINE_ITEM_LIST@30..46
+ 0: MD_TEXTUAL@30..31
+ 0: MD_TEXTUAL_LITERAL@30..31 " " [] []
+ 1: MD_TEXTUAL@31..46
+ 0: MD_TEXTUAL_LITERAL@31..46 "\"Example Title\"" [] []
+ 1: MD_NEWLINE@46..47
+ 0: NEWLINE@46..47 "\n" [] []
+ 2: MD_NEWLINE@47..48
+ 0: NEWLINE@47..48 "\n" [] []
+ 3: MD_PARAGRAPH@48..86
+ 0: MD_INLINE_ITEM_LIST@48..86
+ 0: MD_TEXTUAL@48..64
+ 0: MD_TEXTUAL_LITERAL@48..64 "Full reference: " [] []
+ 1: MD_REFERENCE_LINK@64..85
+ 0: L_BRACK@64..65 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@65..75
+ 0: MD_TEXTUAL@65..75
+ 0: MD_TEXTUAL_LITERAL@65..75 "click here" [] []
+ 2: R_BRACK@75..76 "]" [] []
+ 3: MD_REFERENCE_LINK_LABEL@76..85
+ 0: L_BRACK@76..77 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@77..84
+ 0: MD_TEXTUAL@77..84
+ 0: MD_TEXTUAL_LITERAL@77..84 "example" [] []
+ 2: R_BRACK@84..85 "]" [] []
+ 2: MD_TEXTUAL@85..86
+ 0: MD_TEXTUAL_LITERAL@85..86 "\n" [] []
+ 1: (empty)
+ 4: MD_NEWLINE@86..87
+ 0: NEWLINE@86..87 "\n" [] []
+ 5: MD_PARAGRAPH@87..120
+ 0: MD_INLINE_ITEM_LIST@87..120
+ 0: MD_TEXTUAL@87..108
+ 0: MD_TEXTUAL_LITERAL@87..108 "Collapsed reference: " [] []
+ 1: MD_REFERENCE_LINK@108..119
+ 0: L_BRACK@108..109 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@109..116
+ 0: MD_TEXTUAL@109..116
+ 0: MD_TEXTUAL_LITERAL@109..116 "example" [] []
+ 2: R_BRACK@116..117 "]" [] []
+ 3: MD_REFERENCE_LINK_LABEL@117..119
+ 0: L_BRACK@117..118 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@118..118
+ 2: R_BRACK@118..119 "]" [] []
+ 2: MD_TEXTUAL@119..120
+ 0: MD_TEXTUAL_LITERAL@119..120 "\n" [] []
+ 1: (empty)
+ 6: MD_NEWLINE@120..121
+ 0: NEWLINE@120..121 "\n" [] []
+ 7: MD_PARAGRAPH@121..151
+ 0: MD_INLINE_ITEM_LIST@121..151
+ 0: MD_TEXTUAL@121..141
+ 0: MD_TEXTUAL_LITERAL@121..141 "Shortcut reference: " [] []
+ 1: MD_REFERENCE_LINK@141..150
+ 0: L_BRACK@141..142 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@142..149
+ 0: MD_TEXTUAL@142..149
+ 0: MD_TEXTUAL_LITERAL@142..149 "example" [] []
+ 2: R_BRACK@149..150 "]" [] []
+ 3: (empty)
+ 2: MD_TEXTUAL@150..151
+ 0: MD_TEXTUAL_LITERAL@150..151 "\n" [] []
+ 1: (empty)
+ 8: MD_NEWLINE@151..152
+ 0: NEWLINE@151..152 "\n" [] []
+ 9: MD_LINK_REFERENCE_DEFINITION@152..174
+ 0: L_BRACK@152..153 "[" [] []
+ 1: MD_LINK_LABEL@153..156
+ 0: MD_INLINE_ITEM_LIST@153..156
+ 0: MD_TEXTUAL@153..156
+ 0: MD_TEXTUAL_LITERAL@153..156 "foo" [] []
+ 2: R_BRACK@156..157 "]" [] []
+ 3: COLON@157..158 ":" [] []
+ 4: MD_LINK_DESTINATION@158..174
+ 0: MD_INLINE_ITEM_LIST@158..174
+ 0: MD_TEXTUAL@158..159
+ 0: MD_TEXTUAL_LITERAL@158..159 " " [] []
+ 1: MD_TEXTUAL@159..174
+ 0: MD_TEXTUAL_LITERAL@159..174 "https://foo.com" [] []
+ 5: (empty)
+ 10: MD_NEWLINE@174..175
+ 0: NEWLINE@174..175 "\n" [] []
+ 11: MD_NEWLINE@175..176
+ 0: NEWLINE@175..176 "\n" [] []
+ 12: MD_PARAGRAPH@176..205
+ 0: MD_INLINE_ITEM_LIST@176..205
+ 0: MD_TEXTUAL@176..188
+ 0: MD_TEXTUAL_LITERAL@176..188 "Image full: " [] []
+ 1: MD_REFERENCE_IMAGE@188..204
+ 0: BANG@188..189 "!" [] []
+ 1: L_BRACK@189..190 "[" [] []
+ 2: MD_INLINE_ITEM_LIST@190..198
+ 0: MD_TEXTUAL@190..198
+ 0: MD_TEXTUAL_LITERAL@190..198 "alt text" [] []
+ 3: R_BRACK@198..199 "]" [] []
+ 4: MD_REFERENCE_LINK_LABEL@199..204
+ 0: L_BRACK@199..200 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@200..203
+ 0: MD_TEXTUAL@200..203
+ 0: MD_TEXTUAL_LITERAL@200..203 "foo" [] []
+ 2: R_BRACK@203..204 "]" [] []
+ 2: MD_TEXTUAL@204..205
+ 0: MD_TEXTUAL_LITERAL@204..205 "\n" [] []
+ 1: (empty)
+ 13: MD_NEWLINE@205..206
+ 0: NEWLINE@205..206 "\n" [] []
+ 14: MD_PARAGRAPH@206..232
+ 0: MD_INLINE_ITEM_LIST@206..232
+ 0: MD_TEXTUAL@206..223
+ 0: MD_TEXTUAL_LITERAL@206..223 "Image collapsed: " [] []
+ 1: MD_REFERENCE_IMAGE@223..231
+ 0: BANG@223..224 "!" [] []
+ 1: L_BRACK@224..225 "[" [] []
+ 2: MD_INLINE_ITEM_LIST@225..228
+ 0: MD_TEXTUAL@225..228
+ 0: MD_TEXTUAL_LITERAL@225..228 "foo" [] []
+ 3: R_BRACK@228..229 "]" [] []
+ 4: MD_REFERENCE_LINK_LABEL@229..231
+ 0: L_BRACK@229..230 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@230..230
+ 2: R_BRACK@230..231 "]" [] []
+ 2: MD_TEXTUAL@231..232
+ 0: MD_TEXTUAL_LITERAL@231..232 "\n" [] []
+ 1: (empty)
+ 15: MD_NEWLINE@232..233
+ 0: NEWLINE@232..233 "\n" [] []
+ 16: MD_PARAGRAPH@233..256
+ 0: MD_INLINE_ITEM_LIST@233..256
+ 0: MD_TEXTUAL@233..249
+ 0: MD_TEXTUAL_LITERAL@233..249 "Image shortcut: " [] []
+ 1: MD_REFERENCE_IMAGE@249..255
+ 0: BANG@249..250 "!" [] []
+ 1: L_BRACK@250..251 "[" [] []
+ 2: MD_INLINE_ITEM_LIST@251..254
+ 0: MD_TEXTUAL@251..254
+ 0: MD_TEXTUAL_LITERAL@251..254 "foo" [] []
+ 3: R_BRACK@254..255 "]" [] []
+ 4: (empty)
+ 2: MD_TEXTUAL@255..256
+ 0: MD_TEXTUAL_LITERAL@255..256 "\n" [] []
+ 1: (empty)
+ 17: MD_NEWLINE@256..257
+ 0: NEWLINE@256..257 "\n" [] []
+ 18: MD_PARAGRAPH@257..317
+ 0: MD_INLINE_ITEM_LIST@257..317
+ 0: MD_TEXTUAL@257..281
+ 0: MD_TEXTUAL_LITERAL@257..281 "Multiple words in text: " [] []
+ 1: MD_REFERENCE_LINK@281..316
+ 0: L_BRACK@281..282 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@282..306
+ 0: MD_TEXTUAL@282..306
+ 0: MD_TEXTUAL_LITERAL@282..306 "click here for more info" [] []
+ 2: R_BRACK@306..307 "]" [] []
+ 3: MD_REFERENCE_LINK_LABEL@307..316
+ 0: L_BRACK@307..308 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@308..315
+ 0: MD_TEXTUAL@308..315
+ 0: MD_TEXTUAL_LITERAL@308..315 "example" [] []
+ 2: R_BRACK@315..316 "]" [] []
+ 2: MD_TEXTUAL@316..317
+ 0: MD_TEXTUAL_LITERAL@316..317 "\n" [] []
+ 1: (empty)
+ 19: MD_NEWLINE@317..318
+ 0: NEWLINE@317..318 "\n" [] []
+ 20: MD_PARAGRAPH@318..352
+ 0: MD_INLINE_ITEM_LIST@318..352
+ 0: MD_TEXTUAL@318..330
+ 0: MD_TEXTUAL_LITERAL@318..330 "Empty label " [] []
+ 1: MD_TEXTUAL@330..331
+ 0: MD_TEXTUAL_LITERAL@330..331 "(" [] []
+ 2: MD_TEXTUAL@331..340
+ 0: MD_TEXTUAL_LITERAL@331..340 "collapsed" [] []
+ 3: MD_TEXTUAL@340..341
+ 0: MD_TEXTUAL_LITERAL@340..341 ")" [] []
+ 4: MD_TEXTUAL@341..342
+ 0: MD_TEXTUAL_LITERAL@341..342 ":" [] []
+ 5: MD_TEXTUAL@342..343
+ 0: MD_TEXTUAL_LITERAL@342..343 " " [] []
+ 6: MD_REFERENCE_LINK@343..351
+ 0: L_BRACK@343..344 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@344..348
+ 0: MD_TEXTUAL@344..348
+ 0: MD_TEXTUAL_LITERAL@344..348 "test" [] []
+ 2: R_BRACK@348..349 "]" [] []
+ 3: MD_REFERENCE_LINK_LABEL@349..351
+ 0: L_BRACK@349..350 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@350..350
+ 2: R_BRACK@350..351 "]" [] []
+ 7: MD_TEXTUAL@351..352
+ 0: MD_TEXTUAL_LITERAL@351..352 "\n" [] []
+ 1: (empty)
+ 21: MD_NEWLINE@352..353
+ 0: NEWLINE@352..353 "\n" [] []
+ 22: MD_LINK_REFERENCE_DEFINITION@353..377
+ 0: L_BRACK@353..354 "[" [] []
+ 1: MD_LINK_LABEL@354..358
+ 0: MD_INLINE_ITEM_LIST@354..358
+ 0: MD_TEXTUAL@354..358
+ 0: MD_TEXTUAL_LITERAL@354..358 "test" [] []
+ 2: R_BRACK@358..359 "]" [] []
+ 3: COLON@359..360 ":" [] []
+ 4: MD_LINK_DESTINATION@360..377
+ 0: MD_INLINE_ITEM_LIST@360..377
+ 0: MD_TEXTUAL@360..361
+ 0: MD_TEXTUAL_LITERAL@360..361 " " [] []
+ 1: MD_TEXTUAL@361..377
+ 0: MD_TEXTUAL_LITERAL@361..377 "https://test.com" [] []
+ 5: (empty)
+ 23: MD_NEWLINE@377..378
+ 0: NEWLINE@377..378 "\n" [] []
+ 24: MD_NEWLINE@378..379
+ 0: NEWLINE@378..379 "\n" [] []
+ 25: MD_PARAGRAPH@379..422
+ 0: MD_INLINE_ITEM_LIST@379..422
+ 0: MD_TEXTUAL@379..410
+ 0: MD_TEXTUAL_LITERAL@379..410 "Shortcut that looks like text: " [] []
+ 1: MD_TEXTUAL@410..411
+ 0: MD_TEXTUAL_LITERAL@410..411 "[" [] []
+ 2: MD_TEXTUAL@411..420
+ 0: MD_TEXTUAL_LITERAL@411..420 "undefined" [] []
+ 3: MD_TEXTUAL@420..421
+ 0: MD_TEXTUAL_LITERAL@420..421 "]" [] []
+ 4: MD_TEXTUAL@421..422
+ 0: MD_TEXTUAL_LITERAL@421..422 "\n" [] []
+ 1: (empty)
+ 26: MD_NEWLINE@422..423
+ 0: NEWLINE@422..423 "\n" [] []
+ 27: MD_PARAGRAPH@423..490
+ 0: MD_INLINE_ITEM_LIST@423..490
+ 0: MD_TEXTUAL@423..442
+ 0: MD_TEXTUAL_LITERAL@423..442 "Mixed with inline: " [] []
+ 1: MD_INLINE_LINK@442..470
+ 0: L_BRACK@442..443 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@443..449
+ 0: MD_TEXTUAL@443..449
+ 0: MD_TEXTUAL_LITERAL@443..449 "inline" [] []
+ 2: R_BRACK@449..450 "]" [] []
+ 3: L_PAREN@450..451 "(" [] []
+ 4: MD_INLINE_ITEM_LIST@451..469
+ 0: MD_TEXTUAL@451..469
+ 0: MD_TEXTUAL_LITERAL@451..469 "https://inline.com" [] []
+ 5: (empty)
+ 6: R_PAREN@469..470 ")" [] []
+ 2: MD_TEXTUAL@470..475
+ 0: MD_TEXTUAL_LITERAL@470..475 " and " [] []
+ 3: MD_REFERENCE_LINK@475..489
+ 0: L_BRACK@475..476 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@476..479
+ 0: MD_TEXTUAL@476..479
+ 0: MD_TEXTUAL_LITERAL@476..479 "ref" [] []
+ 2: R_BRACK@479..480 "]" [] []
+ 3: MD_REFERENCE_LINK_LABEL@480..489
+ 0: L_BRACK@480..481 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@481..488
+ 0: MD_TEXTUAL@481..488
+ 0: MD_TEXTUAL_LITERAL@481..488 "example" [] []
+ 2: R_BRACK@488..489 "]" [] []
+ 4: MD_TEXTUAL@489..490
+ 0: MD_TEXTUAL_LITERAL@489..490 "\n" [] []
+ 1: (empty)
+ 28: MD_NEWLINE@490..491
+ 0: NEWLINE@490..491 "\n" [] []
+ 29: MD_PARAGRAPH@491..571
+ 0: MD_INLINE_ITEM_LIST@491..571
+ 0: MD_TEXTUAL@491..537
+ 0: MD_TEXTUAL_LITERAL@491..537 "Nested in paragraph: This is a paragraph with " [] []
+ 1: MD_REFERENCE_LINK@537..555
+ 0: L_BRACK@537..538 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@538..549
+ 0: MD_TEXTUAL@538..549
+ 0: MD_TEXTUAL_LITERAL@538..549 "a reference" [] []
+ 2: R_BRACK@549..550 "]" [] []
+ 3: MD_REFERENCE_LINK_LABEL@550..555
+ 0: L_BRACK@550..551 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@551..554
+ 0: MD_TEXTUAL@551..554
+ 0: MD_TEXTUAL_LITERAL@551..554 "foo" [] []
+ 2: R_BRACK@554..555 "]" [] []
+ 2: MD_TEXTUAL@555..570
+ 0: MD_TEXTUAL_LITERAL@555..570 " in the middle." [] []
+ 3: MD_TEXTUAL@570..571
+ 0: MD_TEXTUAL_LITERAL@570..571 "\n" [] []
+ 1: (empty)
+ 30: MD_NEWLINE@571..572
+ 0: NEWLINE@571..572 "\n" [] []
+ 31: MD_LINK_REFERENCE_DEFINITION@572..606
+ 0: L_BRACK@572..573 "[" [] []
+ 1: MD_LINK_LABEL@573..583
+ 0: MD_INLINE_ITEM_LIST@573..583
+ 0: MD_TEXTUAL@573..583
+ 0: MD_TEXTUAL_LITERAL@573..583 "Case Label" [] []
+ 2: R_BRACK@583..584 "]" [] []
+ 3: COLON@584..585 ":" [] []
+ 4: MD_LINK_DESTINATION@585..606
+ 0: MD_INLINE_ITEM_LIST@585..606
+ 0: MD_TEXTUAL@585..586
+ 0: MD_TEXTUAL_LITERAL@585..586 " " [] []
+ 1: MD_TEXTUAL@586..606
+ 0: MD_TEXTUAL_LITERAL@586..606 "https://case.example" [] []
+ 5: (empty)
+ 32: MD_NEWLINE@606..607
+ 0: NEWLINE@606..607 "\n" [] []
+ 33: MD_NEWLINE@607..608
+ 0: NEWLINE@607..608 "\n" [] []
+ 34: MD_PARAGRAPH@608..639
+ 0: MD_INLINE_ITEM_LIST@608..639
+ 0: MD_TEXTUAL@608..612
+ 0: MD_TEXTUAL_LITERAL@608..612 "Case" [] []
+ 1: MD_TEXTUAL@612..613
+ 0: MD_TEXTUAL_LITERAL@612..613 "-" [] []
+ 2: MD_TEXTUAL@613..626
+ 0: MD_TEXTUAL_LITERAL@613..626 "insensitive: " [] []
+ 3: MD_REFERENCE_LINK@626..638
+ 0: L_BRACK@626..627 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@627..637
+ 0: MD_TEXTUAL@627..637
+ 0: MD_TEXTUAL_LITERAL@627..637 "case label" [] []
+ 2: R_BRACK@637..638 "]" [] []
+ 3: (empty)
+ 4: MD_TEXTUAL@638..639
+ 0: MD_TEXTUAL_LITERAL@638..639 "\n" [] []
+ 1: (empty)
+ 35: MD_NEWLINE@639..640
+ 0: NEWLINE@639..640 "\n" [] []
+ 36: MD_PARAGRAPH@640..678
+ 0: MD_INLINE_ITEM_LIST@640..678
+ 0: MD_TEXTUAL@640..663
+ 0: MD_TEXTUAL_LITERAL@640..663 "Whitespace normalized: " [] []
+ 1: MD_REFERENCE_LINK@663..677
+ 0: L_BRACK@663..664 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@664..676
+ 0: MD_TEXTUAL@664..676
+ 0: MD_TEXTUAL_LITERAL@664..676 "case label" [] []
+ 2: R_BRACK@676..677 "]" [] []
+ 3: (empty)
+ 2: MD_TEXTUAL@677..678
+ 0: MD_TEXTUAL_LITERAL@677..678 "\n" [] []
+ 1: (empty)
+ 37: MD_NEWLINE@678..679
+ 0: NEWLINE@678..679 "\n" [] []
+ 38: MD_LINK_REFERENCE_DEFINITION@679..713
+ 0: L_BRACK@679..680 "[" [] []
+ 1: MD_LINK_LABEL@680..687
+ 0: MD_INLINE_ITEM_LIST@680..687
+ 0: MD_TEXTUAL@680..685
+ 0: MD_TEXTUAL_LITERAL@680..685 "label" [] []
+ 1: MD_TEXTUAL@685..687
+ 0: MD_TEXTUAL_LITERAL@685..687 "\\]" [] []
+ 2: R_BRACK@687..688 "]" [] []
+ 3: COLON@688..689 ":" [] []
+ 4: MD_LINK_DESTINATION@689..713
+ 0: MD_INLINE_ITEM_LIST@689..713
+ 0: MD_TEXTUAL@689..690
+ 0: MD_TEXTUAL_LITERAL@689..690 " " [] []
+ 1: MD_TEXTUAL@690..713
+ 0: MD_TEXTUAL_LITERAL@690..713 "https://escaped.example" [] []
+ 5: (empty)
+ 39: MD_NEWLINE@713..714
+ 0: NEWLINE@713..714 "\n" [] []
+ 40: MD_NEWLINE@714..715
+ 0: NEWLINE@714..715 "\n" [] []
+ 41: MD_PARAGRAPH@715..757
+ 0: MD_INLINE_ITEM_LIST@715..757
+ 0: MD_TEXTUAL@715..741
+ 0: MD_TEXTUAL_LITERAL@715..741 "Escaped bracket in label: " [] []
+ 1: MD_REFERENCE_LINK@741..756
+ 0: L_BRACK@741..742 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@742..746
+ 0: MD_TEXTUAL@742..746
+ 0: MD_TEXTUAL_LITERAL@742..746 "text" [] []
+ 2: R_BRACK@746..747 "]" [] []
+ 3: MD_REFERENCE_LINK_LABEL@747..756
+ 0: L_BRACK@747..748 "[" [] []
+ 1: MD_INLINE_ITEM_LIST@748..755
+ 0: MD_TEXTUAL@748..753
+ 0: MD_TEXTUAL_LITERAL@748..753 "label" [] []
+ 1: MD_TEXTUAL@753..755
+ 0: MD_TEXTUAL_LITERAL@753..755 "\\]" [] []
+ 2: R_BRACK@755..756 "]" [] []
+ 2: MD_TEXTUAL@756..757
+ 0: MD_TEXTUAL_LITERAL@756..757 "\n" [] []
+ 1: (empty)
+ 2: EOF@757..757 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading.md
new file mode 100644
index 000000000000..db3f7fcd82ed
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading.md
@@ -0,0 +1,15 @@
+Heading 1
+=========
+
+Heading 2
+---------
+
+Another H1
+===
+
+Another H2
+---
+
+Multi-line content
+that spans lines
+================
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading.md.snap
new file mode 100644
index 000000000000..c287fd716d41
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading.md.snap
@@ -0,0 +1,202 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+Heading 1
+=========
+
+Heading 2
+---------
+
+Another H1
+===
+
+Another H2
+---
+
+Multi-line content
+that spans lines
+================
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..9 "Heading 1" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@9..10 "\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@10..19 "=========" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@19..20 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@20..21 "\n" [] [],
+ },
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@21..30 "Heading 2" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@30..31 "\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@31..40 "---------" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@40..41 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@41..42 "\n" [] [],
+ },
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@42..52 "Another H1" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@52..53 "\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@53..56 "===" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@56..57 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@57..58 "\n" [] [],
+ },
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@58..68 "Another H2" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@68..69 "\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@69..72 "---" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@72..73 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@73..74 "\n" [] [],
+ },
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@74..79 "Multi" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@79..80 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@80..92 "line content" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@92..93 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@93..109 "that spans lines" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@109..110 "\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@110..126 "================" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@126..127 "\n" [] [],
+ },
+ ],
+ eof_token: EOF@127..127 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..127
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..127
+ 0: MD_SETEXT_HEADER@0..19
+ 0: MD_INLINE_ITEM_LIST@0..10
+ 0: MD_TEXTUAL@0..9
+ 0: MD_TEXTUAL_LITERAL@0..9 "Heading 1" [] []
+ 1: MD_TEXTUAL@9..10
+ 0: MD_TEXTUAL_LITERAL@9..10 "\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@10..19 "=========" [] []
+ 1: MD_NEWLINE@19..20
+ 0: NEWLINE@19..20 "\n" [] []
+ 2: MD_NEWLINE@20..21
+ 0: NEWLINE@20..21 "\n" [] []
+ 3: MD_SETEXT_HEADER@21..40
+ 0: MD_INLINE_ITEM_LIST@21..31
+ 0: MD_TEXTUAL@21..30
+ 0: MD_TEXTUAL_LITERAL@21..30 "Heading 2" [] []
+ 1: MD_TEXTUAL@30..31
+ 0: MD_TEXTUAL_LITERAL@30..31 "\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@31..40 "---------" [] []
+ 4: MD_NEWLINE@40..41
+ 0: NEWLINE@40..41 "\n" [] []
+ 5: MD_NEWLINE@41..42
+ 0: NEWLINE@41..42 "\n" [] []
+ 6: MD_SETEXT_HEADER@42..56
+ 0: MD_INLINE_ITEM_LIST@42..53
+ 0: MD_TEXTUAL@42..52
+ 0: MD_TEXTUAL_LITERAL@42..52 "Another H1" [] []
+ 1: MD_TEXTUAL@52..53
+ 0: MD_TEXTUAL_LITERAL@52..53 "\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@53..56 "===" [] []
+ 7: MD_NEWLINE@56..57
+ 0: NEWLINE@56..57 "\n" [] []
+ 8: MD_NEWLINE@57..58
+ 0: NEWLINE@57..58 "\n" [] []
+ 9: MD_SETEXT_HEADER@58..72
+ 0: MD_INLINE_ITEM_LIST@58..69
+ 0: MD_TEXTUAL@58..68
+ 0: MD_TEXTUAL_LITERAL@58..68 "Another H2" [] []
+ 1: MD_TEXTUAL@68..69
+ 0: MD_TEXTUAL_LITERAL@68..69 "\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@69..72 "---" [] []
+ 10: MD_NEWLINE@72..73
+ 0: NEWLINE@72..73 "\n" [] []
+ 11: MD_NEWLINE@73..74
+ 0: NEWLINE@73..74 "\n" [] []
+ 12: MD_SETEXT_HEADER@74..126
+ 0: MD_INLINE_ITEM_LIST@74..110
+ 0: MD_TEXTUAL@74..79
+ 0: MD_TEXTUAL_LITERAL@74..79 "Multi" [] []
+ 1: MD_TEXTUAL@79..80
+ 0: MD_TEXTUAL_LITERAL@79..80 "-" [] []
+ 2: MD_TEXTUAL@80..92
+ 0: MD_TEXTUAL_LITERAL@80..92 "line content" [] []
+ 3: MD_TEXTUAL@92..93
+ 0: MD_TEXTUAL_LITERAL@92..93 "\n" [] []
+ 4: MD_TEXTUAL@93..109
+ 0: MD_TEXTUAL_LITERAL@93..109 "that spans lines" [] []
+ 5: MD_TEXTUAL@109..110
+ 0: MD_TEXTUAL_LITERAL@109..110 "\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@110..126 "================" [] []
+ 13: MD_NEWLINE@126..127
+ 0: NEWLINE@126..127 "\n" [] []
+ 2: EOF@127..127 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_edge_cases.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_edge_cases.md
new file mode 100644
index 000000000000..65ad27b5b991
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_edge_cases.md
@@ -0,0 +1,15 @@
+Foo
+ ----
+
+Foo
+-----
+
+Foo\
+----
+
+> Foo
+> ---
+
+- Foo
+ ---
+ baz
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_edge_cases.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_edge_cases.md.snap
new file mode 100644
index 000000000000..f5ddc589205c
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_edge_cases.md.snap
@@ -0,0 +1,237 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+Foo
+ ----
+
+Foo
+-----
+
+Foo\
+----
+
+> Foo
+> ---
+
+- Foo
+ ---
+ baz
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..3 "Foo" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@3..4 "\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@4..11 "----" [Skipped(" "), Skipped(" "), Skipped(" ")] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@11..12 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@12..13 "\n" [] [],
+ },
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@13..16 "Foo" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@16..17 "\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@17..22 "-----" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@22..23 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@23..24 "\n" [] [],
+ },
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@24..27 "Foo" [] [],
+ },
+ MdHardLine {
+ value_token: MD_HARD_LINE_LITERAL@27..29 "\\\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@29..33 "----" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@33..34 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@34..35 "\n" [] [],
+ },
+ MdQuote {
+ marker_token: R_ANGLE@35..36 ">" [] [],
+ content: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@36..40 "Foo" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@40..41 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@41..44 "-" [Skipped(">"), Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@44..45 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@45..46 "-" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@46..47 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ MdNewline {
+ value_token: NEWLINE@47..48 "\n" [] [],
+ },
+ MdBulletListItem {
+ md_bullet_list: MdBulletList [
+ MdBullet {
+ bullet: MINUS@48..49 "-" [] [],
+ content: MdBlockList [
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@49..53 "Foo" [Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@53..54 "\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@54..59 "---" [Skipped(" "), Skipped(" ")] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@59..60 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@60..65 "baz" [Skipped(" "), Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@65..66 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ eof_token: EOF@66..66 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..66
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..66
+ 0: MD_SETEXT_HEADER@0..11
+ 0: MD_INLINE_ITEM_LIST@0..4
+ 0: MD_TEXTUAL@0..3
+ 0: MD_TEXTUAL_LITERAL@0..3 "Foo" [] []
+ 1: MD_TEXTUAL@3..4
+ 0: MD_TEXTUAL_LITERAL@3..4 "\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@4..11 "----" [Skipped(" "), Skipped(" "), Skipped(" ")] []
+ 1: MD_NEWLINE@11..12
+ 0: NEWLINE@11..12 "\n" [] []
+ 2: MD_NEWLINE@12..13
+ 0: NEWLINE@12..13 "\n" [] []
+ 3: MD_SETEXT_HEADER@13..22
+ 0: MD_INLINE_ITEM_LIST@13..17
+ 0: MD_TEXTUAL@13..16
+ 0: MD_TEXTUAL_LITERAL@13..16 "Foo" [] []
+ 1: MD_TEXTUAL@16..17
+ 0: MD_TEXTUAL_LITERAL@16..17 "\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@17..22 "-----" [] []
+ 4: MD_NEWLINE@22..23
+ 0: NEWLINE@22..23 "\n" [] []
+ 5: MD_NEWLINE@23..24
+ 0: NEWLINE@23..24 "\n" [] []
+ 6: MD_SETEXT_HEADER@24..33
+ 0: MD_INLINE_ITEM_LIST@24..29
+ 0: MD_TEXTUAL@24..27
+ 0: MD_TEXTUAL_LITERAL@24..27 "Foo" [] []
+ 1: MD_HARD_LINE@27..29
+ 0: MD_HARD_LINE_LITERAL@27..29 "\\\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@29..33 "----" [] []
+ 7: MD_NEWLINE@33..34
+ 0: NEWLINE@33..34 "\n" [] []
+ 8: MD_NEWLINE@34..35
+ 0: NEWLINE@34..35 "\n" [] []
+ 9: MD_QUOTE@35..47
+ 0: R_ANGLE@35..36 ">" [] []
+ 1: MD_BLOCK_LIST@36..47
+ 0: MD_PARAGRAPH@36..47
+ 0: MD_INLINE_ITEM_LIST@36..47
+ 0: MD_TEXTUAL@36..40
+ 0: MD_TEXTUAL_LITERAL@36..40 "Foo" [Skipped(" ")] []
+ 1: MD_TEXTUAL@40..41
+ 0: MD_TEXTUAL_LITERAL@40..41 "\n" [] []
+ 2: MD_TEXTUAL@41..44
+ 0: MD_TEXTUAL_LITERAL@41..44 "-" [Skipped(">"), Skipped(" ")] []
+ 3: MD_TEXTUAL@44..45
+ 0: MD_TEXTUAL_LITERAL@44..45 "-" [] []
+ 4: MD_TEXTUAL@45..46
+ 0: MD_TEXTUAL_LITERAL@45..46 "-" [] []
+ 5: MD_TEXTUAL@46..47
+ 0: MD_TEXTUAL_LITERAL@46..47 "\n" [] []
+ 1: (empty)
+ 10: MD_NEWLINE@47..48
+ 0: NEWLINE@47..48 "\n" [] []
+ 11: MD_BULLET_LIST_ITEM@48..66
+ 0: MD_BULLET_LIST@48..66
+ 0: MD_BULLET@48..66
+ 0: MINUS@48..49 "-" [] []
+ 1: MD_BLOCK_LIST@49..66
+ 0: MD_SETEXT_HEADER@49..59
+ 0: MD_INLINE_ITEM_LIST@49..54
+ 0: MD_TEXTUAL@49..53
+ 0: MD_TEXTUAL_LITERAL@49..53 "Foo" [Skipped(" ")] []
+ 1: MD_TEXTUAL@53..54
+ 0: MD_TEXTUAL_LITERAL@53..54 "\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@54..59 "---" [Skipped(" "), Skipped(" ")] []
+ 1: MD_NEWLINE@59..60
+ 0: NEWLINE@59..60 "\n" [] []
+ 2: MD_PARAGRAPH@60..66
+ 0: MD_INLINE_ITEM_LIST@60..66
+ 0: MD_TEXTUAL@60..65
+ 0: MD_TEXTUAL_LITERAL@60..65 "baz" [Skipped(" "), Skipped(" ")] []
+ 1: MD_TEXTUAL@65..66
+ 0: MD_TEXTUAL_LITERAL@65..66 "\n" [] []
+ 1: (empty)
+ 2: EOF@66..66 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_negative.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_negative.md
new file mode 100644
index 000000000000..2c1bcf55a4bc
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_negative.md
@@ -0,0 +1,13 @@
+Foo
+= =
+
+Foo
+ ---
+
+`Foo
+----
+`
+
+
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_negative.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_negative.md.snap
new file mode 100644
index 000000000000..5d0a9c53db49
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/setext_heading_negative.md.snap
@@ -0,0 +1,213 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+Foo
+= =
+
+Foo
+ ---
+
+`Foo
+----
+`
+
+
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..3 "Foo" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@3..4 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@4..7 "= =" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@7..8 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@8..9 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@9..12 "Foo" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@12..13 "\n" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@13..20 "---" [Skipped(" "), Skipped(" "), Skipped(" "), Skipped(" ")] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@20..21 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@21..22 "\n" [] [],
+ },
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@22..23 "`" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@23..26 "Foo" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@26..27 "\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@27..31 "----" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@31..32 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@32..33 "`" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@33..34 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ MdNewline {
+ value_token: NEWLINE@34..35 "\n" [] [],
+ },
+ MdSetextHeader {
+ content: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@35..36 "<" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@36..50 "a title=\"a lot" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@50..51 "\n" [] [],
+ },
+ ],
+ underline_token: MD_SETEXT_UNDERLINE_LITERAL@51..54 "---" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@54..55 "\n" [] [],
+ },
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@55..66 "of dashes\"/" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@66..67 ">" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@67..68 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@68..68 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..68
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..68
+ 0: MD_PARAGRAPH@0..8
+ 0: MD_INLINE_ITEM_LIST@0..8
+ 0: MD_TEXTUAL@0..3
+ 0: MD_TEXTUAL_LITERAL@0..3 "Foo" [] []
+ 1: MD_TEXTUAL@3..4
+ 0: MD_TEXTUAL_LITERAL@3..4 "\n" [] []
+ 2: MD_TEXTUAL@4..7
+ 0: MD_TEXTUAL_LITERAL@4..7 "= =" [] []
+ 3: MD_TEXTUAL@7..8
+ 0: MD_TEXTUAL_LITERAL@7..8 "\n" [] []
+ 1: (empty)
+ 1: MD_NEWLINE@8..9
+ 0: NEWLINE@8..9 "\n" [] []
+ 2: MD_PARAGRAPH@9..21
+ 0: MD_INLINE_ITEM_LIST@9..21
+ 0: MD_TEXTUAL@9..12
+ 0: MD_TEXTUAL_LITERAL@9..12 "Foo" [] []
+ 1: MD_TEXTUAL@12..13
+ 0: MD_TEXTUAL_LITERAL@12..13 "\n" [] []
+ 2: MD_TEXTUAL@13..20
+ 0: MD_TEXTUAL_LITERAL@13..20 "---" [Skipped(" "), Skipped(" "), Skipped(" "), Skipped(" ")] []
+ 3: MD_TEXTUAL@20..21
+ 0: MD_TEXTUAL_LITERAL@20..21 "\n" [] []
+ 1: (empty)
+ 3: MD_NEWLINE@21..22
+ 0: NEWLINE@21..22 "\n" [] []
+ 4: MD_SETEXT_HEADER@22..31
+ 0: MD_INLINE_ITEM_LIST@22..27
+ 0: MD_TEXTUAL@22..23
+ 0: MD_TEXTUAL_LITERAL@22..23 "`" [] []
+ 1: MD_TEXTUAL@23..26
+ 0: MD_TEXTUAL_LITERAL@23..26 "Foo" [] []
+ 2: MD_TEXTUAL@26..27
+ 0: MD_TEXTUAL_LITERAL@26..27 "\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@27..31 "----" [] []
+ 5: MD_NEWLINE@31..32
+ 0: NEWLINE@31..32 "\n" [] []
+ 6: MD_PARAGRAPH@32..34
+ 0: MD_INLINE_ITEM_LIST@32..34
+ 0: MD_TEXTUAL@32..33
+ 0: MD_TEXTUAL_LITERAL@32..33 "`" [] []
+ 1: MD_TEXTUAL@33..34
+ 0: MD_TEXTUAL_LITERAL@33..34 "\n" [] []
+ 1: (empty)
+ 7: MD_NEWLINE@34..35
+ 0: NEWLINE@34..35 "\n" [] []
+ 8: MD_SETEXT_HEADER@35..54
+ 0: MD_INLINE_ITEM_LIST@35..51
+ 0: MD_TEXTUAL@35..36
+ 0: MD_TEXTUAL_LITERAL@35..36 "<" [] []
+ 1: MD_TEXTUAL@36..50
+ 0: MD_TEXTUAL_LITERAL@36..50 "a title=\"a lot" [] []
+ 2: MD_TEXTUAL@50..51
+ 0: MD_TEXTUAL_LITERAL@50..51 "\n" [] []
+ 1: MD_SETEXT_UNDERLINE_LITERAL@51..54 "---" [] []
+ 9: MD_NEWLINE@54..55
+ 0: NEWLINE@54..55 "\n" [] []
+ 10: MD_PARAGRAPH@55..68
+ 0: MD_INLINE_ITEM_LIST@55..68
+ 0: MD_TEXTUAL@55..66
+ 0: MD_TEXTUAL_LITERAL@55..66 "of dashes\"/" [] []
+ 1: MD_TEXTUAL@66..67
+ 0: MD_TEXTUAL_LITERAL@66..67 ">" [] []
+ 2: MD_TEXTUAL@67..68
+ 0: MD_TEXTUAL_LITERAL@67..68 "\n" [] []
+ 1: (empty)
+ 2: EOF@68..68 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/thematic_break_block.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/thematic_break_block.md.snap
index ed839fc78381..f83e7aa6746c 100644
--- a/crates/biome_markdown_parser/tests/md_test_suite/ok/thematic_break_block.md.snap
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/thematic_break_block.md.snap
@@ -2,6 +2,7 @@
source: crates/biome_markdown_parser/tests/spec_test.rs
expression: snapshot
---
+
## Input
```
@@ -23,22 +24,43 @@ MdDocument {
bom_token: missing (optional),
value: MdBlockList [
MdThematicBreakBlock {
- value_token: MD_THEMATIC_BREAK_LITERAL@0..6 "***" [Whitespace(" ")] [],
+ value_token: MD_THEMATIC_BREAK_LITERAL@0..6 "***" [Skipped(" "), Skipped(" "), Skipped(" ")] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@6..7 "\n" [] [],
},
MdThematicBreakBlock {
- value_token: MD_THEMATIC_BREAK_LITERAL@6..11 "***" [Newline("\n"), Whitespace(" ")] [],
+ value_token: MD_THEMATIC_BREAK_LITERAL@7..11 "***" [Skipped(" ")] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@11..12 "\n" [] [],
},
MdThematicBreakBlock {
- value_token: MD_THEMATIC_BREAK_LITERAL@11..18 "- - -" [Newline("\n"), Whitespace(" ")] [],
+ value_token: MD_THEMATIC_BREAK_LITERAL@12..18 "- - -" [Skipped(" ")] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@18..19 "\n" [] [],
},
MdThematicBreakBlock {
- value_token: MD_THEMATIC_BREAK_LITERAL@18..22 "___" [Newline("\n")] [],
+ value_token: MD_THEMATIC_BREAK_LITERAL@19..22 "___" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@22..23 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@23..24 "\n" [] [],
},
MdThematicBreakBlock {
- value_token: MD_THEMATIC_BREAK_LITERAL@22..30 "_ _ _" [Newline("\n"), Newline("\n"), Whitespace(" ")] [],
+ value_token: MD_THEMATIC_BREAK_LITERAL@24..30 "_ _ _" [Skipped(" ")] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@30..31 "\n" [] [],
+ },
+ MdNewline {
+ value_token: NEWLINE@31..32 "\n" [] [],
},
MdThematicBreakBlock {
- value_token: MD_THEMATIC_BREAK_LITERAL@30..37 "* * *" [Newline("\n"), Newline("\n")] [],
+ value_token: MD_THEMATIC_BREAK_LITERAL@32..37 "* * *" [] [],
},
],
eof_token: EOF@37..37 "" [] [],
@@ -52,17 +74,31 @@ MdDocument {
0: (empty)
1: MD_BLOCK_LIST@0..37
0: MD_THEMATIC_BREAK_BLOCK@0..6
- 0: MD_THEMATIC_BREAK_LITERAL@0..6 "***" [Whitespace(" ")] []
- 1: MD_THEMATIC_BREAK_BLOCK@6..11
- 0: MD_THEMATIC_BREAK_LITERAL@6..11 "***" [Newline("\n"), Whitespace(" ")] []
- 2: MD_THEMATIC_BREAK_BLOCK@11..18
- 0: MD_THEMATIC_BREAK_LITERAL@11..18 "- - -" [Newline("\n"), Whitespace(" ")] []
- 3: MD_THEMATIC_BREAK_BLOCK@18..22
- 0: MD_THEMATIC_BREAK_LITERAL@18..22 "___" [Newline("\n")] []
- 4: MD_THEMATIC_BREAK_BLOCK@22..30
- 0: MD_THEMATIC_BREAK_LITERAL@22..30 "_ _ _" [Newline("\n"), Newline("\n"), Whitespace(" ")] []
- 5: MD_THEMATIC_BREAK_BLOCK@30..37
- 0: MD_THEMATIC_BREAK_LITERAL@30..37 "* * *" [Newline("\n"), Newline("\n")] []
+ 0: MD_THEMATIC_BREAK_LITERAL@0..6 "***" [Skipped(" "), Skipped(" "), Skipped(" ")] []
+ 1: MD_NEWLINE@6..7
+ 0: NEWLINE@6..7 "\n" [] []
+ 2: MD_THEMATIC_BREAK_BLOCK@7..11
+ 0: MD_THEMATIC_BREAK_LITERAL@7..11 "***" [Skipped(" ")] []
+ 3: MD_NEWLINE@11..12
+ 0: NEWLINE@11..12 "\n" [] []
+ 4: MD_THEMATIC_BREAK_BLOCK@12..18
+ 0: MD_THEMATIC_BREAK_LITERAL@12..18 "- - -" [Skipped(" ")] []
+ 5: MD_NEWLINE@18..19
+ 0: NEWLINE@18..19 "\n" [] []
+ 6: MD_THEMATIC_BREAK_BLOCK@19..22
+ 0: MD_THEMATIC_BREAK_LITERAL@19..22 "___" [] []
+ 7: MD_NEWLINE@22..23
+ 0: NEWLINE@22..23 "\n" [] []
+ 8: MD_NEWLINE@23..24
+ 0: NEWLINE@23..24 "\n" [] []
+ 9: MD_THEMATIC_BREAK_BLOCK@24..30
+ 0: MD_THEMATIC_BREAK_LITERAL@24..30 "_ _ _" [Skipped(" ")] []
+ 10: MD_NEWLINE@30..31
+ 0: NEWLINE@30..31 "\n" [] []
+ 11: MD_NEWLINE@31..32
+ 0: NEWLINE@31..32 "\n" [] []
+ 12: MD_THEMATIC_BREAK_BLOCK@32..37
+ 0: MD_THEMATIC_BREAK_LITERAL@32..37 "* * *" [] []
2: EOF@37..37 "" [] []
```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_bold.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_bold.md
new file mode 100644
index 000000000000..89ec5e79be43
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_bold.md
@@ -0,0 +1 @@
+This has **unclosed bold
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_bold.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_bold.md.snap
new file mode 100644
index 000000000000..73b7f6775931
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_bold.md.snap
@@ -0,0 +1,66 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+This has **unclosed bold
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..9 "This has " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@9..10 "*" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@10..11 "*" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@11..24 "unclosed bold" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@24..25 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@25..25 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..25
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..25
+ 0: MD_PARAGRAPH@0..25
+ 0: MD_INLINE_ITEM_LIST@0..25
+ 0: MD_TEXTUAL@0..9
+ 0: MD_TEXTUAL_LITERAL@0..9 "This has " [] []
+ 1: MD_TEXTUAL@9..10
+ 0: MD_TEXTUAL_LITERAL@9..10 "*" [] []
+ 2: MD_TEXTUAL@10..11
+ 0: MD_TEXTUAL_LITERAL@10..11 "*" [] []
+ 3: MD_TEXTUAL@11..24
+ 0: MD_TEXTUAL_LITERAL@11..24 "unclosed bold" [] []
+ 4: MD_TEXTUAL@24..25
+ 0: MD_TEXTUAL_LITERAL@24..25 "\n" [] []
+ 1: (empty)
+ 2: EOF@25..25 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_code_span.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_code_span.md
new file mode 100644
index 000000000000..ec06cc66f72d
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_code_span.md
@@ -0,0 +1 @@
+This has `unclosed code
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_code_span.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_code_span.md.snap
new file mode 100644
index 000000000000..c3dba3556804
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_code_span.md.snap
@@ -0,0 +1,61 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+This has `unclosed code
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..9 "This has " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@9..10 "`" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@10..23 "unclosed code" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@23..24 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@24..24 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..24
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..24
+ 0: MD_PARAGRAPH@0..24
+ 0: MD_INLINE_ITEM_LIST@0..24
+ 0: MD_TEXTUAL@0..9
+ 0: MD_TEXTUAL_LITERAL@0..9 "This has " [] []
+ 1: MD_TEXTUAL@9..10
+ 0: MD_TEXTUAL_LITERAL@9..10 "`" [] []
+ 2: MD_TEXTUAL@10..23
+ 0: MD_TEXTUAL_LITERAL@10..23 "unclosed code" [] []
+ 3: MD_TEXTUAL@23..24
+ 0: MD_TEXTUAL_LITERAL@23..24 "\n" [] []
+ 1: (empty)
+ 2: EOF@24..24 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_emphasis.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_emphasis.md
new file mode 100644
index 000000000000..91297cb3bd0d
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_emphasis.md
@@ -0,0 +1 @@
+This has *unclosed emphasis
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_emphasis.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_emphasis.md.snap
new file mode 100644
index 000000000000..774784707675
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_emphasis.md.snap
@@ -0,0 +1,61 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+This has *unclosed emphasis
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..9 "This has " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@9..10 "*" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@10..27 "unclosed emphasis" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@27..28 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@28..28 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..28
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..28
+ 0: MD_PARAGRAPH@0..28
+ 0: MD_INLINE_ITEM_LIST@0..28
+ 0: MD_TEXTUAL@0..9
+ 0: MD_TEXTUAL_LITERAL@0..9 "This has " [] []
+ 1: MD_TEXTUAL@9..10
+ 0: MD_TEXTUAL_LITERAL@9..10 "*" [] []
+ 2: MD_TEXTUAL@10..27
+ 0: MD_TEXTUAL_LITERAL@10..27 "unclosed emphasis" [] []
+ 3: MD_TEXTUAL@27..28
+ 0: MD_TEXTUAL_LITERAL@27..28 "\n" [] []
+ 1: (empty)
+ 2: EOF@28..28 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_image.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_image.md
new file mode 100644
index 000000000000..eb686c5bb932
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_image.md
@@ -0,0 +1 @@
+This has ![unclosed image
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_image.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_image.md.snap
new file mode 100644
index 000000000000..66b4c340faef
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_image.md.snap
@@ -0,0 +1,66 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+This has ![unclosed image
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..9 "This has " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@9..10 "!" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@10..11 "[" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@11..25 "unclosed image" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@25..26 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@26..26 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..26
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..26
+ 0: MD_PARAGRAPH@0..26
+ 0: MD_INLINE_ITEM_LIST@0..26
+ 0: MD_TEXTUAL@0..9
+ 0: MD_TEXTUAL_LITERAL@0..9 "This has " [] []
+ 1: MD_TEXTUAL@9..10
+ 0: MD_TEXTUAL_LITERAL@9..10 "!" [] []
+ 2: MD_TEXTUAL@10..11
+ 0: MD_TEXTUAL_LITERAL@10..11 "[" [] []
+ 3: MD_TEXTUAL@11..25
+ 0: MD_TEXTUAL_LITERAL@11..25 "unclosed image" [] []
+ 4: MD_TEXTUAL@25..26
+ 0: MD_TEXTUAL_LITERAL@25..26 "\n" [] []
+ 1: (empty)
+ 2: EOF@26..26 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_link.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_link.md
new file mode 100644
index 000000000000..91bfd8656e0d
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_link.md
@@ -0,0 +1 @@
+This has [unclosed link
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_link.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_link.md.snap
new file mode 100644
index 000000000000..5889b9c5a072
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_link.md.snap
@@ -0,0 +1,61 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+This has [unclosed link
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..9 "This has " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@9..10 "[" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@10..23 "unclosed link" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@23..24 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@24..24 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..24
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..24
+ 0: MD_PARAGRAPH@0..24
+ 0: MD_INLINE_ITEM_LIST@0..24
+ 0: MD_TEXTUAL@0..9
+ 0: MD_TEXTUAL_LITERAL@0..9 "This has " [] []
+ 1: MD_TEXTUAL@9..10
+ 0: MD_TEXTUAL_LITERAL@9..10 "[" [] []
+ 2: MD_TEXTUAL@10..23
+ 0: MD_TEXTUAL_LITERAL@10..23 "unclosed link" [] []
+ 3: MD_TEXTUAL@23..24
+ 0: MD_TEXTUAL_LITERAL@23..24 "\n" [] []
+ 1: (empty)
+ 2: EOF@24..24 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_image_label.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_image_label.md
new file mode 100644
index 000000000000..28913e5cc8c0
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_image_label.md
@@ -0,0 +1 @@
+This has ![alt][unclosed label
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_image_label.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_image_label.md.snap
new file mode 100644
index 000000000000..baf2a4b27f71
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_image_label.md.snap
@@ -0,0 +1,81 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+This has ![alt][unclosed label
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..9 "This has " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@9..10 "!" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@10..11 "[" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@11..14 "alt" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@14..15 "]" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@15..16 "[" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@16..30 "unclosed label" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@30..31 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@31..31 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..31
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..31
+ 0: MD_PARAGRAPH@0..31
+ 0: MD_INLINE_ITEM_LIST@0..31
+ 0: MD_TEXTUAL@0..9
+ 0: MD_TEXTUAL_LITERAL@0..9 "This has " [] []
+ 1: MD_TEXTUAL@9..10
+ 0: MD_TEXTUAL_LITERAL@9..10 "!" [] []
+ 2: MD_TEXTUAL@10..11
+ 0: MD_TEXTUAL_LITERAL@10..11 "[" [] []
+ 3: MD_TEXTUAL@11..14
+ 0: MD_TEXTUAL_LITERAL@11..14 "alt" [] []
+ 4: MD_TEXTUAL@14..15
+ 0: MD_TEXTUAL_LITERAL@14..15 "]" [] []
+ 5: MD_TEXTUAL@15..16
+ 0: MD_TEXTUAL_LITERAL@15..16 "[" [] []
+ 6: MD_TEXTUAL@16..30
+ 0: MD_TEXTUAL_LITERAL@16..30 "unclosed label" [] []
+ 7: MD_TEXTUAL@30..31
+ 0: MD_TEXTUAL_LITERAL@30..31 "\n" [] []
+ 1: (empty)
+ 2: EOF@31..31 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_link_label.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_link_label.md
new file mode 100644
index 000000000000..3aaa9c5bf1fd
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_link_label.md
@@ -0,0 +1 @@
+This has [text][unclosed label
diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_link_label.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_link_label.md.snap
new file mode 100644
index 000000000000..67dcb93d1640
--- /dev/null
+++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/unclosed_reference_link_label.md.snap
@@ -0,0 +1,76 @@
+---
+source: crates/biome_markdown_parser/tests/spec_test.rs
+expression: snapshot
+---
+
+## Input
+
+```
+This has [text][unclosed label
+
+```
+
+
+## AST
+
+```
+MdDocument {
+ bom_token: missing (optional),
+ value: MdBlockList [
+ MdParagraph {
+ list: MdInlineItemList [
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@0..9 "This has " [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@9..10 "[" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@10..14 "text" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@14..15 "]" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@15..16 "[" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@16..30 "unclosed label" [] [],
+ },
+ MdTextual {
+ value_token: MD_TEXTUAL_LITERAL@30..31 "\n" [] [],
+ },
+ ],
+ hard_line: missing (optional),
+ },
+ ],
+ eof_token: EOF@31..31 "" [] [],
+}
+```
+
+## CST
+
+```
+0: MD_DOCUMENT@0..31
+ 0: (empty)
+ 1: MD_BLOCK_LIST@0..31
+ 0: MD_PARAGRAPH@0..31
+ 0: MD_INLINE_ITEM_LIST@0..31
+ 0: MD_TEXTUAL@0..9
+ 0: MD_TEXTUAL_LITERAL@0..9 "This has " [] []
+ 1: MD_TEXTUAL@9..10
+ 0: MD_TEXTUAL_LITERAL@9..10 "[" [] []
+ 2: MD_TEXTUAL@10..14
+ 0: MD_TEXTUAL_LITERAL@10..14 "text" [] []
+ 3: MD_TEXTUAL@14..15
+ 0: MD_TEXTUAL_LITERAL@14..15 "]" [] []
+ 4: MD_TEXTUAL@15..16
+ 0: MD_TEXTUAL_LITERAL@15..16 "[" [] []
+ 5: MD_TEXTUAL@16..30
+ 0: MD_TEXTUAL_LITERAL@16..30 "unclosed label" [] []
+ 6: MD_TEXTUAL@30..31
+ 0: MD_TEXTUAL_LITERAL@30..31 "\n" [] []
+ 1: (empty)
+ 2: EOF@31..31 "" [] []
+
+```
diff --git a/crates/biome_markdown_parser/tests/spec_test.rs b/crates/biome_markdown_parser/tests/spec_test.rs
index dee024b5e7e8..796833429571 100644
--- a/crates/biome_markdown_parser/tests/spec_test.rs
+++ b/crates/biome_markdown_parser/tests/spec_test.rs
@@ -132,17 +132,65 @@ pub fn run(test_case: &str, _snapshot_name: &str, test_directory: &str, outcome_
});
}
-#[ignore]
#[test]
pub fn quick_test() {
- let code = r#"
-your test code
-"#;
-
- let root = parse_markdown(code);
- let syntax = root.syntax();
- dbg!(&syntax, root.diagnostics(), root.has_errors());
- if has_bogus_nodes_or_empty_slots(&syntax) {
- panic!("modified tree has bogus nodes or empty slots:\n{syntax:#?} \n\n {syntax}")
+ use biome_markdown_parser::document_to_html;
+ use biome_markdown_syntax::MdDocument;
+ use biome_rowan::AstNode;
+
+ fn test_example(num: u32, input: &str, expected: &str) {
+ let root = parse_markdown(input);
+ let doc = MdDocument::cast(root.syntax())
+ .unwrap_or_else(|| panic!("Example {:03}: parse failed", num));
+ let html = document_to_html(
+ &doc,
+ root.list_tightness(),
+ root.list_item_indents(),
+ root.quote_indents(),
+ );
+
+ assert_eq!(expected, html, "Example {:03} failed", num);
}
+
+ test_example(
+ 7,
+ "-\t\tfoo\n",
+ "\n",
+ );
+ test_example(
+ 42,
+ "- `one\n- two`\n",
+ "\n",
+ );
+ test_example(
+ 61,
+ "- Foo\n- * * *\n",
+ "\n",
+ );
+ test_example(
+ 66,
+ "# foo *bar* \\*baz\\*\n",
+ "foo bar *baz*
\n",
+ );
+ test_example(73, "### foo ### \n", "foo
\n");
+ test_example(
+ 93,
+ "> foo\nbar\n===\n",
+ "\nfoo\nbar\n===
\n
\n",
+ );
+ test_example(
+ 223,
+ "aaa\n bbb\n ccc\n",
+ "aaa\nbbb\nccc
\n",
+ );
+ test_example(
+ 259,
+ " > > 1. one\n>>\n>> two\n",
+ "\n\n\n- \n
one
\ntwo
\n \n
\n
\n
\n",
+ );
+ test_example(
+ 9991,
+ "\n",
+ "
\n",
+ );
}
diff --git a/crates/biome_markdown_syntax/src/generated/kind.rs b/crates/biome_markdown_syntax/src/generated/kind.rs
index a43d2ee90ad1..a703b98db8ab 100644
--- a/crates/biome_markdown_syntax/src/generated/kind.rs
+++ b/crates/biome_markdown_syntax/src/generated/kind.rs
@@ -23,15 +23,18 @@ pub enum MarkdownSyntaxKind {
BANG,
MINUS,
STAR,
+ PLUS,
DOUBLE_STAR,
BACKTICK,
TRIPLE_BACKTICK,
TILDE,
+ TRIPLE_TILDE,
WHITESPACE3,
UNDERSCORE,
DOUBLE_UNDERSCORE,
HASH,
COMMA,
+ COLON,
NULL_KW,
MD_HARD_LINE_LITERAL,
MD_SOFT_BREAK_LITERAL,
@@ -39,13 +42,17 @@ pub enum MarkdownSyntaxKind {
MD_STRING_LITERAL,
MD_INDENT_CHUNK_LITERAL,
MD_THEMATIC_BREAK_LITERAL,
+ MD_SETEXT_UNDERLINE_LITERAL,
+ MD_ORDERED_LIST_MARKER,
MD_ERROR_LITERAL,
+ MD_ENTITY_LITERAL,
ERROR_TOKEN,
NEWLINE,
WHITESPACE,
TAB,
BOGUS,
MD_BOGUS,
+ MD_BOGUS_BULLET,
MD_DOCUMENT,
MD_BLOCK_LIST,
MD_HASH_LIST,
@@ -56,11 +63,14 @@ pub enum MarkdownSyntaxKind {
MD_CODE_NAME_LIST,
MD_HTML_BLOCK,
MD_LINK_BLOCK,
+ MD_LINK_REFERENCE_DEFINITION,
+ MD_LINK_LABEL,
+ MD_LINK_DESTINATION,
+ MD_LINK_TITLE,
MD_QUOTE,
- MD_ORDER_LIST_ITEM,
+ MD_ORDERED_LIST_ITEM,
MD_BULLET_LIST_ITEM,
MD_BULLET_LIST,
- MD_ORDER_LIST,
MD_PARAGRAPH,
MD_INLINE_ITEM_LIST,
MD_INLINE_EMPHASIS,
@@ -69,6 +79,12 @@ pub enum MarkdownSyntaxKind {
MD_BULLET,
MD_INLINE_LINK,
MD_INLINE_IMAGE,
+ MD_REFERENCE_LINK,
+ MD_REFERENCE_IMAGE,
+ MD_REFERENCE_LINK_LABEL,
+ MD_AUTOLINK,
+ MD_INLINE_HTML,
+ MD_ENTITY_REFERENCE,
MD_INLINE_IMAGE_ALT,
MD_INDENTED_CODE_LINE,
MD_INLINE_IMAGE_LINK,
@@ -81,6 +97,7 @@ pub enum MarkdownSyntaxKind {
MD_STRING,
MD_INDENT,
MD_THEMATIC_BREAK_BLOCK,
+ MD_NEWLINE,
#[doc(hidden)]
__LAST,
}
@@ -100,15 +117,18 @@ impl MarkdownSyntaxKind {
| BANG
| MINUS
| STAR
+ | PLUS
| DOUBLE_STAR
| BACKTICK
| TRIPLE_BACKTICK
| TILDE
+ | TRIPLE_TILDE
| WHITESPACE3
| UNDERSCORE
| DOUBLE_UNDERSCORE
| HASH
| COMMA
+ | COLON
)
}
pub const fn is_literal(self) -> bool {
@@ -120,7 +140,10 @@ impl MarkdownSyntaxKind {
| MD_STRING_LITERAL
| MD_INDENT_CHUNK_LITERAL
| MD_THEMATIC_BREAK_LITERAL
+ | MD_SETEXT_UNDERLINE_LITERAL
+ | MD_ORDERED_LIST_MARKER
| MD_ERROR_LITERAL
+ | MD_ENTITY_LITERAL
)
}
pub const fn is_list(self) -> bool {
@@ -130,7 +153,6 @@ impl MarkdownSyntaxKind {
| MD_HASH_LIST
| MD_CODE_NAME_LIST
| MD_BULLET_LIST
- | MD_ORDER_LIST
| MD_INLINE_ITEM_LIST
| MD_INDENTED_CODE_LINE_LIST
)
@@ -155,17 +177,20 @@ impl MarkdownSyntaxKind {
BANG => "!",
MINUS => "-",
STAR => "*",
+ PLUS => "+",
DOUBLE_STAR => "**",
BACKTICK => "`",
TRIPLE_BACKTICK => "```",
TILDE => "~",
+ TRIPLE_TILDE => "~~~",
WHITESPACE3 => " ",
UNDERSCORE => "_",
DOUBLE_UNDERSCORE => "__",
HASH => "#",
COMMA => ",",
+ COLON => ":",
NULL_KW => "null",
- EOF => "EOF",
+ EOF => "",
_ => return None,
};
Some(tok)
@@ -173,4 +198,4 @@ impl MarkdownSyntaxKind {
}
#[doc = r" Utility macro for creating a SyntaxKind through simple macro syntax"]
#[macro_export]
-macro_rules ! T { [<] => { $ crate :: MarkdownSyntaxKind :: L_ANGLE } ; [>] => { $ crate :: MarkdownSyntaxKind :: R_ANGLE } ; ['('] => { $ crate :: MarkdownSyntaxKind :: L_PAREN } ; [')'] => { $ crate :: MarkdownSyntaxKind :: R_PAREN } ; ['['] => { $ crate :: MarkdownSyntaxKind :: L_BRACK } ; [']'] => { $ crate :: MarkdownSyntaxKind :: R_BRACK } ; [/] => { $ crate :: MarkdownSyntaxKind :: SLASH } ; [=] => { $ crate :: MarkdownSyntaxKind :: EQ } ; [!] => { $ crate :: MarkdownSyntaxKind :: BANG } ; [-] => { $ crate :: MarkdownSyntaxKind :: MINUS } ; [*] => { $ crate :: MarkdownSyntaxKind :: STAR } ; [**] => { $ crate :: MarkdownSyntaxKind :: DOUBLE_STAR } ; ['`'] => { $ crate :: MarkdownSyntaxKind :: BACKTICK } ; ["```"] => { $ crate :: MarkdownSyntaxKind :: TRIPLE_BACKTICK } ; [~] => { $ crate :: MarkdownSyntaxKind :: TILDE } ; [" "] => { $ crate :: MarkdownSyntaxKind :: WHITESPACE3 } ; ["_"] => { $ crate :: MarkdownSyntaxKind :: UNDERSCORE } ; ["__"] => { $ crate :: MarkdownSyntaxKind :: DOUBLE_UNDERSCORE } ; [#] => { $ crate :: MarkdownSyntaxKind :: HASH } ; [,] => { $ crate :: MarkdownSyntaxKind :: COMMA } ; [null] => { $ crate :: MarkdownSyntaxKind :: NULL_KW } ; [ident] => { $ crate :: MarkdownSyntaxKind :: IDENT } ; [EOF] => { $ crate :: MarkdownSyntaxKind :: EOF } ; [UNICODE_BOM] => { $ crate :: MarkdownSyntaxKind :: UNICODE_BOM } ; [#] => { $ crate :: MarkdownSyntaxKind :: HASH } ; }
+macro_rules ! T { [<] => { $ crate :: MarkdownSyntaxKind :: L_ANGLE } ; [>] => { $ crate :: MarkdownSyntaxKind :: R_ANGLE } ; ['('] => { $ crate :: MarkdownSyntaxKind :: L_PAREN } ; [')'] => { $ crate :: MarkdownSyntaxKind :: R_PAREN } ; ['['] => { $ crate :: MarkdownSyntaxKind :: L_BRACK } ; [']'] => { $ crate :: MarkdownSyntaxKind :: R_BRACK } ; [/] => { $ crate :: MarkdownSyntaxKind :: SLASH } ; [=] => { $ crate :: MarkdownSyntaxKind :: EQ } ; [!] => { $ crate :: MarkdownSyntaxKind :: BANG } ; [-] => { $ crate :: MarkdownSyntaxKind :: MINUS } ; [*] => { $ crate :: MarkdownSyntaxKind :: STAR } ; [+] => { $ crate :: MarkdownSyntaxKind :: PLUS } ; [**] => { $ crate :: MarkdownSyntaxKind :: DOUBLE_STAR } ; ['`'] => { $ crate :: MarkdownSyntaxKind :: BACKTICK } ; ["```"] => { $ crate :: MarkdownSyntaxKind :: TRIPLE_BACKTICK } ; [~] => { $ crate :: MarkdownSyntaxKind :: TILDE } ; [~~~] => { $ crate :: MarkdownSyntaxKind :: TRIPLE_TILDE } ; [" "] => { $ crate :: MarkdownSyntaxKind :: WHITESPACE3 } ; ["_"] => { $ crate :: MarkdownSyntaxKind :: UNDERSCORE } ; ["__"] => { $ crate :: MarkdownSyntaxKind :: DOUBLE_UNDERSCORE } ; [#] => { $ crate :: MarkdownSyntaxKind :: HASH } ; [,] => { $ crate :: MarkdownSyntaxKind :: COMMA } ; [:] => { $ crate :: MarkdownSyntaxKind :: COLON } ; [null] => { $ crate :: MarkdownSyntaxKind :: NULL_KW } ; [ident] => { $ crate :: MarkdownSyntaxKind :: IDENT } ; [EOF] => { $ crate :: MarkdownSyntaxKind :: EOF } ; [UNICODE_BOM] => { $ crate :: MarkdownSyntaxKind :: UNICODE_BOM } ; [#] => { $ crate :: MarkdownSyntaxKind :: HASH } ; }
diff --git a/crates/biome_markdown_syntax/src/generated/macros.rs b/crates/biome_markdown_syntax/src/generated/macros.rs
index 834bc5073bde..e10554278277 100644
--- a/crates/biome_markdown_syntax/src/generated/macros.rs
+++ b/crates/biome_markdown_syntax/src/generated/macros.rs
@@ -16,6 +16,10 @@ macro_rules! map_syntax_node {
($ node : expr , $ pattern : pat => $ body : expr) => {
match $node {
node => match $crate::MarkdownSyntaxNode::kind(&node) {
+ $crate::MarkdownSyntaxKind::MD_AUTOLINK => {
+ let $pattern = unsafe { $crate::MdAutolink::new_unchecked(node) };
+ $body
+ }
$crate::MarkdownSyntaxKind::MD_BULLET => {
let $pattern = unsafe { $crate::MdBullet::new_unchecked(node) };
$body
@@ -28,6 +32,10 @@ macro_rules! map_syntax_node {
let $pattern = unsafe { $crate::MdDocument::new_unchecked(node) };
$body
}
+ $crate::MarkdownSyntaxKind::MD_ENTITY_REFERENCE => {
+ let $pattern = unsafe { $crate::MdEntityReference::new_unchecked(node) };
+ $body
+ }
$crate::MarkdownSyntaxKind::MD_FENCED_CODE_BLOCK => {
let $pattern = unsafe { $crate::MdFencedCodeBlock::new_unchecked(node) };
$body
@@ -56,10 +64,6 @@ macro_rules! map_syntax_node {
let $pattern = unsafe { $crate::MdIndentCodeBlock::new_unchecked(node) };
$body
}
- $crate::MarkdownSyntaxKind::MD_INDENTED_CODE_LINE => {
- let $pattern = unsafe { $crate::MdIndentedCodeLine::new_unchecked(node) };
- $body
- }
$crate::MarkdownSyntaxKind::MD_INLINE_CODE => {
let $pattern = unsafe { $crate::MdInlineCode::new_unchecked(node) };
$body
@@ -68,20 +72,12 @@ macro_rules! map_syntax_node {
let $pattern = unsafe { $crate::MdInlineEmphasis::new_unchecked(node) };
$body
}
- $crate::MarkdownSyntaxKind::MD_INLINE_IMAGE => {
- let $pattern = unsafe { $crate::MdInlineImage::new_unchecked(node) };
+ $crate::MarkdownSyntaxKind::MD_INLINE_HTML => {
+ let $pattern = unsafe { $crate::MdInlineHtml::new_unchecked(node) };
$body
}
- $crate::MarkdownSyntaxKind::MD_INLINE_IMAGE_ALT => {
- let $pattern = unsafe { $crate::MdInlineImageAlt::new_unchecked(node) };
- $body
- }
- $crate::MarkdownSyntaxKind::MD_INLINE_IMAGE_LINK => {
- let $pattern = unsafe { $crate::MdInlineImageLink::new_unchecked(node) };
- $body
- }
- $crate::MarkdownSyntaxKind::MD_INLINE_IMAGE_SOURCE => {
- let $pattern = unsafe { $crate::MdInlineImageSource::new_unchecked(node) };
+ $crate::MarkdownSyntaxKind::MD_INLINE_IMAGE => {
+ let $pattern = unsafe { $crate::MdInlineImage::new_unchecked(node) };
$body
}
$crate::MarkdownSyntaxKind::MD_INLINE_ITALIC => {
@@ -96,8 +92,29 @@ macro_rules! map_syntax_node {
let $pattern = unsafe { $crate::MdLinkBlock::new_unchecked(node) };
$body
}
- $crate::MarkdownSyntaxKind::MD_ORDER_LIST_ITEM => {
- let $pattern = unsafe { $crate::MdOrderListItem::new_unchecked(node) };
+ $crate::MarkdownSyntaxKind::MD_LINK_DESTINATION => {
+ let $pattern = unsafe { $crate::MdLinkDestination::new_unchecked(node) };
+ $body
+ }
+ $crate::MarkdownSyntaxKind::MD_LINK_LABEL => {
+ let $pattern = unsafe { $crate::MdLinkLabel::new_unchecked(node) };
+ $body
+ }
+ $crate::MarkdownSyntaxKind::MD_LINK_REFERENCE_DEFINITION => {
+ let $pattern =
+ unsafe { $crate::MdLinkReferenceDefinition::new_unchecked(node) };
+ $body
+ }
+ $crate::MarkdownSyntaxKind::MD_LINK_TITLE => {
+ let $pattern = unsafe { $crate::MdLinkTitle::new_unchecked(node) };
+ $body
+ }
+ $crate::MarkdownSyntaxKind::MD_NEWLINE => {
+ let $pattern = unsafe { $crate::MdNewline::new_unchecked(node) };
+ $body
+ }
+ $crate::MarkdownSyntaxKind::MD_ORDERED_LIST_ITEM => {
+ let $pattern = unsafe { $crate::MdOrderedListItem::new_unchecked(node) };
$body
}
$crate::MarkdownSyntaxKind::MD_PARAGRAPH => {
@@ -108,6 +125,18 @@ macro_rules! map_syntax_node {
let $pattern = unsafe { $crate::MdQuote::new_unchecked(node) };
$body
}
+ $crate::MarkdownSyntaxKind::MD_REFERENCE_IMAGE => {
+ let $pattern = unsafe { $crate::MdReferenceImage::new_unchecked(node) };
+ $body
+ }
+ $crate::MarkdownSyntaxKind::MD_REFERENCE_LINK => {
+ let $pattern = unsafe { $crate::MdReferenceLink::new_unchecked(node) };
+ $body
+ }
+ $crate::MarkdownSyntaxKind::MD_REFERENCE_LINK_LABEL => {
+ let $pattern = unsafe { $crate::MdReferenceLinkLabel::new_unchecked(node) };
+ $body
+ }
$crate::MarkdownSyntaxKind::MD_SETEXT_HEADER => {
let $pattern = unsafe { $crate::MdSetextHeader::new_unchecked(node) };
$body
@@ -144,18 +173,10 @@ macro_rules! map_syntax_node {
let $pattern = unsafe { $crate::MdHashList::new_unchecked(node) };
$body
}
- $crate::MarkdownSyntaxKind::MD_INDENTED_CODE_LINE_LIST => {
- let $pattern = unsafe { $crate::MdIndentedCodeLineList::new_unchecked(node) };
- $body
- }
$crate::MarkdownSyntaxKind::MD_INLINE_ITEM_LIST => {
let $pattern = unsafe { $crate::MdInlineItemList::new_unchecked(node) };
$body
}
- $crate::MarkdownSyntaxKind::MD_ORDER_LIST => {
- let $pattern = unsafe { $crate::MdOrderList::new_unchecked(node) };
- $body
- }
_ => unreachable!(),
},
}
diff --git a/crates/biome_markdown_syntax/src/generated/nodes.rs b/crates/biome_markdown_syntax/src/generated/nodes.rs
index b3c37bc737d4..cb1bd8ff55dd 100644
--- a/crates/biome_markdown_syntax/src/generated/nodes.rs
+++ b/crates/biome_markdown_syntax/src/generated/nodes.rs
@@ -21,6 +21,51 @@ use std::fmt::{Debug, Formatter};
#[doc = r" the slots are not statically known."]
pub(crate) const SLOT_MAP_EMPTY_VALUE: u8 = u8::MAX;
#[derive(Clone, PartialEq, Eq, Hash)]
+pub struct MdAutolink {
+ pub(crate) syntax: SyntaxNode,
+}
+impl MdAutolink {
+ #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"]
+ #[doc = r""]
+ #[doc = r" # Safety"]
+ #[doc = r" This function must be guarded with a call to [AstNode::can_cast]"]
+ #[doc = r" or a match on [SyntaxNode::kind]"]
+ #[inline]
+ pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self {
+ Self { syntax }
+ }
+ pub fn as_fields(&self) -> MdAutolinkFields {
+ MdAutolinkFields {
+ l_angle_token: self.l_angle_token(),
+ value: self.value(),
+ r_angle_token: self.r_angle_token(),
+ }
+ }
+ pub fn l_angle_token(&self) -> SyntaxResult {
+ support::required_token(&self.syntax, 0usize)
+ }
+ pub fn value(&self) -> MdInlineItemList {
+ support::list(&self.syntax, 1usize)
+ }
+ pub fn r_angle_token(&self) -> SyntaxResult {
+ support::required_token(&self.syntax, 2usize)
+ }
+}
+impl Serialize for MdAutolink {
+ fn serialize(&self, serializer: S) -> Result
+ where
+ S: Serializer,
+ {
+ self.as_fields().serialize(serializer)
+ }
+}
+#[derive(Serialize)]
+pub struct MdAutolinkFields {
+ pub l_angle_token: SyntaxResult,
+ pub value: MdInlineItemList,
+ pub r_angle_token: SyntaxResult,
+}
+#[derive(Clone, PartialEq, Eq, Hash)]
pub struct MdBullet {
pub(crate) syntax: SyntaxNode,
}
@@ -37,18 +82,14 @@ impl MdBullet {
pub fn as_fields(&self) -> MdBulletFields {
MdBulletFields {
bullet: self.bullet(),
- space_token: self.space_token(),
content: self.content(),
}
}
pub fn bullet(&self) -> SyntaxResult {
support::required_token(&self.syntax, 0usize)
}
- pub fn space_token(&self) -> SyntaxResult {
- support::required_token(&self.syntax, 1usize)
- }
- pub fn content(&self) -> MdInlineItemList {
- support::list(&self.syntax, 2usize)
+ pub fn content(&self) -> MdBlockList {
+ support::list(&self.syntax, 1usize)
}
}
impl Serialize for MdBullet {
@@ -62,8 +103,7 @@ impl Serialize for MdBullet {
#[derive(Serialize)]
pub struct MdBulletFields {
pub bullet: SyntaxResult,
- pub space_token: SyntaxResult,
- pub content: MdInlineItemList,
+ pub content: MdBlockList,
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct MdBulletListItem {
@@ -146,6 +186,41 @@ pub struct MdDocumentFields {
pub eof_token: SyntaxResult,
}
#[derive(Clone, PartialEq, Eq, Hash)]
+pub struct MdEntityReference {
+ pub(crate) syntax: SyntaxNode,
+}
+impl MdEntityReference {
+ #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"]
+ #[doc = r""]
+ #[doc = r" # Safety"]
+ #[doc = r" This function must be guarded with a call to [AstNode::can_cast]"]
+ #[doc = r" or a match on [SyntaxNode::kind]"]
+ #[inline]
+ pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self {
+ Self { syntax }
+ }
+ pub fn as_fields(&self) -> MdEntityReferenceFields {
+ MdEntityReferenceFields {
+ value_token: self.value_token(),
+ }
+ }
+ pub fn value_token(&self) -> SyntaxResult {
+ support::required_token(&self.syntax, 0usize)
+ }
+}
+impl Serialize for MdEntityReference {
+ fn serialize(&self, serializer: S) -> Result
+ where
+ S: Serializer,
+ {
+ self.as_fields().serialize(serializer)
+ }
+}
+#[derive(Serialize)]
+pub struct MdEntityReferenceFields {
+ pub value_token: SyntaxResult,
+}
+#[derive(Clone, PartialEq, Eq, Hash)]
pub struct MdFencedCodeBlock {
pub(crate) syntax: SyntaxNode,
}
@@ -161,31 +236,23 @@ impl MdFencedCodeBlock {
}
pub fn as_fields(&self) -> MdFencedCodeBlockFields {
MdFencedCodeBlockFields {
- l_fence_token: self.l_fence_token(),
+ l_fence: self.l_fence(),
code_list: self.code_list(),
- l_hard_line: self.l_hard_line(),
content: self.content(),
- r_hard_line: self.r_hard_line(),
- r_fence_token: self.r_fence_token(),
+ r_fence: self.r_fence(),
}
}
- pub fn l_fence_token(&self) -> SyntaxResult {
+ pub fn l_fence(&self) -> SyntaxResult {
support::required_token(&self.syntax, 0usize)
}
pub fn code_list(&self) -> MdCodeNameList {
support::list(&self.syntax, 1usize)
}
- pub fn l_hard_line(&self) -> SyntaxResult {
- support::required_node(&self.syntax, 2usize)
- }
- pub fn content(&self) -> SyntaxResult {
- support::required_node(&self.syntax, 3usize)
- }
- pub fn r_hard_line(&self) -> SyntaxResult {
- support::required_node(&self.syntax, 4usize)
+ pub fn content(&self) -> MdInlineItemList {
+ support::list(&self.syntax, 2usize)
}
- pub fn r_fence_token(&self) -> SyntaxResult {
- support::required_token(&self.syntax, 5usize)
+ pub fn r_fence(&self) -> SyntaxResult {
+ support::required_token(&self.syntax, 3usize)
}
}
impl Serialize for MdFencedCodeBlock {
@@ -198,12 +265,10 @@ impl Serialize for MdFencedCodeBlock {
}
#[derive(Serialize)]
pub struct MdFencedCodeBlockFields {
- pub l_fence_token: SyntaxResult,
+ pub l_fence: SyntaxResult,
pub code_list: MdCodeNameList,
- pub l_hard_line: SyntaxResult,
- pub content: SyntaxResult,
- pub r_hard_line: SyntaxResult,
- pub r_fence_token: SyntaxResult,
+ pub content: MdInlineItemList,
+ pub r_fence: SyntaxResult,
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct MdHardLine {
@@ -336,11 +401,11 @@ impl MdHtmlBlock {
}
pub fn as_fields(&self) -> MdHtmlBlockFields {
MdHtmlBlockFields {
- md_textual: self.md_textual(),
+ content: self.content(),
}
}
- pub fn md_textual(&self) -> SyntaxResult {
- support::required_node(&self.syntax, 0usize)
+ pub fn content(&self) -> MdInlineItemList {
+ support::list(&self.syntax, 0usize)
}
}
impl Serialize for MdHtmlBlock {
@@ -353,7 +418,7 @@ impl Serialize for MdHtmlBlock {
}
#[derive(Serialize)]
pub struct MdHtmlBlockFields {
- pub md_textual: SyntaxResult,
+ pub content: MdInlineItemList,
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct MdIndent {
@@ -406,10 +471,10 @@ impl MdIndentCodeBlock {
}
pub fn as_fields(&self) -> MdIndentCodeBlockFields {
MdIndentCodeBlockFields {
- lines: self.lines(),
+ content: self.content(),
}
}
- pub fn lines(&self) -> MdIndentedCodeLineList {
+ pub fn content(&self) -> MdInlineItemList {
support::list(&self.syntax, 0usize)
}
}
@@ -423,47 +488,7 @@ impl Serialize for MdIndentCodeBlock {
}
#[derive(Serialize)]
pub struct MdIndentCodeBlockFields {
- pub lines: MdIndentedCodeLineList,
-}
-#[derive(Clone, PartialEq, Eq, Hash)]
-pub struct MdIndentedCodeLine {
- pub(crate) syntax: SyntaxNode,
-}
-impl MdIndentedCodeLine {
- #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"]
- #[doc = r""]
- #[doc = r" # Safety"]
- #[doc = r" This function must be guarded with a call to [AstNode::can_cast]"]
- #[doc = r" or a match on [SyntaxNode::kind]"]
- #[inline]
- pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self {
- Self { syntax }
- }
- pub fn as_fields(&self) -> MdIndentedCodeLineFields {
- MdIndentedCodeLineFields {
- indentation: self.indentation(),
- content: self.content(),
- }
- }
- pub fn indentation(&self) -> SyntaxResult {
- support::required_node(&self.syntax, 0usize)
- }
- pub fn content(&self) -> SyntaxResult {
- support::required_node(&self.syntax, 1usize)
- }
-}
-impl Serialize for MdIndentedCodeLine {
- fn serialize(&self, serializer: S) -> Result
- where
- S: Serializer,
- {
- self.as_fields().serialize(serializer)
- }
-}
-#[derive(Serialize)]
-pub struct MdIndentedCodeLineFields {
- pub indentation: SyntaxResult,
- pub content: SyntaxResult,
+ pub content: MdInlineItemList,
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct MdInlineCode {
@@ -556,10 +581,10 @@ pub struct MdInlineEmphasisFields {
pub r_fence: SyntaxResult,
}
#[derive(Clone, PartialEq, Eq, Hash)]
-pub struct MdInlineImage {
+pub struct MdInlineHtml {
pub(crate) syntax: SyntaxNode,
}
-impl MdInlineImage {
+impl MdInlineHtml {
#[doc = r" Create an AstNode from a SyntaxNode without checking its kind"]
#[doc = r""]
#[doc = r" # Safety"]
@@ -569,36 +594,16 @@ impl MdInlineImage {
pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self {
Self { syntax }
}
- pub fn as_fields(&self) -> MdInlineImageFields {
- MdInlineImageFields {
- l_brack_token: self.l_brack_token(),
- excl_token: self.excl_token(),
- alt: self.alt(),
- source: self.source(),
- r_brack_token: self.r_brack_token(),
- link: self.link(),
+ pub fn as_fields(&self) -> MdInlineHtmlFields {
+ MdInlineHtmlFields {
+ value: self.value(),
}
}
- pub fn l_brack_token(&self) -> SyntaxResult {
- support::required_token(&self.syntax, 0usize)
- }
- pub fn excl_token(&self) -> SyntaxResult {
- support::required_token(&self.syntax, 1usize)
- }
- pub fn alt(&self) -> SyntaxResult {
- support::required_node(&self.syntax, 2usize)
- }
- pub fn source(&self) -> SyntaxResult {
- support::required_node(&self.syntax, 3usize)
- }
- pub fn r_brack_token(&self) -> SyntaxResult {
- support::required_token(&self.syntax, 4usize)
- }
- pub fn link(&self) -> Option {
- support::node(&self.syntax, 5usize)
+ pub fn value(&self) -> MdInlineItemList {
+ support::list(&self.syntax, 0usize)
}
}
-impl Serialize for MdInlineImage {
+impl Serialize for MdInlineHtml {
fn serialize