Repository: biomejs/biome (language: rust)

Issue:
📝 Contents of `<pre>` elements should not be formatted
### Environment information

```bash
playground
```


### Configuration

_No response_

### Playground link

https://biomejs.dev/playground/?quoteStyle=single&indentWidth=4&arrowParentheses=as-needed&files.main.html=PABwAHIAZQA%2BAAoACgAgACAAIAAgACAAIAAgACAAVABlAHgAdAAgAGkAbgAgAGEAIABwAHIAZQAgAGUAbABlAG0AZQBuAHQACgAKACAAIAAgACAAaQBzACAAZABpAHMAcABsAGEAeQBlAGQAIABpAG4AIABhACAAZgBpAHgAZQBkAC0AdwBpAGQAdABoAAoACgAgACAAIABmAG8AbgB0ACwAIABhAG4AZAAgAGkAdAAgAHAAcgBlAHMAZQByAHYAZQBzAAoACgAgACAAIABiAG8AdABoACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAcwBwAGEAYwBlAHMAIABhAG4AZAAKAAoAIAAgACAAbABpAG4AZQAgAGIAcgBlAGEAawBzAAoACgA8AC8AcAByAGUAPgA%3D

### Code of Conduct

- [X] I agree to follow Biome's Code of Conduct


Discussion / hints:

