diff --git a/CHANGELOG.md b/CHANGELOG.md
index a865083..6b55f67 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip
- Fixed a line of only `=` or `-` after a line break not being escaped, which made a heading out of the line before it, such as in `
Foo
=
` (#226). Lines of `-` were already escaped inside of paragraphs, but not inside of list items, blockquotes or headings.
- Fixed emphasis next to an empty one of the same kind losing one of its delimiters, such as ` hello` becoming ` hello**` (#252). Emphasis next to one of the same kind which is removed with `remove_nodes` also lost one.
+- Fixed `</body>` or `</html>` in code or comments causing the document's own closing tags to be output after it, and everything from `<!DOCTYPE ` in code up to the next `>` being removed, which could be the rest of the document (#254)
## [5.2.3] - 2026-10-19
diff --git a/src/HtmlConverter.php b/src/HtmlConverter.php
index 8c29ac8..66bcbe1 100644
--- a/src/HtmlConverter.php
+++ b/src/HtmlConverter.php
@@ -651,7 +651,8 @@ private function endsOnBlankLine(ElementInterface $element, ConverterInterface $
protected function sanitize(string $markdown): string
{
$markdown = \html_entity_decode($markdown, ENT_QUOTES, 'UTF-8');
- $markdown = \preg_replace('/]+>/', '', $markdown); // Strip doctype declaration
+ // Only the declaration itself, which comes first, as code could contain the same text once decoded
+ $markdown = \preg_replace('/^]+>/', '', $markdown);
\assert($markdown !== null);
$markdown = \trim($markdown); // Remove blank spaces at the beggining of the html
@@ -668,8 +669,8 @@ protected function sanitize(string $markdown): string
$markdown = \substr($markdown, \strlen($tag));
}
} else {
- // Closing tags
- if (\strpos($markdown, $tag) === \strlen($markdown) - \strlen($tag)) {
+ // Closing tags, which code before them could also contain once decoded
+ if (\substr($markdown, -\strlen($tag)) === $tag) {
$markdown = \substr($markdown, 0, -\strlen($tag));
}
}
diff --git a/tests/HtmlConverterTest.php b/tests/HtmlConverterTest.php
index f97810d..b2eaa11 100644
--- a/tests/HtmlConverterTest.php
+++ b/tests/HtmlConverterTest.php
@@ -393,6 +393,22 @@ public function testCodeContainingTextWhichLooksLikeItsOwnTags(): void
$this->assertHtmlGivesMarkdown('x
', '`x`');
}
+ /**
+ * @see https://github.com/thephpleague/html-to-markdown/issues/254
+ */
+ public function testCodeContainingTextWhichLooksLikeDocumentTags(): void
+ {
+ $this->assertHtmlGivesMarkdown('</body>
', "```\n