diff --git a/src/construct/partial_mdx_expression.rs b/src/construct/partial_mdx_expression.rs index 22d0eb5..fd48024 100644 --- a/src/construct/partial_mdx_expression.rs +++ b/src/construct/partial_mdx_expression.rs @@ -56,15 +56,16 @@ //! [mdx_expression_text]: crate::construct::mdx_expression_text //! [interleaving]: https://mdxjs.com/docs/what-is-mdx/#interleaving -use crate::construct::partial_space_or_tab::space_or_tab_min_max; use crate::event::Name; use crate::message; use crate::state::{Name as StateName, State}; use crate::tokenizer::Tokenizer; -use crate::util::{constant::TAB_SIZE, mdx_collect::collect}; +use crate::util::mdx_collect::collect; use crate::{MdxExpressionKind, MdxExpressionParse, MdxSignal}; use alloc::boxed::Box; +pub const INDENT_SIZE: usize = 4; + /// Start of an MDX expression. /// /// ```markdown @@ -180,7 +181,6 @@ pub fn eol_after(tokenizer: &mut Tokenizer) -> State { } ) } else if matches!(tokenizer.current, Some(b'\t' | b' ')) { - tokenizer.attempt(State::Next(StateName::MdxExpressionBefore), State::Nok); // Idea: investigate if we’d need to use more complex stripping. // Take this example: // @@ -200,12 +200,27 @@ pub fn eol_after(tokenizer: &mut Tokenizer) -> State { // the start of the expression and move past whitespace. // For future lines, we’d move at most to // `line_start_shifted.column + 4`. - State::Retry(space_or_tab_min_max(tokenizer, 0, TAB_SIZE)) + tokenizer.enter(Name::LinePrefix); + State::Retry(StateName::MdxExpressionPrefix) } else { State::Retry(StateName::MdxExpressionBefore) } } +pub fn prefix(tokenizer: &mut Tokenizer) -> State { + tokenizer.tokenize_state.size_c += 1; + if matches!(tokenizer.current, Some(b'\t' | b' ')) + && tokenizer.tokenize_state.size_c < INDENT_SIZE - 1 + { + tokenizer.consume(); + return State::Next(StateName::MdxExpressionPrefix); + } + + tokenizer.exit(Name::LinePrefix); + tokenizer.tokenize_state.size_c = 0; + State::Retry(StateName::MdxExpressionBefore) +} + /// Parse an expression with a given function. fn parse_expression(tokenizer: &mut Tokenizer, parse: &MdxExpressionParse) -> State { // Collect the body of the expression and positional info for each run of it. diff --git a/src/event.rs b/src/event.rs index 3e8d513..1ccff84 100644 --- a/src/event.rs +++ b/src/event.rs @@ -3376,6 +3376,8 @@ pub enum Name { /// ^ ^ ^ /// ``` ThematicBreakSequence, + + LinePrefix, } /// List of void events, used to make sure everything is working well. diff --git a/src/state.rs b/src/state.rs index cb32ea8..5e765c7 100644 --- a/src/state.rs +++ b/src/state.rs @@ -360,6 +360,7 @@ pub enum Name { MdxExpressionStart, MdxExpressionBefore, + MdxExpressionPrefix, MdxExpressionInside, MdxExpressionEolAfter, @@ -835,6 +836,7 @@ pub fn call(tokenizer: &mut Tokenizer, name: Name) -> State { Name::MdxEsmAtEnd => construct::mdx_esm::at_end, Name::MdxExpressionStart => construct::partial_mdx_expression::start, + Name::MdxExpressionPrefix => construct::partial_mdx_expression::prefix, Name::MdxExpressionBefore => construct::partial_mdx_expression::before, Name::MdxExpressionInside => construct::partial_mdx_expression::inside, Name::MdxExpressionEolAfter => construct::partial_mdx_expression::eol_after, diff --git a/tests/mdx_expression_flow.rs b/tests/mdx_expression_flow.rs index 49c89b9..e0b6a5a 100644 --- a/tests/mdx_expression_flow.rs +++ b/tests/mdx_expression_flow.rs @@ -144,6 +144,19 @@ fn mdx_expression_flow_agnostic() -> Result<(), message::Message> { "should support mdx expressions (flow) as `MdxFlowExpression`s in mdast" ); + assert_eq!( + to_mdast(" {`\n a\n `}", &mdx.parse)?, + Node::Root(Root { + children: vec![Node::MdxFlowExpression(MdxFlowExpression { + value: "`\n a\n`".into(), + position: Some(Position::new(1, 3, 2, 3, 5, 15)), + stops: vec![(0, 3), (1, 4), (2, 7), (5, 10), (6, 13)] + })], + position: Some(Position::new(1, 1, 0, 3, 5, 15)) + }), + "should support indent in `MdxFlowExpression` in mdast" + ); + Ok(()) }