diff options
40 files changed, 837 insertions, 672 deletions
diff --git a/composer.json b/composer.json index f5654858d..12f6200b6 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ "bshaffer/oauth2-server-php": "^1.9", "ezyang/htmlpurifier": "^4.9", "simplepie/simplepie": "~1.5", - "league/html-to-markdown": "^4.4", + "league/html-to-markdown": "^5.0", "pear/text_languagedetect": "^1.0", "commerceguys/intl": "~1.0.5", "lukasreschke/id3parser": "^0.0.3", diff --git a/composer.lock b/composer.lock index 445ff335f..db81c7fcf 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bc4a925533b7fe89fd5c8e94075835c6", + "content-hash": "64ccf5284f8e6e0326829279c6adb116", "packages": [ { "name": "blueimp/jquery-file-upload", @@ -336,27 +336,30 @@ }, { "name": "league/html-to-markdown", - "version": "4.10.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "0868ae7a552e809e5cd8f93ba022071640408e88" + "reference": "c4dbebbebe0fe454b6b38e6c683a977615bd7dc2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/0868ae7a552e809e5cd8f93ba022071640408e88", - "reference": "0868ae7a552e809e5cd8f93ba022071640408e88", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/c4dbebbebe0fe454b6b38e6c683a977615bd7dc2", + "reference": "c4dbebbebe0fe454b6b38e6c683a977615bd7dc2", "shasum": "" }, "require": { "ext-dom": "*", "ext-xml": "*", - "php": ">=5.3.3" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "mikehaertl/php-shellcommand": "~1.1.0", - "phpunit/phpunit": "^4.8|^5.7", - "scrutinizer/ocular": "~1.1" + "mikehaertl/php-shellcommand": "^1.1.0", + "phpstan/phpstan": "^0.12.82", + "phpunit/phpunit": "^8.5 || ^9.2", + "scrutinizer/ocular": "^1.6", + "unleashedtech/php-coding-standard": "^2.7", + "vimeo/psalm": "^4.6" }, "bin": [ "bin/html-to-markdown" @@ -364,7 +367,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.10-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -398,7 +401,7 @@ ], "support": { "issues": "https://github.com/thephpleague/html-to-markdown/issues", - "source": "https://github.com/thephpleague/html-to-markdown/tree/4.10.0" + "source": "https://github.com/thephpleague/html-to-markdown/tree/5.0.0" }, "funding": [ { @@ -418,7 +421,7 @@ "type": "patreon" } ], - "time": "2020-07-01T00:34:03+00:00" + "time": "2021-03-29T01:29:08+00:00" }, { "name": "lukasreschke/id3parser", diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 5a1f2016d..758f77234 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -32,7 +32,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '0784d2ea4e4f492d9f03d025b56d603d15b5ee89', + 'reference' => '4db384da34595adef68be6226e8b331b4d7b7f31', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -93,12 +93,12 @@ private static $installed = array ( ), 'league/html-to-markdown' => array ( - 'pretty_version' => '4.10.0', - 'version' => '4.10.0.0', + 'pretty_version' => '5.0.0', + 'version' => '5.0.0.0', 'aliases' => array ( ), - 'reference' => '0868ae7a552e809e5cd8f93ba022071640408e88', + 'reference' => 'c4dbebbebe0fe454b6b38e6c683a977615bd7dc2', ), 'lukasreschke/id3parser' => array ( @@ -274,7 +274,7 @@ private static $installed = array ( 'aliases' => array ( ), - 'reference' => '0784d2ea4e4f492d9f03d025b56d603d15b5ee89', + 'reference' => '4db384da34595adef68be6226e8b331b4d7b7f31', ), ), ); diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index c19984103..78189b205 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -299,12 +299,14 @@ return array( 'League\\HTMLToMarkdown\\Converter\\ListItemConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/ListItemConverter.php', 'League\\HTMLToMarkdown\\Converter\\ParagraphConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/ParagraphConverter.php', 'League\\HTMLToMarkdown\\Converter\\PreformattedConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/PreformattedConverter.php', + 'League\\HTMLToMarkdown\\Converter\\TableConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/TableConverter.php', 'League\\HTMLToMarkdown\\Converter\\TextConverter' => $vendorDir . '/league/html-to-markdown/src/Converter/TextConverter.php', 'League\\HTMLToMarkdown\\Element' => $vendorDir . '/league/html-to-markdown/src/Element.php', 'League\\HTMLToMarkdown\\ElementInterface' => $vendorDir . '/league/html-to-markdown/src/ElementInterface.php', 'League\\HTMLToMarkdown\\Environment' => $vendorDir . '/league/html-to-markdown/src/Environment.php', 'League\\HTMLToMarkdown\\HtmlConverter' => $vendorDir . '/league/html-to-markdown/src/HtmlConverter.php', 'League\\HTMLToMarkdown\\HtmlConverterInterface' => $vendorDir . '/league/html-to-markdown/src/HtmlConverterInterface.php', + 'League\\HTMLToMarkdown\\PreConverterInterface' => $vendorDir . '/league/html-to-markdown/src/PreConverterInterface.php', 'Michelf\\Markdown' => $vendorDir . '/michelf/php-markdown/Michelf/Markdown.php', 'Michelf\\MarkdownExtra' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownExtra.php', 'Michelf\\MarkdownInterface' => $vendorDir . '/michelf/php-markdown/Michelf/MarkdownInterface.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index bd6fb0600..cbb89277d 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -489,12 +489,14 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d 'League\\HTMLToMarkdown\\Converter\\ListItemConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/ListItemConverter.php', 'League\\HTMLToMarkdown\\Converter\\ParagraphConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/ParagraphConverter.php', 'League\\HTMLToMarkdown\\Converter\\PreformattedConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/PreformattedConverter.php', + 'League\\HTMLToMarkdown\\Converter\\TableConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/TableConverter.php', 'League\\HTMLToMarkdown\\Converter\\TextConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/Converter/TextConverter.php', 'League\\HTMLToMarkdown\\Element' => __DIR__ . '/..' . '/league/html-to-markdown/src/Element.php', 'League\\HTMLToMarkdown\\ElementInterface' => __DIR__ . '/..' . '/league/html-to-markdown/src/ElementInterface.php', 'League\\HTMLToMarkdown\\Environment' => __DIR__ . '/..' . '/league/html-to-markdown/src/Environment.php', 'League\\HTMLToMarkdown\\HtmlConverter' => __DIR__ . '/..' . '/league/html-to-markdown/src/HtmlConverter.php', 'League\\HTMLToMarkdown\\HtmlConverterInterface' => __DIR__ . '/..' . '/league/html-to-markdown/src/HtmlConverterInterface.php', + 'League\\HTMLToMarkdown\\PreConverterInterface' => __DIR__ . '/..' . '/league/html-to-markdown/src/PreConverterInterface.php', 'Michelf\\Markdown' => __DIR__ . '/..' . '/michelf/php-markdown/Michelf/Markdown.php', 'Michelf\\MarkdownExtra' => __DIR__ . '/..' . '/michelf/php-markdown/Michelf/MarkdownExtra.php', 'Michelf\\MarkdownInterface' => __DIR__ . '/..' . '/michelf/php-markdown/Michelf/MarkdownInterface.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 518683c5c..40545c808 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -332,37 +332,40 @@ }, { "name": "league/html-to-markdown", - "version": "4.10.0", - "version_normalized": "4.10.0.0", + "version": "5.0.0", + "version_normalized": "5.0.0.0", "source": { "type": "git", "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "0868ae7a552e809e5cd8f93ba022071640408e88" + "reference": "c4dbebbebe0fe454b6b38e6c683a977615bd7dc2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/0868ae7a552e809e5cd8f93ba022071640408e88", - "reference": "0868ae7a552e809e5cd8f93ba022071640408e88", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/c4dbebbebe0fe454b6b38e6c683a977615bd7dc2", + "reference": "c4dbebbebe0fe454b6b38e6c683a977615bd7dc2", "shasum": "" }, "require": { "ext-dom": "*", "ext-xml": "*", - "php": ">=5.3.3" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "mikehaertl/php-shellcommand": "~1.1.0", - "phpunit/phpunit": "^4.8|^5.7", - "scrutinizer/ocular": "~1.1" - }, - "time": "2020-07-01T00:34:03+00:00", + "mikehaertl/php-shellcommand": "^1.1.0", + "phpstan/phpstan": "^0.12.82", + "phpunit/phpunit": "^8.5 || ^9.2", + "scrutinizer/ocular": "^1.6", + "unleashedtech/php-coding-standard": "^2.7", + "vimeo/psalm": "^4.6" + }, + "time": "2021-03-29T01:29:08+00:00", "bin": [ "bin/html-to-markdown" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "4.10-dev" + "dev-master": "5.1-dev" } }, "installation-source": "dist", @@ -395,6 +398,10 @@ "html", "markdown" ], + "support": { + "issues": "https://github.com/thephpleague/html-to-markdown/issues", + "source": "https://github.com/thephpleague/html-to-markdown/tree/5.0.0" + }, "funding": [ { "url": "https://www.colinodell.com/sponsor", diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 9d660ee03..73a7d3dbe 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -6,7 +6,7 @@ 'aliases' => array ( ), - 'reference' => '0784d2ea4e4f492d9f03d025b56d603d15b5ee89', + 'reference' => '4db384da34595adef68be6226e8b331b4d7b7f31', 'name' => 'zotlabs/hubzilla', ), 'versions' => @@ -67,12 +67,12 @@ ), 'league/html-to-markdown' => array ( - 'pretty_version' => '4.10.0', - 'version' => '4.10.0.0', + 'pretty_version' => '5.0.0', + 'version' => '5.0.0.0', 'aliases' => array ( ), - 'reference' => '0868ae7a552e809e5cd8f93ba022071640408e88', + 'reference' => 'c4dbebbebe0fe454b6b38e6c683a977615bd7dc2', ), 'lukasreschke/id3parser' => array ( @@ -248,7 +248,7 @@ 'aliases' => array ( ), - 'reference' => '0784d2ea4e4f492d9f03d025b56d603d15b5ee89', + 'reference' => '4db384da34595adef68be6226e8b331b4d7b7f31', ), ), ); diff --git a/vendor/league/html-to-markdown/.github/workflows/tests.yml b/vendor/league/html-to-markdown/.github/workflows/tests.yml new file mode 100644 index 000000000..6abb2de3f --- /dev/null +++ b/vendor/league/html-to-markdown/.github/workflows/tests.yml @@ -0,0 +1,104 @@ +name: Tests + +on: + push: ~ + pull_request: ~ + +jobs: + phpcs: + name: PHPCS + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: shivammathur/setup-php@v2 + with: + php-version: 7.2 + extensions: curl, mbstring + coverage: none + tools: composer:v2, cs2pr + + - run: composer update --no-progress + + - run: vendor/bin/phpcs -q --report=checkstyle | cs2pr + + phpunit: + name: PHPUnit on ${{ matrix.php }} ${{ matrix.composer-flags }} + runs-on: ubuntu-latest + strategy: + matrix: + php: ['7.2', '7.3', '7.4'] + coverage: [true] + composer-flags: [''] + include: + - php: '8.0' + coverage: false + composer-flags: '--ignore-platform-req=php' + - php: '7.2' + coverage: false + composer-flags: '--prefer-lowest' + + steps: + - uses: actions/checkout@v2 + + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: curl, mbstring + coverage: pcov + tools: composer:v2 + + - run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: "Use PHPUnit 9.3+ on PHP 8" + run: composer require --no-update --dev phpunit/phpunit:^9.3 + if: "matrix.php == '8.0'" + + - run: composer update --no-progress ${{ matrix.composer-flags }} + + - run: vendor/bin/phpunit --no-coverage + if: ${{ !matrix.coverage }} + + - run: vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover + if: ${{ matrix.coverage }} + + - run: php vendor/bin/ocular code-coverage:upload --format=php-clover coverage.clover + if: ${{ matrix.coverage }} + continue-on-error: true + + phpstan: + name: PHPStan + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: shivammathur/setup-php@v2 + with: + php-version: 7.2 + extensions: curl, mbstring + coverage: none + tools: composer:v2 + + - run: composer update --no-progress + + - run: vendor/bin/phpstan analyse --no-progress + + psalm: + name: Psalm + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - uses: shivammathur/setup-php@v2 + with: + php-version: 7.2 + extensions: curl, mbstring + coverage: none + tools: composer:v2 + + - run: composer update --no-progress + + - run: vendor/bin/psalm --no-progress --output-format=github diff --git a/vendor/league/html-to-markdown/CHANGELOG.md b/vendor/league/html-to-markdown/CHANGELOG.md index c19cd9f69..71ae9c9a8 100644 --- a/vendor/league/html-to-markdown/CHANGELOG.md +++ b/vendor/league/html-to-markdown/CHANGELOG.md @@ -4,6 +4,31 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip ## [Unreleased][unreleased] +## [5.0.0] - 2021-03-28 + +### Added + + - Added support for tables (#203) + - This feature is disable by default - see README for how to enable it + - Added new `strip_placeholder_links` option to strip `<a>` tags without `href` attributes (#196) + - Added new methods to `ElementInterface`: + - `hasParent()` + - `getNextSibling()` + - `getPreviousSibling()` + - `getListItemLevel()` + - Added several parameter and return types across all classes + - Added new `PreConverterInterface` to allow converters to perform any necessary pre-parsing + +### Changed + + - Supported PHP versions increased to PHP 7.2 - 8.0 + - `HtmlConverter::convert()` may now throw a `\RuntimeException` when unexpected `DOMDocument`-related errors occur + +### Fixed + + - Fixed complex nested lists containing heading and paragraphs (#198) + - Fixed consecutive emphasis producing incorrect markdown (#202) + ## [4.10.0] - 2020-06-30 ### Added @@ -268,7 +293,8 @@ not ideally set, so this releases fixes that. Moving forwards this should reduce ### Added - Initial release -[unreleased]: https://github.com/thephpleague/html-to-markdown/compare/4.10.0...master +[unreleased]: https://github.com/thephpleague/html-to-markdown/compare/5.0.0...master +[5.0.0]: https://github.com/thephpleague/html-to-markdown/compare/4.10.0...5.0.0 [4.10.0]: https://github.com/thephpleague/html-to-markdown/compare/4.9.1...4.10.0 [4.9.1]: https://github.com/thephpleague/html-to-markdown/compare/4.9.0...4.9.1 [4.9.0]: https://github.com/thephpleague/html-to-markdown/compare/4.8.3...4.9.0 diff --git a/vendor/league/html-to-markdown/README.md b/vendor/league/html-to-markdown/README.md index c1ac805ab..fcc256328 100644 --- a/vendor/league/html-to-markdown/README.md +++ b/vendor/league/html-to-markdown/README.md @@ -1,11 +1,9 @@ HTML To Markdown for PHP ======================== -[![Join the chat at https://gitter.im/thephpleague/html-to-markdown](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/thephpleague/html-to-markdown?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - [![Latest Version](https://img.shields.io/packagist/v/league/html-to-markdown.svg?style=flat-square)](https://packagist.org/packages/league/html-to-markdown) [![Software License](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE) -[![Build Status](https://img.shields.io/travis/thephpleague/html-to-markdown/master.svg?style=flat-square)](https://travis-ci.org/thephpleague/html-to-markdown) +[![Build Status](https://img.shields.io/github/workflow/status/thephpleague/html-to-markdown/Tests/master.svg?style=flat-square)](https://github.com/thephpleague/html-to-markdown/actions?query=workflow%3ATests+branch%3Amaster) [![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/thephpleague/html-to-markdown.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/html-to-markdown/code-structure) [![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/html-to-markdown.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/html-to-markdown) [![Total Downloads](https://img.shields.io/packagist/dt/league/html-to-markdown.svg?style=flat-square)](https://packagist.org/packages/league/html-to-markdown) @@ -13,7 +11,7 @@ HTML To Markdown for PHP Library which converts HTML to [Markdown](http://daringfireball.net/projects/markdown/) for your sanity and convenience. -**Requires**: PHP 5.3+ or PHP 7.0+ +**Requires**: PHP 7.2+ **Lead Developer**: [@colinodell](http://twitter.com/colinodell) @@ -113,6 +111,15 @@ $html = '<span>Turnips!</span><!-- Monkeys! --><!-- Eggs! -->'; $markdown = $converter->convert($html); // $markdown now contains "Turnips!<!-- Eggs! -->" ``` +By default, placeholder links are preserved. To strip the placeholder links, use the `strip_placeholder_links` option, like this: + +```php +$converter = new HtmlConverter(array('strip_placeholder_links' => true)); + +$html = '<a>Github</a>'; +$markdown = $converter->convert($html); // $markdown now contains "Github" +``` + ### Style options By default bold tags are converted using the asterisk syntax, and italic tags are converted using the underlined syntax. Change these by using the `bold_style` and `italic_style` options. @@ -174,17 +181,24 @@ $html = '<h3>Header</h3> $markdown = $converter->convert($html); // $markdown now contains "### Header" and "<img src="" />" ``` -### Limitations +### Table support -- Markdown Extra, MultiMarkdown and other variants aren't supported – just Markdown. +Support for Markdown tables is not enabled by default because it is not part of the original Markdown syntax. To use tables add the converter explicitly: -### Known issues +```php +use League\HTMLToMarkdown\HtmlConverter; +use League\HTMLToMarkdown\Converter\TableConverter; + +$converter = new HtmlConverter(); +$converter->getEnvironment()->addConverter(new TableConverter()); + +$html = "<table><tr><th>A</th></tr><tr><td>a</td></tr></table>"; +$markdown = $converter->convert($html); +``` -- Nested lists and lists containing multiple paragraphs aren't converted correctly. -- Lists inside blockquotes aren't converted correctly. -- Any reported [open issues here](https://github.com/thephpleague/html-to-markdown/issues?state=open). +### Limitations -[Report your issue or request a feature here.](https://github.com/thephpleague/html-to-markdown/issues/new) Issues with patches or failing tests are especially welcome. +- Markdown Extra, MultiMarkdown and other variants aren't supported – just Markdown. ### Style notes diff --git a/vendor/league/html-to-markdown/composer.json b/vendor/league/html-to-markdown/composer.json index 7990bcace..af3e41058 100644 --- a/vendor/league/html-to-markdown/composer.json +++ b/vendor/league/html-to-markdown/composer.json @@ -30,19 +30,22 @@ } }, "require": { - "php": ">=5.3.3", + "php": "^7.2.5 || ^8.0", "ext-dom": "*", "ext-xml": "*" }, "require-dev": { - "mikehaertl/php-shellcommand": "~1.1.0", - "phpunit/phpunit": "^4.8|^5.7", - "scrutinizer/ocular": "~1.1" + "mikehaertl/php-shellcommand": "^1.1.0", + "phpstan/phpstan": "^0.12.82", + "phpunit/phpunit": "^8.5 || ^9.2", + "scrutinizer/ocular": "^1.6", + "unleashedtech/php-coding-standard": "^2.7", + "vimeo/psalm": "^4.6" }, "bin": ["bin/html-to-markdown"], "extra": { "branch-alias": { - "dev-master": "4.10-dev" + "dev-master": "5.1-dev" } } } diff --git a/vendor/league/html-to-markdown/phpcs.xml.dist b/vendor/league/html-to-markdown/phpcs.xml.dist new file mode 100644 index 000000000..59f148473 --- /dev/null +++ b/vendor/league/html-to-markdown/phpcs.xml.dist @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<ruleset> + <arg name="basepath" value="."/> + <arg name="extensions" value="php"/> + <arg name="parallel" value="80"/> + <arg name="cache" value=".phpcs-cache"/> + <arg name="colors"/> + + <!-- Ignore warnings, show progress of the run and show sniff names --> + <arg value="nps"/> + + <!-- Directories to be checked --> + <file>src</file> + <file>tests</file> + + <!-- Include full Unleashed Coding Standard --> + <rule ref="Unleashed"/> + + <rule ref="SlevomatCodingStandard.Commenting.ForbiddenAnnotations.AnnotationForbidden"> + <exclude-pattern>src/HtmlConverter*\.php</exclude-pattern> + </rule> + + <rule ref="SlevomatCodingStandard.Commenting.DocCommentSpacing.IncorrectOrderOfAnnotationsGroup"> + <exclude-pattern>src/HtmlConverter*\.php</exclude-pattern> + </rule> + +</ruleset> diff --git a/vendor/league/html-to-markdown/phpstan.neon.dist b/vendor/league/html-to-markdown/phpstan.neon.dist new file mode 100644 index 000000000..a1c637a78 --- /dev/null +++ b/vendor/league/html-to-markdown/phpstan.neon.dist @@ -0,0 +1,4 @@ +parameters: + level: max + paths: + - src diff --git a/vendor/league/html-to-markdown/psalm.xml b/vendor/league/html-to-markdown/psalm.xml new file mode 100644 index 000000000..729e9a919 --- /dev/null +++ b/vendor/league/html-to-markdown/psalm.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<psalm + totallyTyped="false" + errorLevel="3" + resolveFromConfigFile="true" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="https://getpsalm.org/schema/config" + xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" +> + <projectFiles> + <directory name="src" /> + <ignoreFiles> + <directory name="vendor" /> + </ignoreFiles> + </projectFiles> +</psalm> diff --git a/vendor/league/html-to-markdown/src/Configuration.php b/vendor/league/html-to-markdown/src/Configuration.php index 5bc8d5503..7e1d71e68 100644 --- a/vendor/league/html-to-markdown/src/Configuration.php +++ b/vendor/league/html-to-markdown/src/Configuration.php @@ -1,15 +1,18 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown; class Configuration { + /** @var array<string, mixed> */ protected $config; /** - * @param array $config + * @param array<string, mixed> $config */ - public function __construct(array $config = array()) + public function __construct(array $config = []) { $this->config = $config; @@ -17,59 +20,60 @@ class Configuration } /** - * @param array $config + * @param array<string, mixed> $config */ - public function merge(array $config = array()) + public function merge(array $config = []): void { $this->checkForDeprecatedOptions($config); - $this->config = array_replace_recursive($this->config, $config); + $this->config = \array_replace_recursive($this->config, $config); } /** - * @param array $config + * @param array<string, mixed> $config */ - public function replace(array $config = array()) + public function replace(array $config = []): void { $this->checkForDeprecatedOptions($config); $this->config = $config; } /** - * @param string $key - * @param mixed $value + * @param mixed $value */ - public function setOption($key, $value) + public function setOption(string $key, $value): void { - $this->checkForDeprecatedOptions(array($key => $value)); + $this->checkForDeprecatedOptions([$key => $value]); $this->config[$key] = $value; } /** - * @param string|null $key - * @param mixed|null $default + * @param mixed|null $default * * @return mixed|null */ - public function getOption($key = null, $default = null) + public function getOption(?string $key = null, $default = null) { if ($key === null) { return $this->config; } - if (!isset($this->config[$key])) { + if (! isset($this->config[$key])) { return $default; } return $this->config[$key]; } - private function checkForDeprecatedOptions(array $config) + /** + * @param array<string, mixed> $config + */ + private function checkForDeprecatedOptions(array $config): void { foreach ($config as $key => $value) { if ($key === 'bold_style' && $value !== '**') { - @trigger_error('Customizing the bold_style option is deprecated and may be removed in the next major version', E_USER_DEPRECATED); + @\trigger_error('Customizing the bold_style option is deprecated and may be removed in the next major version', E_USER_DEPRECATED); } elseif ($key === 'italic_style' && $value !== '*') { - @trigger_error('Customizing the italic_style option is deprecated and may be removed in the next major version', E_USER_DEPRECATED); + @\trigger_error('Customizing the italic_style option is deprecated and may be removed in the next major version', E_USER_DEPRECATED); } } } diff --git a/vendor/league/html-to-markdown/src/ConfigurationAwareInterface.php b/vendor/league/html-to-markdown/src/ConfigurationAwareInterface.php index 8aca530be..50c004c4a 100644 --- a/vendor/league/html-to-markdown/src/ConfigurationAwareInterface.php +++ b/vendor/league/html-to-markdown/src/ConfigurationAwareInterface.php @@ -1,11 +1,10 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown; interface ConfigurationAwareInterface { - /** - * @param Configuration $config - */ - public function setConfig(Configuration $config); + public function setConfig(Configuration $config): void; } diff --git a/vendor/league/html-to-markdown/src/Converter/BlockquoteConverter.php b/vendor/league/html-to-markdown/src/Converter/BlockquoteConverter.php index eb2d09d17..65034db12 100644 --- a/vendor/league/html-to-markdown/src/Converter/BlockquoteConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/BlockquoteConverter.php @@ -1,32 +1,30 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\ElementInterface; class BlockquoteConverter implements ConverterInterface { - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { // Contents should have already been converted to Markdown by this point, // so we just need to add '>' symbols to each line. $markdown = ''; - $quote_content = trim($element->getValue()); + $quoteContent = \trim($element->getValue()); - $lines = preg_split('/\r\n|\r|\n/', $quote_content); + $lines = \preg_split('/\r\n|\r|\n/', $quoteContent); + \assert(\is_array($lines)); - $total_lines = count($lines); + $totalLines = \count($lines); foreach ($lines as $i => $line) { $markdown .= '> ' . $line . "\n"; - if ($i + 1 === $total_lines) { + if ($i + 1 === $totalLines) { $markdown .= "\n"; } } @@ -37,8 +35,8 @@ class BlockquoteConverter implements ConverterInterface /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('blockquote'); + return ['blockquote']; } } diff --git a/vendor/league/html-to-markdown/src/Converter/CodeConverter.php b/vendor/league/html-to-markdown/src/Converter/CodeConverter.php index 39e6a7bc4..40eb7f85a 100644 --- a/vendor/league/html-to-markdown/src/Converter/CodeConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/CodeConverter.php @@ -1,17 +1,14 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\ElementInterface; class CodeConverter implements ConverterInterface { - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { $language = ''; @@ -20,23 +17,24 @@ class CodeConverter implements ConverterInterface if ($classes) { // Since tags can have more than one class, we need to find the one that starts with 'language-' - $classes = explode(' ', $classes); + $classes = \explode(' ', $classes); foreach ($classes as $class) { - if (strpos($class, 'language-') !== false) { + if (\strpos($class, 'language-') !== false) { // Found one, save it as the selected language and stop looping over the classes. - $language = str_replace('language-', '', $class); + $language = \str_replace('language-', '', $class); break; } } } $markdown = ''; - $code = html_entity_decode($element->getChildrenAsString()); + $code = \html_entity_decode($element->getChildrenAsString()); // In order to remove the code tags we need to search for them and, in the case of the opening tag // use a regular expression to find the tag and the other attributes it might have - $code = preg_replace('/<code\b[^>]*>/', '', $code); - $code = str_replace('</code>', '', $code); + $code = \preg_replace('/<code\b[^>]*>/', '', $code); + \assert($code !== null); + $code = \str_replace('</code>', '', $code); // Checking if it's a code block or span if ($this->shouldBeBlock($element, $code)) { @@ -44,7 +42,7 @@ class CodeConverter implements ConverterInterface $markdown .= '```' . $language . "\n" . $code . "\n" . '```'; } else { // One line of code, wrapping it on one backtick, removing new lines - $markdown .= '`' . preg_replace('/\r\n|\r|\n/', '', $code) . '`'; + $markdown .= '`' . \preg_replace('/\r\n|\r|\n/', '', $code) . '`'; } return $markdown; @@ -53,27 +51,18 @@ class CodeConverter implements ConverterInterface /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('code'); + return ['code']; } - /** - * @param ElementInterface $element - * @param string $code - * - * @return bool - */ - private function shouldBeBlock(ElementInterface $element, $code) + private function shouldBeBlock(ElementInterface $element, string $code): bool { - if ($element->getParent()->getTagName() == 'pre') { - return true; - } - - if (preg_match('/[^\s]` `/', $code)) { + $parent = $element->getParent(); + if ($parent !== null && $parent->getTagName() === 'pre') { return true; } - return false; + return \preg_match('/[^\s]` `/', $code) === 1; } } diff --git a/vendor/league/html-to-markdown/src/Converter/CommentConverter.php b/vendor/league/html-to-markdown/src/Converter/CommentConverter.php index 959381d1b..c69dea551 100644 --- a/vendor/league/html-to-markdown/src/Converter/CommentConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/CommentConverter.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\Configuration; @@ -8,55 +10,44 @@ use League\HTMLToMarkdown\ElementInterface; class CommentConverter implements ConverterInterface, ConfigurationAwareInterface { - /** - * @var Configuration - */ + /** @var Configuration */ protected $config; - /** - * @param Configuration $config - */ - public function setConfig(Configuration $config) + public function setConfig(Configuration $config): void { $this->config = $config; } - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { if ($this->shouldPreserve($element)) { return '<!--' . $element->getValue() . '-->'; } + return ''; } /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('#comment'); + return ['#comment']; } - /** - * @param ElementInterface $element - * - * @return bool - */ - private function shouldPreserve(ElementInterface $element) + private function shouldPreserve(ElementInterface $element): bool { $preserve = $this->config->getOption('preserve_comments'); if ($preserve === true) { return true; } - if (is_array($preserve)) { - $value = trim($element->getValue()); - return in_array($value, $preserve); + + if (\is_array($preserve)) { + $value = \trim($element->getValue()); + + return \in_array($value, $preserve, true); } + return false; } } diff --git a/vendor/league/html-to-markdown/src/Converter/ConverterInterface.php b/vendor/league/html-to-markdown/src/Converter/ConverterInterface.php index 8530559a0..f10498578 100644 --- a/vendor/league/html-to-markdown/src/Converter/ConverterInterface.php +++ b/vendor/league/html-to-markdown/src/Converter/ConverterInterface.php @@ -1,20 +1,17 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\ElementInterface; interface ConverterInterface { - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element); + public function convert(ElementInterface $element): string; /** * @return string[] */ - public function getSupportedTags(); + public function getSupportedTags(): array; } diff --git a/vendor/league/html-to-markdown/src/Converter/DefaultConverter.php b/vendor/league/html-to-markdown/src/Converter/DefaultConverter.php index 8de0af210..e71dd10cc 100644 --- a/vendor/league/html-to-markdown/src/Converter/DefaultConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/DefaultConverter.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\Configuration; @@ -8,27 +10,17 @@ use League\HTMLToMarkdown\ElementInterface; class DefaultConverter implements ConverterInterface, ConfigurationAwareInterface { - const DEFAULT_CONVERTER = '_default'; + public const DEFAULT_CONVERTER = '_default'; - /** - * @var Configuration - */ + /** @var Configuration */ protected $config; - /** - * @param Configuration $config - */ - public function setConfig(Configuration $config) + public function setConfig(Configuration $config): void { $this->config = $config; } - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { // If strip_tags is false (the default), preserve tags that don't have Markdown equivalents, // such as <span> nodes on their own. C14N() canonicalizes the node to a string. @@ -37,8 +29,9 @@ class DefaultConverter implements ConverterInterface, ConfigurationAwareInterfac return $element->getValue(); } - $markdown = html_entity_decode($element->getChildrenAsString()); + $markdown = \html_entity_decode($element->getChildrenAsString()); + // Tables are only handled here if TableConverter is not used if ($element->getTagName() === 'table') { $markdown .= "\n\n"; } @@ -49,8 +42,8 @@ class DefaultConverter implements ConverterInterface, ConfigurationAwareInterfac /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array(self::DEFAULT_CONVERTER); + return [self::DEFAULT_CONVERTER]; } } diff --git a/vendor/league/html-to-markdown/src/Converter/DivConverter.php b/vendor/league/html-to-markdown/src/Converter/DivConverter.php index 656a0ba4d..6453a2a27 100644 --- a/vendor/league/html-to-markdown/src/Converter/DivConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/DivConverter.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\Configuration; @@ -8,38 +10,28 @@ use League\HTMLToMarkdown\ElementInterface; class DivConverter implements ConverterInterface, ConfigurationAwareInterface { - /** - * @var Configuration - */ + /** @var Configuration */ protected $config; - /** - * @param Configuration $config - */ - public function setConfig(Configuration $config) + public function setConfig(Configuration $config): void { $this->config = $config; } - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { if ($this->config->getOption('strip_tags', false)) { return $element->getValue() . "\n\n"; } - return html_entity_decode($element->getChildrenAsString()); + return \html_entity_decode($element->getChildrenAsString()); } /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('div'); + return ['div']; } } diff --git a/vendor/league/html-to-markdown/src/Converter/EmphasisConverter.php b/vendor/league/html-to-markdown/src/Converter/EmphasisConverter.php index 8fd4dd6e2..a122f4052 100644 --- a/vendor/league/html-to-markdown/src/Converter/EmphasisConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/EmphasisConverter.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\Configuration; @@ -8,50 +10,63 @@ use League\HTMLToMarkdown\ElementInterface; class EmphasisConverter implements ConverterInterface, ConfigurationAwareInterface { - /** - * @var Configuration - */ + /** @var Configuration */ protected $config; - /** - * @param Configuration $config - */ - public function setConfig(Configuration $config) + protected function getNormTag(?ElementInterface $element): string + { + if ($element !== null && ! $element->isText()) { + $tag = $element->getTagName(); + if ($tag === 'i' || $tag === 'em') { + return 'em'; + } + + if ($tag === 'b' || $tag === 'strong') { + return 'strong'; + } + } + + return ''; + } + + public function setConfig(Configuration $config): void { $this->config = $config; } - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { - $tag = $element->getTagName(); + $tag = $this->getNormTag($element); $value = $element->getValue(); - if (!trim($value)) { + if (! \trim($value)) { return $value; } - if ($tag === 'i' || $tag === 'em') { + if ($tag === 'em') { $style = $this->config->getOption('italic_style'); } else { $style = $this->config->getOption('bold_style'); } - $prefix = ltrim($value) !== $value ? ' ' : ''; - $suffix = rtrim($value) !== $value ? ' ' : ''; + $prefix = \ltrim($value) !== $value ? ' ' : ''; + $suffix = \rtrim($value) !== $value ? ' ' : ''; + + /* If this node is immediately preceded or followed by one of the same type don't emit + * the start or end $style, respectively. This prevents <em>foo</em><em>bar</em> from + * being converted to *foo**bar* which is incorrect. We want *foobar* instead. + */ + $preStyle = $this->getNormTag($element->getPreviousSibling()) === $tag ? '' : $style; + $postStyle = $this->getNormTag($element->getNextSibling()) === $tag ? '' : $style; - return $prefix . $style . trim($value) . $style . $suffix; + return $prefix . $preStyle . \trim($value) . $postStyle . $suffix; } /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('em', 'i', 'strong', 'b'); + return ['em', 'i', 'strong', 'b']; } } diff --git a/vendor/league/html-to-markdown/src/Converter/HardBreakConverter.php b/vendor/league/html-to-markdown/src/Converter/HardBreakConverter.php index 1be10bd63..45e89682e 100644 --- a/vendor/league/html-to-markdown/src/Converter/HardBreakConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/HardBreakConverter.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\Configuration; @@ -8,35 +10,25 @@ use League\HTMLToMarkdown\ElementInterface; class HardBreakConverter implements ConverterInterface, ConfigurationAwareInterface { - /** - * @var Configuration - */ + /** @var Configuration */ protected $config; - /** - * @param Configuration $config - */ - public function setConfig(Configuration $config) + public function setConfig(Configuration $config): void { $this->config = $config; } - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { $return = $this->config->getOption('hard_break') ? "\n" : " \n"; $next = $element->getNext(); if ($next) { - $next_value = $next->getValue(); - if ($next_value) { - if (in_array(substr($next_value, 0, 2), array('- ', '* ', '+ '))) { + $nextValue = $next->getValue(); + if ($nextValue) { + if (\in_array(\substr($nextValue, 0, 2), ['- ', '* ', '+ '], true)) { $parent = $element->getParent(); - if ($parent && $parent->getTagName() == 'li') { + if ($parent && $parent->getTagName() === 'li') { $return .= '\\'; } } @@ -49,8 +41,8 @@ class HardBreakConverter implements ConverterInterface, ConfigurationAwareInterf /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('br'); + return ['br']; } } diff --git a/vendor/league/html-to-markdown/src/Converter/HeaderConverter.php b/vendor/league/html-to-markdown/src/Converter/HeaderConverter.php index 353833263..e99dfa0f4 100644 --- a/vendor/league/html-to-markdown/src/Converter/HeaderConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/HeaderConverter.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\Configuration; @@ -8,37 +10,27 @@ use League\HTMLToMarkdown\ElementInterface; class HeaderConverter implements ConverterInterface, ConfigurationAwareInterface { - const STYLE_ATX = 'atx'; - const STYLE_SETEXT = 'setext'; + public const STYLE_ATX = 'atx'; + public const STYLE_SETEXT = 'setext'; - /** - * @var Configuration - */ + /** @var Configuration */ protected $config; - /** - * @param Configuration $config - */ - public function setConfig(Configuration $config) + public function setConfig(Configuration $config): void { $this->config = $config; } - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { - $level = (int) substr($element->getTagName(), 1, 1); + $level = (int) \substr($element->getTagName(), 1, 1); $style = $this->config->getOption('header_style', self::STYLE_SETEXT); - if (strlen($element->getValue()) === 0) { + if (\strlen($element->getValue()) === 0) { return "\n"; } - if (($level === 1 || $level === 2) && !$element->isDescendantOf('blockquote') && $style === self::STYLE_SETEXT) { + if (($level === 1 || $level === 2) && ! $element->isDescendantOf('blockquote') && $style === self::STYLE_SETEXT) { return $this->createSetextHeader($level, $element->getValue()); } @@ -48,34 +40,22 @@ class HeaderConverter implements ConverterInterface, ConfigurationAwareInterface /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'); + return ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; } - /** - * @param int $level - * @param string $content - * - * @return string - */ - private function createSetextHeader($level, $content) + private function createSetextHeader(int $level, string $content): string { - $length = function_exists('mb_strlen') ? mb_strlen($content, 'utf-8') : strlen($content); - $underline = ($level === 1) ? '=' : '-'; + $length = \function_exists('mb_strlen') ? \mb_strlen($content, 'utf-8') : \strlen($content); + $underline = $level === 1 ? '=' : '-'; - return $content . "\n" . str_repeat($underline, $length) . "\n\n"; + return $content . "\n" . \str_repeat($underline, $length) . "\n\n"; } - /** - * @param int $level - * @param string $content - * - * @return string - */ - private function createAtxHeader($level, $content) + private function createAtxHeader(int $level, string $content): string { - $prefix = str_repeat('#', $level) . ' '; + $prefix = \str_repeat('#', $level) . ' '; return $prefix . $content . "\n\n"; } diff --git a/vendor/league/html-to-markdown/src/Converter/HorizontalRuleConverter.php b/vendor/league/html-to-markdown/src/Converter/HorizontalRuleConverter.php index 8f54f9397..ce280cc79 100644 --- a/vendor/league/html-to-markdown/src/Converter/HorizontalRuleConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/HorizontalRuleConverter.php @@ -1,17 +1,14 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\ElementInterface; class HorizontalRuleConverter implements ConverterInterface { - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { return "- - - - - -\n\n"; } @@ -19,8 +16,8 @@ class HorizontalRuleConverter implements ConverterInterface /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('hr'); + return ['hr']; } } diff --git a/vendor/league/html-to-markdown/src/Converter/ImageConverter.php b/vendor/league/html-to-markdown/src/Converter/ImageConverter.php index 657c769c2..5cd8aec67 100644 --- a/vendor/league/html-to-markdown/src/Converter/ImageConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/ImageConverter.php @@ -1,20 +1,17 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\ElementInterface; class ImageConverter implements ConverterInterface { - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { - $src = $element->getAttribute('src'); - $alt = $element->getAttribute('alt'); + $src = $element->getAttribute('src'); + $alt = $element->getAttribute('alt'); $title = $element->getAttribute('title'); if ($title !== '') { @@ -28,8 +25,8 @@ class ImageConverter implements ConverterInterface /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('img'); + return ['img']; } } diff --git a/vendor/league/html-to-markdown/src/Converter/LinkConverter.php b/vendor/league/html-to-markdown/src/Converter/LinkConverter.php index ed52619d2..25a3540fe 100644 --- a/vendor/league/html-to-markdown/src/Converter/LinkConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/LinkConverter.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\Configuration; @@ -8,28 +10,19 @@ use League\HTMLToMarkdown\ElementInterface; class LinkConverter implements ConverterInterface, ConfigurationAwareInterface { - /** - * @var Configuration - */ + /** @var Configuration */ protected $config; - /** - * @param Configuration $config - */ - public function setConfig(Configuration $config) { + public function setConfig(Configuration $config): void + { $this->config = $config; } - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { - $href = $element->getAttribute('href'); + $href = $element->getAttribute('href'); $title = $element->getAttribute('title'); - $text = trim($element->getValue(), "\t\n\r\0\x0B"); + $text = \trim($element->getValue(), "\t\n\r\0\x0B"); if ($title !== '') { $markdown = '[' . $text . '](' . $href . ' "' . $title . '")'; @@ -38,14 +31,19 @@ class LinkConverter implements ConverterInterface, ConfigurationAwareInterface } elseif ($href === 'mailto:' . $text && $this->isValidEmail($text)) { $markdown = '<' . $text . '>'; } else { - if (stristr($href, ' ')) { - $href = '<'.$href.'>'; + if (\stristr($href, ' ')) { + $href = '<' . $href . '>'; } + $markdown = '[' . $text . '](' . $href . ')'; } - if (!$href) { - $markdown = html_entity_decode($element->getChildrenAsString()); + if (! $href) { + if ($this->shouldStrip()) { + $markdown = $text; + } else { + $markdown = \html_entity_decode($element->getChildrenAsString()); + } } return $markdown; @@ -54,30 +52,26 @@ class LinkConverter implements ConverterInterface, ConfigurationAwareInterface /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('a'); + return ['a']; } - /** - * @param string $href - * - * @return bool - */ - private function isValidAutolink($href) + private function isValidAutolink(string $href): bool { $useAutolinks = $this->config->getOption('use_autolinks'); - return $useAutolinks && (preg_match('/^[A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>\x00-\x20]*/i', $href) === 1); + + return $useAutolinks && (\preg_match('/^[A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>\x00-\x20]*/i', $href) === 1); } - /** - * @param string $email - * - * @return bool - */ - private function isValidEmail($email) + private function isValidEmail(string $email): bool { // Email validation is messy business, but this should cover most cases - return filter_var($email, FILTER_VALIDATE_EMAIL); + return \filter_var($email, FILTER_VALIDATE_EMAIL) !== false; + } + + private function shouldStrip(): bool + { + return $this->config->getOption('strip_placeholder_links') ?? false; } } diff --git a/vendor/league/html-to-markdown/src/Converter/ListBlockConverter.php b/vendor/league/html-to-markdown/src/Converter/ListBlockConverter.php index 07a4c85a9..ce7b94654 100644 --- a/vendor/league/html-to-markdown/src/Converter/ListBlockConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/ListBlockConverter.php @@ -1,17 +1,14 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\ElementInterface; class ListBlockConverter implements ConverterInterface { - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { return $element->getValue() . "\n"; } @@ -19,8 +16,8 @@ class ListBlockConverter implements ConverterInterface /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('ol', 'ul'); + return ['ol', 'ul']; } } diff --git a/vendor/league/html-to-markdown/src/Converter/ListItemConverter.php b/vendor/league/html-to-markdown/src/Converter/ListItemConverter.php index c56ab89cd..91b3b5dbe 100644 --- a/vendor/league/html-to-markdown/src/Converter/ListItemConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/ListItemConverter.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\Configuration; @@ -8,39 +10,26 @@ use League\HTMLToMarkdown\ElementInterface; class ListItemConverter implements ConverterInterface, ConfigurationAwareInterface { - /** - * @var Configuration - */ + /** @var Configuration */ protected $config; - /** - * @var string - */ + /** @var string|null */ protected $listItemStyle; - /** - * @param Configuration $config - */ - public function setConfig(Configuration $config) + public function setConfig(Configuration $config): void { $this->config = $config; } - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { // If parent is an ol, use numbers, otherwise, use dashes - $list_type = $element->getParent()->getTagName(); + $listType = ($parent = $element->getParent()) ? $parent->getTagName() : 'ul'; // Add spaces to start for nested list items - $level = $element->getListItemLevel($element); + $level = $element->getListItemLevel(); - $prefixForParagraph = str_repeat(' ', $level + 1); - $value = trim(implode("\n" . $prefixForParagraph, explode("\n", trim($element->getValue())))); + $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 = ''; @@ -48,21 +37,21 @@ class ListItemConverter implements ConverterInterface, ConfigurationAwareInterfa $prefix = "\n"; } - if ($list_type === 'ul') { - $list_item_style = $this->config->getOption('list_item_style', '-'); - $list_item_style_alternate = $this->config->getOption('list_item_style_alternate'); - if (!isset($this->listItemStyle)) { - $this->listItemStyle = $list_item_style_alternate ? $list_item_style_alternate : $list_item_style; + if ($listType === 'ul') { + $listItemStyle = $this->config->getOption('list_item_style', '-'); + $listItemStyleAlternate = $this->config->getOption('list_item_style_alternate'); + if (! isset($this->listItemStyle)) { + $this->listItemStyle = $listItemStyleAlternate ?: $listItemStyle; } - if ($list_item_style_alternate && $level == 0 && $element->getSiblingPosition() === 1) { - $this->listItemStyle = $this->listItemStyle == $list_item_style ? $list_item_style_alternate : $list_item_style; + if ($listItemStyleAlternate && $level === 0 && $element->getSiblingPosition() === 1) { + $this->listItemStyle = $this->listItemStyle === $listItemStyle ? $listItemStyleAlternate : $listItemStyle; } return $prefix . $this->listItemStyle . ' ' . $value . "\n"; } - if ($list_type === 'ol' && $start = $element->getParent()->getAttribute('start')) { + if ($listType === 'ol' && ($parent = $element->getParent()) && ($start = \intval($parent->getAttribute('start')))) { $number = $start + $element->getSiblingPosition() - 1; } else { $number = $element->getSiblingPosition(); @@ -74,8 +63,8 @@ class ListItemConverter implements ConverterInterface, ConfigurationAwareInterfa /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('li'); + return ['li']; } } diff --git a/vendor/league/html-to-markdown/src/Converter/ParagraphConverter.php b/vendor/league/html-to-markdown/src/Converter/ParagraphConverter.php index 7207b81a6..65b37a4db 100644 --- a/vendor/league/html-to-markdown/src/Converter/ParagraphConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/ParagraphConverter.php @@ -1,23 +1,22 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\ElementInterface; class ParagraphConverter implements ConverterInterface { - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { $value = $element->getValue(); $markdown = ''; - $lines = preg_split('/\r\n|\r|\n/', $value); + $lines = \preg_split('/\r\n|\r|\n/', $value); + \assert($lines !== false); + foreach ($lines as $line) { /* * Some special characters need to be escaped based on the position that they appear @@ -27,23 +26,18 @@ class ParagraphConverter implements ConverterInterface $markdown .= "\n"; } - return trim($markdown) !== '' ? rtrim($markdown) . "\n\n" : ''; + return \trim($markdown) !== '' ? \rtrim($markdown) . "\n\n" : ''; } /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('p'); + return ['p']; } - /** - * @param string $line - * - * @return string - */ - private function escapeSpecialCharacters($line) + private function escapeSpecialCharacters(string $line): string { $line = $this->escapeFirstCharacters($line); $line = $this->escapeOtherCharacters($line); @@ -52,72 +46,61 @@ class ParagraphConverter implements ConverterInterface return $line; } - /** - * @param string $line - * - * @return string - */ - private function escapeFirstCharacters($line) + private function escapeFirstCharacters(string $line): string { - $escapable = array( + $escapable = [ '>', '- ', '+ ', '--', '~~~', '---', - '- - -' - ); + '- - -', + ]; foreach ($escapable as $i) { - if (strpos(ltrim($line), $i) === 0) { + if (\strpos(\ltrim($line), $i) === 0) { // Found a character that must be escaped, adding a backslash before - return '\\' . ltrim($line); + return '\\' . \ltrim($line); } } return $line; } - /** - * @param string $line - * - * @return string - */ - private function escapeOtherCharacters($line) + private function escapeOtherCharacters(string $line): string { - $escapable = array( - '<!--' - ); + $escapable = [ + '<!--', + ]; foreach ($escapable as $i) { - if (strpos($line, $i) !== false) { - // Found an escapable character, escaping it - $line = substr_replace($line, '\\', strpos($line, $i), 0); + if (($pos = \strpos($line, $i)) === false) { + continue; } + + // Found an escapable character, escaping it + $line = \substr_replace($line, '\\', $pos, 0); } return $line; } - /** - * @param string $line - * - * @return string - */ - private function escapeOtherCharactersRegex($line) + private function escapeOtherCharactersRegex(string $line): string { - $regExs = array( + $regExs = [ // Match numbers ending on ')' or '.' that are at the beginning of the line. // They will be escaped if immediately followed by a space or newline. - '/^[0-9]+(?=(\)|\.)( |$))/' - ); + '/^[0-9]+(?=(\)|\.)( |$))/', + ]; foreach ($regExs as $i) { - if (preg_match($i, $line, $match)) { - // Matched an escapable character, adding a backslash on the string before the offending character - $line = substr_replace($line, '\\', strlen($match[0]), 0); + if (! \preg_match($i, $line, $match)) { + continue; } + + // Matched an escapable character, adding a backslash on the string before the offending character + $line = \substr_replace($line, '\\', \strlen($match[0]), 0); } return $line; diff --git a/vendor/league/html-to-markdown/src/Converter/PreformattedConverter.php b/vendor/league/html-to-markdown/src/Converter/PreformattedConverter.php index 321c898b1..7d8ccc132 100644 --- a/vendor/league/html-to-markdown/src/Converter/PreformattedConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/PreformattedConverter.php @@ -1,20 +1,17 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\ElementInterface; class PreformattedConverter implements ConverterInterface { - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { - $pre_content = html_entity_decode($element->getChildrenAsString()); - $pre_content = str_replace(array('<pre>', '</pre>'), '', $pre_content); + $preContent = \html_entity_decode($element->getChildrenAsString()); + $preContent = \str_replace(['<pre>', '</pre>'], '', $preContent); /* * Checking for the code tag. @@ -23,36 +20,37 @@ class PreformattedConverter implements ConverterInterface * there's no more information to convert. */ - $firstBacktick = strpos(trim($pre_content), '`'); - $lastBacktick = strrpos(trim($pre_content), '`'); - if ($firstBacktick === 0 && $lastBacktick === strlen(trim($pre_content)) - 1) { - return $pre_content . "\n\n"; + $firstBacktick = \strpos(\trim($preContent), '`'); + $lastBacktick = \strrpos(\trim($preContent), '`'); + if ($firstBacktick === 0 && $lastBacktick === \strlen(\trim($preContent)) - 1) { + return $preContent . "\n\n"; } // If the execution reaches this point it means it's just a pre tag, with no code tag nested // Empty lines are a special case - if ($pre_content === '') { + if ($preContent === '') { return "```\n```\n\n"; } // Normalizing new lines - $pre_content = preg_replace('/\r\n|\r|\n/', "\n", $pre_content); + $preContent = \preg_replace('/\r\n|\r|\n/', "\n", $preContent); + \assert(\is_string($preContent)); // Ensure there's a newline at the end - if (strrpos($pre_content, "\n") !== strlen($pre_content) - strlen("\n")) { - $pre_content .= "\n"; + if (\strrpos($preContent, "\n") !== \strlen($preContent) - \strlen("\n")) { + $preContent .= "\n"; } // Use three backticks - return "```\n" . $pre_content . "```\n\n"; + return "```\n" . $preContent . "```\n\n"; } /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('pre'); + return ['pre']; } } diff --git a/vendor/league/html-to-markdown/src/Converter/TableConverter.php b/vendor/league/html-to-markdown/src/Converter/TableConverter.php new file mode 100644 index 000000000..2e63e9a5b --- /dev/null +++ b/vendor/league/html-to-markdown/src/Converter/TableConverter.php @@ -0,0 +1,113 @@ +<?php + +declare(strict_types=1); + +namespace League\HTMLToMarkdown\Converter; + +use League\HTMLToMarkdown\Configuration; +use League\HTMLToMarkdown\ConfigurationAwareInterface; +use League\HTMLToMarkdown\ElementInterface; +use League\HTMLToMarkdown\PreConverterInterface; + +class TableConverter implements ConverterInterface, PreConverterInterface, ConfigurationAwareInterface +{ + /** @var Configuration */ + protected $config; + + public function setConfig(Configuration $config): void + { + $this->config = $config; + } + + /** @var array<string, string> */ + private static $alignments = [ + 'left' => ':--', + 'right' => '--:', + 'center' => ':-:', + ]; + + /** @var array<int, string>|null */ + private $columnAlignments = []; + + /** @var string|null */ + private $caption = null; + + public function preConvert(ElementInterface $element): void + { + $tag = $element->getTagName(); + // Only table cells and caption are allowed to contain content. + // Remove all text between other table elements. + if ($tag === 'th' || $tag === 'td' || $tag === 'caption') { + return; + } + + foreach ($element->getChildren() as $child) { + if ($child->isText()) { + $child->setFinalMarkdown(''); + } + } + } + + public function convert(ElementInterface $element): string + { + $value = $element->getValue(); + + switch ($element->getTagName()) { + case 'table': + $this->columnAlignments = []; + if ($this->caption) { + $side = $this->config->getOption('table_caption_side'); + if ($side === 'top') { + $value = $this->caption . "\n" . $value; + } elseif ($side === 'bottom') { + $value .= $this->caption; + } + + $this->caption = null; + } + + return $value . "\n"; + case 'caption': + $this->caption = \trim($value); + + return ''; + case 'tr': + $value .= "|\n"; + if ($this->columnAlignments !== null) { + $value .= '|' . \implode('|', $this->columnAlignments) . "|\n"; + + $this->columnAlignments = null; + } + + return $value; + case 'th': + case 'td': + if ($this->columnAlignments !== null) { + $align = $element->getAttribute('align'); + + $this->columnAlignments[] = self::$alignments[$align] ?? '---'; + } + + $value = \str_replace("\n", ' ', $value); + $value = \str_replace('|', $this->config->getOption('table_pipe_escape') ?? '\|', $value); + + return '| ' . \trim($value) . ' '; + case 'thead': + case 'tbody': + case 'tfoot': + case 'colgroup': + case 'col': + return $value; + default: + return ''; + } + } + + /** + * @return string[] + */ + public function getSupportedTags(): array + { + return ['table', 'tr', 'th', 'td', 'thead', 'tbody', 'tfoot', 'colgroup', 'col', 'caption']; + } +} diff --git a/vendor/league/html-to-markdown/src/Converter/TextConverter.php b/vendor/league/html-to-markdown/src/Converter/TextConverter.php index 6236a1e9d..465dd4883 100644 --- a/vendor/league/html-to-markdown/src/Converter/TextConverter.php +++ b/vendor/league/html-to-markdown/src/Converter/TextConverter.php @@ -1,48 +1,48 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown\Converter; use League\HTMLToMarkdown\ElementInterface; class TextConverter implements ConverterInterface { - /** - * @param ElementInterface $element - * - * @return string - */ - public function convert(ElementInterface $element) + public function convert(ElementInterface $element): string { $markdown = $element->getValue(); // Remove leftover \n at the beginning of the line - $markdown = ltrim($markdown, "\n"); + $markdown = \ltrim($markdown, "\n"); // Replace sequences of invisible characters with spaces - $markdown = preg_replace('~\s+~u', ' ', $markdown); + $markdown = \preg_replace('~\s+~u', ' ', $markdown); + \assert(\is_string($markdown)); // Escape the following characters: '*', '_', '[', ']' and '\' - if ($element->getParent() && $element->getParent()->getTagName() !== 'div') { - $markdown = preg_replace('~([*_\\[\\]\\\\])~u', '\\\\$1', $markdown); + if (($parent = $element->getParent()) && $parent->getTagName() !== 'div') { + $markdown = \preg_replace('~([*_\\[\\]\\\\])~u', '\\\\$1', $markdown); + \assert(\is_string($markdown)); } - $markdown = preg_replace('~^#~u', '\\\\#', $markdown); + $markdown = \preg_replace('~^#~u', '\\\\#', $markdown); + \assert(\is_string($markdown)); if ($markdown === ' ') { $next = $element->getNext(); - if (!$next || $next->isBlock()) { + if (! $next || $next->isBlock()) { $markdown = ''; } } - return htmlspecialchars($markdown, ENT_NOQUOTES, 'UTF-8'); + return \htmlspecialchars($markdown, ENT_NOQUOTES, 'UTF-8'); } /** * @return string[] */ - public function getSupportedTags() + public function getSupportedTags(): array { - return array('#text'); + return ['#text']; } } diff --git a/vendor/league/html-to-markdown/src/Element.php b/vendor/league/html-to-markdown/src/Element.php index 80ae7a911..5407f1ffb 100644 --- a/vendor/league/html-to-markdown/src/Element.php +++ b/vendor/league/html-to-markdown/src/Element.php @@ -1,28 +1,28 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown; class Element implements ElementInterface { - /** - * @var \DOMNode - */ + /** @var \DOMNode */ protected $node; - /** - * @var ElementInterface|null - */ + /** @var ElementInterface|null */ private $nextCached; + /** @var \DOMNode|null */ + private $previousSiblingCached; + public function __construct(\DOMNode $node) { $this->node = $node; + + $this->previousSiblingCached = $this->node->previousSibling; } - /** - * @return bool - */ - public function isBlock() + public function isBlock(): bool { switch ($this->getTagName()) { case 'blockquote': @@ -46,50 +46,47 @@ class Element implements ElementInterface } } - /** - * @return bool - */ - public function isText() + public function isText(): bool { return $this->getTagName() === '#text'; } - /** - * @return bool - */ - public function isWhitespace() + public function isWhitespace(): bool { - return $this->getTagName() === '#text' && trim($this->getValue()) === ''; + return $this->getTagName() === '#text' && \trim($this->getValue()) === ''; } - /** - * @return string - */ - public function getTagName() + public function getTagName(): string { return $this->node->nodeName; } - /** - * @return string - */ - public function getValue() + public function getValue(): string { return $this->node->nodeValue; } - /** - * @return ElementInterface|null - */ - public function getParent() + public function hasParent(): bool { - return new static($this->node->parentNode) ?: null; + return $this->node->parentNode !== null; } - /** - * @return bool - */ - public function hasChildren() + public function getParent(): ?ElementInterface + { + return $this->node->parentNode ? new self($this->node->parentNode) : null; + } + + public function getNextSibling(): ?ElementInterface + { + return $this->node->nextSibling !== null ? new self($this->node->nextSibling) : null; + } + + public function getPreviousSibling(): ?ElementInterface + { + return $this->previousSiblingCached !== null ? new self($this->previousSiblingCached) : null; + } + + public function hasChildren(): bool { return $this->node->hasChildNodes(); } @@ -97,39 +94,29 @@ class Element implements ElementInterface /** * @return ElementInterface[] */ - public function getChildren() + public function getChildren(): array { - $ret = array(); - /** @var \DOMNode $node */ + $ret = []; foreach ($this->node->childNodes as $node) { - $ret[] = new static($node); + $ret[] = new self($node); } return $ret; } - /** - * @return ElementInterface|null - */ - public function getNext() + public function getNext(): ?ElementInterface { if ($this->nextCached === null) { $nextNode = $this->getNextNode($this->node); if ($nextNode !== null) { - $this->nextCached = new static($nextNode); + $this->nextCached = new self($nextNode); } } return $this->nextCached; } - /** - * @param \DomNode $node - * @param bool $checkChildren - * - * @return \DomNode|null - */ - private function getNextNode($node, $checkChildren = true) + private function getNextNode(\DomNode $node, bool $checkChildren = true): ?\DomNode { if ($checkChildren && $node->firstChild) { return $node->firstChild; @@ -142,25 +129,25 @@ class Element implements ElementInterface if ($node->parentNode) { return $this->getNextNode($node->parentNode, false); } + + return null; } /** * @param string[]|string $tagNames - * - * @return bool */ - public function isDescendantOf($tagNames) + public function isDescendantOf($tagNames): bool { - if (!is_array($tagNames)) { - $tagNames = array($tagNames); + if (! \is_array($tagNames)) { + $tagNames = [$tagNames]; } for ($p = $this->node->parentNode; $p !== false; $p = $p->parentNode) { - if (is_null($p)) { + if ($p === null) { return false; } - if (in_array($p->nodeName, $tagNames)) { + if (\in_array($p->nodeName, $tagNames, true)) { return true; } } @@ -168,39 +155,43 @@ class Element implements ElementInterface return false; } - /** - * @param string $markdown - */ - public function setFinalMarkdown($markdown) + public function setFinalMarkdown(string $markdown): void { - $markdown_node = $this->node->ownerDocument->createTextNode($markdown); - $this->node->parentNode->replaceChild($markdown_node, $this->node); + if ($this->node->ownerDocument === null) { + throw new \RuntimeException('Unowned node'); + } + + if ($this->node->parentNode === null) { + throw new \RuntimeException('Cannot setFinalMarkdown() on a node without a parent'); + } + + $markdownNode = $this->node->ownerDocument->createTextNode($markdown); + $this->node->parentNode->replaceChild($markdownNode, $this->node); } - /** - * @return string - */ - public function getChildrenAsString() + public function getChildrenAsString(): string { return $this->node->C14N(); } - /** - * @return int - */ - public function getSiblingPosition() + public function getSiblingPosition(): int { $position = 0; + $parent = $this->getParent(); + if ($parent === null) { + return $position; + } + // Loop through all nodes and find the given $node - foreach ($this->getParent()->getChildren() as $current_node) { - if (!$current_node->isWhitespace()) { + foreach ($parent->getChildren() as $currentNode) { + if (! $currentNode->isWhitespace()) { $position++; } // TODO: Need a less-buggy way of comparing these // Perhaps we can somehow ensure that we always have the exact same object and use === instead? - if ($this->equals($current_node)) { + if ($this->equals($currentNode)) { break; } } @@ -208,30 +199,23 @@ class Element implements ElementInterface return $position; } - /** - * @return int - */ - public function getListItemLevel() + public function getListItemLevel(): int { - $level = 0; + $level = 0; $parent = $this->getParent(); - while ($parent !== null && $parent->node->parentNode) { + while ($parent !== null && $parent->hasParent()) { if ($parent->getTagName() === 'li') { $level++; } + $parent = $parent->getParent(); } return $level; } - /** - * @param string $name - * - * @return string - */ - public function getAttribute($name) + public function getAttribute(string $name): string { if ($this->node instanceof \DOMElement) { return $this->node->getAttribute($name); @@ -240,17 +224,12 @@ class Element implements ElementInterface return ''; } - /** - * @param ElementInterface $element - * - * @return bool - */ - public function equals(ElementInterface $element) + public function equals(ElementInterface $element): bool { if ($element instanceof self) { return $element->node === $this->node; } - return $element === $this; + return false; } } diff --git a/vendor/league/html-to-markdown/src/ElementInterface.php b/vendor/league/html-to-markdown/src/ElementInterface.php index 138ddf286..d8477cfae 100644 --- a/vendor/league/html-to-markdown/src/ElementInterface.php +++ b/vendor/league/html-to-markdown/src/ElementInterface.php @@ -1,80 +1,50 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown; interface ElementInterface { - /** - * @return bool - */ - public function isBlock(); + public function isBlock(): bool; - /** - * @return bool - */ - public function isText(); + public function isText(): bool; - /** - * @return bool - */ - public function isWhitespace(); + public function isWhitespace(): bool; - /** - * @return string - */ - public function getTagName(); + public function getTagName(): string; - /** - * @return string - */ - public function getValue(); + public function getValue(): string; - /** - * @return ElementInterface|null - */ - public function getParent(); + public function hasParent(): bool; + + public function getParent(): ?ElementInterface; + + public function getNextSibling(): ?ElementInterface; + + public function getPreviousSibling(): ?ElementInterface; /** * @param string|string[] $tagNames - * - * @return bool */ - public function isDescendantOf($tagNames); + public function isDescendantOf($tagNames): bool; - /** - * @return bool - */ - public function hasChildren(); + public function hasChildren(): bool; /** * @return ElementInterface[] */ - public function getChildren(); + public function getChildren(): array; - /** - * @return ElementInterface|null - */ - public function getNext(); + public function getNext(): ?ElementInterface; - /** - * @return int - */ - public function getSiblingPosition(); + public function getSiblingPosition(): int; - /** - * @return string - */ - public function getChildrenAsString(); + public function getChildrenAsString(): string; - /** - * @param string $markdown - */ - public function setFinalMarkdown($markdown); + public function setFinalMarkdown(string $markdown): void; - /** - * @param string $name - * - * @return string - */ - public function getAttribute($name); + public function getListItemLevel(): int; + + public function getAttribute(string $name): string; } diff --git a/vendor/league/html-to-markdown/src/Environment.php b/vendor/league/html-to-markdown/src/Environment.php index 560cfe613..7ea19d410 100644 --- a/vendor/league/html-to-markdown/src/Environment.php +++ b/vendor/league/html-to-markdown/src/Environment.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown; use League\HTMLToMarkdown\Converter\BlockquoteConverter; @@ -22,34 +24,27 @@ use League\HTMLToMarkdown\Converter\TextConverter; final class Environment { - /** - * @var Configuration - */ + /** @var Configuration */ protected $config; + /** @var ConverterInterface[] */ + protected $converters = []; + /** - * @var ConverterInterface[] + * @param array<string, mixed> $config */ - protected $converters = array(); - - public function __construct(array $config = array()) + public function __construct(array $config = []) { $this->config = new Configuration($config); $this->addConverter(new DefaultConverter()); } - /** - * @return Configuration - */ - public function getConfig() + public function getConfig(): Configuration { return $this->config; } - /** - * @param ConverterInterface $converter - */ - public function addConverter(ConverterInterface $converter) + public function addConverter(ConverterInterface $converter): void { if ($converter instanceof ConfigurationAwareInterface) { $converter->setConfig($this->config); @@ -60,12 +55,7 @@ final class Environment } } - /** - * @param string $tag - * - * @return ConverterInterface - */ - public function getConverterByTag($tag) + public function getConverterByTag(string $tag): ConverterInterface { if (isset($this->converters[$tag])) { return $this->converters[$tag]; @@ -75,11 +65,9 @@ final class Environment } /** - * @param array $config - * - * @return Environment + * @param array<string, mixed> $config */ - public static function createDefaultEnvironment(array $config = array()) + public static function createDefaultEnvironment(array $config = []): Environment { $environment = new static($config); diff --git a/vendor/league/html-to-markdown/src/HtmlConverter.php b/vendor/league/html-to-markdown/src/HtmlConverter.php index 6f98e97b4..7cd543b34 100644 --- a/vendor/league/html-to-markdown/src/HtmlConverter.php +++ b/vendor/league/html-to-markdown/src/HtmlConverter.php @@ -1,10 +1,10 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown; /** - * Class HtmlConverter - * * A helper class to convert HTML to Markdown. * * @author Colin O'Dell <colinodell@gmail.com> @@ -16,25 +16,24 @@ namespace League\HTMLToMarkdown; */ class HtmlConverter implements HtmlConverterInterface { - /** - * @var Environment - */ + /** @var Environment */ protected $environment; /** * Constructor * - * @param Environment|array $options Environment object or configuration options + * @param Environment|array<string, mixed> $options Environment object or configuration options */ - public function __construct($options = array()) + public function __construct($options = []) { if ($options instanceof Environment) { $this->environment = $options; - } elseif (is_array($options)) { - $defaults = array( + } elseif (\is_array($options)) { + $defaults = [ 'header_style' => 'setext', // Set to 'atx' to output H1 and H2 headers as # Header1 and ## Header2 'suppress_errors' => true, // Set to false to show warnings when loading malformed HTML 'strip_tags' => false, // Set to true to strip tags that don't have markdown equivalents. N.B. Strips tags, not their content. Useful to clean MS Word HTML output. + 'strip_placeholder_links' => false, // Set to true to remove <a> that doesn't have href. 'bold_style' => '**', // DEPRECATED: Set to '__' if you prefer the underlined style 'italic_style' => '*', // DEPRECATED: Set to '_' if you prefer the underlined style 'remove_nodes' => '', // space-separated list of dom nodes that should be removed. example: 'meta style script' @@ -42,7 +41,9 @@ class HtmlConverter implements HtmlConverterInterface 'list_item_style' => '-', // Set the default character for each <li> in a <ul>. Can be '-', '*', or '+' 'preserve_comments' => false, // Set to true to preserve comments, or set to an array of strings to preserve specific comments 'use_autolinks' => true, // Set to true to use simple link syntax if possible. Will always use []() if set to false - ); + 'table_pipe_escape' => '\|', // Replacement string for pipe characters inside markdown table cells + 'table_caption_side' => 'top', // Set to 'top' or 'bottom' to show <caption> content before or after table, null to suppress + ]; $this->environment = Environment::createDefaultEnvironment($defaults); @@ -50,18 +51,12 @@ class HtmlConverter implements HtmlConverterInterface } } - /** - * @return Environment - */ - public function getEnvironment() + public function getEnvironment(): Environment { return $this->environment; } - /** - * @return Configuration - */ - public function getConfig() + public function getConfig(): Configuration { return $this->environment->getConfig(); } @@ -71,11 +66,9 @@ class HtmlConverter implements HtmlConverterInterface * * @see HtmlConverter::convert * - * @param string $html - * * @return string The Markdown version of the html */ - public function __invoke($html) + public function __invoke(string $html): string { return $this->convert($html); } @@ -85,22 +78,20 @@ class HtmlConverter implements HtmlConverterInterface * * Loads HTML and passes to getMarkdown() * - * @param string $html - * - * @throws \InvalidArgumentException - * * @return string The Markdown version of the html + * + * @throws \InvalidArgumentException|\RuntimeException */ - public function convert($html) + public function convert(string $html): string { - if (trim($html) === '') { + if (\trim($html) === '') { return ''; } $document = $this->createDOMDocument($html); // Work on the entire DOM tree (including head and body) - if (!($root = $document->getElementsByTagName('html')->item(0))) { + if (! ($root = $document->getElementsByTagName('html')->item(0))) { throw new \InvalidArgumentException('Invalid HTML was provided'); } @@ -110,21 +101,20 @@ class HtmlConverter implements HtmlConverterInterface // Store the now-modified DOMDocument as a string $markdown = $document->saveHTML(); + if ($markdown === false) { + throw new \RuntimeException('Unknown error occurred during HTML to Markdown conversion'); + } + return $this->sanitize($markdown); } - /** - * @param string $html - * - * @return \DOMDocument - */ - private function createDOMDocument($html) + private function createDOMDocument(string $html): \DOMDocument { $document = new \DOMDocument(); if ($this->getConfig()->getOption('suppress_errors')) { // Suppress conversion errors (from http://bit.ly/pCCRSX) - libxml_use_internal_errors(true); + \libxml_use_internal_errors(true); } // Hack to load utf-8 HTML (from http://bit.ly/pVDyCt) @@ -132,7 +122,7 @@ class HtmlConverter implements HtmlConverterInterface $document->encoding = 'UTF-8'; if ($this->getConfig()->getOption('suppress_errors')) { - libxml_clear_errors(); + \libxml_clear_errors(); } return $document; @@ -145,17 +135,21 @@ class HtmlConverter implements HtmlConverterInterface * * Finds children of each node and convert those to #text nodes containing their Markdown equivalent, * starting with the innermost element and working up to the outermost element. - * - * @param ElementInterface $element */ - private function convertChildren(ElementInterface $element) + private function convertChildren(ElementInterface $element): void { // Don't convert HTML code inside <code> and <pre> 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(array('pre', 'code')) && $element->getTagName() !== 'code') { + 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) { @@ -179,18 +173,16 @@ class HtmlConverter implements HtmlConverterInterface * * Example: An <h3> node with text content of 'Title' becomes a text node with content of '### Title' * - * @param ElementInterface $element - * * @return string The converted HTML as Markdown */ - protected function convertToMarkdown(ElementInterface $element) + protected function convertToMarkdown(ElementInterface $element): string { $tag = $element->getTagName(); // Strip nodes named in remove_nodes - $tags_to_remove = explode(' ', $this->getConfig()->getOption('remove_nodes')); - if (in_array($tag, $tags_to_remove)) { - return false; + $tagsToRemove = \explode(' ', $this->getConfig()->getOption('remove_nodes') ?? ''); + if (\in_array($tag, $tagsToRemove, true)) { + return ''; } $converter = $this->environment->getConverterByTag($tag); @@ -198,38 +190,34 @@ class HtmlConverter implements HtmlConverterInterface return $converter->convert($element); } - /** - * @param string $markdown - * - * @return string - */ - protected function sanitize($markdown) + protected function sanitize(string $markdown): string { - $markdown = html_entity_decode($markdown, ENT_QUOTES, 'UTF-8'); - $markdown = preg_replace('/<!DOCTYPE [^>]+>/', '', $markdown); // Strip doctype declaration - $markdown = trim($markdown); // Remove blank spaces at the beggining of the html + $markdown = \html_entity_decode($markdown, ENT_QUOTES, 'UTF-8'); + $markdown = \preg_replace('/<!DOCTYPE [^>]+>/', '', $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 = array('<?xml encoding="UTF-8">', '<html>', '</html>', '<body>', '</body>', '<head>', '</head>', '
'); + $unwanted = ['<?xml encoding="UTF-8">', '<html>', '</html>', '<body>', '</body>', '<head>', '</head>', '
']; foreach ($unwanted as $tag) { - if (strpos($tag, '/') === false) { + if (\strpos($tag, '/') === false) { // Opening tags - if (strpos($markdown, $tag) === 0) { - $markdown = substr($markdown, strlen($tag)); + 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)); + if (\strpos($markdown, $tag) === \strlen($markdown) - \strlen($tag)) { + $markdown = \substr($markdown, 0, -\strlen($tag)); } } } - return trim($markdown, "\n\r\0\x0B"); + return \trim($markdown, "\n\r\0\x0B"); } /** @@ -239,6 +227,10 @@ class HtmlConverter implements HtmlConverterInterface * An example being: * * HtmlConverter::setOptions(['strip_tags' => true])->convert('<h1>test</h1>'); + * + * @param array<string, mixed> $options + * + * @return $this */ public function setOptions(array $options) { diff --git a/vendor/league/html-to-markdown/src/HtmlConverterInterface.php b/vendor/league/html-to-markdown/src/HtmlConverterInterface.php index 7d43cf87e..5c7e9eb65 100644 --- a/vendor/league/html-to-markdown/src/HtmlConverterInterface.php +++ b/vendor/league/html-to-markdown/src/HtmlConverterInterface.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace League\HTMLToMarkdown; /** @@ -16,11 +18,9 @@ interface HtmlConverterInterface /** * Convert the given $html to Markdown * - * @param string $html + * @return string The Markdown version of the html * * @throws \InvalidArgumentException - * - * @return string The Markdown version of the html */ - public function convert($html); + public function convert(string $html): string; } diff --git a/vendor/league/html-to-markdown/src/PreConverterInterface.php b/vendor/league/html-to-markdown/src/PreConverterInterface.php new file mode 100644 index 000000000..f835086ef --- /dev/null +++ b/vendor/league/html-to-markdown/src/PreConverterInterface.php @@ -0,0 +1,10 @@ +<?php + +declare(strict_types=1); + +namespace League\HTMLToMarkdown; + +interface PreConverterInterface +{ + public function preConvert(ElementInterface $element): void; +} |