Merge remote-tracking branch 'github/lib' into lib-1.x

This commit is contained in:
Michel Fortin 2022-09-22 23:23:01 -04:00
commit 5bbf780e31
9 changed files with 139 additions and 140 deletions

30
.github/workflows/ci.yml vendored Normal file
View file

@ -0,0 +1,30 @@
name: CI
on:
pull_request: null
push:
branches:
- lib
jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
php:
- '7.4'
- '8.0'
- '8.1'
- '8.2'
name: Linting - PHP ${{ matrix.php }}
steps:
- uses: actions/checkout@v2
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: none
extensions: intl
- run: composer install --no-progress
# - run: composer codestyle
- run: composer phpstan
if: matrix.php == '8.1'
- run: composer tests

View file

@ -1,7 +1,7 @@
build: build:
environment: environment:
php: php:
version: '7.0.20' version: '7.4'
nodes: nodes:
analysis: analysis:
project_setup: project_setup:

View file

@ -4,24 +4,10 @@ matrix:
include: include:
- php: hhvm-3.18 - php: hhvm-3.18
dist: trusty dist: trusty
- php: 5.3
dist: precise
- php: 5.4
dist: trusty
- php: 5.5
dist: trusty
- php: 5.6
dist: xenial
- php: 7.0
dist: xenial
- php: 7.1
dist: bionic
- php: 7.2
dist: bionic
- php: 7.3
dist: bionic
- php: 7.4 - php: 7.4
dist: bionic dist: bionic
- php: 8.0
dist: bionic
install: install:
- composer install --prefer-dist - composer install --prefer-dist

View file

