diff --git a/crates/biome_markdown_factory/src/generated/node_factory.rs b/crates/biome_markdown_factory/src/generated/node_factory.rs index cd3c50230d89..6520598db14f 100644 --- a/crates/biome_markdown_factory/src/generated/node_factory.rs +++ b/crates/biome_markdown_factory/src/generated/node_factory.rs @@ -430,23 +430,28 @@ pub fn md_quote(prefix: MdQuotePrefix, content: MdBlockList) -> MdQuote { ], )) } -pub fn md_quote_prefix(marker_token: SyntaxToken) -> MdQuotePrefixBuilder { +pub fn md_quote_indent(md_quote_pre_marker_indent_token: SyntaxToken) -> MdQuoteIndent { + MdQuoteIndent::unwrap_cast(SyntaxNode::new_detached( + MarkdownSyntaxKind::MD_QUOTE_INDENT, + [Some(SyntaxElement::Token(md_quote_pre_marker_indent_token))], + )) +} +pub fn md_quote_prefix( + pre_marker_indent: MdQuoteIndentList, + marker_token: SyntaxToken, +) -> MdQuotePrefixBuilder { MdQuotePrefixBuilder { + pre_marker_indent, marker_token, - pre_marker_indent_token: None, post_marker_space_token: None, } } pub struct MdQuotePrefixBuilder { + pre_marker_indent: MdQuoteIndentList, marker_token: SyntaxToken, - pre_marker_indent_token: Option, post_marker_space_token: Option, } impl MdQuotePrefixBuilder { - pub fn with_pre_marker_indent_token(mut self, pre_marker_indent_token: SyntaxToken) -> Self { - self.pre_marker_indent_token = Some(pre_marker_indent_token); - self - } pub fn with_post_marker_space_token(mut self, post_marker_space_token: SyntaxToken) -> Self { self.post_marker_space_token = Some(post_marker_space_token); self @@ -455,8 +460,7 @@ impl MdQuotePrefixBuilder { MdQuotePrefix::unwrap_cast(SyntaxNode::new_detached( MarkdownSyntaxKind::MD_QUOTE_PREFIX, [ - self.pre_marker_indent_token - .map(|token| SyntaxElement::Token(token)), + Some(SyntaxElement::Node(self.pre_marker_indent.into_syntax())), Some(SyntaxElement::Token(self.marker_token)), self.post_marker_space_token .map(|token| SyntaxElement::Token(token)), @@ -641,6 +645,18 @@ where .map(|item| Some(item.into_syntax().into())), )) } +pub fn md_quote_indent_list(items: I) -> MdQuoteIndentList +where + I: IntoIterator, + I::IntoIter: ExactSizeIterator, +{ + MdQuoteIndentList::unwrap_cast(SyntaxNode::new_detached( + MarkdownSyntaxKind::MD_QUOTE_INDENT_LIST, + items + .into_iter() + .map(|item| Some(item.into_syntax().into())), + )) +} pub fn md_bogus(slots: I) -> MdBogus where I: IntoIterator>, diff --git a/crates/biome_markdown_factory/src/generated/syntax_factory.rs b/crates/biome_markdown_factory/src/generated/syntax_factory.rs index 6c8f82426cc2..079fcdff278b 100644 --- a/crates/biome_markdown_factory/src/generated/syntax_factory.rs +++ b/crates/biome_markdown_factory/src/generated/syntax_factory.rs @@ -791,12 +791,31 @@ impl SyntaxFactory for MarkdownSyntaxFactory { } slots.into_node(MD_QUOTE, children) } + MD_QUOTE_INDENT => { + let mut elements = (&children).into_iter(); + let mut slots: RawNodeSlots<1usize> = RawNodeSlots::default(); + let mut current_element = elements.next(); + if let Some(element) = ¤t_element + && element.kind() == MD_QUOTE_PRE_MARKER_INDENT + { + slots.mark_present(); + current_element = elements.next(); + } + slots.next_slot(); + if current_element.is_some() { + return RawSyntaxNode::new( + MD_QUOTE_INDENT.to_bogus(), + children.into_iter().map(Some), + ); + } + slots.into_node(MD_QUOTE_INDENT, children) + } MD_QUOTE_PREFIX => { let mut elements = (&children).into_iter(); let mut slots: RawNodeSlots<3usize> = RawNodeSlots::default(); let mut current_element = elements.next(); if let Some(element) = ¤t_element - && element.kind() == MD_QUOTE_PRE_MARKER_INDENT + && MdQuoteIndentList::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); @@ -1034,6 +1053,9 @@ impl SyntaxFactory for MarkdownSyntaxFactory { MD_INLINE_ITEM_LIST => { Self::make_node_list_syntax(kind, children, AnyMdInline::can_cast) } + MD_QUOTE_INDENT_LIST => { + Self::make_node_list_syntax(kind, children, MdQuoteIndent::can_cast) + } _ => unreachable!("Is {:?} a token?", kind), } } diff --git a/crates/biome_markdown_formatter/src/generated.rs b/crates/biome_markdown_formatter/src/generated.rs index f3ebbc6d6cb2..c0eddac2ddc4 100644 --- a/crates/biome_markdown_formatter/src/generated.rs +++ b/crates/biome_markdown_formatter/src/generated.rs @@ -1025,6 +1025,44 @@ impl IntoFormat for biome_markdown_syntax::MdQuote { ) } } +impl FormatRule + for crate::markdown::auxiliary::quote_indent::FormatMdQuoteIndent +{ + type Context = MarkdownFormatContext; + #[inline(always)] + fn fmt( + &self, + node: &biome_markdown_syntax::MdQuoteIndent, + f: &mut MarkdownFormatter, + ) -> FormatResult<()> { + FormatNodeRule::::fmt(self, node, f) + } +} +impl AsFormat for biome_markdown_syntax::MdQuoteIndent { + type Format<'a> = FormatRefWithRule< + 'a, + biome_markdown_syntax::MdQuoteIndent, + crate::markdown::auxiliary::quote_indent::FormatMdQuoteIndent, + >; + fn format(&self) -> Self::Format<'_> { + FormatRefWithRule::new( + self, + crate::markdown::auxiliary::quote_indent::FormatMdQuoteIndent::default(), + ) + } +} +impl IntoFormat for biome_markdown_syntax::MdQuoteIndent { + type Format = FormatOwnedWithRule< + biome_markdown_syntax::MdQuoteIndent, + crate::markdown::auxiliary::quote_indent::FormatMdQuoteIndent, + >; + fn into_format(self) -> Self::Format { + FormatOwnedWithRule::new( + self, + crate::markdown::auxiliary::quote_indent::FormatMdQuoteIndent::default(), + ) + } +} impl FormatRule for crate::markdown::auxiliary::quote_prefix::FormatMdQuotePrefix { @@ -1454,6 +1492,31 @@ impl IntoFormat for biome_markdown_syntax::MdInlineItemLi ) } } +impl AsFormat for biome_markdown_syntax::MdQuoteIndentList { + type Format<'a> = FormatRefWithRule< + 'a, + biome_markdown_syntax::MdQuoteIndentList, + crate::markdown::lists::quote_indent_list::FormatMdQuoteIndentList, + >; + fn format(&self) -> Self::Format<'_> { + FormatRefWithRule::new( + self, + crate::markdown::lists::quote_indent_list::FormatMdQuoteIndentList::default(), + ) + } +} +impl IntoFormat for biome_markdown_syntax::MdQuoteIndentList { + type Format = FormatOwnedWithRule< + biome_markdown_syntax::MdQuoteIndentList, + crate::markdown::lists::quote_indent_list::FormatMdQuoteIndentList, + >; + fn into_format(self) -> Self::Format { + FormatOwnedWithRule::new( + self, + crate::markdown::lists::quote_indent_list::FormatMdQuoteIndentList::default(), + ) + } +} impl FormatRule for crate::markdown::bogus::bogus::FormatMdBogus { type Context = MarkdownFormatContext; #[inline(always)] diff --git a/crates/biome_markdown_formatter/src/markdown/auxiliary/mod.rs b/crates/biome_markdown_formatter/src/markdown/auxiliary/mod.rs index 9258fe63a718..853b9be651c9 100644 --- a/crates/biome_markdown_formatter/src/markdown/auxiliary/mod.rs +++ b/crates/biome_markdown_formatter/src/markdown/auxiliary/mod.rs @@ -27,6 +27,7 @@ pub(crate) mod newline; pub(crate) mod ordered_list_item; pub(crate) mod paragraph; pub(crate) mod quote; +pub(crate) mod quote_indent; pub(crate) mod quote_prefix; pub(crate) mod reference_image; pub(crate) mod reference_link; diff --git a/crates/biome_markdown_formatter/src/markdown/auxiliary/quote_indent.rs b/crates/biome_markdown_formatter/src/markdown/auxiliary/quote_indent.rs new file mode 100644 index 000000000000..dcaed27b0f40 --- /dev/null +++ b/crates/biome_markdown_formatter/src/markdown/auxiliary/quote_indent.rs @@ -0,0 +1,10 @@ +use crate::prelude::*; +use biome_markdown_syntax::MdQuoteIndent; +use biome_rowan::AstNode; +#[derive(Debug, Clone, Default)] +pub(crate) struct FormatMdQuoteIndent; +impl FormatNodeRule for FormatMdQuoteIndent { + fn fmt_fields(&self, node: &MdQuoteIndent, f: &mut MarkdownFormatter) -> FormatResult<()> { + format_verbatim_node(node.syntax()).fmt(f) + } +} diff --git a/crates/biome_markdown_formatter/src/markdown/lists/mod.rs b/crates/biome_markdown_formatter/src/markdown/lists/mod.rs index 0c12a0f97a00..5e7f4656a05f 100644 --- a/crates/biome_markdown_formatter/src/markdown/lists/mod.rs +++ b/crates/biome_markdown_formatter/src/markdown/lists/mod.rs @@ -5,3 +5,4 @@ pub(crate) mod bullet_list; pub(crate) mod code_name_list; pub(crate) mod hash_list; pub(crate) mod inline_item_list; +pub(crate) mod quote_indent_list; diff --git a/crates/biome_markdown_formatter/src/markdown/lists/quote_indent_list.rs b/crates/biome_markdown_formatter/src/markdown/lists/quote_indent_list.rs new file mode 100644 index 000000000000..2099db44da6c --- /dev/null +++ b/crates/biome_markdown_formatter/src/markdown/lists/quote_indent_list.rs @@ -0,0 +1,10 @@ +use crate::prelude::*; +use biome_markdown_syntax::MdQuoteIndentList; +#[derive(Debug, Clone, Default)] +pub(crate) struct FormatMdQuoteIndentList; +impl FormatRule for FormatMdQuoteIndentList { + type Context = MarkdownFormatContext; + fn fmt(&self, node: &MdQuoteIndentList, f: &mut MarkdownFormatter) -> FormatResult<()> { + f.join().entries(node.iter().formatted()).finish() + } +} diff --git a/crates/biome_markdown_parser/src/syntax/mod.rs b/crates/biome_markdown_parser/src/syntax/mod.rs index cb3769de06c7..53a789142620 100644 --- a/crates/biome_markdown_parser/src/syntax/mod.rs +++ b/crates/biome_markdown_parser/src/syntax/mod.rs @@ -69,6 +69,9 @@ pub(crate) const MAX_LINK_DESTINATION_PAREN_DEPTH: i32 = 32; const INDENT_CODE_BLOCK_SPACES: usize = 4; /// Tabs advance to the next 4-space tab stop in CommonMark parsing. const TAB_STOP_SPACES: usize = 4; +/// CommonMark allows 0-3 spaces of optional indentation before block-level +/// markers (blockquotes §5.1, list items §5.2/§5.3, ATX headings §4.2, etc.). +pub(crate) const MAX_BLOCK_PREFIX_INDENT: usize = 3; pub(crate) fn parse_document(p: &mut MarkdownParser) { let m = p.start(); diff --git a/crates/biome_markdown_parser/src/syntax/quote.rs b/crates/biome_markdown_parser/src/syntax/quote.rs index 50196eb44fe3..49ee3043bb18 100644 --- a/crates/biome_markdown_parser/src/syntax/quote.rs +++ b/crates/biome_markdown_parser/src/syntax/quote.rs @@ -41,7 +41,9 @@ use biome_parser::prelude::ParsedSyntax::{self, *}; use crate::MarkdownParser; use crate::syntax::parse_any_block_with_indent_code_policy; use crate::syntax::parse_error::quote_nesting_too_deep; -use crate::syntax::{INDENT_CODE_BLOCK_SPACES, TAB_STOP_SPACES, is_paragraph_like}; +use crate::syntax::{ + INDENT_CODE_BLOCK_SPACES, MAX_BLOCK_PREFIX_INDENT, TAB_STOP_SPACES, is_paragraph_like, +}; /// Check if we're at the start of a block quote (`>`). pub(crate) fn at_quote(p: &mut MarkdownParser) -> bool { @@ -55,10 +57,10 @@ pub(crate) fn at_quote(p: &mut MarkdownParser) -> bool { // Treat virtual line start as column 0. indent = 0; } - if indent > 3 { + if indent > MAX_BLOCK_PREFIX_INDENT { return false; } - p.skip_line_indent(3); + p.skip_line_indent(MAX_BLOCK_PREFIX_INDENT); p.at(T![>]) }) } @@ -80,7 +82,7 @@ pub(crate) fn parse_quote(p: &mut MarkdownParser) -> ParsedSyntax { let range = p.cur_range(); p.error(quote_nesting_too_deep(p, range, max_nesting_depth)); p.state_mut().quote_depth_exceeded = true; - p.skip_line_indent(3); + p.skip_line_indent(MAX_BLOCK_PREFIX_INDENT); if p.at(T![>]) { p.parse_as_skipped_trivia_tokens(|p| p.bump(T![>])); } else if p.at(MD_TEXTUAL_LITERAL) && p.cur_text() == ">" { @@ -127,8 +129,6 @@ fn emit_quote_prefix_node(p: &mut MarkdownParser) -> bool { /// /// Returns whether a post-marker separator was consumed. fn emit_quote_prefix_tokens(p: &mut MarkdownParser, use_virtual_line_start: bool) -> Option { - // TODO: Emit MD_QUOTE_PRE_MARKER_INDENT directly instead of skipping indent trivia. - // This is intentionally deferred from Step 1b to keep parser migration scope narrow. let saved_virtual = if use_virtual_line_start { let prev = p.state().virtual_line_start; p.state_mut().virtual_line_start = Some(p.cur_range().start()); @@ -136,7 +136,31 @@ fn emit_quote_prefix_tokens(p: &mut MarkdownParser, use_virtual_line_start: bool } else { None }; - p.skip_line_indent(3); + + // Direct bounded scan (0-3 cols per CommonMark §5.1): simpler than ParseNodeList + // here because we immediately validate `>` and keep this path no-recovery. + let indent_list_m = p.start(); + let mut consumed = 0usize; + while p.at(MD_TEXTUAL_LITERAL) { + let text = p.cur_text(); + if text.is_empty() || !text.chars().all(|c| c == ' ' || c == '\t') { + break; + } + // Tabs expand to tab-stop width (CommonMark §2.2). + let indent: usize = text + .chars() + .map(|c| if c == '\t' { TAB_STOP_SPACES } else { 1 }) + .sum(); + if consumed + indent > MAX_BLOCK_PREFIX_INDENT { + break; + } + consumed += indent; + let indent_m = p.start(); + p.bump_remap(MD_QUOTE_PRE_MARKER_INDENT); + indent_m.complete(p, MD_QUOTE_INDENT); + } + indent_list_m.complete(p, MD_QUOTE_INDENT_LIST); + if let Some(prev) = saved_virtual { p.state_mut().virtual_line_start = prev; } @@ -311,7 +335,7 @@ pub(crate) fn line_has_quote_prefix_at_current(p: &MarkdownParser, depth: usize) } _ => break, } - if indent > 3 { + if indent > MAX_BLOCK_PREFIX_INDENT { return false; } } diff --git a/crates/biome_markdown_parser/tests/md_test_suite/error/quote_nesting_too_deep.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/error/quote_nesting_too_deep.md.snap index 2b0eea730d20..b5cf601cc283 100644 --- a/crates/biome_markdown_parser/tests/md_test_suite/error/quote_nesting_too_deep.md.snap +++ b/crates/biome_markdown_parser/tests/md_test_suite/error/quote_nesting_too_deep.md.snap @@ -19,112 +19,112 @@ MdDocument { value: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@0..1 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@1..2 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@2..3 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@3..4 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@4..5 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@5..6 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@6..7 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@7..8 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@8..9 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@9..10 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@10..11 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@11..12 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@12..13 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@13..14 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@14..15 ">" [] [], post_marker_space_token: missing (optional), }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@15..16 ">" [] [], post_marker_space_token: missing (optional), }, @@ -186,601 +186,601 @@ MdDocument { 1: MD_BLOCK_LIST@0..111 0: MD_QUOTE@0..100 0: MD_QUOTE_PREFIX@0..1 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@0..0 1: R_ANGLE@0..1 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@1..100 0: MD_QUOTE@1..100 0: MD_QUOTE_PREFIX@1..2 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@1..1 1: R_ANGLE@1..2 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@2..100 0: MD_QUOTE@2..100 0: MD_QUOTE_PREFIX@2..3 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@2..2 1: R_ANGLE@2..3 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@3..100 0: MD_QUOTE@3..100 0: MD_QUOTE_PREFIX@3..4 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@3..3 1: R_ANGLE@3..4 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@4..100 0: MD_QUOTE@4..100 0: MD_QUOTE_PREFIX@4..5 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@4..4 1: R_ANGLE@4..5 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@5..100 0: MD_QUOTE@5..100 0: MD_QUOTE_PREFIX@5..6 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@5..5 1: R_ANGLE@5..6 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@6..100 0: MD_QUOTE@6..100 0: MD_QUOTE_PREFIX@6..7 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@6..6 1: R_ANGLE@6..7 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@7..100 0: MD_QUOTE@7..100 0: MD_QUOTE_PREFIX@7..8 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@7..7 1: R_ANGLE@7..8 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@8..100 0: MD_QUOTE@8..100 0: MD_QUOTE_PREFIX@8..9 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@8..8 1: R_ANGLE@8..9 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@9..100 0: MD_QUOTE@9..100 0: MD_QUOTE_PREFIX@9..10 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@9..9 1: R_ANGLE@9..10 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@10..100 0: MD_QUOTE@10..100 0: MD_QUOTE_PREFIX@10..11 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@10..10 1: R_ANGLE@10..11 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@11..100 0: MD_QUOTE@11..100 0: MD_QUOTE_PREFIX@11..12 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@11..11 1: R_ANGLE@11..12 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@12..100 0: MD_QUOTE@12..100 0: MD_QUOTE_PREFIX@12..13 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@12..12 1: R_ANGLE@12..13 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@13..100 0: MD_QUOTE@13..100 0: MD_QUOTE_PREFIX@13..14 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@13..13 1: R_ANGLE@13..14 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@14..100 0: MD_QUOTE@14..100 0: MD_QUOTE_PREFIX@14..15 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@14..14 1: R_ANGLE@14..15 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@15..100 0: MD_QUOTE@15..100 0: MD_QUOTE_PREFIX@15..16 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@15..15 1: R_ANGLE@15..16 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@16..100 0: MD_QUOTE@16..100 0: MD_QUOTE_PREFIX@16..17 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@16..16 1: R_ANGLE@16..17 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@17..100 0: MD_QUOTE@17..100 0: MD_QUOTE_PREFIX@17..18 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@17..17 1: R_ANGLE@17..18 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@18..100 0: MD_QUOTE@18..100 0: MD_QUOTE_PREFIX@18..19 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@18..18 1: R_ANGLE@18..19 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@19..100 0: MD_QUOTE@19..100 0: MD_QUOTE_PREFIX@19..20 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@19..19 1: R_ANGLE@19..20 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@20..100 0: MD_QUOTE@20..100 0: MD_QUOTE_PREFIX@20..21 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@20..20 1: R_ANGLE@20..21 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@21..100 0: MD_QUOTE@21..100 0: MD_QUOTE_PREFIX@21..22 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@21..21 1: R_ANGLE@21..22 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@22..100 0: MD_QUOTE@22..100 0: MD_QUOTE_PREFIX@22..23 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@22..22 1: R_ANGLE@22..23 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@23..100 0: MD_QUOTE@23..100 0: MD_QUOTE_PREFIX@23..24 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@23..23 1: R_ANGLE@23..24 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@24..100 0: MD_QUOTE@24..100 0: MD_QUOTE_PREFIX@24..25 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@24..24 1: R_ANGLE@24..25 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@25..100 0: MD_QUOTE@25..100 0: MD_QUOTE_PREFIX@25..26 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@25..25 1: R_ANGLE@25..26 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@26..100 0: MD_QUOTE@26..100 0: MD_QUOTE_PREFIX@26..27 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@26..26 1: R_ANGLE@26..27 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@27..100 0: MD_QUOTE@27..100 0: MD_QUOTE_PREFIX@27..28 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@27..27 1: R_ANGLE@27..28 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@28..100 0: MD_QUOTE@28..100 0: MD_QUOTE_PREFIX@28..29 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@28..28 1: R_ANGLE@28..29 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@29..100 0: MD_QUOTE@29..100 0: MD_QUOTE_PREFIX@29..30 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@29..29 1: R_ANGLE@29..30 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@30..100 0: MD_QUOTE@30..100 0: MD_QUOTE_PREFIX@30..31 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@30..30 1: R_ANGLE@30..31 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@31..100 0: MD_QUOTE@31..100 0: MD_QUOTE_PREFIX@31..32 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@31..31 1: R_ANGLE@31..32 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@32..100 0: MD_QUOTE@32..100 0: MD_QUOTE_PREFIX@32..33 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@32..32 1: R_ANGLE@32..33 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@33..100 0: MD_QUOTE@33..100 0: MD_QUOTE_PREFIX@33..34 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@33..33 1: R_ANGLE@33..34 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@34..100 0: MD_QUOTE@34..100 0: MD_QUOTE_PREFIX@34..35 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@34..34 1: R_ANGLE@34..35 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@35..100 0: MD_QUOTE@35..100 0: MD_QUOTE_PREFIX@35..36 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@35..35 1: R_ANGLE@35..36 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@36..100 0: MD_QUOTE@36..100 0: MD_QUOTE_PREFIX@36..37 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@36..36 1: R_ANGLE@36..37 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@37..100 0: MD_QUOTE@37..100 0: MD_QUOTE_PREFIX@37..38 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@37..37 1: R_ANGLE@37..38 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@38..100 0: MD_QUOTE@38..100 0: MD_QUOTE_PREFIX@38..39 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@38..38 1: R_ANGLE@38..39 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@39..100 0: MD_QUOTE@39..100 0: MD_QUOTE_PREFIX@39..40 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@39..39 1: R_ANGLE@39..40 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@40..100 0: MD_QUOTE@40..100 0: MD_QUOTE_PREFIX@40..41 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@40..40 1: R_ANGLE@40..41 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@41..100 0: MD_QUOTE@41..100 0: MD_QUOTE_PREFIX@41..42 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@41..41 1: R_ANGLE@41..42 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@42..100 0: MD_QUOTE@42..100 0: MD_QUOTE_PREFIX@42..43 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@42..42 1: R_ANGLE@42..43 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@43..100 0: MD_QUOTE@43..100 0: MD_QUOTE_PREFIX@43..44 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@43..43 1: R_ANGLE@43..44 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@44..100 0: MD_QUOTE@44..100 0: MD_QUOTE_PREFIX@44..45 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@44..44 1: R_ANGLE@44..45 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@45..100 0: MD_QUOTE@45..100 0: MD_QUOTE_PREFIX@45..46 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@45..45 1: R_ANGLE@45..46 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@46..100 0: MD_QUOTE@46..100 0: MD_QUOTE_PREFIX@46..47 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@46..46 1: R_ANGLE@46..47 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@47..100 0: MD_QUOTE@47..100 0: MD_QUOTE_PREFIX@47..48 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@47..47 1: R_ANGLE@47..48 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@48..100 0: MD_QUOTE@48..100 0: MD_QUOTE_PREFIX@48..49 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@48..48 1: R_ANGLE@48..49 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@49..100 0: MD_QUOTE@49..100 0: MD_QUOTE_PREFIX@49..50 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@49..49 1: R_ANGLE@49..50 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@50..100 0: MD_QUOTE@50..100 0: MD_QUOTE_PREFIX@50..51 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@50..50 1: R_ANGLE@50..51 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@51..100 0: MD_QUOTE@51..100 0: MD_QUOTE_PREFIX@51..52 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@51..51 1: R_ANGLE@51..52 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@52..100 0: MD_QUOTE@52..100 0: MD_QUOTE_PREFIX@52..53 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@52..52 1: R_ANGLE@52..53 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@53..100 0: MD_QUOTE@53..100 0: MD_QUOTE_PREFIX@53..54 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@53..53 1: R_ANGLE@53..54 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@54..100 0: MD_QUOTE@54..100 0: MD_QUOTE_PREFIX@54..55 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@54..54 1: R_ANGLE@54..55 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@55..100 0: MD_QUOTE@55..100 0: MD_QUOTE_PREFIX@55..56 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@55..55 1: R_ANGLE@55..56 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@56..100 0: MD_QUOTE@56..100 0: MD_QUOTE_PREFIX@56..57 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@56..56 1: R_ANGLE@56..57 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@57..100 0: MD_QUOTE@57..100 0: MD_QUOTE_PREFIX@57..58 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@57..57 1: R_ANGLE@57..58 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@58..100 0: MD_QUOTE@58..100 0: MD_QUOTE_PREFIX@58..59 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@58..58 1: R_ANGLE@58..59 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@59..100 0: MD_QUOTE@59..100 0: MD_QUOTE_PREFIX@59..60 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@59..59 1: R_ANGLE@59..60 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@60..100 0: MD_QUOTE@60..100 0: MD_QUOTE_PREFIX@60..61 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@60..60 1: R_ANGLE@60..61 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@61..100 0: MD_QUOTE@61..100 0: MD_QUOTE_PREFIX@61..62 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@61..61 1: R_ANGLE@61..62 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@62..100 0: MD_QUOTE@62..100 0: MD_QUOTE_PREFIX@62..63 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@62..62 1: R_ANGLE@62..63 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@63..100 0: MD_QUOTE@63..100 0: MD_QUOTE_PREFIX@63..64 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@63..63 1: R_ANGLE@63..64 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@64..100 0: MD_QUOTE@64..100 0: MD_QUOTE_PREFIX@64..65 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@64..64 1: R_ANGLE@64..65 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@65..100 0: MD_QUOTE@65..100 0: MD_QUOTE_PREFIX@65..66 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@65..65 1: R_ANGLE@65..66 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@66..100 0: MD_QUOTE@66..100 0: MD_QUOTE_PREFIX@66..67 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@66..66 1: R_ANGLE@66..67 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@67..100 0: MD_QUOTE@67..100 0: MD_QUOTE_PREFIX@67..68 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@67..67 1: R_ANGLE@67..68 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@68..100 0: MD_QUOTE@68..100 0: MD_QUOTE_PREFIX@68..69 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@68..68 1: R_ANGLE@68..69 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@69..100 0: MD_QUOTE@69..100 0: MD_QUOTE_PREFIX@69..70 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@69..69 1: R_ANGLE@69..70 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@70..100 0: MD_QUOTE@70..100 0: MD_QUOTE_PREFIX@70..71 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@70..70 1: R_ANGLE@70..71 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@71..100 0: MD_QUOTE@71..100 0: MD_QUOTE_PREFIX@71..72 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@71..71 1: R_ANGLE@71..72 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@72..100 0: MD_QUOTE@72..100 0: MD_QUOTE_PREFIX@72..73 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@72..72 1: R_ANGLE@72..73 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@73..100 0: MD_QUOTE@73..100 0: MD_QUOTE_PREFIX@73..74 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@73..73 1: R_ANGLE@73..74 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@74..100 0: MD_QUOTE@74..100 0: MD_QUOTE_PREFIX@74..75 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@74..74 1: R_ANGLE@74..75 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@75..100 0: MD_QUOTE@75..100 0: MD_QUOTE_PREFIX@75..76 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@75..75 1: R_ANGLE@75..76 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@76..100 0: MD_QUOTE@76..100 0: MD_QUOTE_PREFIX@76..77 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@76..76 1: R_ANGLE@76..77 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@77..100 0: MD_QUOTE@77..100 0: MD_QUOTE_PREFIX@77..78 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@77..77 1: R_ANGLE@77..78 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@78..100 0: MD_QUOTE@78..100 0: MD_QUOTE_PREFIX@78..79 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@78..78 1: R_ANGLE@78..79 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@79..100 0: MD_QUOTE@79..100 0: MD_QUOTE_PREFIX@79..80 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@79..79 1: R_ANGLE@79..80 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@80..100 0: MD_QUOTE@80..100 0: MD_QUOTE_PREFIX@80..81 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@80..80 1: R_ANGLE@80..81 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@81..100 0: MD_QUOTE@81..100 0: MD_QUOTE_PREFIX@81..82 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@81..81 1: R_ANGLE@81..82 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@82..100 0: MD_QUOTE@82..100 0: MD_QUOTE_PREFIX@82..83 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@82..82 1: R_ANGLE@82..83 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@83..100 0: MD_QUOTE@83..100 0: MD_QUOTE_PREFIX@83..84 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@83..83 1: R_ANGLE@83..84 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@84..100 0: MD_QUOTE@84..100 0: MD_QUOTE_PREFIX@84..85 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@84..84 1: R_ANGLE@84..85 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@85..100 0: MD_QUOTE@85..100 0: MD_QUOTE_PREFIX@85..86 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@85..85 1: R_ANGLE@85..86 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@86..100 0: MD_QUOTE@86..100 0: MD_QUOTE_PREFIX@86..87 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@86..86 1: R_ANGLE@86..87 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@87..100 0: MD_QUOTE@87..100 0: MD_QUOTE_PREFIX@87..88 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@87..87 1: R_ANGLE@87..88 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@88..100 0: MD_QUOTE@88..100 0: MD_QUOTE_PREFIX@88..89 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@88..88 1: R_ANGLE@88..89 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@89..100 0: MD_QUOTE@89..100 0: MD_QUOTE_PREFIX@89..90 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@89..89 1: R_ANGLE@89..90 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@90..100 0: MD_QUOTE@90..100 0: MD_QUOTE_PREFIX@90..91 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@90..90 1: R_ANGLE@90..91 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@91..100 0: MD_QUOTE@91..100 0: MD_QUOTE_PREFIX@91..92 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@91..91 1: R_ANGLE@91..92 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@92..100 0: MD_QUOTE@92..100 0: MD_QUOTE_PREFIX@92..93 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@92..92 1: R_ANGLE@92..93 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@93..100 0: MD_QUOTE@93..100 0: MD_QUOTE_PREFIX@93..94 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@93..93 1: R_ANGLE@93..94 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@94..100 0: MD_QUOTE@94..100 0: MD_QUOTE_PREFIX@94..95 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@94..94 1: R_ANGLE@94..95 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@95..100 0: MD_QUOTE@95..100 0: MD_QUOTE_PREFIX@95..96 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@95..95 1: R_ANGLE@95..96 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@96..100 0: MD_QUOTE@96..100 0: MD_QUOTE_PREFIX@96..97 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@96..96 1: R_ANGLE@96..97 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@97..100 0: MD_QUOTE@97..100 0: MD_QUOTE_PREFIX@97..98 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@97..97 1: R_ANGLE@97..98 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@98..100 0: MD_QUOTE@98..100 0: MD_QUOTE_PREFIX@98..99 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@98..98 1: R_ANGLE@98..99 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@99..100 0: MD_QUOTE@99..100 0: MD_QUOTE_PREFIX@99..100 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@99..99 1: R_ANGLE@99..100 ">" [] [] 2: (empty) 1: MD_BLOCK_LIST@100..100 diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/block_quote.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/block_quote.md.snap index 06c80d164b92..f6790a57aa02 100644 --- a/crates/biome_markdown_parser/tests/md_test_suite/ok/block_quote.md.snap +++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/block_quote.md.snap @@ -22,7 +22,7 @@ MdDocument { value: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@0..1 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@1..2 " " [] [], }, @@ -36,7 +36,7 @@ MdDocument { value_token: MD_TEXTUAL_LITERAL@17..18 "\n" [] [], }, MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@18..19 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@19..20 " " [] [], }, @@ -56,7 +56,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@39..40 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@40..41 " " [] [], }, @@ -87,7 +87,7 @@ MdDocument { 1: MD_BLOCK_LIST@0..61 0: MD_QUOTE@0..38 0: MD_QUOTE_PREFIX@0..2 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@0..0 1: R_ANGLE@0..1 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@1..2 " " [] [] 1: MD_BLOCK_LIST@2..38 @@ -98,7 +98,7 @@ MdDocument { 1: MD_TEXTUAL@17..18 0: MD_TEXTUAL_LITERAL@17..18 "\n" [] [] 2: MD_QUOTE_PREFIX@18..20 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@18..18 1: R_ANGLE@18..19 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@19..20 " " [] [] 3: MD_TEXTUAL@20..37 @@ -110,7 +110,7 @@ MdDocument { 0: NEWLINE@38..39 "\n" [] [] 2: MD_QUOTE@39..61 0: MD_QUOTE_PREFIX@39..41 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@39..39 1: R_ANGLE@39..40 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@40..41 " " [] [] 1: MD_BLOCK_LIST@41..61 diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/block_quote_grouping.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/block_quote_grouping.md.snap index 339d50b91c3d..8dce5aa584a4 100644 --- a/crates/biome_markdown_parser/tests/md_test_suite/ok/block_quote_grouping.md.snap +++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/block_quote_grouping.md.snap @@ -25,7 +25,7 @@ MdDocument { value: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@0..1 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@1..2 " " [] [], }, @@ -39,7 +39,7 @@ MdDocument { value_token: MD_TEXTUAL_LITERAL@3..4 "\n" [] [], }, MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@4..5 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@5..6 " " [] [], }, @@ -59,7 +59,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@9..10 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@10..11 " " [] [], }, @@ -73,7 +73,7 @@ MdDocument { value_token: MD_TEXTUAL_LITERAL@13..14 "\n" [] [], }, MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@14..15 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@15..16 " " [] [], }, @@ -93,14 +93,14 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@19..20 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@20..21 " " [] [], }, content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@21..22 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@22..23 " " [] [], }, @@ -133,7 +133,7 @@ MdDocument { 1: MD_BLOCK_LIST@0..30 0: MD_QUOTE@0..8 0: MD_QUOTE_PREFIX@0..2 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@0..0 1: R_ANGLE@0..1 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@1..2 " " [] [] 1: MD_BLOCK_LIST@2..8 @@ -144,7 +144,7 @@ MdDocument { 1: MD_TEXTUAL@3..4 0: MD_TEXTUAL_LITERAL@3..4 "\n" [] [] 2: MD_QUOTE_PREFIX@4..6 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@4..4 1: R_ANGLE@4..5 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@5..6 " " [] [] 3: MD_TEXTUAL@6..7 @@ -156,7 +156,7 @@ MdDocument { 0: NEWLINE@8..9 "\n" [] [] 2: MD_QUOTE@9..18 0: MD_QUOTE_PREFIX@9..11 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@9..9 1: R_ANGLE@9..10 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@10..11 " " [] [] 1: MD_BLOCK_LIST@11..18 @@ -167,7 +167,7 @@ MdDocument { 1: MD_TEXTUAL@13..14 0: MD_TEXTUAL_LITERAL@13..14 "\n" [] [] 2: MD_QUOTE_PREFIX@14..16 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@14..14 1: R_ANGLE@14..15 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@15..16 " " [] [] 3: MD_TEXTUAL@16..17 @@ -179,13 +179,13 @@ MdDocument { 0: NEWLINE@18..19 "\n" [] [] 4: MD_QUOTE@19..30 0: MD_QUOTE_PREFIX@19..21 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@19..19 1: R_ANGLE@19..20 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@20..21 " " [] [] 1: MD_BLOCK_LIST@21..30 0: MD_QUOTE@21..30 0: MD_QUOTE_PREFIX@21..23 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@21..21 1: R_ANGLE@21..22 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@22..23 " " [] [] 1: MD_BLOCK_LIST@23..30 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 index 948c18d871bf..76dc39d7bbe9 100644 --- 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 @@ -49,7 +49,7 @@ MdDocument { value: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@0..1 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@1..2 " " [] [], }, @@ -78,7 +78,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@41..42 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@42..43 " " [] [], }, @@ -98,7 +98,7 @@ MdDocument { value_token: MD_TEXTUAL_LITERAL@79..80 "\n" [] [], }, MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@80..81 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@81..82 " " [] [], }, @@ -118,7 +118,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@109..110 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@110..111 " " [] [], }, @@ -159,7 +159,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@174..175 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@175..176 " " [] [], }, @@ -201,7 +201,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@248..249 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@249..250 " " [] [], }, @@ -236,7 +236,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@306..307 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@307..308 " " [] [], }, @@ -279,7 +279,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@375..376 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@376..377 " " [] [], }, @@ -321,7 +321,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@430..431 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@431..432 " " [] [], }, @@ -350,7 +350,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@473..474 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@474..475 " " [] [], }, @@ -387,7 +387,7 @@ MdDocument { 1: MD_BLOCK_LIST@0..545 0: MD_QUOTE@0..40 0: MD_QUOTE_PREFIX@0..2 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@0..0 1: R_ANGLE@0..1 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@1..2 " " [] [] 1: MD_BLOCK_LIST@2..40 @@ -406,7 +406,7 @@ MdDocument { 0: NEWLINE@40..41 "\n" [] [] 2: MD_QUOTE@41..108 0: MD_QUOTE_PREFIX@41..43 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@41..41 1: R_ANGLE@41..42 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@42..43 " " [] [] 1: MD_BLOCK_LIST@43..108 @@ -421,7 +421,7 @@ MdDocument { 3: MD_TEXTUAL@79..80 0: MD_TEXTUAL_LITERAL@79..80 "\n" [] [] 4: MD_QUOTE_PREFIX@80..82 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@80..80 1: R_ANGLE@80..81 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@81..82 " " [] [] 5: MD_TEXTUAL@82..107 @@ -433,7 +433,7 @@ MdDocument { 0: NEWLINE@108..109 "\n" [] [] 4: MD_QUOTE@109..173 0: MD_QUOTE_PREFIX@109..111 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@109..109 1: R_ANGLE@109..110 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@110..111 " " [] [] 1: MD_BLOCK_LIST@111..173 @@ -460,7 +460,7 @@ MdDocument { 0: NEWLINE@173..174 "\n" [] [] 6: MD_QUOTE@174..205 0: MD_QUOTE_PREFIX@174..176 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@174..174 1: R_ANGLE@174..175 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@175..176 " " [] [] 1: MD_BLOCK_LIST@176..205 @@ -487,7 +487,7 @@ MdDocument { 0: NEWLINE@247..248 "\n" [] [] 10: MD_QUOTE@248..301 0: MD_QUOTE_PREFIX@248..250 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@248..248 1: R_ANGLE@248..249 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@249..250 " " [] [] 1: MD_BLOCK_LIST@250..301 @@ -510,7 +510,7 @@ MdDocument { 0: NEWLINE@305..306 "\n" [] [] 14: MD_QUOTE@306..334 0: MD_QUOTE_PREFIX@306..308 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@306..306 1: R_ANGLE@306..307 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@307..308 " " [] [] 1: MD_BLOCK_LIST@308..334 @@ -537,7 +537,7 @@ MdDocument { 0: NEWLINE@374..375 "\n" [] [] 17: MD_QUOTE@375..410 0: MD_QUOTE_PREFIX@375..377 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@375..375 1: R_ANGLE@375..376 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@376..377 " " [] [] 1: MD_BLOCK_LIST@377..410 @@ -565,7 +565,7 @@ MdDocument { 0: NEWLINE@429..430 "\n" [] [] 21: MD_QUOTE@430..468 0: MD_QUOTE_PREFIX@430..432 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@430..430 1: R_ANGLE@430..431 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@431..432 " " [] [] 1: MD_BLOCK_LIST@432..468 @@ -584,7 +584,7 @@ MdDocument { 0: NEWLINE@472..473 "\n" [] [] 25: MD_QUOTE@473..545 0: MD_QUOTE_PREFIX@473..475 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@473..473 1: R_ANGLE@473..474 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@474..475 " " [] [] 1: MD_BLOCK_LIST@475..545 diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/list_continuation_edge_cases.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/list_continuation_edge_cases.md.snap index a9fd5d82b107..965e5117a8df 100644 --- a/crates/biome_markdown_parser/tests/md_test_suite/ok/list_continuation_edge_cases.md.snap +++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/list_continuation_edge_cases.md.snap @@ -85,7 +85,7 @@ MdDocument { content: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@46..48 ">" [Skipped(" ")] [], post_marker_space_token: missing (optional), }, @@ -102,16 +102,30 @@ MdDocument { hard_line: missing (optional), }, MdQuotePrefix { - pre_marker_indent_token: missing (optional), - marker_token: R_ANGLE@61..64 ">" [Skipped(" "), Skipped(" ")] [], + pre_marker_indent: MdQuoteIndentList [ + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@61..62 " " [] [], + }, + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@62..63 " " [] [], + }, + ], + marker_token: R_ANGLE@63..64 ">" [] [], post_marker_space_token: missing (optional), }, MdNewline { value_token: NEWLINE@64..65 "\n" [] [], }, MdQuotePrefix { - pre_marker_indent_token: missing (optional), - marker_token: R_ANGLE@65..68 ">" [Skipped(" "), Skipped(" ")] [], + pre_marker_indent: MdQuoteIndentList [ + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@65..66 " " [] [], + }, + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@66..67 " " [] [], + }, + ], + marker_token: R_ANGLE@67..68 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@68..69 " " [] [], }, MdParagraph { @@ -436,7 +450,7 @@ MdDocument { 1: MD_BLOCK_LIST@46..91 0: MD_QUOTE@46..90 0: MD_QUOTE_PREFIX@46..48 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@46..46 1: R_ANGLE@46..48 ">" [Skipped(" ")] [] 2: (empty) 1: MD_BLOCK_LIST@48..90 @@ -448,14 +462,22 @@ MdDocument { 0: MD_TEXTUAL_LITERAL@60..61 "\n" [] [] 1: (empty) 1: MD_QUOTE_PREFIX@61..64 - 0: (empty) - 1: R_ANGLE@61..64 ">" [Skipped(" "), Skipped(" ")] [] + 0: MD_QUOTE_INDENT_LIST@61..63 + 0: MD_QUOTE_INDENT@61..62 + 0: MD_QUOTE_PRE_MARKER_INDENT@61..62 " " [] [] + 1: MD_QUOTE_INDENT@62..63 + 0: MD_QUOTE_PRE_MARKER_INDENT@62..63 " " [] [] + 1: R_ANGLE@63..64 ">" [] [] 2: (empty) 2: MD_NEWLINE@64..65 0: NEWLINE@64..65 "\n" [] [] 3: MD_QUOTE_PREFIX@65..69 - 0: (empty) - 1: R_ANGLE@65..68 ">" [Skipped(" "), Skipped(" ")] [] + 0: MD_QUOTE_INDENT_LIST@65..67 + 0: MD_QUOTE_INDENT@65..66 + 0: MD_QUOTE_PRE_MARKER_INDENT@65..66 " " [] [] + 1: MD_QUOTE_INDENT@66..67 + 0: MD_QUOTE_PRE_MARKER_INDENT@66..67 " " [] [] + 1: R_ANGLE@67..68 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@68..69 " " [] [] 4: MD_PARAGRAPH@69..90 0: MD_INLINE_ITEM_LIST@69..90 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 index b5f4a98e317e..c0763fe3b13a 100644 --- 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 @@ -23,7 +23,7 @@ MdDocument { value: MdBlockList [ MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@0..1 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@1..2 " " [] [], }, @@ -40,13 +40,13 @@ MdDocument { hard_line: missing (optional), }, MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@14..15 ">" [] [], post_marker_space_token: missing (optional), }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@15..16 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@16..17 " " [] [], }, @@ -63,18 +63,18 @@ MdDocument { hard_line: missing (optional), }, MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@30..31 ">" [] [], post_marker_space_token: missing (optional), }, MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@31..32 ">" [] [], post_marker_space_token: missing (optional), }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@32..33 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@33..34 " " [] [], }, @@ -101,7 +101,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@49..50 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@50..51 " " [] [], }, @@ -132,7 +132,7 @@ MdDocument { 1: MD_BLOCK_LIST@0..65 0: MD_QUOTE@0..48 0: MD_QUOTE_PREFIX@0..2 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@0..0 1: R_ANGLE@0..1 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@1..2 " " [] [] 1: MD_BLOCK_LIST@2..48 @@ -144,12 +144,12 @@ MdDocument { 0: MD_TEXTUAL_LITERAL@13..14 "\n" [] [] 1: (empty) 1: MD_QUOTE_PREFIX@14..15 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@14..14 1: R_ANGLE@14..15 ">" [] [] 2: (empty) 2: MD_QUOTE@15..48 0: MD_QUOTE_PREFIX@15..17 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@15..15 1: R_ANGLE@15..16 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@16..17 " " [] [] 1: MD_BLOCK_LIST@17..48 @@ -161,16 +161,16 @@ MdDocument { 0: MD_TEXTUAL_LITERAL@29..30 "\n" [] [] 1: (empty) 1: MD_QUOTE_PREFIX@30..31 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@30..30 1: R_ANGLE@30..31 ">" [] [] 2: (empty) 2: MD_QUOTE_PREFIX@31..32 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@31..31 1: R_ANGLE@31..32 ">" [] [] 2: (empty) 3: MD_QUOTE@32..48 0: MD_QUOTE_PREFIX@32..34 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@32..32 1: R_ANGLE@32..33 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@33..34 " " [] [] 1: MD_BLOCK_LIST@34..48 @@ -185,7 +185,7 @@ MdDocument { 0: NEWLINE@48..49 "\n" [] [] 2: MD_QUOTE@49..65 0: MD_QUOTE_PREFIX@49..51 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@49..49 1: R_ANGLE@49..50 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@50..51 " " [] [] 1: MD_BLOCK_LIST@51..65 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 index 8264c3d8a603..001299ce640d 100644 --- 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 @@ -112,7 +112,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@84..85 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@85..86 " " [] [], }, @@ -245,7 +245,7 @@ MdDocument { 1: (empty) 8: MD_QUOTE@84..103 0: MD_QUOTE_PREFIX@84..86 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@84..84 1: R_ANGLE@84..85 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@85..86 " " [] [] 1: MD_BLOCK_LIST@86..103 diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/quote_pre_marker_indent.md b/crates/biome_markdown_parser/tests/md_test_suite/ok/quote_pre_marker_indent.md new file mode 100644 index 000000000000..0a35fb663dda --- /dev/null +++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/quote_pre_marker_indent.md @@ -0,0 +1,9 @@ + > one space indent + + > two space indent + + > three space indent + + > > nested with outer indent + + > tab before marker \ No newline at end of file diff --git a/crates/biome_markdown_parser/tests/md_test_suite/ok/quote_pre_marker_indent.md.snap b/crates/biome_markdown_parser/tests/md_test_suite/ok/quote_pre_marker_indent.md.snap new file mode 100644 index 000000000000..3200ad246b0c --- /dev/null +++ b/crates/biome_markdown_parser/tests/md_test_suite/ok/quote_pre_marker_indent.md.snap @@ -0,0 +1,268 @@ +--- +source: crates/biome_markdown_parser/tests/spec_test.rs +expression: snapshot +--- + +## Input + +``` + > one space indent + + > two space indent + + > three space indent + + > > nested with outer indent + + > tab before marker +``` + + +## AST + +``` +MdDocument { + bom_token: missing (optional), + value: MdBlockList [ + MdQuote { + prefix: MdQuotePrefix { + pre_marker_indent: MdQuoteIndentList [ + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@0..1 " " [] [], + }, + ], + marker_token: R_ANGLE@1..2 ">" [] [], + post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@2..3 " " [] [], + }, + content: MdBlockList [ + MdParagraph { + list: MdInlineItemList [ + MdTextual { + value_token: MD_TEXTUAL_LITERAL@3..19 "one space indent" [] [], + }, + MdTextual { + value_token: MD_TEXTUAL_LITERAL@19..20 "\n" [] [], + }, + ], + hard_line: missing (optional), + }, + ], + }, + MdNewline { + value_token: NEWLINE@20..21 "\n" [] [], + }, + MdQuote { + prefix: MdQuotePrefix { + pre_marker_indent: MdQuoteIndentList [ + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@21..22 " " [] [], + }, + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@22..23 " " [] [], + }, + ], + marker_token: R_ANGLE@23..24 ">" [] [], + post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@24..25 " " [] [], + }, + content: MdBlockList [ + MdParagraph { + list: MdInlineItemList [ + MdTextual { + value_token: MD_TEXTUAL_LITERAL@25..41 "two space indent" [] [], + }, + MdTextual { + value_token: MD_TEXTUAL_LITERAL@41..42 "\n" [] [], + }, + ], + hard_line: missing (optional), + }, + ], + }, + MdNewline { + value_token: NEWLINE@42..43 "\n" [] [], + }, + MdQuote { + prefix: MdQuotePrefix { + pre_marker_indent: MdQuoteIndentList [ + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@43..44 " " [] [], + }, + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@44..45 " " [] [], + }, + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@45..46 " " [] [], + }, + ], + marker_token: R_ANGLE@46..47 ">" [] [], + post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@47..48 " " [] [], + }, + content: MdBlockList [ + MdParagraph { + list: MdInlineItemList [ + MdTextual { + value_token: MD_TEXTUAL_LITERAL@48..66 "three space indent" [] [], + }, + MdTextual { + value_token: MD_TEXTUAL_LITERAL@66..67 "\n" [] [], + }, + ], + hard_line: missing (optional), + }, + ], + }, + MdNewline { + value_token: NEWLINE@67..68 "\n" [] [], + }, + MdQuote { + prefix: MdQuotePrefix { + pre_marker_indent: MdQuoteIndentList [ + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@68..69 " " [] [], + }, + ], + marker_token: R_ANGLE@69..70 ">" [] [], + post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@70..71 " " [] [], + }, + content: MdBlockList [ + MdQuote { + prefix: MdQuotePrefix { + pre_marker_indent: MdQuoteIndentList [ + MdQuoteIndent { + md_quote_pre_marker_indent_token: MD_QUOTE_PRE_MARKER_INDENT@71..72 " " [] [], + }, + ], + marker_token: R_ANGLE@72..73 ">" [] [], + post_marker_space_token: missing (optional), + }, + content: MdBlockList [ + MdParagraph { + list: MdInlineItemList [ + MdTextual { + value_token: MD_TEXTUAL_LITERAL@73..98 " nested with outer indent" [] [], + }, + MdTextual { + value_token: MD_TEXTUAL_LITERAL@98..99 "\n" [] [], + }, + ], + hard_line: missing (optional), + }, + ], + }, + ], + }, + MdNewline { + value_token: NEWLINE@99..100 "\n" [] [], + }, + MdIndentCodeBlock { + content: MdInlineItemList [ + MdTextual { + value_token: MD_TEXTUAL_LITERAL@100..102 ">" [Skipped("\t")] [], + }, + MdTextual { + value_token: MD_TEXTUAL_LITERAL@102..120 " tab before marker" [] [], + }, + ], + }, + ], + eof_token: EOF@120..120 "" [] [], +} +``` + +## CST + +``` +0: MD_DOCUMENT@0..120 + 0: (empty) + 1: MD_BLOCK_LIST@0..120 + 0: MD_QUOTE@0..20 + 0: MD_QUOTE_PREFIX@0..3 + 0: MD_QUOTE_INDENT_LIST@0..1 + 0: MD_QUOTE_INDENT@0..1 + 0: MD_QUOTE_PRE_MARKER_INDENT@0..1 " " [] [] + 1: R_ANGLE@1..2 ">" [] [] + 2: MD_QUOTE_POST_MARKER_SPACE@2..3 " " [] [] + 1: MD_BLOCK_LIST@3..20 + 0: MD_PARAGRAPH@3..20 + 0: MD_INLINE_ITEM_LIST@3..20 + 0: MD_TEXTUAL@3..19 + 0: MD_TEXTUAL_LITERAL@3..19 "one space indent" [] [] + 1: MD_TEXTUAL@19..20 + 0: MD_TEXTUAL_LITERAL@19..20 "\n" [] [] + 1: (empty) + 1: MD_NEWLINE@20..21 + 0: NEWLINE@20..21 "\n" [] [] + 2: MD_QUOTE@21..42 + 0: MD_QUOTE_PREFIX@21..25 + 0: MD_QUOTE_INDENT_LIST@21..23 + 0: MD_QUOTE_INDENT@21..22 + 0: MD_QUOTE_PRE_MARKER_INDENT@21..22 " " [] [] + 1: MD_QUOTE_INDENT@22..23 + 0: MD_QUOTE_PRE_MARKER_INDENT@22..23 " " [] [] + 1: R_ANGLE@23..24 ">" [] [] + 2: MD_QUOTE_POST_MARKER_SPACE@24..25 " " [] [] + 1: MD_BLOCK_LIST@25..42 + 0: MD_PARAGRAPH@25..42 + 0: MD_INLINE_ITEM_LIST@25..42 + 0: MD_TEXTUAL@25..41 + 0: MD_TEXTUAL_LITERAL@25..41 "two space indent" [] [] + 1: MD_TEXTUAL@41..42 + 0: MD_TEXTUAL_LITERAL@41..42 "\n" [] [] + 1: (empty) + 3: MD_NEWLINE@42..43 + 0: NEWLINE@42..43 "\n" [] [] + 4: MD_QUOTE@43..67 + 0: MD_QUOTE_PREFIX@43..48 + 0: MD_QUOTE_INDENT_LIST@43..46 + 0: MD_QUOTE_INDENT@43..44 + 0: MD_QUOTE_PRE_MARKER_INDENT@43..44 " " [] [] + 1: MD_QUOTE_INDENT@44..45 + 0: MD_QUOTE_PRE_MARKER_INDENT@44..45 " " [] [] + 2: MD_QUOTE_INDENT@45..46 + 0: MD_QUOTE_PRE_MARKER_INDENT@45..46 " " [] [] + 1: R_ANGLE@46..47 ">" [] [] + 2: MD_QUOTE_POST_MARKER_SPACE@47..48 " " [] [] + 1: MD_BLOCK_LIST@48..67 + 0: MD_PARAGRAPH@48..67 + 0: MD_INLINE_ITEM_LIST@48..67 + 0: MD_TEXTUAL@48..66 + 0: MD_TEXTUAL_LITERAL@48..66 "three space indent" [] [] + 1: MD_TEXTUAL@66..67 + 0: MD_TEXTUAL_LITERAL@66..67 "\n" [] [] + 1: (empty) + 5: MD_NEWLINE@67..68 + 0: NEWLINE@67..68 "\n" [] [] + 6: MD_QUOTE@68..99 + 0: MD_QUOTE_PREFIX@68..71 + 0: MD_QUOTE_INDENT_LIST@68..69 + 0: MD_QUOTE_INDENT@68..69 + 0: MD_QUOTE_PRE_MARKER_INDENT@68..69 " " [] [] + 1: R_ANGLE@69..70 ">" [] [] + 2: MD_QUOTE_POST_MARKER_SPACE@70..71 " " [] [] + 1: MD_BLOCK_LIST@71..99 + 0: MD_QUOTE@71..99 + 0: MD_QUOTE_PREFIX@71..73 + 0: MD_QUOTE_INDENT_LIST@71..72 + 0: MD_QUOTE_INDENT@71..72 + 0: MD_QUOTE_PRE_MARKER_INDENT@71..72 " " [] [] + 1: R_ANGLE@72..73 ">" [] [] + 2: (empty) + 1: MD_BLOCK_LIST@73..99 + 0: MD_PARAGRAPH@73..99 + 0: MD_INLINE_ITEM_LIST@73..99 + 0: MD_TEXTUAL@73..98 + 0: MD_TEXTUAL_LITERAL@73..98 " nested with outer indent" [] [] + 1: MD_TEXTUAL@98..99 + 0: MD_TEXTUAL_LITERAL@98..99 "\n" [] [] + 1: (empty) + 7: MD_NEWLINE@99..100 + 0: NEWLINE@99..100 "\n" [] [] + 8: MD_INDENT_CODE_BLOCK@100..120 + 0: MD_INLINE_ITEM_LIST@100..120 + 0: MD_TEXTUAL@100..102 + 0: MD_TEXTUAL_LITERAL@100..102 ">" [Skipped("\t")] [] + 1: MD_TEXTUAL@102..120 + 0: MD_TEXTUAL_LITERAL@102..120 " tab before marker" [] [] + 2: EOF@120..120 "" [] [] + +``` 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 index 69b13dda3108..38c56e66ae82 100644 --- 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 @@ -84,7 +84,7 @@ MdDocument { }, MdQuote { prefix: MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@35..36 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@36..37 " " [] [], }, @@ -98,7 +98,7 @@ MdDocument { value_token: MD_TEXTUAL_LITERAL@40..41 "\n" [] [], }, MdQuotePrefix { - pre_marker_indent_token: missing (optional), + pre_marker_indent: MdQuoteIndentList [], marker_token: R_ANGLE@41..42 ">" [] [], post_marker_space_token: MD_QUOTE_POST_MARKER_SPACE@42..43 " " [] [], }, @@ -202,7 +202,7 @@ MdDocument { 0: NEWLINE@34..35 "\n" [] [] 9: MD_QUOTE@35..47 0: MD_QUOTE_PREFIX@35..37 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@35..35 1: R_ANGLE@35..36 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@36..37 " " [] [] 1: MD_BLOCK_LIST@37..47 @@ -213,7 +213,7 @@ MdDocument { 1: MD_TEXTUAL@40..41 0: MD_TEXTUAL_LITERAL@40..41 "\n" [] [] 2: MD_QUOTE_PREFIX@41..43 - 0: (empty) + 0: MD_QUOTE_INDENT_LIST@41..41 1: R_ANGLE@41..42 ">" [] [] 2: MD_QUOTE_POST_MARKER_SPACE@42..43 " " [] [] 3: MD_TEXTUAL@43..44 diff --git a/crates/biome_markdown_syntax/src/generated/kind.rs b/crates/biome_markdown_syntax/src/generated/kind.rs index 25c7e9389a61..675db8d4392a 100644 --- a/crates/biome_markdown_syntax/src/generated/kind.rs +++ b/crates/biome_markdown_syntax/src/generated/kind.rs @@ -71,6 +71,8 @@ pub enum MarkdownSyntaxKind { MD_LINK_TITLE, MD_QUOTE, MD_QUOTE_PREFIX, + MD_QUOTE_INDENT, + MD_QUOTE_INDENT_LIST, MD_ORDERED_LIST_ITEM, MD_BULLET_LIST_ITEM, MD_BULLET_LIST, @@ -157,6 +159,7 @@ impl MarkdownSyntaxKind { MD_BLOCK_LIST | MD_HASH_LIST | MD_CODE_NAME_LIST + | MD_QUOTE_INDENT_LIST | MD_BULLET_LIST | MD_INLINE_ITEM_LIST | MD_INDENTED_CODE_LINE_LIST diff --git a/crates/biome_markdown_syntax/src/generated/macros.rs b/crates/biome_markdown_syntax/src/generated/macros.rs index ececa17da671..a9283a42f552 100644 --- a/crates/biome_markdown_syntax/src/generated/macros.rs +++ b/crates/biome_markdown_syntax/src/generated/macros.rs @@ -125,6 +125,10 @@ macro_rules! map_syntax_node { let $pattern = unsafe { $crate::MdQuote::new_unchecked(node) }; $body } + $crate::MarkdownSyntaxKind::MD_QUOTE_INDENT => { + let $pattern = unsafe { $crate::MdQuoteIndent::new_unchecked(node) }; + $body + } $crate::MarkdownSyntaxKind::MD_QUOTE_PREFIX => { let $pattern = unsafe { $crate::MdQuotePrefix::new_unchecked(node) }; $body @@ -181,6 +185,10 @@ macro_rules! map_syntax_node { let $pattern = unsafe { $crate::MdInlineItemList::new_unchecked(node) }; $body } + $crate::MarkdownSyntaxKind::MD_QUOTE_INDENT_LIST => { + let $pattern = unsafe { $crate::MdQuoteIndentList::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 a011662ee23d..fd51a99c381f 100644 --- a/crates/biome_markdown_syntax/src/generated/nodes.rs +++ b/crates/biome_markdown_syntax/src/generated/nodes.rs @@ -1156,6 +1156,41 @@ pub struct MdQuoteFields { pub content: MdBlockList, } #[derive(Clone, PartialEq, Eq, Hash)] +pub struct MdQuoteIndent { + pub(crate) syntax: SyntaxNode, +} +impl MdQuoteIndent { + #[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) -> MdQuoteIndentFields { + MdQuoteIndentFields { + md_quote_pre_marker_indent_token: self.md_quote_pre_marker_indent_token(), + } + } + pub fn md_quote_pre_marker_indent_token(&self) -> SyntaxResult { + support::required_token(&self.syntax, 0usize) + } +} +impl Serialize for MdQuoteIndent { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.as_fields().serialize(serializer) + } +} +#[derive(Serialize)] +pub struct MdQuoteIndentFields { + pub md_quote_pre_marker_indent_token: SyntaxResult, +} +#[derive(Clone, PartialEq, Eq, Hash)] pub struct MdQuotePrefix { pub(crate) syntax: SyntaxNode, } @@ -1171,13 +1206,13 @@ impl MdQuotePrefix { } pub fn as_fields(&self) -> MdQuotePrefixFields { MdQuotePrefixFields { - pre_marker_indent_token: self.pre_marker_indent_token(), + pre_marker_indent: self.pre_marker_indent(), marker_token: self.marker_token(), post_marker_space_token: self.post_marker_space_token(), } } - pub fn pre_marker_indent_token(&self) -> Option { - support::token(&self.syntax, 0usize) + pub fn pre_marker_indent(&self) -> MdQuoteIndentList { + support::list(&self.syntax, 0usize) } pub fn marker_token(&self) -> SyntaxResult { support::required_token(&self.syntax, 1usize) @@ -1196,7 +1231,7 @@ impl Serialize for MdQuotePrefix { } #[derive(Serialize)] pub struct MdQuotePrefixFields { - pub pre_marker_indent_token: Option, + pub pre_marker_indent: MdQuoteIndentList, pub marker_token: SyntaxResult, pub post_marker_space_token: Option, } @@ -3117,6 +3152,56 @@ impl From for SyntaxElement { n.syntax.into() } } +impl AstNode for MdQuoteIndent { + type Language = Language; + const KIND_SET: SyntaxKindSet = + SyntaxKindSet::from_raw(RawSyntaxKind(MD_QUOTE_INDENT as u16)); + fn can_cast(kind: SyntaxKind) -> bool { + kind == MD_QUOTE_INDENT + } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } + fn into_syntax(self) -> SyntaxNode { + self.syntax + } +} +impl std::fmt::Debug for MdQuoteIndent { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + thread_local! { static DEPTH : std :: cell :: Cell < u8 > = const { std :: cell :: Cell :: new (0) } }; + let current_depth = DEPTH.get(); + let result = if current_depth < 16 { + DEPTH.set(current_depth + 1); + f.debug_struct("MdQuoteIndent") + .field( + "md_quote_pre_marker_indent_token", + &support::DebugSyntaxResult(self.md_quote_pre_marker_indent_token()), + ) + .finish() + } else { + f.debug_struct("MdQuoteIndent").finish() + }; + DEPTH.set(current_depth); + result + } +} +impl From for SyntaxNode { + fn from(n: MdQuoteIndent) -> Self { + n.syntax + } +} +impl From for SyntaxElement { + fn from(n: MdQuoteIndent) -> Self { + n.syntax.into() + } +} impl AstNode for MdQuotePrefix { type Language = Language; const KIND_SET: SyntaxKindSet = @@ -3145,10 +3230,7 @@ impl std::fmt::Debug for MdQuotePrefix { let result = if current_depth < 16 { DEPTH.set(current_depth + 1); f.debug_struct("MdQuotePrefix") - .field( - "pre_marker_indent_token", - &support::DebugOptionalElement(self.pre_marker_indent_token()), - ) + .field("pre_marker_indent", &self.pre_marker_indent()) .field( "marker_token", &support::DebugSyntaxResult(self.marker_token()), @@ -4279,6 +4361,11 @@ impl std::fmt::Display for MdQuote { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for MdQuoteIndent { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for MdQuotePrefix { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -4786,6 +4873,88 @@ impl IntoIterator for MdInlineItemList { self.iter() } } +#[derive(Clone, Eq, PartialEq, Hash)] +pub struct MdQuoteIndentList { + syntax_list: SyntaxList, +} +impl MdQuoteIndentList { + #[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 unsafe fn new_unchecked(syntax: SyntaxNode) -> Self { + Self { + syntax_list: syntax.into_list(), + } + } +} +impl AstNode for MdQuoteIndentList { + type Language = Language; + const KIND_SET: SyntaxKindSet = + SyntaxKindSet::from_raw(RawSyntaxKind(MD_QUOTE_INDENT_LIST as u16)); + fn can_cast(kind: SyntaxKind) -> bool { + kind == MD_QUOTE_INDENT_LIST + } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { + syntax_list: syntax.into_list(), + }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { + self.syntax_list.node() + } + fn into_syntax(self) -> SyntaxNode { + self.syntax_list.into_node() + } +} +impl Serialize for MdQuoteIndentList { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.len()))?; + for e in self.iter() { + seq.serialize_element(&e)?; + } + seq.end() + } +} +impl AstNodeList for MdQuoteIndentList { + type Language = Language; + type Node = MdQuoteIndent; + fn syntax_list(&self) -> &SyntaxList { + &self.syntax_list + } + fn into_syntax_list(self) -> SyntaxList { + self.syntax_list + } +} +impl Debug for MdQuoteIndentList { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str("MdQuoteIndentList ")?; + f.debug_list().entries(self.iter()).finish() + } +} +impl IntoIterator for &MdQuoteIndentList { + type Item = MdQuoteIndent; + type IntoIter = AstNodeListIterator; + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} +impl IntoIterator for MdQuoteIndentList { + type Item = MdQuoteIndent; + type IntoIter = AstNodeListIterator; + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} #[derive(Clone)] pub struct DebugSyntaxElementChildren(pub SyntaxElementChildren); impl Debug for DebugSyntaxElementChildren { diff --git a/crates/biome_markdown_syntax/src/generated/nodes_mut.rs b/crates/biome_markdown_syntax/src/generated/nodes_mut.rs index 7e84005b0ab7..4c6007784345 100644 --- a/crates/biome_markdown_syntax/src/generated/nodes_mut.rs +++ b/crates/biome_markdown_syntax/src/generated/nodes_mut.rs @@ -447,11 +447,19 @@ impl MdQuote { ) } } +impl MdQuoteIndent { + pub fn with_md_quote_pre_marker_indent_token(self, element: SyntaxToken) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(0usize..=0usize, once(Some(element.into()))), + ) + } +} impl MdQuotePrefix { - pub fn with_pre_marker_indent_token(self, element: Option) -> Self { + pub fn with_pre_marker_indent(self, element: MdQuoteIndentList) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(0usize..=0usize, once(element.map(|element| element.into()))), + .splice_slots(0usize..=0usize, once(Some(element.into_syntax().into()))), ) } pub fn with_marker_token(self, element: SyntaxToken) -> Self { diff --git a/xtask/codegen/markdown.ungram b/xtask/codegen/markdown.ungram index b8027a5ba0d7..c4470c402370 100644 --- a/xtask/codegen/markdown.ungram +++ b/xtask/codegen/markdown.ungram @@ -170,10 +170,14 @@ MdQuote = // Post-marker space captures exactly 0 or 1 space after '>'; // additional spaces are content indentation, not part of the prefix. MdQuotePrefix = - pre_marker_indent: 'md_quote_pre_marker_indent'? + pre_marker_indent: MdQuoteIndentList marker: '>' post_marker_space: 'md_quote_post_marker_space'? +// Single pre-marker indent token (MdHash/MdHashList pattern). +MdQuoteIndent = 'md_quote_pre_marker_indent' +MdQuoteIndentList = MdQuoteIndent* + MdBulletListItem = MdBulletList MdOrderedListItem = MdBulletList diff --git a/xtask/codegen/src/markdown_kinds_src.rs b/xtask/codegen/src/markdown_kinds_src.rs index 9141ea74fa15..e69fb971cbc5 100644 --- a/xtask/codegen/src/markdown_kinds_src.rs +++ b/xtask/codegen/src/markdown_kinds_src.rs @@ -64,6 +64,8 @@ pub const MARKDOWN_KINDS_SRC: KindsSrc = KindsSrc { "MD_LINK_TITLE", "MD_QUOTE", "MD_QUOTE_PREFIX", + "MD_QUOTE_INDENT", + "MD_QUOTE_INDENT_LIST", "MD_ORDERED_LIST_ITEM", "MD_BULLET_LIST_ITEM", "MD_BULLET_LIST",