diff --git a/src/prompt_toolkit/formatted_text/html.py b/src/prompt_toolkit/formatted_text/html.py
index a940ac8f8..9265bc18f 100644
--- a/src/prompt_toolkit/formatted_text/html.py
+++ b/src/prompt_toolkit/formatted_text/html.py
@@ -54,9 +54,9 @@ def get_current_style() -> str:
def process_node(node: Any) -> None:
"Process node recursively."
for child in node.childNodes:
- if child.nodeType == child.TEXT_NODE:
+ if child.nodeType in (child.TEXT_NODE, child.CDATA_SECTION_NODE):
result.append((get_current_style(), child.data))
- else:
+ elif child.nodeType == child.ELEMENT_NODE:
add_to_name_stack = child.nodeName not in (
"#document",
"html-root",
diff --git a/tests/test_html_nodes.py b/tests/test_html_nodes.py
new file mode 100644
index 000000000..5346c57a0
--- /dev/null
+++ b/tests/test_html_nodes.py
@@ -0,0 +1,50 @@
+from __future__ import annotations
+
+import io
+
+import pytest
+
+from prompt_toolkit import print_formatted_text
+from prompt_toolkit.formatted_text import HTML, to_formatted_text
+
+
+@pytest.mark.parametrize(
+ "markup, expected",
+ [
+ ("", []),
+ ("beforeafter", [("", "before"), ("", "after")]),
+ (
+ "beforeafter",
+ [("class:b", "before"), ("class:b", "after")],
+ ),
+ (
+ 'after',
+ [("class:b fg:ansired", "text"), ("", "after")],
+ ),
+ ("visible", [("", "visible")]),
+ (
+ "beforeafter",
+ [("class:b", "before"), ("class:b", "after")],
+ ),
+ ("", [("", "a < b & c")]),
+ (
+ 'literal]]>after',
+ [("class:b fg:ansired", "literal"), ("", "after")],
+ ),
+ (
+ "beforeafter",
+ [("class:b", "before"), ("class:b", " & "), ("class:b", "after")],
+ ),
+ ],
+)
+def test_html_non_element_nodes(markup, expected):
+ assert to_formatted_text(HTML(markup)) == expected
+
+
+def test_print_html_with_comments_and_cdata():
+ output = io.StringIO()
+ print_formatted_text(
+ HTML("Result: "),
+ file=output,
+ )
+ assert output.getvalue() == "Result: x < 3\r\n"