mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-31 17:19:59 +09:00
Update composer.json for PHP 7.2
This commit is contained in:
parent
35a93f3928
commit
e79493bda5
549 changed files with 21493 additions and 24634 deletions
|
|
@ -1,3 +1,3 @@
|
|||
github: colinodell
|
||||
patreon: colinodell
|
||||
tidelift: "packagist/league/html-to-markdown"
|
||||
custom: ["https://www.colinodell.com/sponsor", "https://www.paypal.me/colinpodell/10.00"]
|
||||
|
|
|
|||
25
vendor/league/html-to-markdown/.github/ISSUE_TEMPLATE/1_Conversion_error.yaml
vendored
Normal file
25
vendor/league/html-to-markdown/.github/ISSUE_TEMPLATE/1_Conversion_error.yaml
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
name: "📃 Bug Report (Incorrect Markdown)"
|
||||
description: I'm not getting the Markdown I expect
|
||||
body:
|
||||
- type: input
|
||||
id: affected-versions
|
||||
attributes:
|
||||
label: Version(s) affected
|
||||
placeholder: x.y.z
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: A clear and concise description of the problem.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: how-to-reproduce
|
||||
attributes:
|
||||
label: How to reproduce
|
||||
description: |
|
||||
Provide the HTML input and any other information that would help us reproduce the problem.
|
||||
validations:
|
||||
required: true
|
||||
43
vendor/league/html-to-markdown/.github/ISSUE_TEMPLATE/2_Bug_report.yaml
vendored
Normal file
43
vendor/league/html-to-markdown/.github/ISSUE_TEMPLATE/2_Bug_report.yaml
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
name: "🐛 Bug Report (Other)"
|
||||
description: Report all other errors and problems
|
||||
body:
|
||||
- type: input
|
||||
id: affected-versions
|
||||
attributes:
|
||||
label: Version(s) affected
|
||||
placeholder: x.y.z
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: A clear and concise description of the problem.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: how-to-reproduce
|
||||
attributes:
|
||||
label: How to reproduce
|
||||
description: |
|
||||
HTML and/or any other information needed to reproduce the problem.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: possible-solution
|
||||
attributes:
|
||||
label: Possible solution
|
||||
description: |
|
||||
Optional: only if you have suggestions on a fix/reason for the bug
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: |
|
||||
Optional: any other context about the problem: log messages, screenshots, etc.
|
||||
- type: textarea
|
||||
id: feedback
|
||||
attributes:
|
||||
label: Did this project help you today? Did it make you happy in any way?
|
||||
description: |
|
||||
Optional: Sometimes we get tired of reading bug reports and working on complex features, so if you have anything positive to share about how this library might have helped you we'd love to hear it!
|
||||
27
vendor/league/html-to-markdown/.github/ISSUE_TEMPLATE/3_Feature_request.yaml
vendored
Normal file
27
vendor/league/html-to-markdown/.github/ISSUE_TEMPLATE/3_Feature_request.yaml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
name: "🚀 Feature Request"
|
||||
description: RFC and ideas for new features and improvements
|
||||
labels:
|
||||
- enhancement
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: A clear and concise description of the problem.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: example
|
||||
attributes:
|
||||
label: Example
|
||||
description: |
|
||||
A simple example of the new feature in action (include PHP code, sample HTML/Markdown, etc.)
|
||||
If the new feature changes an existing feature, include a simple before/after comparison.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: feedback
|
||||
attributes:
|
||||
label: Did this project help you today? Did it make you happy in any way?
|
||||
description: |
|
||||
Optional: Sometimes we get tired of reading bug reports and working on complex features, so if you have anything positive to share about how this library might have helped you we'd love to hear it!
|
||||
13
vendor/league/html-to-markdown/.github/SECURITY.md
vendored
Normal file
13
vendor/league/html-to-markdown/.github/SECURITY.md
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# SECURITY POLICY
|
||||
|
||||
## Supported Versions
|
||||
|
||||
When a new **minor** version (`5.x`) is released, the previous one will continue to receive security and bug fixes for *at least* 3 months.
|
||||
|
||||
When a new **major** version is released (`4.0`, `5.0`, etc), the previous one will receive bug fixes for *at least* 3 months and security updates for 6 months after that new release comes out.
|
||||
|
||||
(This policy may change in the future and exceptions may be made on a case-by-case basis.)
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a security vulnerability within this package, please use the [Tidelift security contact form](https://tidelift.com/security) or email Colin O'Dell at <colinodell@gmail.com>. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced.
|
||||
104
vendor/league/html-to-markdown/.github/workflows/tests.yml
vendored
Normal file
104
vendor/league/html-to-markdown/.github/workflows/tests.yml
vendored
Normal file
|
|
@ -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
|
||||
53
vendor/league/html-to-markdown/CHANGELOG.md
vendored
53
vendor/league/html-to-markdown/CHANGELOG.md
vendored
|
|
@ -4,6 +4,53 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip
|
|||
|
||||
## [Unreleased][unreleased]
|
||||
|
||||
## [5.1.0] - 2022-03-02
|
||||
|
||||
### Changed
|
||||
|
||||
- Changed horizontal rule style (#218, #219)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `Element::getValue()` not handling possible nulls
|
||||
|
||||
## [5.0.2] - 2021-11-06
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed missplaced comment nodes appearing at the start of the HTML input (#212)
|
||||
|
||||
## [5.0.1] - 2021-09-17
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed lists not using the correct amount of indentation (#211)
|
||||
|
||||
## [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 +315,11 @@ 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.1.0...master
|
||||
[5.1.0]: https://github.com/thephpleague/html-to-markdown/compare/5.0.2...5.1.0
|
||||
[5.0.2]: https://github.com/thephpleague/html-to-markdown/compare/5.0.1...5.0.2
|
||||
[5.0.1]: https://github.com/thephpleague/html-to-markdown/compare/5.0.0...5.0.1
|
||||
[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
|
||||
|
|
|
|||
4
vendor/league/html-to-markdown/LICENSE
vendored
4
vendor/league/html-to-markdown/LICENSE
vendored
|
|
@ -1,8 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Colin O'Dell
|
||||
|
||||
Originally created by Nick Cernis
|
||||
Copyright (c) 2015 Colin O'Dell; Originally created by Nick Cernis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
|
|
|||
38
vendor/league/html-to-markdown/README.md
vendored
38
vendor/league/html-to-markdown/README.md
vendored
|
|
@ -1,11 +1,9 @@
|
|||
HTML To Markdown for PHP
|
||||
========================
|
||||
|
||||
[](https://gitter.im/thephpleague/html-to-markdown?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
[](https://packagist.org/packages/league/html-to-markdown)
|
||||
[](LICENSE)
|
||||
[](https://travis-ci.org/thephpleague/html-to-markdown)
|
||||
[](https://github.com/thephpleague/html-to-markdown/actions?query=workflow%3ATests+branch%3Amaster)
|
||||
[](https://scrutinizer-ci.com/g/thephpleague/html-to-markdown/code-structure)
|
||||
[](https://scrutinizer-ci.com/g/thephpleague/html-to-markdown)
|
||||
[](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,18 +181,25 @@ $html = '<h3>Header</h3>
|
|||
$markdown = $converter->convert($html); // $markdown now contains "### Header" and "<img src="" />"
|
||||
```
|
||||
|
||||
### Table support
|
||||
|
||||
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:
|
||||
|
||||
```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);
|
||||
```
|
||||
|
||||
### Limitations
|
||||
|
||||
- Markdown Extra, MultiMarkdown and other variants aren't supported – just Markdown.
|
||||
|
||||
### Known issues
|
||||
|
||||
- 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).
|
||||
|
||||
[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.
|
||||
|
||||
### Style notes
|
||||
|
||||
- Setext (underlined) headers are the default for H1 and H2. If you prefer the ATX style for H1 and H2 (# Header 1 and ## Header 2), set `header_style` to 'atx' in the options array when you instantiate the object:
|
||||
|
|
|
|||
18
vendor/league/html-to-markdown/composer.json
vendored
18
vendor/league/html-to-markdown/composer.json
vendored
|
|
@ -30,19 +30,27 @@
|
|||
}
|
||||
},
|
||||
"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.99",
|
||||
"phpunit/phpunit": "^8.5 || ^9.2",
|
||||
"scrutinizer/ocular": "^1.6",
|
||||
"unleashedtech/php-coding-standard": "^2.7",
|
||||
"vimeo/psalm": "^4.22"
|
||||
},
|
||||
"bin": ["bin/html-to-markdown"],
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.10-dev"
|
||||
"dev-master": "5.2-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
27
vendor/league/html-to-markdown/phpcs.xml.dist
vendored
Normal file
27
vendor/league/html-to-markdown/phpcs.xml.dist
vendored
Normal file
|
|
@ -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>
|
||||
4
vendor/league/html-to-markdown/phpstan.neon.dist
vendored
Normal file
4
vendor/league/html-to-markdown/phpstan.neon.dist
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
parameters:
|
||||
level: max
|
||||
paths:
|
||||
- src
|
||||
15
vendor/league/html-to-markdown/psalm.xml
vendored
Normal file
15
vendor/league/html-to-markdown/psalm.xml
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
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>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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') {
|
||||
$parent = $element->getParent();
|
||||
if ($parent !== null && $parent->getTagName() === 'pre') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (preg_match('/[^\s]` `/', $code)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return \preg_match('/[^\s]` `/', $code) === 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ? ' ' : '';
|
||||
|
||||
return $prefix . $style . trim($value) . $style . $suffix;
|
||||
/* 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 . $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'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,23 @@
|
|||
<?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";
|
||||
return "---\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getSupportedTags()
|
||||
public function getSupportedTags(): array
|
||||
{
|
||||
return array('hr');
|
||||
return ['hr'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
113
vendor/league/html-to-markdown/src/Converter/TableConverter.php
vendored
Normal file
113
vendor/league/html-to-markdown/src/Converter/TableConverter.php
vendored
Normal file
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
@ -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'];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
171
vendor/league/html-to-markdown/src/Element.php
vendored
171
vendor/league/html-to-markdown/src/Element.php
vendored
|
|
@ -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 $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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = array();
|
||||
/** @var ConverterInterface[] */
|
||||
protected $converters = [];
|
||||
|
||||
public function __construct(array $config = array())
|
||||
/**
|
||||
* @param array<string, mixed> $config
|
||||
*/
|
||||
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);
|
||||
|
||||
|
|
|
|||
148
vendor/league/html-to-markdown/src/HtmlConverter.php
vendored
148
vendor/league/html-to-markdown/src/HtmlConverter.php
vendored
|
|
@ -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,34 +101,65 @@ 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)
|
||||
$document->loadHTML('<?xml encoding="UTF-8">' . $html);
|
||||
$document->encoding = 'UTF-8';
|
||||
|
||||
$this->replaceMisplacedComments($document);
|
||||
|
||||
if ($this->getConfig()->getOption('suppress_errors')) {
|
||||
libxml_clear_errors();
|
||||
\libxml_clear_errors();
|
||||
}
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds any comment nodes outside <html> element and moves them into <body>.
|
||||
*
|
||||
* @see https://github.com/thephpleague/html-to-markdown/issues/212
|
||||
* @see https://3v4l.org/7bC33
|
||||
*/
|
||||
private function replaceMisplacedComments(\DOMDocument $document): void
|
||||
{
|
||||
// Find ny comment nodes at the root of the document.
|
||||
$misplacedComments = (new \DOMXPath($document))->query('/comment()');
|
||||
if ($misplacedComments === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$body = $document->getElementsByTagName('body')->item(0);
|
||||
if ($body === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop over comment nodes in reverse so we put them inside <body> in
|
||||
// their original order.
|
||||
for ($index = $misplacedComments->length - 1; $index >= 0; $index--) {
|
||||
if ($body->firstChild === null) {
|
||||
$body->insertBefore($misplacedComments[$index]);
|
||||
} else {
|
||||
$body->insertBefore($misplacedComments[$index], $body->firstChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Children
|
||||
*
|
||||
|
|
@ -145,17 +167,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 +205,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 +222,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 +259,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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
10
vendor/league/html-to-markdown/src/PreConverterInterface.php
vendored
Normal file
10
vendor/league/html-to-markdown/src/PreConverterInterface.php
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace League\HTMLToMarkdown;
|
||||
|
||||
interface PreConverterInterface
|
||||
{
|
||||
public function preConvert(ElementInterface $element): void;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue