and blocks to Markdown - that should stay as HTML
+ // except if the current node is a code tag, which needs to be converted by the CodeConverter.
+ if ($element->isDescendantOf(['pre', 'code']) && $element->getTagName() !== 'code') {
+ return;
+ }
+
+ // Give converter a chance to inspect/modify the DOM before children are converted
+ $converter = $this->environment->getConverterByTag($element->getTagName());
+ if ($converter instanceof PreConverterInterface) {
+ $converter->preConvert($element);
+ }
+
+ // If the node has children, convert those to Markdown first
+ if ($element->hasChildren()) {
+ foreach ($element->getChildren() as $child) {
+ $this->convertChildren($child);
+ }
+ }
+
+ // Now that child nodes have been converted, convert the original node
+ $markdown = $this->convertToMarkdown($element);
+
+ // Create a DOM text node containing the Markdown equivalent of the original node
+
+ // Replace the old $node e.g. 'Title
' with the new $markdown_node e.g. '### Title'
+ $element->setFinalMarkdown($markdown);
+ }
+
+ /**
+ * Convert to Markdown
+ *
+ * Converts an individual node into a #text node containing a string of its Markdown equivalent.
+ *
+ * Example: An node with text content of 'Title' becomes a text node with content of '### Title'
+ *
+ * @return string The converted HTML as Markdown
+ */
+ protected function convertToMarkdown(ElementInterface $element): string
+ {
+ $tag = $element->getTagName();
+
+ // Strip nodes named in remove_nodes
+ $tagsToRemove = \explode(' ', Coerce::toString($this->getConfig()->getOption('remove_nodes') ?? ''));
+ if (\in_array($tag, $tagsToRemove, true)) {
+ return '';
+ }
+
+ $converter = $this->environment->getConverterByTag($tag);
+
+ return $converter->convert($element);
+ }
+
+ protected function sanitize(string $markdown): string
+ {
+ $markdown = \html_entity_decode($markdown, ENT_QUOTES, 'UTF-8');
+ $markdown = \preg_replace('/]+>/', '', $markdown); // Strip doctype declaration
+ \assert($markdown !== null);
+ $markdown = \trim($markdown); // Remove blank spaces at the beggining of the html
+
+ /*
+ * Removing unwanted tags. Tags should be added to the array in the order they are expected.
+ * XML, html and body opening tags should be in that order. Same case with closing tags
+ */
+ $unwanted = ['', '', '', '', '', '', '', '
'];
+
+ foreach ($unwanted as $tag) {
+ if (\strpos($tag, '/') === false) {
+ // Opening tags
+ if (\strpos($markdown, $tag) === 0) {
+ $markdown = \substr($markdown, \strlen($tag));
+ }
+ } else {
+ // Closing tags
+ if (\strpos($markdown, $tag) === \strlen($markdown) - \strlen($tag)) {
+ $markdown = \substr($markdown, 0, -\strlen($tag));
+ }
+ }
+ }
+
+ return \trim($markdown, "\n\r\0\x0B");
+ }
+
+ /**
+ * Pass a series of key-value pairs in an array; these will be passed
+ * through the config and set.
+ * The advantage of this is that it can allow for static use (IE in Laravel).
+ * An example being:
+ *
+ * HtmlConverter::setOptions(['strip_tags' => true])->convert('test
');
+ *
+ * @param array $options
+ *
+ * @return $this
+ */
+ public function setOptions(array $options)
+ {
+ $config = $this->getConfig();
+
+ foreach ($options as $key => $option) {
+ $config->setOption($key, $option);
+ }
+
+ return $this;
+ }
+}
diff --git a/tests/HtmlConverterTest.php b/tests/HtmlConverterTest.php
index 673bff1..e62247e 100644
--- a/tests/HtmlConverterTest.php
+++ b/tests/HtmlConverterTest.php
@@ -293,15 +293,13 @@ EOT;
$this->assertHtmlGivesMarkdown(' one line with spaces
', "```\n one line with spaces \n```");
$this->assertHtmlGivesMarkdown('', "```\n```");
$this->assertHtmlGivesMarkdown('', "```\n```\n\n```\n```");
- $this->assertHtmlGivesMarkdown("\n
", "```\n```");
+ $this->assertHtmlGivesMarkdown("\n
", "```\n\n```");
$this->assertHtmlGivesMarkdown("foo\n
", "```\nfoo\n```");
- $this->assertHtmlGivesMarkdown("\nfoo
", "```\nfoo\n```");
- $this->assertHtmlGivesMarkdown("\nfoo\n
", "```\nfoo\n```");
- $this->assertHtmlGivesMarkdown("\r\nfoo
", "```\nfoo\n```");
- $this->assertHtmlGivesMarkdown("\n\nfoo
", "```\n\nfoo\n```");
- $this->assertHtmlGivesMarkdown("\n\n
", "```\n\n```");
- $this->assertHtmlGivesMarkdown("\n\n\n
", "```\n\n\n```");
- $this->assertHtmlGivesMarkdown("\n
\n
", "```\n```\n\n```\n```");
+ $this->assertHtmlGivesMarkdown("\nfoo
", "```\n\nfoo\n```");
+ $this->assertHtmlGivesMarkdown("\nfoo\n
", "```\n\nfoo\n```");
+ $this->assertHtmlGivesMarkdown("\n\n
", "```\n\n\n```");
+ $this->assertHtmlGivesMarkdown("\n\n\n
", "```\n\n\n\n```");
+ $this->assertHtmlGivesMarkdown("\n
\n
", "```\n\n```\n\n```\n\n```");
$this->assertHtmlGivesMarkdown("one\ntwo\r\nthree
\nline
", "```\none\ntwo\nthree\n```\n\nline");
$this->assertHtmlGivesMarkdown("test with attributes
", "```\ntest with attributes\n```");
}