From 31ab712f2e45de567fd699786a49af678a30cd15 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Thu, 8 Sep 2022 10:23:03 +0200 Subject: Add tests for mdx jsx (text) --- src/compiler.rs | 6 +++++- src/construct/mdx_jsx_text.rs | 47 +++++++++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/compiler.rs b/src/compiler.rs index 4f0f958..572cc4e 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -364,6 +364,7 @@ fn enter(context: &mut CompileContext) { | Name::HeadingAtxText | Name::HeadingSetextText | Name::Label + | Name::MdxJsxTextTag | Name::ReferenceString | Name::ResourceTitleString => on_enter_buffer(context), @@ -401,7 +402,10 @@ fn enter(context: &mut CompileContext) { /// Handle [`Exit`][Kind::Exit]. fn exit(context: &mut CompileContext) { match context.events[context.index].name { - Name::CodeFencedFenceMeta | Name::MathFlowFenceMeta | Name::Resource => { + Name::CodeFencedFenceMeta + | Name::MathFlowFenceMeta + | Name::MdxJsxTextTag + | Name::Resource => { on_exit_drop(context); } Name::CharacterEscapeValue | Name::CodeTextData | Name::Data | Name::MathTextData => { diff --git a/src/construct/mdx_jsx_text.rs b/src/construct/mdx_jsx_text.rs index 4c71fec..f6981ce 100644 --- a/src/construct/mdx_jsx_text.rs +++ b/src/construct/mdx_jsx_text.rs @@ -553,7 +553,7 @@ pub fn attribute_primary_name_after(tokenizer: &mut Tokenizer) -> State { State::Next(StateName::MdxJsxTextAttributeLocalNameBefore), State::Nok, ); - State::Retry(StateName::MdxJsxTextEsWhitespaceStart) + State::Next(StateName::MdxJsxTextEsWhitespaceStart) } // Initializer: start of an attribute value. Some(b'=') => { @@ -678,7 +678,7 @@ pub fn attribute_local_name_after(tokenizer: &mut Tokenizer) -> State { State::Next(StateName::MdxJsxTextAttributeValueBefore), State::Nok, ); - State::Retry(StateName::MdxJsxTextEsWhitespaceStart) + State::Next(StateName::MdxJsxTextEsWhitespaceStart) } _ => { // End of name. @@ -750,9 +750,10 @@ pub fn attribute_value_quoted_start(tokenizer: &mut Tokenizer) -> State { tokenizer.enter(Name::MdxJsxTextTagAttributeValueLiteralMarker); tokenizer.consume(); tokenizer.exit(Name::MdxJsxTextTagAttributeValueLiteralMarker); - tokenizer.enter(Name::MdxJsxTextTagAttributeValueLiteral); + tokenizer.exit(Name::MdxJsxTextTagAttributeValueLiteral); + tokenizer.exit(Name::MdxJsxTextTagAttribute); tokenizer.attempt( - State::Next(StateName::MdxJsxTextAttributeValueBefore), + State::Next(StateName::MdxJsxTextAttributeBefore), State::Nok, ); State::Next(StateName::MdxJsxTextEsWhitespaceStart) @@ -793,7 +794,7 @@ pub fn attribute_value_quoted(tokenizer: &mut Tokenizer) -> State { || matches!(tokenizer.current, None | Some(b'\n')) { tokenizer.exit(Name::MdxJsxTextTagAttributeValueLiteralValue); - State::Retry(StateName::MdxJsxTextAttributeValueQuoted) + State::Retry(StateName::MdxJsxTextAttributeValueQuotedStart) } else { tokenizer.consume(); State::Next(StateName::MdxJsxTextAttributeValueQuoted) @@ -920,11 +921,13 @@ fn id_cont(code: Option) -> bool { } fn crash(tokenizer: &Tokenizer, at: &str, expect: &str) -> State { + let char = char_after_index(tokenizer.parse_state.bytes, tokenizer.point.index); + // To do: externalize this, and the print mechanism in the tokenizer, // to one proper formatter. - let actual = match tokenizer.current { + let actual = match char { None => "end of file".to_string(), - Some(byte) => format_byte(byte), + Some(char) => format!("character {}", format_char(char)), }; State::Error(format!( @@ -933,10 +936,32 @@ fn crash(tokenizer: &Tokenizer, at: &str, expect: &str) -> State { )) } +fn format_char(char: char) -> String { + let unicode = format!("U+{:>04X}", char as u32); + let printable = match char { + '`' => Some("`` ` ``".to_string()), + ' '..='~' => Some(format!("`{}`", char)), + _ => None, + }; + + if let Some(char) = printable { + format!("{} ({})", char, unicode) + } else { + unicode + } +} + fn format_byte(byte: u8) -> String { - match byte { - b'`' => "`` ` ``".to_string(), - b' '..=b'~' => format!("`{}`", str::from_utf8(&[byte]).unwrap()), - _ => format!("character U+{:>04X}", byte), + let unicode = format!("U+{:>04X}", byte); + let printable = match byte { + b'`' => Some("`` ` ``".to_string()), + b' '..=b'~' => Some(format!("`{}`", str::from_utf8(&[byte]).unwrap())), + _ => None, + }; + + if let Some(char) = printable { + format!("{} ({})", char, unicode) + } else { + unicode } } -- cgit