@ -31,7 +31,7 @@ class Markdown implements MarkdownInterface {
*/ */
public static function defaultTransform($text) { public static function defaultTransform($text) {
// Take parser class on which this function was called. // Take parser class on which this function was called.
$parser_class = \get_called_class(); $parser_class = static::class;
// Try to take parser from the static parser list // Try to take parser from the static parser list
static $parser_list; static $parser_list;
@ -49,39 +49,34 @@ class Markdown implements MarkdownInterface {
/** /**
* Configuration variables * Configuration variables
*/ */
/** /**
* Change to ">" for HTML output. * Change to ">" for HTML output.
* @var string
*/ */
public $empty_element_suffix = " />"; public string $empty_element_suffix = " />";
/** /**
* The width of indentation of the output markup * The width of indentation of the output markup
* @var int
*/ */
public $tab_width = 4; public int $tab_width = 4;
/** /**
* Change to `true` to disallow markup or entities. * Change to `true` to disallow markup or entities.
* @var boolean
*/ */
public $no_markup = false; public bool $no_markup = false;
public $no_entities = false; public bool $no_entities = false;
/** /**
* Change to `true` to enable line breaks on \n without two trailling spaces * Change to `true` to enable line breaks on \n without two trailling spaces
* @var boolean * @var boolean
*/ */
public $hard_wrap = false; public bool $hard_wrap = false;
/** /**
* Predefined URLs and titles for reference links and images. * Predefined URLs and titles for reference links and images.
* @var array
*/ */
public $predef_urls = array(); public array $predef_urls = array();
public $predef_titles = array(); public array $predef_titles = array();
/** /**
* Optional filter function for URLs * Optional filter function for URLs
@ -121,32 +116,27 @@ class Markdown implements MarkdownInterface {
* <li>List item two</li> * <li>List item two</li>
* <li>List item three</li> * <li>List item three</li>
* </ol> * </ol>
*
* @var bool
*/ */
public $enhanced_ordered_list = false; public bool $enhanced_ordered_list = false;
/** /**
* Parser implementation * Parser implementation
*/ */
/** /**
* Regex to match balanced [brackets]. * Regex to match balanced [brackets].
* Needed to insert a maximum bracked depth while converting to PHP. * Needed to insert a maximum bracked depth while converting to PHP.
* @var int
*/ */
protected $nested_brackets_depth = 6; protected int $nested_brackets_depth = 6;
protected $nested_brackets_re; protected $nested_brackets_re;
protected $nested_url_parenthesis_depth = 4; protected int $nested_url_parenthesis_depth = 4;
protected $nested_url_parenthesis_re; protected $nested_url_parenthesis_re;
/** /**
* Table of hash values for escaped characters: * Table of hash values for escaped characters:
* @var string
*/ */
protected $escape_chars = '\`*_{}[]()>#+-.!'; protected string $escape_chars = '\`*_{}[]()>#+-.!';
protected $escape_chars_re; protected string $escape_chars_re;
/** /**
* Constructor function. Initialize appropriate member variables. * Constructor function. Initialize appropriate member variables.
@ -175,23 +165,20 @@ class Markdown implements MarkdownInterface {
/** /**
* Internal hashes used during transformation. * Internal hashes used during transformation.
* @var array
*/ */
protected $urls = array(); protected array $urls = array();
protected $titles = array(); protected $titles = array();
protected $html_hashes = array(); protected array $html_hashes = array();
/** /**
* Status flag to avoid invalid nesting. * Status flag to avoid invalid nesting.
* @var boolean
*/ */
protected $in_anchor = false; protected bool $in_anchor = false;
/** /**
* Status flag to avoid invalid nesting. * Status flag to avoid invalid nesting.
* @var boolean
*/ */
protected $in_emphasis_processing = false; protected bool $in_emphasis_processing = false;
/** /**
* Called before the transformation process starts to setup parser states. * Called before the transformation process starts to setup parser states.
@ -263,9 +250,8 @@ class Markdown implements MarkdownInterface {
/** /**
* Define the document gamut * Define the document gamut
* @var array
*/ */
protected $document_gamut = array( protected array $document_gamut = array(
// Strip link definitions, store in hashes. // Strip link definitions, store in hashes.
"stripLinkDefinitions" => 20, "stripLinkDefinitions" => 20,
"runBasicBlockGamut" => 30, "runBasicBlockGamut" => 30,
@ -525,9 +511,8 @@ class Markdown implements MarkdownInterface {
/** /**
* Define the block gamut - these are all the transformations that form * Define the block gamut - these are all the transformations that form
* block-level tags like paragraphs, headers, and list items. * block-level tags like paragraphs, headers, and list items.
* @var array
*/ */
protected $block_gamut = array( protected array $block_gamut = array(
"doHeaders" => 10, "doHeaders" => 10,
"doHorizontalRules" => 20, "doHorizontalRules" => 20,
"doLists" => 40, "doLists" => 40,
@ -597,9 +582,8 @@ class Markdown implements MarkdownInterface {
/** /**
* These are all the transformations that occur *within* block-level * These are all the transformations that occur *within* block-level
* tags like paragraphs, headers, and list items. * tags like paragraphs, headers, and list items.
* @var array
*/ */
protected $span_gamut = array( protected array $span_gamut = array(
// Process character escapes, code spans, and inline HTML // Process character escapes, code spans, and inline HTML
// in one shot. // in one shot.
"parseSpan" => -30, "parseSpan" => -30,
@ -724,7 +708,7 @@ class Markdown implements MarkdownInterface {
/** /**
* Callback method to parse referenced anchors * Callback method to parse referenced anchors
* @param string $matches * @param array $matches
* @return string * @return string
*/ */
protected function _doAnchors_reference_callback($matches) { protected function _doAnchors_reference_callback($matches) {
@ -763,7 +747,7 @@ class Markdown implements MarkdownInterface {
/** /**
* Callback method to parse inline anchors * Callback method to parse inline anchors
* @param string $matches * @param array $matches
* @return string * @return string
*/ */
protected function _doAnchors_inline_callback($matches) { protected function _doAnchors_inline_callback($matches) {
@ -781,7 +765,7 @@ class Markdown implements MarkdownInterface {
$url = $this->encodeURLAttribute($url); $url = $this->encodeURLAttribute($url);
$result = "<a href=\"$url\""; $result = "<a href=\"$url\"";
if (isset($title)) { if ($title) {
$title = $this->encodeAttribute($title); $title = $this->encodeAttribute($title);
$result .= " title=\"$title\""; $result .= " title=\"$title\"";
} }
@ -1105,9 +1089,8 @@ class Markdown implements MarkdownInterface {
/** /**
* Nesting tracker for list levels * Nesting tracker for list levels
* @var integer
*/ */
protected $list_level = 0; protected int $list_level = 0;
/** /**
* Process the contents of a single ordered or unordered list, splitting it * Process the contents of a single ordered or unordered list, splitting it
@ -1248,7 +1231,7 @@ class Markdown implements MarkdownInterface {
* Define the emphasis operators with their regex matches * Define the emphasis operators with their regex matches
* @var array * @var array
*/ */
protected $em_relist = array( protected array $em_relist = array(
'' => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?![\.,:;]?\s)', '' => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?![\.,:;]?\s)',
'*' => '(?<![\s*])\*(?!\*)', '*' => '(?<![\s*])\*(?!\*)',
'_' => '(?<![\s_])_(?!_)', '_' => '(?<![\s_])_(?!_)',
@ -1258,7 +1241,7 @@ class Markdown implements MarkdownInterface {
* Define the strong operators with their regex matches * Define the strong operators with their regex matches
* @var array * @var array
*/ */
protected $strong_relist = array( protected array $strong_relist = array(
'' => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?![\.,:;]?\s)', '' => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?![\.,:;]?\s)',
'**' => '(?<![\s*])\*\*(?!\*)', '**' => '(?<![\s*])\*\*(?!\*)',
'__' => '(?<![\s_])__(?!_)', '__' => '(?<![\s_])__(?!_)',
@ -1268,7 +1251,7 @@ class Markdown implements MarkdownInterface {
* Define the emphasis + strong operators with their regex matches * Define the emphasis + strong operators with their regex matches
* @var array * @var array
*/ */
protected $em_strong_relist = array( protected array $em_strong_relist = array(
'' => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?![\.,:;]?\s)', '' => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?![\.,:;]?\s)',
'***' => '(?<![\s*])\*\*\*(?!\*)', '***' => '(?<![\s*])\*\*\*(?!\*)',
'___' => '(?<![\s_])___(?!_)', '___' => '(?<![\s_])___(?!_)',
@ -1276,9 +1259,8 @@ class Markdown implements MarkdownInterface {
/** /**
* Container for prepared regular expressions * Container for prepared regular expressions
* @var array
*/ */
protected $em_strong_prepared_relist; protected ?array $em_strong_prepared_relist = null;
/** /**
* Prepare regular expressions for searching emphasis tokens in any * Prepare regular expressions for searching emphasis tokens in any
@ -1826,7 +1808,7 @@ class Markdown implements MarkdownInterface {
/** /**
* String length function for detab. `_initDetab` will create a function to * String length function for detab. `_initDetab` will create a function to
* handle UTF-8 if the default function does not exist. * handle UTF-8 if the default function does not exist.
* @var string * can be a string or function
*/ */
protected $utf8_strlen = 'mb_strlen'; protected $utf8_strlen = 'mb_strlen';
@ -1883,9 +1865,7 @@ class Markdown implements MarkdownInterface {
return; return;
} }
$this->utf8_strlen = function($text) { $this->utf8_strlen = fn($text) => preg_match_all('/[\x00-\xBF]|[\xC0-\xFF][\x80-\xBF]*/', $text, $m);
return preg_match_all('/[\x00-\xBF]|[\xC0-\xFF][\x80-\xBF]*/', $text, $m);
};
} }
/** /**

View file

@ -17,25 +17,21 @@ class MarkdownExtra extends \Michelf\Markdown {
/** /**
* Configuration variables * Configuration variables
*/ */
/** /**
* Prefix for footnote ids. * Prefix for footnote ids.
* @var string
*/ */
public $fn_id_prefix = ""; public string $fn_id_prefix = "";
/** /**
* Optional title attribute for footnote links. * Optional title attribute for footnote links.
* @var string
*/ */
public $fn_link_title = ""; public string $fn_link_title = "";
/** /**
* Optional class attribute for footnote links and backlinks. * Optional class attribute for footnote links and backlinks.
* @var string
*/ */
public $fn_link_class = "footnote-ref"; public string $fn_link_class = "footnote-ref";
public $fn_backlink_class = "footnote-backref"; public string $fn_backlink_class = "footnote-backref";
/** /**
* Content to be displayed within footnote backlinks. The default is '↩'; * Content to be displayed within footnote backlinks. The default is '↩';
@ -43,59 +39,51 @@ class MarkdownExtra extends \Michelf\Markdown {
* from displaying the arrow character as an emoji. * from displaying the arrow character as an emoji.
* Optionally use '^^' and '%%' to refer to the footnote number and * Optionally use '^^' and '%%' to refer to the footnote number and
* reference number respectively. {@see parseFootnotePlaceholders()} * reference number respectively. {@see parseFootnotePlaceholders()}
* @var string
*/ */
public $fn_backlink_html = '&#8617;&#xFE0E;'; public string $fn_backlink_html = '&#8617;&#xFE0E;';
/** /**
* Optional title and aria-label attributes for footnote backlinks for * Optional title and aria-label attributes for footnote backlinks for
* added accessibility (to ensure backlink uniqueness). * added accessibility (to ensure backlink uniqueness).
* Use '^^' and '%%' to refer to the footnote number and reference number * Use '^^' and '%%' to refer to the footnote number and reference number
* respectively. {@see parseFootnotePlaceholders()} * respectively. {@see parseFootnotePlaceholders()}
* @var string
*/ */
public $fn_backlink_title = ""; public string $fn_backlink_title = "";
public $fn_backlink_label = ""; public string $fn_backlink_label = "";
/** /**
* Class name for table cell alignment (%% replaced left/center/right) * Class name for table cell alignment (%% replaced left/center/right)
* For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center' * For instance: 'go-%%' becomes 'go-left' or 'go-right' or 'go-center'
* If empty, the align attribute is used instead of a class name. * If empty, the align attribute is used instead of a class name.
* @var string
*/ */
public $table_align_class_tmpl = ''; public string $table_align_class_tmpl = '';
/** /**
* Optional class prefix for fenced code block. * Optional class prefix for fenced code block.
* @var string
*/ */
public $code_class_prefix = ""; public string $code_class_prefix = "";
/** /**
* Class attribute for code blocks goes on the `code` tag; * Class attribute for code blocks goes on the `code` tag;
* setting this to true will put attributes on the `pre` tag instead. * setting this to true will put attributes on the `pre` tag instead.
* @var boolean
*/ */
public $code_attr_on_pre = false; public bool $code_attr_on_pre = false;
/** /**
* Predefined abbreviations. * Predefined abbreviations.
* @var array
*/ */
public $predef_abbr = array(); public array $predef_abbr = array();
/** /**
* Only convert atx-style headers if there's a space between the header and # * Only convert atx-style headers if there's a space between the header and #
* @var boolean
*/ */
public $hashtag_protection = false; public bool $hashtag_protection = false;
/** /**
* Determines whether footnotes should be appended to the end of the document. * Determines whether footnotes should be appended to the end of the document.
* If true, footnote html can be retrieved from $this->footnotes_assembled. * If true, footnote html can be retrieved from $this->footnotes_assembled.
* @var boolean
*/ */
public $omit_footnotes = false; public bool $omit_footnotes = false;
/** /**
@ -107,9 +95,8 @@ class MarkdownExtra extends \Michelf\Markdown {
* `section` that will enclose the list of footnotes so they are * `section` that will enclose the list of footnotes so they are
* reachable to accessibility tools the same way they would be with the * reachable to accessibility tools the same way they would be with the
* default HTML output. * default HTML output.
* @var null|string
*/ */
public $footnotes_assembled = null; public ?string $footnotes_assembled = null;
/** /**
* Parser implementation * Parser implementation
@ -149,27 +136,23 @@ class MarkdownExtra extends \Michelf\Markdown {
/** /**
* Extra variables used during extra transformations. * Extra variables used during extra transformations.
* @var array
*/ */
protected $footnotes = array(); protected array $footnotes = array();
protected $footnotes_ordered = array(); protected array $footnotes_ordered = array();
protected $footnotes_ref_count = array(); protected array $footnotes_ref_count = array();
protected $footnotes_numbers = array(); protected array $footnotes_numbers = array();
protected $abbr_desciptions = array(); protected array $abbr_desciptions = array();
/** @var string */ protected string $abbr_word_re = '';
protected $abbr_word_re = '';
/** /**
* Give the current footnote number. * Give the current footnote number.
* @var integer
*/ */
protected $footnote_counter = 1; protected int $footnote_counter = 1;
/** /**
* Ref attribute for links * Ref attribute for links
* @var array */
*/ protected array $ref_attr = array();
protected $ref_attr = array();
/** /**
* Setting up Extra-specific variables. * Setting up Extra-specific variables.
@ -215,18 +198,15 @@ class MarkdownExtra extends \Michelf\Markdown {
/** /**
* Extra attribute parser * Extra attribute parser
*/ */
/** /**
* Expression to use to catch attributes (includes the braces) * Expression to use to catch attributes (includes the braces)
* @var string
*/ */
protected $id_class_attr_catch_re = '\{((?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}'; protected string $id_class_attr_catch_re = '\{((?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,})[ ]*\}';
/** /**
* Expression to use when parsing in a context when no capture is desired * Expression to use when parsing in a context when no capture is desired
* @var string
*/ */
protected $id_class_attr_nocatch_re = '\{(?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}'; protected string $id_class_attr_nocatch_re = '\{(?>[ ]*[#.a-z][-_:a-zA-Z0-9=]+){1,}[ ]*\}';
/** /**
* Parse attributes caught by the $this->id_class_attr_catch_re expression * Parse attributes caught by the $this->id_class_attr_catch_re expression
@ -340,37 +320,31 @@ class MarkdownExtra extends \Michelf\Markdown {
/** /**
* HTML block parser * HTML block parser
*/ */
/** /**
* Tags that are always treated as block tags * Tags that are always treated as block tags
* @var string
*/ */
protected $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure|details|summary'; protected string $block_tags_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend|article|section|nav|aside|hgroup|header|footer|figcaption|figure|details|summary';
/** /**
* Tags treated as block tags only if the opening tag is alone on its line * Tags treated as block tags only if the opening tag is alone on its line
* @var string
*/ */
protected $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video'; protected string $context_block_tags_re = 'script|noscript|style|ins|del|iframe|object|source|track|param|math|svg|canvas|audio|video';
/** /**
* Tags where markdown="1" default to span mode: * Tags where markdown="1" default to span mode:
* @var string
*/ */
protected $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address'; protected string $contain_span_tags_re = 'p|h[1-6]|li|dd|dt|td|th|legend|address';
/** /**
* Tags which must not have their contents modified, no matter where * Tags which must not have their contents modified, no matter where
* they appear * they appear
* @var string
*/ */
protected $clean_tags_re = 'script|style|math|svg'; protected string $clean_tags_re = 'script|style|math|svg';
/** /**
* Tags that do not need to be closed. * Tags that do not need to be closed.
* @var string
*/ */
protected $auto_close_tags_re = 'hr|img|param|source|track'; protected string $auto_close_tags_re = 'hr|img|param|source|track';
/** /**
* Hashify HTML Blocks and "clean tags". * Hashify HTML Blocks and "clean tags".
@ -627,6 +601,7 @@ class MarkdownExtra extends \Michelf\Markdown {
else { else {
$parsed .= $tag; $parsed .= $tag;
} }
// @phpstan-ignore-next-line
} while ($depth >= 0); } while ($depth >= 0);
return array($parsed, $text); return array($parsed, $text);
@ -708,7 +683,7 @@ class MarkdownExtra extends \Michelf\Markdown {
// by the pattern. // by the pattern.
$parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE); $parts = preg_split($tag_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
if (count($parts) < 3) { if ($parts === false || count($parts) < 3) {
// End of $text reached with unbalenced tag(s). // End of $text reached with unbalenced tag(s).
// In that case, we return original text unchanged and pass the // In that case, we return original text unchanged and pass the
// first character as filtered to prevent an infinite loop in the // first character as filtered to prevent an infinite loop in the
@ -1248,6 +1223,7 @@ class MarkdownExtra extends \Michelf\Markdown {
$head = $matches[1]; $head = $matches[1];
$underline = $matches[2]; $underline = $matches[2];
$content = $matches[3]; $content = $matches[3];
$attr = [];
// Remove any tailing pipes for each line. // Remove any tailing pipes for each line.
$head = preg_replace('/[|] *$/m', '', $head); $head = preg_replace('/[|] *$/m', '', $head);
@ -1549,17 +1525,17 @@ class MarkdownExtra extends \Michelf\Markdown {
* work in the middle of a word. * work in the middle of a word.
* @var array * @var array
*/ */
protected $em_relist = array( protected array $em_relist = array(
'' => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?![\.,:;]?\s)', '' => '(?:(?<!\*)\*(?!\*)|(?<![a-zA-Z0-9_])_(?!_))(?![\.,:;]?\s)',
'*' => '(?<![\s*])\*(?!\*)', '*' => '(?<![\s*])\*(?!\*)',
'_' => '(?<![\s_])_(?![a-zA-Z0-9_])', '_' => '(?<![\s_])_(?![a-zA-Z0-9_])',
); );
protected $strong_relist = array( protected array $strong_relist = array(
'' => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?![\.,:;]?\s)', '' => '(?:(?<!\*)\*\*(?!\*)|(?<![a-zA-Z0-9_])__(?!_))(?![\.,:;]?\s)',
'**' => '(?<![\s*])\*\*(?!\*)', '**' => '(?<![\s*])\*\*(?!\*)',
'__' => '(?<![\s_])__(?![a-zA-Z0-9_])', '__' => '(?<![\s_])__(?![a-zA-Z0-9_])',
); );
protected $em_strong_relist = array( protected array $em_strong_relist = array(
'' => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?![\.,:;]?\s)', '' => '(?:(?<!\*)\*\*\*(?!\*)|(?<![a-zA-Z0-9_])___(?!_))(?![\.,:;]?\s)',
'***' => '(?<![\s*])\*\*\*(?!\*)', '***' => '(?<![\s*])\*\*\*(?!\*)',
'___' => '(?<![\s_])___(?![a-zA-Z0-9_])', '___' => '(?<![\s_])___(?![a-zA-Z0-9_])',

View file

@ -1,7 +1,7 @@
PHP Markdown PHP Markdown
============ ============
PHP Markdown Lib 1.9.1 - 23 Nov 2021 ![ci.yml](https://github.com/michelf/php-markdown/actions/workflows/ci.yml/badge.svg)
by Michel Fortin by Michel Fortin
<https://michelf.ca/> <https://michelf.ca/>
@ -34,15 +34,14 @@ program by John Gruber.
Requirement Requirement
----------- -----------
This library package requires PHP 5.3 or later. This library package requires PHP 7.4 or later.
Note: The older plugin/library hybrid package for PHP Markdown and Note: The older plugin/library hybrid package for PHP Markdown and
PHP Markdown Extra is no longer maintained but will work with PHP 4.0.5 and PHP Markdown Extra is no longer maintained but will work with PHP 4.0.5 and
later. later.
Before PHP 5.3.7, pcre.backtrack_limit defaults to 100 000, which is too small You might need to set pcre.backtrack_limit higher than 1 000 000
in many situations. You might need to set it to higher values. Later PHP (the default), though the default is usually fine.
releases defaults to 1 000 000, which is usually fine.
Usage Usage

View file

@ -18,12 +18,37 @@
} }
], ],
"require": { "require": {
"php": ">=5.3.0" "php": ">=7.4"
}, },
"autoload": { "autoload": {
"psr-4": { "Michelf\\": "Michelf/" } "psr-4": { "Michelf\\": "Michelf/" }
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": ">=4.3 <5.8" "friendsofphp/php-cs-fixer": "^3.0",
"phpunit/phpunit": "^9.5",
"phpstan/phpstan": ">=1.0",
"phpstan/phpstan-phpunit": ">=1.0"
},
"scripts": {
"tests": "vendor/bin/phpunit test/",
"phpstan": [
"vendor/bin/phpstan analyse Michelf/ --level=5",
"vendor/bin/phpstan analyse -c test/phpstan.neon test/ --level=5"
],
"codestyle": "vendor/bin/php-cs-fixer fix Michelf --dry-run --verbose --show-progress=none",
"codestyle-fix": "vendor/bin/php-cs-fixer fix Michelf"
},
"archive": {
"exclude": [
"/.github/",
"/test/",
"/.editorconfig",
"/.gitignore",
"/.scrutinizer.yml",
"/.travis.yml",
"/phpunit.xml.dist"
]
} }
} }

View file

@ -22,7 +22,6 @@ class MarkdownTestHelper
$dataValues = array(); $dataValues = array();
/** @var SplFileInfo $inputFile */
foreach ($regexIterator as $inputFiles) { foreach ($regexIterator as $inputFiles) {
foreach ($inputFiles as $inputMarkdownPath) { foreach ($inputFiles as $inputMarkdownPath) {
$xhtml = true; $xhtml = true;
@ -163,6 +162,7 @@ class MarkdownTestHelper
foreach ($node_list as $node) { foreach ($node_list as $node) {
switch ($node->nodeType) { switch ($node->nodeType) {
case XML_ELEMENT_NODE: case XML_ELEMENT_NODE:
/** @var DOMElement $node */
static::normalizeElementContent($node, $whitespace_preserve); static::normalizeElementContent($node, $whitespace_preserve);
static::normalizeElementAttributes($node); static::normalizeElementAttributes($node);
@ -207,6 +207,7 @@ class MarkdownTestHelper
break; break;
case XML_TEXT_NODE: case XML_TEXT_NODE:
/** @var DOMText $node */
if (!$whitespace_preserve) { if (!$whitespace_preserve) {
if (trim($node->data) === "") { if (trim($node->data) === "") {
$node->data = $whitespace; $node->data = $whitespace;
@ -222,8 +223,8 @@ class MarkdownTestHelper
($whitespace === "\n\n" || $whitespace === "\n")) { ($whitespace === "\n\n" || $whitespace === "\n")) {
if ($element->firstChild) { if ($element->firstChild) {
if ($element->firstChild->nodeType == XML_TEXT_NODE) { if ($element->firstChild->nodeType == XML_TEXT_NODE) {
$element->firstChild->data = $element->firstChild->data = // @phpstan-ignore-line
preg_replace('{^\s+}', "\n", $element->firstChild->data); preg_replace('{^\s+}', "\n", $element->firstChild->data ?? '');
} }
else { else {
$element->insertBefore(new DOMText("\n"), $element->firstChild); $element->insertBefore(new DOMText("\n"), $element->firstChild);
@ -231,8 +232,8 @@ class MarkdownTestHelper
} }
if ($element->lastChild) { if ($element->lastChild) {
if ($element->lastChild->nodeType == XML_TEXT_NODE) { if ($element->lastChild->nodeType == XML_TEXT_NODE) {
$element->lastChild->data = $element->lastChild->data = // @phpstan-ignore-line
preg_replace('{\s+$}', "\n", $element->lastChild->data); preg_replace('{\s+$}', "\n", $element->lastChild->data ?? '');
} }
else { else {
$element->insertBefore(new DOMText("\n"), null); $element->insertBefore(new DOMText("\n"), null);

2
test/phpstan.neon Normal file
View file

@ -0,0 +1,2 @@
includes:
- ../vendor/phpstan/phpstan-phpunit/extension.neon