From d1f1f481d099f7b2dc22f55d584581317b2158a0 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Sat, 3 Oct 2026 23:56:19 +0000 Subject: [PATCH 1/2] Preserve whitespace when serializing without indentation The serializer dropped whitespace-only text nodes and trimmed trailing whitespace from all other text nodes, regardless of the indent setting. Even with indent=0, this changed the meaning of the document: "a b" serialized as "ab", and
, ",
+            markupever.HtmlOptions(full_document=False),
+        ),
+        (
+            "",
+            markupever.HtmlOptions(full_document=False),
+        ),
+        (" x \n  \t", markupever.XmlOptions()),
+    ]:
+        dom = markupever.parse(content, options)
+        assert dom.serialize(indent=0) == content
+
+
 def test_add_itself():
     tag = markupever.parse("

").root().first_child diff --git a/treedom/src/dom.rs b/treedom/src/dom.rs index fff86d1..63c962f 100644 --- a/treedom/src/dom.rs +++ b/treedom/src/dom.rs @@ -230,7 +230,10 @@ impl<'a> Serializer<'a> { serializer.write_processing_instruction(&pi.target, &pi.data)? } interface::Interface::Text(text) => { - if !text.contents.trim_ascii().is_empty() { + // Without indentation, whitespace is significant: write it unchanged. + if self.indent == 0 { + serializer.write_text(&text.contents)?; + } else if !text.contents.trim_ascii().is_empty() { serializer.write_text(text.contents.trim_ascii_end())?; } } diff --git a/treedom/src/parser.rs b/treedom/src/parser.rs index 76a5848..3e2d6b7 100644 --- a/treedom/src/parser.rs +++ b/treedom/src/parser.rs @@ -579,6 +579,27 @@ mod tests { assert_eq!(HTML, String::from_utf8_lossy(&buf)); } + #[cfg(feature = "html5ever")] + #[test] + fn html_serializer_preserves_whitespace() { + use crate::Serializer; + + const HTML: &str = "\n\n

a b

\n
  x\n\n
\n"; + + let parser = ParserSink::parse_html(true, Default::default(), Default::default()); + let dom = parser.one(HTML).into_dom(); + + let mut buf: Vec = Vec::new(); + html5ever::serialize::serialize( + &mut buf, + &Serializer::new(&dom, dom.root().id(), 0), + Default::default(), + ) + .unwrap(); + + assert_eq!(HTML, String::from_utf8_lossy(&buf)); + } + #[cfg(feature = "xml5ever")] #[test] fn xml_serializer() { From 977fae6e77d247980b3029a1052f3b233b5a9cfb Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Mon, 5 Oct 2026 10:59:10 +0000 Subject: [PATCH 2/2] Serialize without indentation by default serialize() and serialize_bytes() pretty-printed with indent=4 by default, which adds and removes whitespace and so can change the meaning of the document: it changes the rendering of whitespace between inline elements, and the contents of
,