From e017c9ceda7dfc3ebf882fb886c2f0b0a508e68c Mon Sep 17 00:00:00 2001 From: upstream Date: Fri, 4 Sep 2026 09:09:04 +0200 Subject: [PATCH] Upstream thephpleague/html-to-markdown state of the touched files before b7d420c301 --- src/Converter/ListItemConverter.php | 71 +++++ tests/HtmlConverterTest.php | 425 ++++++++++++++++++++++++++++ 2 files changed, 496 insertions(+) create mode 100644 src/Converter/ListItemConverter.php create mode 100644 tests/HtmlConverterTest.php diff --git a/src/Converter/ListItemConverter.php b/src/Converter/ListItemConverter.php new file mode 100644 index 0000000..d71f601 --- /dev/null +++ b/src/Converter/ListItemConverter.php @@ -0,0 +1,71 @@ +config = $config; + } + + public function convert(ElementInterface $element): string + { + // If parent is an ol, use numbers, otherwise, use dashes + $listType = ($parent = $element->getParent()) ? $parent->getTagName() : 'ul'; + + // Add spaces to start for nested list items + $level = $element->getListItemLevel(); + + $value = \trim(\implode("\n" . ' ', \explode("\n", \trim($element->getValue())))); + + // If list item is the first in a nested list, add a newline before it + $prefix = ''; + if ($level > 0 && $element->getSiblingPosition() === 1) { + $prefix = "\n"; + } + + if ($listType === 'ul') { + $listItemStyle = Coerce::toString($this->config->getOption('list_item_style', '-')); + $listItemStyleAlternate = Coerce::toString($this->config->getOption('list_item_style_alternate', '')); + if (! isset($this->listItemStyle)) { + $this->listItemStyle = $listItemStyleAlternate ?: $listItemStyle; + } + + if ($listItemStyleAlternate && $level === 0 && $element->getSiblingPosition() === 1) { + $this->listItemStyle = $this->listItemStyle === $listItemStyle ? $listItemStyleAlternate : $listItemStyle; + } + + return $prefix . $this->listItemStyle . ' ' . $value . "\n"; + } + + if ($listType === 'ol' && ($parent = $element->getParent()) && ($start = \intval($parent->getAttribute('start')))) { + $number = $start + $element->getSiblingPosition() - 1; + } else { + $number = $element->getSiblingPosition(); + } + + return $prefix . $number . '. ' . $value . "\n"; + } + + /** + * @return string[] + */ + public function getSupportedTags(): array + { + return ['li']; + } +} diff --git a/tests/HtmlConverterTest.php b/tests/HtmlConverterTest.php new file mode 100644 index 0000000..4b71832 --- /dev/null +++ b/tests/HtmlConverterTest.php @@ -0,0 +1,425 @@ + $options + * @param ConverterInterface[] $converters + */ + private function assertHtmlGivesMarkdown(string $html, string $expectedMarkdown, array $options = [], array $converters = []): void + { + $markdown = new HtmlConverter($options); + foreach ($converters as $converter) { + $markdown->getEnvironment()->addConverter($converter); + } + + $result = $markdown->convert($html); + $this->assertSame($expectedMarkdown, $result); + } + + public function testEmptyInput(): void + { + $this->assertHtmlGivesMarkdown('', ''); + $this->assertHtmlGivesMarkdown(' ', ''); + } + + public function testPlainText(): void + { + $this->assertHtmlGivesMarkdown('test', 'test'); + $this->assertHtmlGivesMarkdown('

test

', 'test'); + + //expected result is in the comment for better readability + $this->assertHtmlGivesMarkdown('

*test*

', '\\*test\\*'); // \*test\* + $this->assertHtmlGivesMarkdown('

_test_

', '\\_test\\_'); // \_test\_ + $this->assertHtmlGivesMarkdown('

\\*test\\*

', '\\\\\\*test\\\\\\*'); // \\\*test\\\* + $this->assertHtmlGivesMarkdown('

test[test]

', 'test\\[test\\]'); // test\[test\] + + // Markdown-like syntax in
text should be preserved as-is - no escaping + $this->assertHtmlGivesMarkdown('
_test_
', '
_test_
'); + $this->assertHtmlGivesMarkdown('
*test*
', '
*test*
'); + + $this->assertHtmlGivesMarkdown('

\ ` * _ { } [ ] ( ) > > # + - . !

', '\\\\ ` \* \_ { } \[ \] ( ) > > # + - . !'); + } + + public function testLineBreaks(): void + { + $this->assertHtmlGivesMarkdown("test\nanother line", 'test another line'); + $this->assertHtmlGivesMarkdown("

test\nanother line

", 'test another line'); + $this->assertHtmlGivesMarkdown("

test
\nanother line

", "test \nanother line"); + $this->assertHtmlGivesMarkdown("

test
\n another line

", "test \n another line"); + $this->assertHtmlGivesMarkdown("

test
\nanother line

", "test \n*another* line"); + $this->assertHtmlGivesMarkdown('

test
another line

', "test \nanother line"); + $this->assertHtmlGivesMarkdown('

test
another line

', "test \nanother line"); + $this->assertHtmlGivesMarkdown('

test
another line

', "test \nanother line"); + $this->assertHtmlGivesMarkdown('

test
another line

', "test \nanother line"); + $this->assertHtmlGivesMarkdown('

test
another line

', "test\nanother line", ['hard_break' => true]); + $this->assertHtmlGivesMarkdown('

test
another line

', "test\nanother line", ['hard_break' => true]); + $this->assertHtmlGivesMarkdown('

test
another line

', "test\nanother line", ['hard_break' => true]); + $this->assertHtmlGivesMarkdown('

test
another line

', "test\nanother line", ['hard_break' => true]); + $this->assertHtmlGivesMarkdown('

foo

bar

baz

', "foo\n\n
bar
\n\nbaz"); + } + + public function testHeaders(): void + { + $this->assertHtmlGivesMarkdown('

Test

', "Test\n===="); + $this->assertHtmlGivesMarkdown('

Test

', "Test\n----"); + $this->assertHtmlGivesMarkdown('

Test

', '> # Test'); + $this->assertHtmlGivesMarkdown('

Test

', '> ## Test'); + $this->assertHtmlGivesMarkdown('

Test

', '### Test'); + $this->assertHtmlGivesMarkdown('

Test

', '#### Test'); + $this->assertHtmlGivesMarkdown('
Test
', '##### Test'); + $this->assertHtmlGivesMarkdown('
Test
', '###### Test'); + $this->assertHtmlGivesMarkdown('

', ''); + $this->assertHtmlGivesMarkdown('

', ''); + $this->assertHtmlGivesMarkdown('

', ''); + $this->assertHtmlGivesMarkdown('

# Test

', "\# Test\n======="); + $this->assertHtmlGivesMarkdown('

# Test #

', "\# Test #\n========="); + $this->assertHtmlGivesMarkdown('

Mismatched Tags

', '### Mismatched Tags'); + } + + public function testSpans(): void + { + $this->assertHtmlGivesMarkdown('Test', '*Test*'); + $this->assertHtmlGivesMarkdown('Test', '*Test*'); + $this->assertHtmlGivesMarkdown('Test', '**Test**'); + $this->assertHtmlGivesMarkdown('Test', '**Test**'); + $this->assertHtmlGivesMarkdown('Test', '*Test*', ['italic_style' => '*']); + $this->assertHtmlGivesMarkdown('Italic and a bold', '*Italic* and a __bold__', ['italic_style' => '*', 'bold_style' => '__']); + $this->assertHtmlGivesMarkdown('Test', '_Test_', ['italic_style' => '_']); + $this->assertHtmlGivesMarkdown('Test', '__Test__', ['bold_style' => '__']); + $this->assertHtmlGivesMarkdown('Test', '__Test__', ['bold_style' => '__']); + $this->assertHtmlGivesMarkdown('Test', 'Test'); + $this->assertHtmlGivesMarkdown('Bold Italic', '**Bold** *Italic*'); + $this->assertHtmlGivesMarkdown('BoldItalic', '**Bold***Italic*'); + $this->assertHtmlGivesMarkdown('This is a test', '*This is **a test***'); + $this->assertHtmlGivesMarkdown('This is a test', '*This is* **a** test'); + $this->assertHtmlGivesMarkdown('Emphasis with no text preserves spaces.', 'Emphasis with no text **preserves** spaces.'); + $this->assertHtmlGivesMarkdown("Emphasis discards \nline breaks", 'Emphasis discards line breaks'); + $this->assertHtmlGivesMarkdown('Emphasis preserves
HTML breaks', "Emphasis preserves \nHTML breaks"); + } + + public function testConsecutiveSpans(): void + { + $this->assertHtmlGivesMarkdown('FooBar', '*FooBar*'); + $this->assertHtmlGivesMarkdown('FooBar', '*FooBar*'); + $this->assertHtmlGivesMarkdown('FooBarFoo', '*FooBarFoo*'); + $this->assertHtmlGivesMarkdown('FooBar', '**FooBar**'); + $this->assertHtmlGivesMarkdown('FooBar', '**FooBar**'); + $this->assertHtmlGivesMarkdown('FooBarFoo', '**FooBarFoo**'); + $this->assertHtmlGivesMarkdown('Foo Bar', '*Foo* *Bar*'); + $this->assertHtmlGivesMarkdown('Foo Bar', '**Foo** **Bar**'); + $this->assertHtmlGivesMarkdown('FooBarFoo', '**FooBar***Foo*'); + } + + public function testNesting(): void + { + $this->assertHtmlGivesMarkdown('Test', 'Test'); + } + + public function testScript(): void + { + $this->assertHtmlGivesMarkdown("", ""); + } + + public function testImage(): void + { + $this->assertHtmlGivesMarkdown('alt text', '![alt text](/path/img.jpg "Title")'); + } + + public function testAnchor(): void + { + $this->assertHtmlGivesMarkdown('http://modernnerd.net', ''); + $this->assertHtmlGivesMarkdown('Modern Nerd', '[Modern Nerd](http://modernnerd.net "Title")'); + $this->assertHtmlGivesMarkdown('Modern Nerd Modern Nerd', '[Modern Nerd](http://modernnerd.net "Title") [Modern Nerd](http://modernnerd.net "Title")'); + $this->assertHtmlGivesMarkdown('

Modern Nerd

', '[### Modern Nerd](http://modernnerd.net)'); + $this->assertHtmlGivesMarkdown('The Modern Nerd (MN)', 'The [Modern Nerd ](http://modernnerd.net)(MN)'); + $this->assertHtmlGivesMarkdown('alt text', '[![alt text](/path/img.jpg "Title")](http://modernnerd.net/ "Title")'); + $this->assertHtmlGivesMarkdown('alt text Test', '[![alt text](/path/img.jpg "Title") Test](http://modernnerd.net/ "Title")'); + + // Placeholder links and fragment identifiers + $this->assertHtmlGivesMarkdown('Test', 'Test'); + $this->assertHtmlGivesMarkdown('Test', 'Test'); + $this->assertHtmlGivesMarkdown('Test', '[Test](#nerd "Title")'); + $this->assertHtmlGivesMarkdown('Test', '[Test](#nerd)'); + + // Strip placeholder links + $this->assertHtmlGivesMarkdown('Test', 'Test', ['strip_placeholder_links' => true]); + $this->assertHtmlGivesMarkdown('Test', 'Test', ['strip_placeholder_links' => true]); + $this->assertHtmlGivesMarkdown('Test', '[Test](#nerd "Title")', ['strip_placeholder_links' => true]); + $this->assertHtmlGivesMarkdown('Test', '[Test](#nerd)', ['strip_placeholder_links' => true]); + + // Autolinking + $this->assertHtmlGivesMarkdown('test', '[test](test)'); + $this->assertHtmlGivesMarkdown('google.com', '[google.com](google.com)'); + $this->assertHtmlGivesMarkdown('https://www.google.com', ''); + $this->assertHtmlGivesMarkdown('ftp://files.example.com', ''); + $this->assertHtmlGivesMarkdown('test@example.com', ''); + $this->assertHtmlGivesMarkdown('test+foo@example.bar-baz.com', ''); + + // Autolinking can be toggled off + $this->assertHtmlGivesMarkdown('https://www.google.com', '[https://www.google.com](https://www.google.com)', ['use_autolinks' => false]); + $this->assertHtmlGivesMarkdown('Google', '[Google](https://www.google.com)', ['use_autolinks' => false]); + $this->assertHtmlGivesMarkdown('google.com', '[google.com](google.com)', ['use_autolinks' => false]); + } + + public function testHorizontalRule(): void + { + $this->assertHtmlGivesMarkdown('
', '---'); + $this->assertHtmlGivesMarkdown('
', '---'); + $this->assertHtmlGivesMarkdown('
', '---'); + $this->assertHtmlGivesMarkdown('
', '---'); + $this->assertHtmlGivesMarkdown('

Test


', "Test\n\n---"); + } + + public function testLists(): void + { + $this->assertHtmlGivesMarkdown('
  • Item A
  • Item B
  • Item C
', "- Item A\n- Item B\n- Item C"); + $this->assertHtmlGivesMarkdown('
  • Item A
  • Item B
', "- Item A\n- Item B"); + $this->assertHtmlGivesMarkdown('
  • Item A

    Description

  • Item B
', "- ### Item A\n \n Description\n- Item B"); + $this->assertHtmlGivesMarkdown('
  • First
  • Second
', "* First\n* Second", ['list_item_style' => '*']); + $this->assertHtmlGivesMarkdown('
  1. Item A
  2. Item B
', "1. Item A\n2. Item B"); + $this->assertHtmlGivesMarkdown("
    \n
  1. Item A
  2. \n
  3. Item B
  4. \n
", "1. Item A\n2. Item B"); + $this->assertHtmlGivesMarkdown('
  1. Item A
  2. Item B
', "1. Item A\n2. Item B"); + $this->assertHtmlGivesMarkdown('
  1. Item A

    Description

  2. Item B
', "1. ### Item A\n \n Description\n2. Item B"); + $this->assertHtmlGivesMarkdown('
  1. Item A
  2. Item B
', "120. Item A\n121. Item B"); + $this->assertHtmlGivesMarkdown('
  • first item of first list
  • second item of first list
  • first item of second list
', "- first item of first list\n- second item of first list\n\n* first item of second list", ['list_item_style_alternate' => '*']); + } + + public function testNestedLists(): void + { + $this->assertHtmlGivesMarkdown('
  • Item A
  • Item B
    • Nested A
    • Nested B
  • Item C
', "- Item A\n- Item B\n - Nested A\n - Nested B\n- Item C"); + $this->assertHtmlGivesMarkdown('
  • Item A
    1. Nested A
  • Item B
', "- Item A\n 1. Nested A\n- Item B"); + $this->assertHtmlGivesMarkdown('
  1. Item A
    • Nested A
  2. Item B
', "1. Item A\n - Nested A\n2. Item B"); + } + + public function testComplexNestedLists(): void + { + $this->assertHtmlGivesMarkdown("
    \n
  • Item A
  • \n
  • Item B\n
      \n
    • Nested A
    • \n
    • Nested B\n
        \n
      • Subnested A
      • \n
      • Subnested B
      • \n
      \n
    • \n
    \n
  • \n
  • Item C
  • \n
", "- Item A\n- Item B \n - Nested A\n - Nested B \n - Subnested A\n - Subnested B\n- Item C"); + $this->assertHtmlGivesMarkdown("
    \n
  • Item A
  • \n
  • Item B

    \n

    Paragraph Item B

    \n
      \n
    • Nested A
    • \n
    • Nested B\n
        \n
      • Subnested A
      • \n
      • Subnested B
      • \n
      \n
    • \n
    \n
  • \n
  • Item C
  • \n
", "* Item A\n* ## Item B\n \n Paragraph Item B\n \n \n * Nested A\n * Nested B \n * Subnested A\n * Subnested B\n* Item C", ['list_item_style' => '*', 'header_style' => 'atx']); + $this->assertHtmlGivesMarkdown("
    \n
  • Item A
  • \n
  • Item B

    \n

    Paragraph Item B

    \n
      \n
    • Nested A
    • \n
    • Nested B

      \n

      Paragraph Nested B

      \n
        \n
      • Subnested A
      • \n
      • Subnested B\n
          \n
        • Subsubnested A
        • \n
        • Subsubnested B

          \n

          Paragraph Subsubnested B

          \n
            \n
          • Subsubsubnested A
          • \n
          • Subsubsubnested B
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    \n
  • \n
  • Item C
  • \n
", "* Item A\n* ## Item B\n \n Paragraph Item B\n \n \n * Nested A\n * ## Nested B\n \n Paragraph Nested B\n \n \n * Subnested A\n * Subnested B \n * Subsubnested A\n * ## Subsubnested B\n \n Paragraph Subsubnested B\n \n \n * Subsubsubnested A\n * Subsubsubnested B\n* Item C", ['list_item_style' => '*', 'header_style' => 'atx']); + $this->assertHtmlGivesMarkdown("
    \n
  • Item A
  • \n
  • Item B\n
      \n
    • Nested A
    • \n
    • Nested B\n
        \n
      • Subnested A
      • \n
      • Subnested B\n
          \n
        • Subsubnested A
        • \n
        • Subsubnested B \n
            \n
          • Subsubsubnested A
          • \n
          • Subsubsubnested B
          • \n
          \n
        • \n
        \n
      • \n
      \n
    • \n
    \n
  • \n
  • Item C
  • \n
", "* Item A\n* Item B \n * Nested A\n * Nested B \n * Subnested A\n * Subnested B \n * Subsubnested A\n * Subsubnested B \n * Subsubsubnested A\n * Subsubsubnested B\n* Item C", ['list_item_style' => '*', 'header_style' => 'atx']); + } + + public function testListLikeThingsWhichArentLists(): void + { + $this->assertHtmlGivesMarkdown('

120.

', '120\.'); + $this->assertHtmlGivesMarkdown('

120.

', '120\.'); + $this->assertHtmlGivesMarkdown('

120.00

', '120.00'); + $this->assertHtmlGivesMarkdown('

120.00 USD

', '120.00 USD'); + } + + public function testTables(): void + { + $opt = []; + $conv = [new TableConverter()]; + $this->assertHtmlGivesMarkdown('
A
', "| A |\n|---|", $opt, $conv); + $this->assertHtmlGivesMarkdown('
A
', "| A |\n|---|", $opt, $conv); + $this->assertHtmlGivesMarkdown('
AB
ab
cd
', "| A | B |\n|---|---|\n| a | b |\n| c | d |", $opt, $conv); + $this->assertHtmlGivesMarkdown('
AB
afoo
', "| A | B |\n|---|---|\n| a | `foo` |", $opt, $conv); + $this->assertHtmlGivesMarkdown('
AB
afoobar
', "| A | B |\n|---|---|\n| a | *foo*bar |", $opt, $conv); + $this->assertHtmlGivesMarkdown('
AB
a

foo

bar
', "| A | B |\n|---|---|\n| a | foo bar |", $opt, $conv); + $this->assertHtmlGivesMarkdown('
link
', "| [link](http://example.com) |\n|---|", $opt, $conv); + $this->assertHtmlGivesMarkdown('
A
a | b
', "| A |\n|---|\n| a \\| b |", $opt, $conv); + $this->assertHtmlGivesMarkdown('
A
a | b
', "| A |\n|---|\n| a ][ b |", ['table_pipe_escape' => ']['], $conv); + $this->assertHtmlGivesMarkdown('
Cap
A
', "Cap\n| A |\n|---|", ['table_caption_side' => 'top'], $conv); + $this->assertHtmlGivesMarkdown('
Cap
A
', "| A |\n|---|\nCap", ['table_caption_side' => 'bottom'], $conv); + $this->assertHtmlGivesMarkdown('
Cap
A
', "| A |\n|---|", ['table_caption_side' => null], $conv); + $this->assertHtmlGivesMarkdown('
A
', "| A |\n|:--|", $opt, $conv); + $this->assertHtmlGivesMarkdown('
A
', "| A |\n|--:|", $opt, $conv); + $this->assertHtmlGivesMarkdown('
A
', "| A |\n|:-:|", $opt, $conv); + $this->assertHtmlGivesMarkdown('
A
', "| A |\n|---|", $opt, $conv); + $html = <<<'EOT' + + + + + + + + + + + + + + + + + + + + + + +
BatmanRobinThe FlashKid Flash
SkillSmartsDex, acrobatSuper speedSuper speed
+EOT; + $this->assertHtmlGivesMarkdown($html, "| | Batman | Robin | The Flash | Kid Flash |\n|---|---|---|---|---|\n| Skill | Smarts | Dex, acrobat | Super speed | Super speed |", $opt, $conv); + } + + public function testCodeSamples(): void + { + $this->assertHtmlGivesMarkdown('<p>Some sample HTML</p>', '`

Some sample HTML

`'); + $this->assertHtmlGivesMarkdown("\n<p>Some sample HTML</p>\n<p>And another line</p>\n", '`

Some sample HTML

And another line

`'); + $this->assertHtmlGivesMarkdown('`', '```'); + $this->assertHtmlGivesMarkdown('test', '`test`'); + $this->assertHtmlGivesMarkdown('test `` test', '`test `` test`'); + $this->assertHtmlGivesMarkdown('test` `test', "```\ntest` `test\n```"); + $this->assertHtmlGivesMarkdown("

\n<p>Some sample HTML</p>\n<p>And another line</p>\n

Paragraph after code.

", "`

Some sample HTML

And another line

`\n\nParagraph after code."); + $this->assertHtmlGivesMarkdown("

\n#sidebar h1 {\n font-size: 1.5em;\n font-weight: bold;\n}\n

", '`#sidebar h1 { font-size: 1.5em; font-weight: bold;}`'); + $this->assertHtmlGivesMarkdown("

#sidebar h1 {\n font-size: 1.5em;\n font-weight: bold;\n}\n

", '`#sidebar h1 { font-size: 1.5em; font-weight: bold;}`'); + $this->assertHtmlGivesMarkdown('
<p>Some sample HTML</p>
', "```\n

Some sample HTML

\n```"); + $this->assertHtmlGivesMarkdown('
<?php //Some php code ?>
', "```php\n\n```"); + $this->assertHtmlGivesMarkdown("
<?php //Some multiline php code\n\$myVar = 2; ?>
", "```php\n\n```"); + $this->assertHtmlGivesMarkdown("
<p>Multiline HTML</p>\n<p>Here's the second line</p>
", "```\n

Multiline HTML

\n

Here's the second line

\n```"); + $this->assertHtmlGivesMarkdown("
<p>Multiline HTML</p>\n<p>Here's the second line</p>
\n

line

", "```\n

Multiline HTML

\n

Here's the second line

\n```\n\nline"); + } + + public function testPreformat(): void + { + $this->assertHtmlGivesMarkdown("
test\ntest\r\ntest
", "```\ntest\ntest\ntest\n```"); + $this->assertHtmlGivesMarkdown("
test\ntest\r\ntest\n
", "```\ntest\ntest\ntest\n```"); + $this->assertHtmlGivesMarkdown("
test\n\ttab\r\n
", "```\ntest\n\ttab\n```"); + $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\n```"); + $this->assertHtmlGivesMarkdown("
foo\n
", "```\nfoo\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
\n

line

", "```\none\ntwo\nthree\n```\n\nline"); + $this->assertHtmlGivesMarkdown("
test with attributes
", "```\ntest with attributes\n```"); + } + + public function testBlockquotes(): void + { + $this->assertHtmlGivesMarkdown('
Something I said?
', '> Something I said?'); + $this->assertHtmlGivesMarkdown('
Something I said?
', '> > Something I said?'); + $this->assertHtmlGivesMarkdown('

Something I said?

Why, yes it was!

', "> Something I said?\n> \n> Why, yes it was!"); + } + + public function testMalformedHtml(): void + { + $this->assertHtmlGivesMarkdown('

Some sample HTML

', '`

Some sample HTML

`'); // Invalid HTML, but should still work + $this->assertHtmlGivesMarkdown('Strong italic Regular text', '***Strong italic*** Regular text'); // Missing closing + } + + public function testHtml5TagsArePreserved(): void + { + $this->assertHtmlGivesMarkdown('
Some stuff
', '
Some stuff
'); + } + + public function testStripUnmarkdownable(): void + { + $this->assertHtmlGivesMarkdown('Span', 'Span', ['strip_tags' => true]); + } + + public function testStripComments(): void + { + $this->assertHtmlGivesMarkdown('

Test

', 'Test'); + $this->assertHtmlGivesMarkdown('

Test

', 'Test'); + $this->assertHtmlGivesMarkdown('

Test

', 'Test', ['strip_tags' => true]); + $this->assertHtmlGivesMarkdown('

Test

', 'Test', ['strip_tags' => true]); + } + + public function testPreserveComments(): void + { + $this->assertHtmlGivesMarkdown('

Test

', "Test\n\n", ['preserve_comments' => ['more']]); + $this->assertHtmlGivesMarkdown('

Test

', "Test\n\n", ['preserve_comments' => ['more']]); + $this->assertHtmlGivesMarkdown('

Test

', "Test\n\n", ['preserve_comments' => true]); + } + + public function testPreserveCommentOrder(): void + { + $this->assertHtmlGivesMarkdown('

Test

', "Test\n\n", ['preserve_comments' => true]); + } + + public function testPreserveWhitespace(): void + { + $this->assertHtmlGivesMarkdown('google.com test', '[google.com](google.com) `test`'); + } + + public function testDeleteBlankP(): void + { + $this->assertHtmlGivesMarkdown('

', ''); + $this->assertHtmlGivesMarkdown('

', '', ['strip_tags' => true]); + } + + public function testDivs(): void + { + $this->assertHtmlGivesMarkdown('
Hello
World
', '
Hello
World
'); + $this->assertHtmlGivesMarkdown('
Hello
World
', "Hello\n\nWorld", ['strip_tags' => true]); + $this->assertHtmlGivesMarkdown("
Hello
\n
World
", "Hello\n\nWorld", ['strip_tags' => true]); + $this->assertHtmlGivesMarkdown('

Paragraph

Hello
World
', "Paragraph\n\nHello\n\nWorld", ['strip_tags' => true]); + } + + public function testRemoveNodes(): void + { + $this->assertHtmlGivesMarkdown('
Hello
World
', '', ['remove_nodes' => 'div']); + $this->assertHtmlGivesMarkdown('

Hello

World', '', ['remove_nodes' => 'p span']); + } + + public function testHtmlEntities(): void + { + $this->assertHtmlGivesMarkdown('

&euro;

', '&euro;'); + $this->assertHtmlGivesMarkdown('<p>Some sample HTML</p>', '`

Some sample HTML

`'); + } + + public function testSetOption(): void + { + $markdown = new HtmlConverter(); + $markdown->getConfig()->setOption('strip_tags', true); + $result = $markdown->convert('Strip'); + + $this->assertEquals('Strip', $result); + } + + public function testInvoke(): void + { + $markdown = new HtmlConverter(); + $markdown->getConfig()->setOption('strip_tags', true); + $result = $markdown('Strip'); + + $this->assertEquals('Strip', $result); + } + + public function testSanitization(): void + { + $html = '
<script type = "text/javascript"> function startTimer() { var tim = window.setTimeout("hideMessage()", 5000) } </head> <body>
'; + $markdown = '```' . "\n" . '