diff options
| author | Michael Färber <01mf02@gmail.com> | 2024-12-10 10:57:22 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-10 09:57:22 +0000 |
| commit | 17f20c6944d569d5f0bb57caee37d9f208d87d0d (patch) | |
| tree | 9e48c3a6525adb876d06711bc48ef82eb64e59ff /crates/typst-html/src/encode.rs | |
| parent | bb0c8140950b3eec020a4f0147bbc4ea65f3952a (diff) | |
Basic HTML pretty-printing (#5533)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
Diffstat (limited to 'crates/typst-html/src/encode.rs')
| -rw-r--r-- | crates/typst-html/src/encode.rs | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/crates/typst-html/src/encode.rs b/crates/typst-html/src/encode.rs index d4ff83d6..b87b0e1d 100644 --- a/crates/typst-html/src/encode.rs +++ b/crates/typst-html/src/encode.rs @@ -8,14 +8,30 @@ use typst_syntax::Span; /// Encodes an HTML document into a string. pub fn html(document: &HtmlDocument) -> SourceResult<String> { - let mut w = Writer { buf: String::new() }; + let mut w = Writer { pretty: true, ..Writer::default() }; w.buf.push_str("<!DOCTYPE html>"); + write_indent(&mut w); write_element(&mut w, &document.root)?; Ok(w.buf) } +#[derive(Default)] struct Writer { buf: String, + /// current indentation level + level: usize, + /// pretty printing enabled? + pretty: bool, +} + +/// Write a newline and indent, if pretty printing is enabled. +fn write_indent(w: &mut Writer) { + if w.pretty { + w.buf.push('\n'); + for _ in 0..w.level { + w.buf.push_str(" "); + } + } } /// Encode an HTML node into the writer. @@ -67,9 +83,30 @@ fn write_element(w: &mut Writer, element: &HtmlElement) -> SourceResult<()> { return Ok(()); } - for node in &element.children { - write_node(w, node)?; + let pretty = w.pretty; + if !element.children.is_empty() { + w.pretty &= is_pretty(element); + let mut indent = w.pretty; + + w.level += 1; + for c in &element.children { + let pretty_child = match c { + HtmlNode::Tag(_) => continue, + HtmlNode::Element(element) => is_pretty(element), + HtmlNode::Text(..) | HtmlNode::Frame(_) => false, + }; + + if core::mem::take(&mut indent) || pretty_child { + write_indent(w); + } + write_node(w, c)?; + indent = pretty_child; + } + w.level -= 1; + + write_indent(w) } + w.pretty = pretty; w.buf.push_str("</"); w.buf.push_str(&element.tag.resolve()); @@ -78,6 +115,11 @@ fn write_element(w: &mut Writer, element: &HtmlElement) -> SourceResult<()> { Ok(()) } +/// Whether the element should be pretty-printed. +fn is_pretty(element: &HtmlElement) -> bool { + tag::is_block_by_default(element.tag) || matches!(element.tag, tag::meta) +} + /// Escape a character. fn write_escape(w: &mut Writer, c: char) -> StrResult<()> { // See <https://html.spec.whatwg.org/multipage/syntax.html#syntax-charref> |
