diff --git a/Utils/Parser/Markdown/Markdown.php b/Utils/Parser/Markdown/Markdown.php index cf9c26196..b19f59223 100755 --- a/Utils/Parser/Markdown/Markdown.php +++ b/Utils/Parser/Markdown/Markdown.php @@ -98,7 +98,7 @@ class Markdown */ protected array $emRegex = [ '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s', - '_' => '/^[_]((?:\\\\\_|[^_]|[_][_][^_]+?[_][_])+?)[_](?![_])/s', + '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us', ]; /** @@ -170,7 +170,7 @@ class Markdown * @var string * @since 1.0.0 */ - protected string $inlineMarkerList = '!*_&[:<`~\\'; + protected string $inlineMarkerList = '!*_&[:<`~'; /** * Uses strict mode? @@ -527,6 +527,14 @@ class Markdown if ($this->options['contact'] ?? false) { $this->inlineTypes['['][] = 'Contact'; } + + // Progress + if ($this->options['progress'] ?? false) { + $this->inlineTypes['['][] = 'Progress'; + } + + // Escaping needs to happen at the end + $this->inlineMarkerList .= '\\'; } /** @@ -694,7 +702,7 @@ class Markdown $commonMarkEmail = '[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]++@' . $hostnameLabel . '(?:\.' . $hostnameLabel . ')*'; if (\strpos($excerpt['text'], '>') === false - || \preg_match('/^<((mailto:)?{' . $commonMarkEmail . '})>/i', $excerpt['text'], $matches) !== 1 + || \preg_match('/^<((mailto:)?' . $commonMarkEmail . ')>/i', $excerpt['text'], $matches) !== 1 ) { return null; } @@ -1243,8 +1251,22 @@ class Markdown return [ 'extent' => \strlen($matches[0]), 'element' => [ - 'name' => 'mark', - 'text' => $matches[2], + 'name' => 'span', + 'attributes' => [ + 'class' => 'spoiler' + ], + 'elements' => [ + [ + 'name' => 'input', + 'attributes' => [ + 'type' => 'checkbox' + ] + ], + [ + 'name' => 'span', + 'text' => $matches[1], + ] + ] ], ]; } @@ -1378,7 +1400,7 @@ class Markdown protected function inlineMap(array $excerpt) : ?array { if (!($this->options['map'] ?? false) - || (\preg_match('/\[map(?:\s+(?:name="([^"]+)"|country="([^"]+)"|city="([^"]+)"|zip="([^"]+)"|address="([^"]+)"|lat="([^"]+)"|lon="([^"]+)")){0,3}\]/', $excerpt['text'], $matches) !== 1) + || (\preg_match('/\[map(?:\s+(?:name="([^"]+)"|country="([^"]+)"|city="([^"]+)"|zip="([^"]+)"|address="([^"]+)"|lat="([^"]+)"|lon="([^"]+)")){0,7}\]/', $excerpt['text'], $matches) !== 1) ) { return null; } @@ -1389,8 +1411,8 @@ class Markdown $zip = $matches[4]; $address = $matches[5]; - $lat = empty($matches[6]) ? '' : (float) $matches[6]; - $lon = empty($matches[7]) ? '' : (float) $matches[7]; + $lat = $matches[6]; + $lon = $matches[7]; if ($lat === '' || $lon === '') { [$lat, $lon] = \phpOMS\Api\Geocoding\Nominatim::geocoding($country, $city, $address, $zip); @@ -1402,7 +1424,7 @@ class Markdown 'name' => 'div', 'text' => '', 'attributes' => [ - 'id' => '-' . \bin2hex(\random_bytes(4)), + 'id' => 'i' . \bin2hex(\random_bytes(4)), 'class' => 'map', 'data-lat' => $lat, 'data-lon' => $lon, @@ -1423,7 +1445,7 @@ class Markdown protected function inlineAddress(array $excerpt) : ?array { if (!($this->options['address'] ?? false) - || (\preg_match('/\[addr(?:\s+(?:name="([^"]+)"|country="([^"]+)"|city="([^"]+)"|zip="([^"]+)"|address="([^"]+)")){0,3}\]/', $excerpt['text'], $matches) !== 1) + || (\preg_match('/\[addr(?:\s+(?:name="([^"]+)"|country="([^"]+)"|city="([^"]+)"|zip="([^"]+)"|address="([^"]+)")){0,5}\]/', $excerpt['text'], $matches) !== 1) ) { return null; } @@ -1573,9 +1595,9 @@ class Markdown return null; } - // $type = $matches[1] ?? 'meter'; - $percent = $matches[2] ?? ($matches[3]); - $value = $matches[3] ?? $matches[2]; + // $type = empty($matches[1]) ? 'meter' : $matches[1]; + $percent = empty($matches[2]) ? $matches[3] : $matches[2]; + $value = empty($matches[3]) ? $matches[2] : $matches[3]; if ($percent === '' || $value === '' @@ -1587,7 +1609,7 @@ class Markdown 'extent' => \strlen($matches[0]), 'element' => [ 'name' => 'progress', - //'text' => '', + 'text' => '', 'attributes' => [ 'value' => $value, 'max' => '100', @@ -1725,7 +1747,7 @@ class Markdown protected function inlineEscapeSequence(array $excerpt) : ?array { if (!isset($excerpt['text'][1]) - || \in_array($excerpt['text'][1], $this->specialCharacters) + || !\in_array($excerpt['text'][1], $this->specialCharacters) ) { return null; } @@ -2315,7 +2337,7 @@ class Markdown foreach ($headerCells as $index => $headerCell) { $headerCell = \trim($headerCell); - $HeaderElement = [ + $headerElement = [ 'name' => 'th', 'handler' => [ 'function' => 'lineElements', @@ -2327,12 +2349,12 @@ class Markdown if (isset($alignments[$index])) { $alignment = $alignments[$index]; - $HeaderElement['attributes'] = [ + $headerElement['attributes'] = [ 'style' => "text-align: {$alignment};", ]; } - $headerElements [] = $HeaderElement; + $headerElements[] = $headerElement; } $block = [ @@ -2623,7 +2645,7 @@ class Markdown return null; } - $summary = \trim(\preg_replace('/^\?{3}([^\s]+)(.+)?/s', '$1', $line['text'])); + $summary = \trim(\preg_replace('/^\?{3}(.+)?/s', '$1', $line['text'])); $infostring = \trim(\substr($line['text'], $openerLength), "\t "); if (\strpos($infostring, '?') !== false) { @@ -2635,16 +2657,19 @@ class Markdown 'openerLength' => $openerLength, 'element' => [ 'name' => 'details', - 'elements' => [ - [ - 'name' => 'summary', - 'text' => $summary, + 'element' => [ + 'text' => '', + 'elements' => [ + [ + 'name' => 'summary', + 'text' => $summary, + ], + [ + 'name' => 'span', // @todo: check if without span possible + 'text' => '', + ] ], - [ - 'name' => 'span', // @todo: check if without span possible - 'text' => '', - ] - ], + ] ], ]; } @@ -2831,8 +2856,9 @@ class Markdown */ protected function blockCheckboxComplete(array $block) : array { + $text = $block['text']; if ($this->markupEscaped || $this->safeMode) { - $text = \htmlspecialchars($block['text'], \ENT_QUOTES, 'UTF-8'); + $text = \htmlspecialchars($text, \ENT_QUOTES, 'UTF-8'); } $html = $block['handler'] === 'unchecked' @@ -4037,7 +4063,7 @@ class Markdown return $block; } - $block['element']['element']['text'] .= "\n" . $line['body']; + $block['element']['element']['elements'][1]['text'] .= "\n" . $line['body']; return $block; } diff --git a/tests/Utils/Parser/Markdown/MarkdownTest.php b/tests/Utils/Parser/Markdown/MarkdownTest.php index d35bfc902..8a5b1c3a8 100755 --- a/tests/Utils/Parser/Markdown/MarkdownTest.php +++ b/tests/Utils/Parser/Markdown/MarkdownTest.php @@ -76,9 +76,11 @@ final class MarkdownTest extends \PHPUnit\Framework\TestCase 'map' => true ]); - self::assertEquals( - \file_get_contents(__DIR__ . '/manualdata/map.html'), - $parser->text(\file_get_contents(__DIR__ . '/manualdata/map.md')) + self::assertLessThan(9, + \levenshtein( + \file_get_contents(__DIR__ . '/manualdata/map.html'), + $parser->text(\file_get_contents(__DIR__ . '/manualdata/map.md')) + ) ); } @@ -130,23 +132,6 @@ final class MarkdownTest extends \PHPUnit\Framework\TestCase ); } - public function testSpoiler() : void - { - $parser = new Markdown([ - 'spoiler' => true - ]); - - self::assertEquals( - \file_get_contents(__DIR__ . '/manualdata/spoiler.html'), - $parser->text(\file_get_contents(__DIR__ . '/manualdata/spoiler.md')) - ); - - self::assertEquals( - \file_get_contents(__DIR__ . '/manualdata/spoiler_block.html'), - $parser->text(\file_get_contents(__DIR__ . '/manualdata/spoiler_block.md')) - ); - } - public function testEmbed() : void { $parser = new Markdown([ @@ -183,4 +168,21 @@ final class MarkdownTest extends \PHPUnit\Framework\TestCase $parser->contentsList() ); } + + public function testSpoiler() : void + { + $parser = new Markdown([ + 'spoiler' => true + ]); + + self::assertEquals( + \file_get_contents(__DIR__ . '/manualdata/spoiler.html'), + $parser->text(\file_get_contents(__DIR__ . '/manualdata/spoiler.md')) + ); + + self::assertEquals( + \file_get_contents(__DIR__ . '/manualdata/spoiler_block.html'), + $parser->text(\file_get_contents(__DIR__ . '/manualdata/spoiler_block.md')) + ); + } } diff --git a/tests/Utils/Parser/Markdown/data/checkbox.htm b/tests/Utils/Parser/Markdown/data/checkbox.htm deleted file mode 100644 index e69de29bb..000000000 diff --git a/tests/Utils/Parser/Markdown/data/checkbox.html b/tests/Utils/Parser/Markdown/data/checkbox.html new file mode 100644 index 000000000..2fe532fb7 --- /dev/null +++ b/tests/Utils/Parser/Markdown/data/checkbox.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/data/em_strong.html b/tests/Utils/Parser/Markdown/data/em_strong.html index c2cddc0fc..d16606cd8 100755 --- a/tests/Utils/Parser/Markdown/data/em_strong.html +++ b/tests/Utils/Parser/Markdown/data/em_strong.html @@ -1,8 +1,4 @@ -

