From 47facf57b8e56a42441ec02f4193c2968a0abdc2 Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Mon, 28 Oct 2024 11:35:44 +0800 Subject: [PATCH] fix: fix nested `
` (fix #70)

---
 markup_fmt/src/parser.rs                      | 67 +++++++++++--------
 .../tests/fmt/html/tags/pre.default.snap      |  4 ++
 markup_fmt/tests/fmt/html/tags/pre.html       |  4 ++
 .../fmt/html/tags/pre.ignore-whitespace.snap  |  4 ++
 .../fmt/html/tags/pre.large-print-width.snap  |  4 ++
 .../fmt/html/tags/pre.small-print-width.snap  |  8 +++
 .../fmt/html/tags/pre.strict-whitespace.snap  |  4 ++
 7 files changed, 68 insertions(+), 27 deletions(-)

diff --git a/markup_fmt/src/parser.rs b/markup_fmt/src/parser.rs
index c7da490..e41b747 100644
--- a/markup_fmt/src/parser.rs
+++ b/markup_fmt/src/parser.rs
@@ -1028,23 +1028,22 @@ impl<'s> Parser<'s> {
                     children.push(self.parse_node()?);
                 }
                 Some(..) => {
-                    children.push(
-                        if tag_name.eq_ignore_ascii_case("script")
-                            || tag_name.eq_ignore_ascii_case("style")
-                            || tag_name.eq_ignore_ascii_case("pre")
-                            || tag_name.eq_ignore_ascii_case("textarea")
-                        {
-                            self.parse_raw_text_node(tag_name).map(|text_node| {
-                                let raw = text_node.raw;
-                                Node {
-                                    kind: NodeKind::Text(text_node),
-                                    raw,
-                                }
-                            })?
-                        } else {
-                            self.parse_node()?
-                        },
-                    );
+                    if tag_name.eq_ignore_ascii_case("script")
+                        || tag_name.eq_ignore_ascii_case("style")
+                        || tag_name.eq_ignore_ascii_case("pre")
+                        || tag_name.eq_ignore_ascii_case("textarea")
+                    {
+                        let text_node = self.parse_raw_text_node(tag_name)?;
+                        let raw = text_node.raw;
+                        if !raw.is_empty() {
+                            children.push(Node {
+                                kind: NodeKind::Text(text_node),
+                                raw,
+                            });
+                        }
+                    } else {
+                        children.push(self.parse_node()?);
+                    }
                 }
                 None => return Err(self.emit_error(SyntaxErrorKind::ExpectCloseTag)),
             }
@@ -1539,6 +1538,8 @@ impl<'s> Parser<'s> {
             .map(|(i, _)| *i)
             .unwrap_or(self.source.len());
 
+        let allow_nested = tag_name.eq_ignore_ascii_case("pre");
+        let mut nested = 0u16;
         let mut line_breaks = 0;
         let end;
         loop {
@@ -1547,17 +1548,29 @@ impl<'s> Parser<'s> {
                     let i = *i;
                     let mut chars = self.chars.clone();
                     chars.next();
-                    if chars
-                        .next_if(|(_, c)| *c == '/')
-                        .map(|_| {
-                            chars
-                                .zip(tag_name.chars())
-                                .all(|((_, a), b)| a.eq_ignore_ascii_case(&b))
-                        })
-                        .unwrap_or_default()
+                    if chars.next_if(|(_, c)| *c == '/').is_some()
+                        && chars
+                            .by_ref()
+                            .zip(tag_name.chars())
+                            .all(|((_, a), b)| a.eq_ignore_ascii_case(&b))
                     {
-                        end = i;
-                        break;
+                        if nested == 0 {
+                            end = i;
+                            break;
+                        } else {
+                            nested -= 1;
+                            self.chars = chars;
+                            continue;
+                        }
+                    } else if allow_nested
+                        && chars
+                            .by_ref()
+                            .zip(tag_name.chars())
+                            .all(|((_, a), b)| a.eq_ignore_ascii_case(&b))
+                    {
+                        nested += 1;
+                        self.chars = chars;
+                        continue;
                     }
                     self.chars.next();
                 }
diff --git a/markup_fmt/tests/fmt/html/tags/pre.default.snap b/markup_fmt/tests/fmt/html/tags/pre.default.snap
index 6678428..8898b95 100644
--- a/markup_fmt/tests/fmt/html/tags/pre.default.snap
+++ b/markup_fmt/tests/fmt/html/tags/pre.default.snap
@@ -127,3 +127,7 @@ ___________________________
 
 

+
+
+
+
diff --git a/markup_fmt/tests/fmt/html/tags/pre.html b/markup_fmt/tests/fmt/html/tags/pre.html index 7cd20b7..bc7cb76 100644 --- a/markup_fmt/tests/fmt/html/tags/pre.html +++ b/markup_fmt/tests/fmt/html/tags/pre.html @@ -102,3 +102,7 @@

+
+
+
+
diff --git a/markup_fmt/tests/fmt/html/tags/pre.ignore-whitespace.snap b/markup_fmt/tests/fmt/html/tags/pre.ignore-whitespace.snap index 6678428..8898b95 100644 --- a/markup_fmt/tests/fmt/html/tags/pre.ignore-whitespace.snap +++ b/markup_fmt/tests/fmt/html/tags/pre.ignore-whitespace.snap @@ -127,3 +127,7 @@ ___________________________

+
+
+
+
diff --git a/markup_fmt/tests/fmt/html/tags/pre.large-print-width.snap b/markup_fmt/tests/fmt/html/tags/pre.large-print-width.snap index 3f608e2..d70afad 100644 --- a/markup_fmt/tests/fmt/html/tags/pre.large-print-width.snap +++ b/markup_fmt/tests/fmt/html/tags/pre.large-print-width.snap @@ -109,3 +109,7 @@ ___________________________

+
+
+
+
diff --git a/markup_fmt/tests/fmt/html/tags/pre.small-print-width.snap b/markup_fmt/tests/fmt/html/tags/pre.small-print-width.snap index 2ab1557..2f1e776 100644 --- a/markup_fmt/tests/fmt/html/tags/pre.small-print-width.snap +++ b/markup_fmt/tests/fmt/html/tags/pre.small-print-width.snap @@ -200,3 +200,11 @@ ___________________________

+
+
+
+
diff --git a/markup_fmt/tests/fmt/html/tags/pre.strict-whitespace.snap b/markup_fmt/tests/fmt/html/tags/pre.strict-whitespace.snap index 64b9081..b804e59 100644 --- a/markup_fmt/tests/fmt/html/tags/pre.strict-whitespace.snap +++ b/markup_fmt/tests/fmt/html/tags/pre.strict-whitespace.snap @@ -125,3 +125,7 @@ ___________________________

+
+
+
+