Fix patch:
diff --git a/crates/biome_formatter/src/format_element/tag.rs b/crates/biome_formatter/src/format_element/tag.rs
index ef4a1ca8a732..e07427347ce1 100644
--- a/crates/biome_formatter/src/format_element/tag.rs
+++ b/crates/biome_formatter/src/format_element/tag.rs
@@ -282,6 +282,8 @@ pub trait Label {
 pub enum VerbatimKind {
     Bogus,
     Suppressed,
+    /// This was intentionally skipped, not as a result of suppression.
+    Skipped,
     Verbatim {
         /// the length of the formatted node
         length: TextSize,
diff --git a/crates/biome_formatter/src/prelude.rs b/crates/biome_formatter/src/prelude.rs
index 78de2340d051..8513c0973f68 100644
--- a/crates/biome_formatter/src/prelude.rs
+++ b/crates/biome_formatter/src/prelude.rs
@@ -13,6 +13,7 @@ pub use crate::format_element::document::Document;
 pub use crate::format_element::tag::{LabelId, Tag, TagKind};
 pub use crate::verbatim::{
     format_bogus_node, format_or_verbatim, format_suppressed_node, format_verbatim_node,
+    format_verbatim_skipped,
 };
 
 pub use crate::{
diff --git a/crates/biome_formatter/src/verbatim.rs b/crates/biome_formatter/src/verbatim.rs
index 59429c924e15..47d308dd0367 100644
--- a/crates/biome_formatter/src/verbatim.rs
+++ b/crates/biome_formatter/src/verbatim.rs
@@ -24,6 +24,16 @@ pub fn format_verbatim_node<L: Language>(node: &SyntaxNode<L>) -> FormatVerbatim
     }
 }
 
+/// "Formats" a node according to its original formatting in the source text. It's functionally equal to
+/// [`format_verbatim_node`], but it doesn't track the node as [VerbatimKind::Verbatim].
+pub fn format_verbatim_skipped<L: Language>(node: &SyntaxNode<L>) -> FormatVerbatimNode<L> {
+    FormatVerbatimNode {
+        node,
+        kind: VerbatimKind::Skipped,
+        format_comments: true,
+    }
+}
+
 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
 pub struct FormatVerbatimNode<'node, L: Language> {
     node: &'node SyntaxNode<L>,
diff --git a/crates/biome_html_formatter/src/html/auxiliary/element.rs b/crates/biome_html_formatter/src/html/auxiliary/element.rs
index 6c468d16daea..f15cf06962c6 100644
--- a/crates/biome_html_formatter/src/html/auxiliary/element.rs
+++ b/crates/biome_html_formatter/src/html/auxiliary/element.rs
@@ -11,14 +11,25 @@ impl FormatNodeRule<HtmlElement> for FormatHtmlElement {
             closing_element,
         } = node.as_fields();
 
-        write!(
-            f,
-            [
-                opening_element.format(),
-                children.format(),
-                closing_element.format(),
-            ]
-        )?;
+        let tag_name = opening_element
+            .clone()
+            .and_then(|e| e.name())
+            .map(|e| e.text())
+            .unwrap_or_default();
+        // `pre` tags are "preformatted", so we should not format the content inside them. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre
+        // We ignore the `script` and `style` tags as well, since embedded language parsing/formatting is not yet implemented.
+        let should_be_verbatim = ["script", "style", "pre"]
+            .iter()
+            .any(|tag| tag_name.eq_ignore_ascii_case(tag));
+
+        write!(f, [opening_element.format()])?;
+        if should_be_verbatim {
+            format_verbatim_skipped(children.syntax()).fmt(f)?;
+            write!(f, [hard_line_break()])?;
+        } else {
+            write!(f, [children.format()])?;
+        }
+        write!(f, [closing_element.format()])?;
 
         Ok(())
     }
diff --git a/crates/biome_html_formatter/src/prelude.rs b/crates/biome_html_formatter/src/prelude.rs
index e5c3661049a9..b6cf7b5b1213 100644
--- a/crates/biome_html_formatter/src/prelude.rs
+++ b/crates/biome_html_formatter/src/prelude.rs
@@ -1,7 +1,7 @@
 #[allow(unused_imports)]
 pub(crate) use crate::{
-    format_verbatim_node, AsFormat, FormatNodeRule, FormatResult, FormatRule, FormattedIterExt,
-    HtmlFormatContext, HtmlFormatter,
+    format_verbatim_node, format_verbatim_skipped, AsFormat, FormatNodeRule, FormatResult,
+    FormatRule, FormattedIterExt, HtmlFormatContext, HtmlFormatter,
 };
 pub(crate) use biome_formatter::prelude::*;
 #[allow(unused_imports)]


Test patch:
diff --git a/crates/biome_html_formatter/tests/specs/html/elements/pre.html b/crates/biome_html_formatter/tests/specs/html/elements/pre.html
new file mode 100644
index 000000000000..1d3423e9d132
--- /dev/null
+++ b/crates/biome_html_formatter/tests/specs/html/elements/pre.html
@@ -0,0 +1,13 @@
+<pre>
+	___                       ___           ___           ___
+	/\  \          ___        /\  \         /\__\         /\  \
+ /::\  \        /\  \      /::\  \       /::|  |       /::\  \
+/:/\:\  \       \:\  \    /:/\:\  \     /:|:|  |      /:/\:\  \
+/::\~\:\__\      /::\__\  /:/  \:\  \   /:/|:|__|__   /::\~\:\  \
+/:/\:\ \:|__|  __/:/\/__/ /:/__/ \:\__\ /:/ |::::\__\ /:/\:\ \:\__\
+\:\~\:\/:/  / /\/:/  /    \:\  \ /:/  / \/__/~~/:/  / \:\~\:\ \/__/
+\:\ \::/  /  \::/__/      \:\  /:/  /        /:/  /   \:\ \:\__\
+\:\/:/  /    \:\__\       \:\/:/  /        /:/  /     \:\ \/__/
+ \::/__/      \/__/        \::/  /        /:/  /       \:\__\
+	~~                        \/__/         \/__/         \/__/
+</pre>
diff --git a/crates/biome_html_formatter/tests/specs/html/elements/pre.html.snap b/crates/biome_html_formatter/tests/specs/html/elements/pre.html.snap
new file mode 100644
index 000000000000..03b6e5a24b53
--- /dev/null
+++ b/crates/biome_html_formatter/tests/specs/html/elements/pre.html.snap
@@ -0,0 +1,52 @@
+---
+source: crates/biome_formatter_test/src/snapshot_builder.rs
+info: elements/pre.html
+---
+# Input
+
+```html
+<pre>
+	___                       ___           ___           ___
+	/\  \          ___        /\  \         /\__\         /\  \
+ /::\  \        /\  \      /::\  \       /::|  |       /::\  \
+/:/\:\  \       \:\  \    /:/\:\  \     /:|:|  |      /:/\:\  \
+/::\~\:\__\      /::\__\  /:/  \:\  \   /:/|:|__|__   /::\~\:\  \
+/:/\:\ \:|__|  __/:/\/__/ /:/__/ \:\__\ /:/ |::::\__\ /:/\:\ \:\__\
+\:\~\:\/:/  / /\/:/  /    \:\  \ /:/  / \/__/~~/:/  / \:\~\:\ \/__/
+\:\ \::/  /  \::/__/      \:\  /:/  /        /:/  /   \:\ \:\__\
+\:\/:/  /    \:\__\       \:\/:/  /        /:/  /     \:\ \/__/
+ \::/__/      \/__/        \::/  /        /:/  /       \:\__\
+	~~                        \/__/         \/__/         \/__/
+</pre>
+
+```
+
+
+=============================
+
+# Outputs
+
+## Output 1
+
+-----
+Indent style: Tab
+Indent width: 2
+Line ending: LF
+Line width: 80
+Attribute Position: Auto
+-----
+
+```html
+<pre>___                       ___           ___           ___
+	/\  \          ___        /\  \         /\__\         /\  \
+ /::\  \        /\  \      /::\  \       /::|  |       /::\  \
+/:/\:\  \       \:\  \    /:/\:\  \     /:|:|  |      /:/\:\  \
+/::\~\:\__\      /::\__\  /:/  \:\  \   /:/|:|__|__   /::\~\:\  \
+/:/\:\ \:|__|  __/:/\/__/ /:/__/ \:\__\ /:/ |::::\__\ /:/\:\ \:\__\
+\:\~\:\/:/  / /\/:/  /    \:\  \ /:/  / \/__/~~/:/  / \:\~\:\ \/__/
+\:\ \::/  /  \::/__/      \:\  /:/  /        /:/  /   \:\ \:\__\
+\:\/:/  /    \:\__\       \:\/:/  /        /:/  /     \:\ \/__/
+ \::/__/      \/__/        \::/  /        /:/  /       \:\__\
+	~~                        \/__/         \/__/         \/__/
+</pre>
+```