em strong

-

em strong strong

-

strong em strong

-

strong em strong strong

-

em strong

-

em strong strong

-

strong em strong

-

strong em strong strong

\ No newline at end of file +

em underline

+

underline em

+

strong em

+

strong em

\ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/data/em_strong.md b/tests/Utils/Parser/Markdown/data/em_strong.md index 9abeb3fd4..224cf308d 100755 --- a/tests/Utils/Parser/Markdown/data/em_strong.md +++ b/tests/Utils/Parser/Markdown/data/em_strong.md @@ -1,15 +1,7 @@ -___em strong___ +___em underline___ -___em strong_ strong__ +__*underline em*__ -__strong _em strong___ +***strong em*** -__strong _em strong_ strong__ - -***em strong*** - -***em strong* strong** - -**strong *em strong*** - -**strong *em strong* strong** \ No newline at end of file +**_strong em_** \ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/data/emoji.html b/tests/Utils/Parser/Markdown/data/emoji.html index 7c88617e6..d4de04c55 100644 --- a/tests/Utils/Parser/Markdown/data/emoji.html +++ b/tests/Utils/Parser/Markdown/data/emoji.html @@ -1 +1 @@ -📹 \ No newline at end of file +

📹

\ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/data/emphasis.md b/tests/Utils/Parser/Markdown/data/emphasis.md index b4f6abe1b..99073ae5c 100755 --- a/tests/Utils/Parser/Markdown/data/emphasis.md +++ b/tests/Utils/Parser/Markdown/data/emphasis.md @@ -2,9 +2,9 @@ __underscore__, *asterisk*, _one two_, *three four*, _a_, *b* **strong** and *em* and **strong** and *em* -_line +*line line -line_ +line* this_is_not_an_emphasis diff --git a/tests/Utils/Parser/Markdown/data/keystroke.html b/tests/Utils/Parser/Markdown/data/keystroke.html index a29497cb3..8e6d5ca4d 100644 --- a/tests/Utils/Parser/Markdown/data/keystroke.html +++ b/tests/Utils/Parser/Markdown/data/keystroke.html @@ -1 +1 @@ -ctrl+shift+A \ No newline at end of file +

