Skip to content

Commit 1cb1638

Browse files
bigsweatercolinodell
authored andcommitted
Find and move any misplaced comment nodes
1 parent 426f2e8 commit 1cb1638

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/HtmlConverter.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,45 @@ private function createDOMDocument(string $html): \DOMDocument
121121
$document->loadHTML('<?xml encoding="UTF-8">' . $html);
122122
$document->encoding = 'UTF-8';
123123

124+
$this->replaceMisplacedComments($document);
125+
124126
if ($this->getConfig()->getOption('suppress_errors')) {
125127
\libxml_clear_errors();
126128
}
127129

128130
return $document;
129131
}
130132

133+
/**
134+
* Finds any comment nodes outside <html> element and moves them into <body>.
135+
*
136+
* @see https://github.com/thephpleague/html-to-markdown/issues/212
137+
* @see https://3v4l.org/7bC33
138+
*/
139+
private function replaceMisplacedComments(\DOMDocument $document): void
140+
{
141+
// Find ny comment nodes at the root of the document.
142+
$misplacedComments = (new \DOMXPath($document))->query('/comment()');
143+
if ($misplacedComments === false) {
144+
return;
145+
}
146+
147+
$body = $document->getElementsByTagName('body')->item(0);
148+
if ($body === null) {
149+
return;
150+
}
151+
152+
// Loop over comment nodes in reverse so we put them inside <body> in
153+
// their original order.
154+
for ($index = $misplacedComments->length - 1; $index >= 0; $index--) {
155+
if ($body->firstChild === null) {
156+
$body->insertBefore($misplacedComments[$index]);
157+
} else {
158+
$body->insertBefore($misplacedComments[$index], $body->firstChild);
159+
}
160+
}
161+
}
162+
131163
/**
132164
* Convert Children
133165
*

tests/HtmlConverterTest.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,14 +327,21 @@ public function testStripUnmarkdownable(): void
327327
public function testStripComments(): void
328328
{
329329
$this->assertHtmlGivesMarkdown('<p>Test</p><!-- Test comment -->', 'Test');
330+
$this->assertHtmlGivesMarkdown('<!-- Test comment --><p>Test</p>', 'Test');
330331
$this->assertHtmlGivesMarkdown('<p>Test</p><!-- Test comment -->', 'Test', ['strip_tags' => true]);
332+
$this->assertHtmlGivesMarkdown('<!-- Test comment --><p>Test</p>', 'Test', ['strip_tags' => true]);
331333
}
332334

333335
public function testPreserveComments(): void
334336
{
335-
$this->assertHtmlGivesMarkdown('<p>Test</p><!-- Test comment -->', "Test\n\n<!-- Test comment -->", ['preserve_comments' => true]);
336337
$this->assertHtmlGivesMarkdown('<p>Test</p><!-- more -->', "Test\n\n<!-- more -->", ['preserve_comments' => ['more']]);
337338
$this->assertHtmlGivesMarkdown('<p>Test</p><!-- Test comment --><!-- more -->', "Test\n\n<!-- more -->", ['preserve_comments' => ['more']]);
339+
$this->assertHtmlGivesMarkdown('<!-- Test comment --><p>Test</p><!-- Test comment -->', "<!-- Test comment -->Test\n\n<!-- Test comment -->", ['preserve_comments' => true]);
340+
}
341+
342+
public function testPreserveCommentOrder(): void
343+
{
344+
$this->assertHtmlGivesMarkdown('<!-- 1 --><!-- 2 --><p>Test</p><!-- 3 -->', "<!-- 1 --><!-- 2 -->Test\n\n<!-- 3 -->", ['preserve_comments' => true]);
338345
}
339346

340347
public function testPreserveWhitespace(): void

0 commit comments

Comments
 (0)