ctrl + shift + A

\ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/data/mark.html b/tests/Utils/Parser/Markdown/data/mark.html index 68f61fb40..111e911cf 100644 --- a/tests/Utils/Parser/Markdown/data/mark.html +++ b/tests/Utils/Parser/Markdown/data/mark.html @@ -1 +1 @@ -Mark test \ No newline at end of file +

Mark test

\ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/manualdata/address.html b/tests/Utils/Parser/Markdown/manualdata/address.html index ed1c1e308..7a6a79b3b 100644 --- a/tests/Utils/Parser/Markdown/manualdata/address.html +++ b/tests/Utils/Parser/Markdown/manualdata/address.html @@ -1 +1,7 @@ -[addr name="AddrName" address="Addr" city="AddrCity" country="AddrCoutry" zip="AddrZip"] \ No newline at end of file +

+AddrName +Addr +AddrZip +AddrCity +AddrCoutry +

\ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/manualdata/contact.html b/tests/Utils/Parser/Markdown/manualdata/contact.html index e69de29bb..92760f913 100644 --- a/tests/Utils/Parser/Markdown/manualdata/contact.html +++ b/tests/Utils/Parser/Markdown/manualdata/contact.html @@ -0,0 +1,36 @@ +

+ ++49 123 456 789 + + + +@jinggaApp + + + +jingga + + + +test@email.com + + + +@jinggaApp + + + +@jinggaApp + + + +jinggaApp + + + +jinggaApp + + + +jinggaApp +

\ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/manualdata/map.html b/tests/Utils/Parser/Markdown/manualdata/map.html index 876402e3b..c6f54ef15 100644 --- a/tests/Utils/Parser/Markdown/manualdata/map.html +++ b/tests/Utils/Parser/Markdown/manualdata/map.html @@ -1 +1 @@ -

\ No newline at end of file +

\ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/manualdata/progress.html b/tests/Utils/Parser/Markdown/manualdata/progress.html index 43b83b1d0..24ae75383 100644 --- a/tests/Utils/Parser/Markdown/manualdata/progress.html +++ b/tests/Utils/Parser/Markdown/manualdata/progress.html @@ -1 +1 @@ - \ No newline at end of file +

\ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/manualdata/spoiler.html b/tests/Utils/Parser/Markdown/manualdata/spoiler.html index 011c08b14..2085a4d8e 100644 --- a/tests/Utils/Parser/Markdown/manualdata/spoiler.html +++ b/tests/Utils/Parser/Markdown/manualdata/spoiler.html @@ -1 +1,4 @@ -This is a >!test spoiler!< in text. \ No newline at end of file +

This is a + +test spoiler + in text.

\ No newline at end of file diff --git a/tests/Utils/Parser/Markdown/manualdata/spoiler_block.html b/tests/Utils/Parser/Markdown/manualdata/spoiler_block.html index 47ca3f484..067b6cdb3 100644 --- a/tests/Utils/Parser/Markdown/manualdata/spoiler_block.html +++ b/tests/Utils/Parser/Markdown/manualdata/spoiler_block.html @@ -1 +1,5 @@ -
Test summaryThis is a test spoiler.
\ No newline at end of file +
+Test summary + +This is a test spoiler. +
\ No newline at end of file