Upgrade serendipity_event_markdown for PHP 8.0/8.1 compatibility (#141)
Upgrade bundled markdown lib `michelf/php-markdown` to version 1.9.1 that enables PHP 8 compatibility. Also dump support for EOL PHP versions in serendipity_event_markdown, because the new version of the bundled markdown lib raises the required PHP version to PHP >=7.4.
This commit is contained in:
parent
9dc7a400d2
commit
76f75e5351
|
@ -1,3 +1,10 @@
|
||||||
|
Version 1.31:
|
||||||
|
=============
|
||||||
|
Changes by spackmat
|
||||||
|
|
||||||
|
- Upgrade PHP Markdown Lib to 1.9.1 (was 1.8.0) to enable compatibility with PHP 8.0 and 8.1.
|
||||||
|
- Raise required PHP version to >=7.4 to reflect the changes in PHP Markdown Lib to 1.9
|
||||||
|
|
||||||
Version 1.30.1:
|
Version 1.30.1:
|
||||||
=============
|
=============
|
||||||
Changes by surrim
|
Changes by surrim
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
PHP Markdown Lib
|
PHP Markdown Lib
|
||||||
Copyright (c) 2004-2018 Michel Fortin
|
Copyright (c) 2004-2021 Michel Fortin
|
||||||
<https://michelf.ca/>
|
<https://michelf.ca/>
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* @package php-markdown
|
* @package php-markdown
|
||||||
* @author Michel Fortin <michel.fortin@michelf.com>
|
* @author Michel Fortin <michel.fortin@michelf.com>
|
||||||
* @copyright 2004-2018 Michel Fortin <https://michelf.com/projects/php-markdown/>
|
* @copyright 2004-2019 Michel Fortin <https://michelf.com/projects/php-markdown/>
|
||||||
* @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
|
* @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class Markdown implements MarkdownInterface {
|
||||||
* Define the package version
|
* Define the package version
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
const MARKDOWNLIB_VERSION = "1.8.0";
|
const MARKDOWNLIB_VERSION = "2.0";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple function interface - Initialize the parser and return the result
|
* Simple function interface - Initialize the parser and return the result
|
||||||
|
@ -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,61 +49,56 @@ 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
|
||||||
* @var callable
|
* @var callable|null
|
||||||
*/
|
*/
|
||||||
public $url_filter_func = null;
|
public $url_filter_func = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional header id="" generation callback function.
|
* Optional header id="" generation callback function.
|
||||||
* @var callable
|
* @var callable|null
|
||||||
*/
|
*/
|
||||||
public $header_id_func = null;
|
public $header_id_func = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional function for converting code block content to HTML
|
* Optional function for converting code block content to HTML
|
||||||
* @var callable
|
* @var callable|null
|
||||||
*/
|
*/
|
||||||
public $code_block_content_func = null;
|
public $code_block_content_func = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional function for converting code span content to HTML.
|
* Optional function for converting code span content to HTML.
|
||||||
* @var callable
|
* @var callable|null
|
||||||
*/
|
*/
|
||||||
public $code_span_content_func = null;
|
public $code_span_content_func = null;
|
||||||
|
|
||||||
|
@ -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,26 +747,25 @@ 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) {
|
||||||
$whole_match = $matches[1];
|
|
||||||
$link_text = $this->runSpanGamut($matches[2]);
|
$link_text = $this->runSpanGamut($matches[2]);
|
||||||
$url = $matches[3] == '' ? $matches[4] : $matches[3];
|
$url = $matches[3] === '' ? $matches[4] : $matches[3];
|
||||||
$title =& $matches[7];
|
$title =& $matches[7];
|
||||||
|
|
||||||
// If the URL was of the form <s p a c e s> it got caught by the HTML
|
// If the URL was of the form <s p a c e s> it got caught by the HTML
|
||||||
// tag parser and hashed. Need to reverse the process before using
|
// tag parser and hashed. Need to reverse the process before using
|
||||||
// the URL.
|
// the URL.
|
||||||
$unhashed = $this->unhash($url);
|
$unhashed = $this->unhash($url);
|
||||||
if ($unhashed != $url)
|
if ($unhashed !== $url)
|
||||||
$url = preg_replace('/^<(.*)>$/', '\1', $unhashed);
|
$url = preg_replace('/^<(.*)>$/', '\1', $unhashed);
|
||||||
|
|
||||||
$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\"";
|
||||||
}
|
}
|
||||||
|
@ -952,7 +935,7 @@ class Markdown implements MarkdownInterface {
|
||||||
return $matches[0];
|
return $matches[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$level = $matches[2]{0} == '=' ? 1 : 2;
|
$level = $matches[2][0] == '=' ? 1 : 2;
|
||||||
|
|
||||||
// ID attribute generation
|
// ID attribute generation
|
||||||
$idAtt = $this->_generateIdFromHeaderValue($matches[1]);
|
$idAtt = $this->_generateIdFromHeaderValue($matches[1]);
|
||||||
|
@ -1106,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
|
||||||
|
@ -1218,7 +1200,7 @@ class Markdown implements MarkdownInterface {
|
||||||
$codeblock = $matches[1];
|
$codeblock = $matches[1];
|
||||||
|
|
||||||
$codeblock = $this->outdent($codeblock);
|
$codeblock = $this->outdent($codeblock);
|
||||||
if ($this->code_block_content_func) {
|
if (is_callable($this->code_block_content_func)) {
|
||||||
$codeblock = call_user_func($this->code_block_content_func, $codeblock, "");
|
$codeblock = call_user_func($this->code_block_content_func, $codeblock, "");
|
||||||
} else {
|
} else {
|
||||||
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
|
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
|
||||||
|
@ -1237,7 +1219,7 @@ class Markdown implements MarkdownInterface {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function makeCodeSpan($code) {
|
protected function makeCodeSpan($code) {
|
||||||
if ($this->code_span_content_func) {
|
if (is_callable($this->code_span_content_func)) {
|
||||||
$code = call_user_func($this->code_span_content_func, $code);
|
$code = call_user_func($this->code_span_content_func, $code);
|
||||||
} else {
|
} else {
|
||||||
$code = htmlspecialchars(trim($code), ENT_NOQUOTES);
|
$code = htmlspecialchars(trim($code), ENT_NOQUOTES);
|
||||||
|
@ -1249,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_])_(?!_)',
|
||||||
|
@ -1259,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_])__(?!_)',
|
||||||
|
@ -1269,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_])___(?!_)',
|
||||||
|
@ -1277,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
|
||||||
|
@ -1358,7 +1339,7 @@ class Markdown implements MarkdownInterface {
|
||||||
} else {
|
} else {
|
||||||
// Other closing marker: close one em or strong and
|
// Other closing marker: close one em or strong and
|
||||||
// change current token state to match the other
|
// change current token state to match the other
|
||||||
$token_stack[0] = str_repeat($token{0}, 3-$token_len);
|
$token_stack[0] = str_repeat($token[0], 3-$token_len);
|
||||||
$tag = $token_len == 2 ? "strong" : "em";
|
$tag = $token_len == 2 ? "strong" : "em";
|
||||||
$span = $text_stack[0];
|
$span = $text_stack[0];
|
||||||
$span = $this->runSpanGamut($span);
|
$span = $this->runSpanGamut($span);
|
||||||
|
@ -1383,7 +1364,7 @@ class Markdown implements MarkdownInterface {
|
||||||
} else {
|
} else {
|
||||||
// Reached opening three-char emphasis marker. Push on token
|
// Reached opening three-char emphasis marker. Push on token
|
||||||
// stack; will be handled by the special condition above.
|
// stack; will be handled by the special condition above.
|
||||||
$em = $token{0};
|
$em = $token[0];
|
||||||
$strong = "$em$em";
|
$strong = "$em$em";
|
||||||
array_unshift($token_stack, $token);
|
array_unshift($token_stack, $token);
|
||||||
array_unshift($text_stack, '');
|
array_unshift($text_stack, '');
|
||||||
|
@ -1576,11 +1557,11 @@ class Markdown implements MarkdownInterface {
|
||||||
* This function is *not* suitable for attributes enclosed in single quotes.
|
* This function is *not* suitable for attributes enclosed in single quotes.
|
||||||
*
|
*
|
||||||
* @param string $url
|
* @param string $url
|
||||||
* @param string &$text Passed by reference
|
* @param string $text Passed by reference
|
||||||
* @return string URL
|
* @return string URL
|
||||||
*/
|
*/
|
||||||
protected function encodeURLAttribute($url, &$text = null) {
|
protected function encodeURLAttribute($url, &$text = null) {
|
||||||
if ($this->url_filter_func) {
|
if (is_callable($this->url_filter_func)) {
|
||||||
$url = call_user_func($this->url_filter_func, $url);
|
$url = call_user_func($this->url_filter_func, $url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1694,7 +1675,7 @@ class Markdown implements MarkdownInterface {
|
||||||
* attribute special characters by Allan Odgaard.
|
* attribute special characters by Allan Odgaard.
|
||||||
*
|
*
|
||||||
* @param string $text
|
* @param string $text
|
||||||
* @param string &$tail
|
* @param string $tail Passed by reference
|
||||||
* @param integer $head_length
|
* @param integer $head_length
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
@ -1792,13 +1773,13 @@ class Markdown implements MarkdownInterface {
|
||||||
* Handle $token provided by parseSpan by determining its nature and
|
* Handle $token provided by parseSpan by determining its nature and
|
||||||
* returning the corresponding value that should replace it.
|
* returning the corresponding value that should replace it.
|
||||||
* @param string $token
|
* @param string $token
|
||||||
* @param string &$str
|
* @param string $str Passed by reference
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function handleSpanToken($token, &$str) {
|
protected function handleSpanToken($token, &$str) {
|
||||||
switch ($token{0}) {
|
switch ($token[0]) {
|
||||||
case "\\":
|
case "\\":
|
||||||
return $this->hashPart("&#". ord($token{1}). ";");
|
return $this->hashPart("&#". ord($token[1]). ";");
|
||||||
case "`":
|
case "`":
|
||||||
// Search for end marker in remaining text.
|
// Search for end marker in remaining text.
|
||||||
if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
|
if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
|
||||||
|
@ -1827,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';
|
||||||
|
|
||||||
|
@ -1884,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);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* @package php-markdown
|
* @package php-markdown
|
||||||
* @author Michel Fortin <michel.fortin@michelf.com>
|
* @author Michel Fortin <michel.fortin@michelf.com>
|
||||||
* @copyright 2004-2018 Michel Fortin <https://michelf.com/projects/php-markdown/>
|
* @copyright 2004-2019 Michel Fortin <https://michelf.com/projects/php-markdown/>
|
||||||
* @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
|
* @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -17,67 +17,86 @@ 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 and backlinks.
|
* Optional title attribute for footnote links.
|
||||||
* @var string
|
|
||||||
*/
|
*/
|
||||||
public $fn_link_title = "";
|
public string $fn_link_title = "";
|
||||||
public $fn_backlink_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 '↩';
|
||||||
* the U+FE0E on the end is a Unicode variant selector used to prevent iOS
|
* the U+FE0E on the end is a Unicode variant selector used to prevent iOS
|
||||||
* from displaying the arrow character as an emoji.
|
* from displaying the arrow character as an emoji.
|
||||||
* @var string
|
* Optionally use '^^' and '%%' to refer to the footnote number and
|
||||||
|
* reference number respectively. {@see parseFootnotePlaceholders()}
|
||||||
*/
|
*/
|
||||||
public $fn_backlink_html = '↩︎';
|
public string $fn_backlink_html = '↩︎';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional title and aria-label attributes for footnote backlinks for
|
||||||
|
* added accessibility (to ensure backlink uniqueness).
|
||||||
|
* Use '^^' and '%%' to refer to the footnote number and reference number
|
||||||
|
* respectively. {@see parseFootnotePlaceholders()}
|
||||||
|
*/
|
||||||
|
public string $fn_backlink_title = "";
|
||||||
|
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.
|
||||||
|
* If true, footnote html can be retrieved from $this->footnotes_assembled.
|
||||||
|
*/
|
||||||
|
public bool $omit_footnotes = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After parsing, the HTML for the list of footnotes appears here.
|
||||||
|
* This is available only if $omit_footnotes == true.
|
||||||
|
*
|
||||||
|
* Note: when placing the content of `footnotes_assembled` on the page,
|
||||||
|
* consider adding the attribute `role="doc-endnotes"` to the `div` or
|
||||||
|
* `section` that will enclose the list of footnotes so they are
|
||||||
|
* reachable to accessibility tools the same way they would be with the
|
||||||
|
* default HTML output.
|
||||||
|
*/
|
||||||
|
public ?string $footnotes_assembled = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parser implementation
|
* Parser implementation
|
||||||
|
@ -117,21 +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
|
||||||
|
*/
|
||||||
|
protected array $ref_attr = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setting up Extra-specific variables.
|
* Setting up Extra-specific variables.
|
||||||
|
@ -146,6 +167,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$this->abbr_desciptions = array();
|
$this->abbr_desciptions = array();
|
||||||
$this->abbr_word_re = '';
|
$this->abbr_word_re = '';
|
||||||
$this->footnote_counter = 1;
|
$this->footnote_counter = 1;
|
||||||
|
$this->footnotes_assembled = null;
|
||||||
|
|
||||||
foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
|
foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
|
||||||
if ($this->abbr_word_re)
|
if ($this->abbr_word_re)
|
||||||
|
@ -166,6 +188,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$this->abbr_desciptions = array();
|
$this->abbr_desciptions = array();
|
||||||
$this->abbr_word_re = '';
|
$this->abbr_word_re = '';
|
||||||
|
|
||||||
|
if ( ! $this->omit_footnotes )
|
||||||
|
$this->footnotes_assembled = null;
|
||||||
|
|
||||||
parent::teardown();
|
parent::teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,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
|
||||||
|
@ -202,7 +224,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null, $classes = array()) {
|
protected function doExtraAttributes($tag_name, $attr, $defaultIdValue = null, $classes = array()) {
|
||||||
if (empty($attr) && !$defaultIdValue && empty($classes)) return "";
|
if (empty($attr) && !$defaultIdValue && empty($classes)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
// Split on components
|
// Split on components
|
||||||
preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches);
|
preg_match_all('/[#.a-z][-_:a-zA-Z0-9=]+/', $attr, $matches);
|
||||||
|
@ -212,9 +236,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$attributes = array();
|
$attributes = array();
|
||||||
$id = false;
|
$id = false;
|
||||||
foreach ($elements as $element) {
|
foreach ($elements as $element) {
|
||||||
if ($element{0} == '.') {
|
if ($element[0] === '.') {
|
||||||
$classes[] = substr($element, 1);
|
$classes[] = substr($element, 1);
|
||||||
} else if ($element{0} == '#') {
|
} else if ($element[0] === '#') {
|
||||||
if ($id === false) $id = substr($element, 1);
|
if ($id === false) $id = substr($element, 1);
|
||||||
} else if (strpos($element, '=') > 0) {
|
} else if (strpos($element, '=') > 0) {
|
||||||
$parts = explode('=', $element, 2);
|
$parts = explode('=', $element, 2);
|
||||||
|
@ -222,7 +246,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$id) $id = $defaultIdValue;
|
if ($id === false || $id === '') {
|
||||||
|
$id = $defaultIdValue;
|
||||||
|
}
|
||||||
|
|
||||||
// Compose attributes as string
|
// Compose attributes as string
|
||||||
$attr_str = "";
|
$attr_str = "";
|
||||||
|
@ -294,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".
|
||||||
|
@ -486,7 +506,6 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
|
|
||||||
$tag = $parts[1]; // Tag to handle.
|
$tag = $parts[1]; // Tag to handle.
|
||||||
$text = $parts[2]; // Remaining text after current tag.
|
$text = $parts[2]; // Remaining text after current tag.
|
||||||
$tag_re = preg_quote($tag); // For use in a regular expression.
|
|
||||||
|
|
||||||
// Check for: Fenced code block marker.
|
// Check for: Fenced code block marker.
|
||||||
// Note: need to recheck the whole tag to disambiguate backtick
|
// Note: need to recheck the whole tag to disambiguate backtick
|
||||||
|
@ -508,14 +527,14 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check for: Indented code block.
|
// Check for: Indented code block.
|
||||||
else if ($tag{0} == "\n" || $tag{0} == " ") {
|
else if ($tag[0] === "\n" || $tag[0] === " ") {
|
||||||
// Indented code block: pass it unchanged, will be handled
|
// Indented code block: pass it unchanged, will be handled
|
||||||
// later.
|
// later.
|
||||||
$parsed .= $tag;
|
$parsed .= $tag;
|
||||||
}
|
}
|
||||||
// Check for: Code span marker
|
// Check for: Code span marker
|
||||||
// Note: need to check this after backtick fenced code blocks
|
// Note: need to check this after backtick fenced code blocks
|
||||||
else if ($tag{0} == "`") {
|
else if ($tag[0] === "`") {
|
||||||
// Find corresponding end marker.
|
// Find corresponding end marker.
|
||||||
$tag_re = preg_quote($tag);
|
$tag_re = preg_quote($tag);
|
||||||
if (preg_match('{^(?>.+?|\n(?!\n))*?(?<!`)' . $tag_re . '(?!`)}',
|
if (preg_match('{^(?>.+?|\n(?!\n))*?(?<!`)' . $tag_re . '(?!`)}',
|
||||||
|
@ -549,7 +568,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
// Check for: Clean tag (like script, math)
|
// Check for: Clean tag (like script, math)
|
||||||
// HTML Comments, processing instructions.
|
// HTML Comments, processing instructions.
|
||||||
else if (preg_match('{^<(?:' . $this->clean_tags_re . ')\b}', $tag) ||
|
else if (preg_match('{^<(?:' . $this->clean_tags_re . ')\b}', $tag) ||
|
||||||
$tag{1} == '!' || $tag{1} == '?')
|
$tag[1] === '!' || $tag[1] === '?')
|
||||||
{
|
{
|
||||||
// Need to parse tag and following text using the HTML parser.
|
// Need to parse tag and following text using the HTML parser.
|
||||||
// (don't check for markdown attribute)
|
// (don't check for markdown attribute)
|
||||||
|
@ -564,8 +583,11 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
preg_match('{^</?(?:' . $enclosing_tag_re . ')\b}', $tag))
|
preg_match('{^</?(?:' . $enclosing_tag_re . ')\b}', $tag))
|
||||||
{
|
{
|
||||||
// Increase/decrease nested tag count.
|
// Increase/decrease nested tag count.
|
||||||
if ($tag{1} == '/') $depth--;
|
if ($tag[1] === '/') {
|
||||||
else if ($tag{strlen($tag)-2} != '/') $depth++;
|
$depth--;
|
||||||
|
} else if ($tag[strlen($tag)-2] !== '/') {
|
||||||
|
$depth++;
|
||||||
|
}
|
||||||
|
|
||||||
if ($depth < 0) {
|
if ($depth < 0) {
|
||||||
// Going out of parent element. Clean up and break so we
|
// Going out of parent element. Clean up and break so we
|
||||||
|
@ -595,7 +617,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
* Returns an array of that form: ( processed text , remaining text )
|
* Returns an array of that form: ( processed text , remaining text )
|
||||||
* @param string $text
|
* @param string $text
|
||||||
* @param string $hash_method
|
* @param string $hash_method
|
||||||
* @param string $md_attr
|
* @param bool $md_attr Handle `markdown="1"` attribute
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
|
protected function _hashHTMLBlocks_inHTML($text, $hash_method, $md_attr) {
|
||||||
|
@ -645,6 +667,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$depth = 0; // Current depth inside the tag tree.
|
$depth = 0; // Current depth inside the tag tree.
|
||||||
$block_text = ""; // Temporary text holder for current text.
|
$block_text = ""; // Temporary text holder for current text.
|
||||||
$parsed = ""; // Parsed text that will be returned.
|
$parsed = ""; // Parsed text that will be returned.
|
||||||
|
$base_tag_name_re = '';
|
||||||
|
|
||||||
// Get the name of the starting tag.
|
// Get the name of the starting tag.
|
||||||
// (This pattern makes $base_tag_name_re safe without quoting.)
|
// (This pattern makes $base_tag_name_re safe without quoting.)
|
||||||
|
@ -664,7 +687,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
// 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
|
||||||
// parent function.
|
// parent function.
|
||||||
return array($original_text{0}, substr($original_text, 1));
|
return array($original_text[0], substr($original_text, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
$block_text .= $parts[0]; // Text before current tag.
|
$block_text .= $parts[0]; // Text before current tag.
|
||||||
|
@ -674,7 +697,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
// Check for: Auto-close tag (like <hr/>)
|
// Check for: Auto-close tag (like <hr/>)
|
||||||
// Comments and Processing Instructions.
|
// Comments and Processing Instructions.
|
||||||
if (preg_match('{^</?(?:' . $this->auto_close_tags_re . ')\b}', $tag) ||
|
if (preg_match('{^</?(?:' . $this->auto_close_tags_re . ')\b}', $tag) ||
|
||||||
$tag{1} == '!' || $tag{1} == '?')
|
$tag[1] === '!' || $tag[1] === '?')
|
||||||
{
|
{
|
||||||
// Just add the tag to the block as if it was text.
|
// Just add the tag to the block as if it was text.
|
||||||
$block_text .= $tag;
|
$block_text .= $tag;
|
||||||
|
@ -683,8 +706,11 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
// Increase/decrease nested tag count. Only do so if
|
// Increase/decrease nested tag count. Only do so if
|
||||||
// the tag's name match base tag's.
|
// the tag's name match base tag's.
|
||||||
if (preg_match('{^</?' . $base_tag_name_re . '\b}', $tag)) {
|
if (preg_match('{^</?' . $base_tag_name_re . '\b}', $tag)) {
|
||||||
if ($tag{1} == '/') $depth--;
|
if ($tag[1] === '/') {
|
||||||
else if ($tag{strlen($tag)-2} != '/') $depth++;
|
$depth--;
|
||||||
|
} else if ($tag[strlen($tag)-2] !== '/') {
|
||||||
|
$depth++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for `markdown="1"` attribute and handle it.
|
// Check for `markdown="1"` attribute and handle it.
|
||||||
|
@ -696,9 +722,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$tag = preg_replace($markdown_attr_re, '', $tag);
|
$tag = preg_replace($markdown_attr_re, '', $tag);
|
||||||
|
|
||||||
// Check if text inside this tag must be parsed in span mode.
|
// Check if text inside this tag must be parsed in span mode.
|
||||||
$this->mode = $attr_m[2] . $attr_m[3];
|
$mode = $attr_m[2] . $attr_m[3];
|
||||||
$span_mode = $this->mode == 'span' || $this->mode != 'block' &&
|
$span_mode = $mode === 'span' || ($mode !== 'block' &&
|
||||||
preg_match('{^<(?:' . $this->contain_span_tags_re . ')\b}', $tag);
|
preg_match('{^<(?:' . $this->contain_span_tags_re . ')\b}', $tag));
|
||||||
|
|
||||||
// Calculate indent before tag.
|
// Calculate indent before tag.
|
||||||
if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
|
if (preg_match('/(?:^|\n)( *?)(?! ).*?$/', $block_text, $matches)) {
|
||||||
|
@ -729,8 +755,11 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append tag content to parsed text.
|
// Append tag content to parsed text.
|
||||||
if (!$span_mode) $parsed .= "\n\n$block_text\n\n";
|
if (!$span_mode) {
|
||||||
else $parsed .= "$block_text";
|
$parsed .= "\n\n$block_text\n\n";
|
||||||
|
} else {
|
||||||
|
$parsed .= (string) $block_text;
|
||||||
|
}
|
||||||
|
|
||||||
// Start over with a new block.
|
// Start over with a new block.
|
||||||
$block_text = "";
|
$block_text = "";
|
||||||
|
@ -875,22 +904,22 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function _doAnchors_inline_callback($matches) {
|
protected function _doAnchors_inline_callback($matches) {
|
||||||
$whole_match = $matches[1];
|
|
||||||
$link_text = $this->runSpanGamut($matches[2]);
|
$link_text = $this->runSpanGamut($matches[2]);
|
||||||
$url = $matches[3] == '' ? $matches[4] : $matches[3];
|
$url = $matches[3] === '' ? $matches[4] : $matches[3];
|
||||||
|
$title_quote =& $matches[6];
|
||||||
$title =& $matches[7];
|
$title =& $matches[7];
|
||||||
$attr = $this->doExtraAttributes("a", $dummy =& $matches[8]);
|
$attr = $this->doExtraAttributes("a", $dummy =& $matches[8]);
|
||||||
|
|
||||||
// if the URL was of the form <s p a c e s> it got caught by the HTML
|
// if the URL was of the form <s p a c e s> it got caught by the HTML
|
||||||
// tag parser and hashed. Need to reverse the process before using the URL.
|
// tag parser and hashed. Need to reverse the process before using the URL.
|
||||||
$unhashed = $this->unhash($url);
|
$unhashed = $this->unhash($url);
|
||||||
if ($unhashed != $url)
|
if ($unhashed !== $url)
|
||||||
$url = preg_replace('/^<(.*)>$/', '\1', $unhashed);
|
$url = preg_replace('/^<(.*)>$/', '\1', $unhashed);
|
||||||
|
|
||||||
$url = $this->encodeURLAttribute($url);
|
$url = $this->encodeURLAttribute($url);
|
||||||
|
|
||||||
$result = "<a href=\"$url\"";
|
$result = "<a href=\"$url\"";
|
||||||
if (isset($title)) {
|
if (isset($title) && $title_quote) {
|
||||||
$title = $this->encodeAttribute($title);
|
$title = $this->encodeAttribute($title);
|
||||||
$result .= " title=\"$title\"";
|
$result .= " title=\"$title\"";
|
||||||
}
|
}
|
||||||
|
@ -967,7 +996,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$alt_text = $matches[2];
|
$alt_text = $matches[2];
|
||||||
$link_id = strtolower($matches[3]);
|
$link_id = strtolower($matches[3]);
|
||||||
|
|
||||||
if ($link_id == "") {
|
if ($link_id === "") {
|
||||||
$link_id = strtolower($alt_text); // for shortcut links like ![this][].
|
$link_id = strtolower($alt_text); // for shortcut links like ![this][].
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -980,8 +1009,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$title = $this->encodeAttribute($title);
|
$title = $this->encodeAttribute($title);
|
||||||
$result .= " title=\"$title\"";
|
$result .= " title=\"$title\"";
|
||||||
}
|
}
|
||||||
if (isset($this->ref_attr[$link_id]))
|
if (isset($this->ref_attr[$link_id])) {
|
||||||
$result .= $this->ref_attr[$link_id];
|
$result .= $this->ref_attr[$link_id];
|
||||||
|
}
|
||||||
$result .= $this->empty_element_suffix;
|
$result .= $this->empty_element_suffix;
|
||||||
$result = $this->hashPart($result);
|
$result = $this->hashPart($result);
|
||||||
}
|
}
|
||||||
|
@ -999,16 +1029,16 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function _doImages_inline_callback($matches) {
|
protected function _doImages_inline_callback($matches) {
|
||||||
$whole_match = $matches[1];
|
|
||||||
$alt_text = $matches[2];
|
$alt_text = $matches[2];
|
||||||
$url = $matches[3] == '' ? $matches[4] : $matches[3];
|
$url = $matches[3] === '' ? $matches[4] : $matches[3];
|
||||||
|
$title_quote =& $matches[6];
|
||||||
$title =& $matches[7];
|
$title =& $matches[7];
|
||||||
$attr = $this->doExtraAttributes("img", $dummy =& $matches[8]);
|
$attr = $this->doExtraAttributes("img", $dummy =& $matches[8]);
|
||||||
|
|
||||||
$alt_text = $this->encodeAttribute($alt_text);
|
$alt_text = $this->encodeAttribute($alt_text);
|
||||||
$url = $this->encodeURLAttribute($url);
|
$url = $this->encodeURLAttribute($url);
|
||||||
$result = "<img src=\"$url\" alt=\"$alt_text\"";
|
$result = "<img src=\"$url\" alt=\"$alt_text\"";
|
||||||
if (isset($title)) {
|
if (isset($title) && $title_quote) {
|
||||||
$title = $this->encodeAttribute($title);
|
$title = $this->encodeAttribute($title);
|
||||||
$result .= " title=\"$title\""; // $title already quoted
|
$result .= " title=\"$title\""; // $title already quoted
|
||||||
}
|
}
|
||||||
|
@ -1067,11 +1097,11 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function _doHeaders_callback_setext($matches) {
|
protected function _doHeaders_callback_setext($matches) {
|
||||||
if ($matches[3] == '-' && preg_match('{^- }', $matches[1])) {
|
if ($matches[3] === '-' && preg_match('{^- }', $matches[1])) {
|
||||||
return $matches[0];
|
return $matches[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$level = $matches[3]{0} == '=' ? 1 : 2;
|
$level = $matches[3][0] === '=' ? 1 : 2;
|
||||||
|
|
||||||
$defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[1]) : null;
|
$defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[1]) : null;
|
||||||
|
|
||||||
|
@ -1174,8 +1204,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
* @param string $alignname
|
* @param string $alignname
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function _doTable_makeAlignAttr($alignname)
|
protected function _doTable_makeAlignAttr($alignname) {
|
||||||
{
|
|
||||||
if (empty($this->table_align_class_tmpl)) {
|
if (empty($this->table_align_class_tmpl)) {
|
||||||
return " align=\"$alignname\"";
|
return " align=\"$alignname\"";
|
||||||
}
|
}
|
||||||
|
@ -1193,6 +1222,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);
|
||||||
|
@ -1223,8 +1253,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$text = "<table>\n";
|
$text = "<table>\n";
|
||||||
$text .= "<thead>\n";
|
$text .= "<thead>\n";
|
||||||
$text .= "<tr>\n";
|
$text .= "<tr>\n";
|
||||||
foreach ($headers as $n => $header)
|
foreach ($headers as $n => $header) {
|
||||||
$text .= " <th$attr[$n]>" . $this->runSpanGamut(trim($header)) . "</th>\n";
|
$text .= " <th$attr[$n]>" . $this->runSpanGamut(trim($header)) . "</th>\n";
|
||||||
|
}
|
||||||
$text .= "</tr>\n";
|
$text .= "</tr>\n";
|
||||||
$text .= "</thead>\n";
|
$text .= "</thead>\n";
|
||||||
|
|
||||||
|
@ -1242,8 +1273,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$row_cells = array_pad($row_cells, $col_count, '');
|
$row_cells = array_pad($row_cells, $col_count, '');
|
||||||
|
|
||||||
$text .= "<tr>\n";
|
$text .= "<tr>\n";
|
||||||
foreach ($row_cells as $n => $cell)
|
foreach ($row_cells as $n => $cell) {
|
||||||
$text .= " <td$attr[$n]>" . $this->runSpanGamut(trim($cell)) . "</td>\n";
|
$text .= " <td$attr[$n]>" . $this->runSpanGamut(trim($cell)) . "</td>\n";
|
||||||
|
}
|
||||||
$text .= "</tr>\n";
|
$text .= "</tr>\n";
|
||||||
}
|
}
|
||||||
$text .= "</tbody>\n";
|
$text .= "</tbody>\n";
|
||||||
|
@ -1411,8 +1443,6 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
*/
|
*/
|
||||||
protected function doFencedCodeBlocks($text) {
|
protected function doFencedCodeBlocks($text) {
|
||||||
|
|
||||||
$less_than_tab = $this->tab_width;
|
|
||||||
|
|
||||||
$text = preg_replace_callback('{
|
$text = preg_replace_callback('{
|
||||||
(?:\n|\A)
|
(?:\n|\A)
|
||||||
# 1: Opening marker
|
# 1: Opening marker
|
||||||
|
@ -1465,9 +1495,10 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
array($this, '_doFencedCodeBlocks_newlines'), $codeblock);
|
array($this, '_doFencedCodeBlocks_newlines'), $codeblock);
|
||||||
|
|
||||||
$classes = array();
|
$classes = array();
|
||||||
if ($classname != "") {
|
if ($classname !== "") {
|
||||||
if ($classname{0} == '.')
|
if ($classname[0] === '.') {
|
||||||
$classname = substr($classname, 1);
|
$classname = substr($classname, 1);
|
||||||
|
}
|
||||||
$classes[] = $this->code_class_prefix . $classname;
|
$classes[] = $this->code_class_prefix . $classname;
|
||||||
}
|
}
|
||||||
$attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes);
|
$attr_str = $this->doExtraAttributes($this->code_attr_on_pre ? "pre" : "code", $attrs, null, $classes);
|
||||||
|
@ -1493,17 +1524,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_])',
|
||||||
|
@ -1608,65 +1639,95 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
|
$text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
|
||||||
array($this, '_appendFootnotes_callback'), $text);
|
array($this, '_appendFootnotes_callback'), $text);
|
||||||
|
|
||||||
if (!empty($this->footnotes_ordered)) {
|
if ( ! empty( $this->footnotes_ordered ) ) {
|
||||||
$text .= "\n\n";
|
$this->_doFootnotes();
|
||||||
$text .= "<div class=\"footnotes\" role=\"doc-endnotes\">\n";
|
if ( ! $this->omit_footnotes ) {
|
||||||
$text .= "<hr" . $this->empty_element_suffix . "\n";
|
$text .= "\n\n";
|
||||||
$text .= "<ol>\n\n";
|
$text .= "<div class=\"footnotes\" role=\"doc-endnotes\">\n";
|
||||||
|
$text .= "<hr" . $this->empty_element_suffix . "\n";
|
||||||
$attr = "";
|
$text .= $this->footnotes_assembled;
|
||||||
if ($this->fn_backlink_class != "") {
|
$text .= "</div>";
|
||||||
$class = $this->fn_backlink_class;
|
|
||||||
$class = $this->encodeAttribute($class);
|
|
||||||
$attr .= " class=\"$class\"";
|
|
||||||
}
|
}
|
||||||
if ($this->fn_backlink_title != "") {
|
}
|
||||||
$title = $this->fn_backlink_title;
|
return $text;
|
||||||
$title = $this->encodeAttribute($title);
|
}
|
||||||
$attr .= " title=\"$title\"";
|
|
||||||
$attr .= " aria-label=\"$title\"";
|
|
||||||
}
|
|
||||||
$attr .= " role=\"doc-backlink\"";
|
|
||||||
$backlink_text = $this->fn_backlink_html;
|
|
||||||
$num = 0;
|
|
||||||
|
|
||||||
while (!empty($this->footnotes_ordered)) {
|
|
||||||
$footnote = reset($this->footnotes_ordered);
|
|
||||||
$note_id = key($this->footnotes_ordered);
|
|
||||||
unset($this->footnotes_ordered[$note_id]);
|
|
||||||
$ref_count = $this->footnotes_ref_count[$note_id];
|
|
||||||
unset($this->footnotes_ref_count[$note_id]);
|
|
||||||
unset($this->footnotes[$note_id]);
|
|
||||||
|
|
||||||
$footnote .= "\n"; // Need to append newline before parsing.
|
/**
|
||||||
$footnote = $this->runBlockGamut("$footnote\n");
|
* Generates the HTML for footnotes. Called by appendFootnotes, even if
|
||||||
$footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
|
* footnotes are not being appended.
|
||||||
array($this, '_appendFootnotes_callback'), $footnote);
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function _doFootnotes() {
|
||||||
|
$attr = array();
|
||||||
|
if ($this->fn_backlink_class !== "") {
|
||||||
|
$class = $this->fn_backlink_class;
|
||||||
|
$class = $this->encodeAttribute($class);
|
||||||
|
$attr['class'] = " class=\"$class\"";
|
||||||
|
}
|
||||||
|
$attr['role'] = " role=\"doc-backlink\"";
|
||||||
|
$num = 0;
|
||||||
|
|
||||||
$attr = str_replace("%%", ++$num, $attr);
|
$text = "<ol>\n\n";
|
||||||
$note_id = $this->encodeAttribute($note_id);
|
while (!empty($this->footnotes_ordered)) {
|
||||||
|
$footnote = reset($this->footnotes_ordered);
|
||||||
|
$note_id = key($this->footnotes_ordered);
|
||||||
|
unset($this->footnotes_ordered[$note_id]);
|
||||||
|
$ref_count = $this->footnotes_ref_count[$note_id];
|
||||||
|
unset($this->footnotes_ref_count[$note_id]);
|
||||||
|
unset($this->footnotes[$note_id]);
|
||||||
|
|
||||||
// Prepare backlink, multiple backlinks if multiple references
|
$footnote .= "\n"; // Need to append newline before parsing.
|
||||||
$backlink = "<a href=\"#fnref:$note_id\"$attr>$backlink_text</a>";
|
$footnote = $this->runBlockGamut("$footnote\n");
|
||||||
for ($ref_num = 2; $ref_num <= $ref_count; ++$ref_num) {
|
$footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
|
||||||
$backlink .= " <a href=\"#fnref$ref_num:$note_id\"$attr>$backlink_text</a>";
|
array($this, '_appendFootnotes_callback'), $footnote);
|
||||||
|
|
||||||
|
$num++;
|
||||||
|
$note_id = $this->encodeAttribute($note_id);
|
||||||
|
|
||||||
|
// Prepare backlink, multiple backlinks if multiple references
|
||||||
|
// Do not create empty backlinks if the html is blank
|
||||||
|
$backlink = "";
|
||||||
|
if (!empty($this->fn_backlink_html)) {
|
||||||
|
for ($ref_num = 1; $ref_num <= $ref_count; ++$ref_num) {
|
||||||
|
if (!empty($this->fn_backlink_title)) {
|
||||||
|
$attr['title'] = ' title="' . $this->encodeAttribute($this->fn_backlink_title) . '"';
|
||||||
|
}
|
||||||
|
if (!empty($this->fn_backlink_label)) {
|
||||||
|
$attr['label'] = ' aria-label="' . $this->encodeAttribute($this->fn_backlink_label) . '"';
|
||||||
|
}
|
||||||
|
$parsed_attr = $this->parseFootnotePlaceholders(
|
||||||
|
implode('', $attr),
|
||||||
|
$num,
|
||||||
|
$ref_num
|
||||||
|
);
|
||||||
|
$backlink_text = $this->parseFootnotePlaceholders(
|
||||||
|
$this->fn_backlink_html,
|
||||||
|
$num,
|
||||||
|
$ref_num
|
||||||
|
);
|
||||||
|
$ref_count_mark = $ref_num > 1 ? $ref_num : '';
|
||||||
|
$backlink .= " <a href=\"#fnref$ref_count_mark:$note_id\"$parsed_attr>$backlink_text</a>";
|
||||||
}
|
}
|
||||||
// Add backlink to last paragraph; create new paragraph if needed.
|
$backlink = trim($backlink);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add backlink to last paragraph; create new paragraph if needed.
|
||||||
|
if (!empty($backlink)) {
|
||||||
if (preg_match('{</p>$}', $footnote)) {
|
if (preg_match('{</p>$}', $footnote)) {
|
||||||
$footnote = substr($footnote, 0, -4) . " $backlink</p>";
|
$footnote = substr($footnote, 0, -4) . " $backlink</p>";
|
||||||
} else {
|
} else {
|
||||||
$footnote .= "\n\n<p>$backlink</p>";
|
$footnote .= "\n\n<p>$backlink</p>";
|
||||||
}
|
}
|
||||||
|
|
||||||
$text .= "<li id=\"fn:$note_id\" role=\"doc-endnote\">\n";
|
|
||||||
$text .= $footnote . "\n";
|
|
||||||
$text .= "</li>\n\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$text .= "</ol>\n";
|
$text .= "<li id=\"fn:$note_id\" role=\"doc-endnote\">\n";
|
||||||
$text .= "</div>";
|
$text .= $footnote . "\n";
|
||||||
|
$text .= "</li>\n\n";
|
||||||
}
|
}
|
||||||
return $text;
|
$text .= "</ol>\n";
|
||||||
|
|
||||||
|
$this->footnotes_assembled = $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1693,12 +1754,12 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
}
|
}
|
||||||
|
|
||||||
$attr = "";
|
$attr = "";
|
||||||
if ($this->fn_link_class != "") {
|
if ($this->fn_link_class !== "") {
|
||||||
$class = $this->fn_link_class;
|
$class = $this->fn_link_class;
|
||||||
$class = $this->encodeAttribute($class);
|
$class = $this->encodeAttribute($class);
|
||||||
$attr .= " class=\"$class\"";
|
$attr .= " class=\"$class\"";
|
||||||
}
|
}
|
||||||
if ($this->fn_link_title != "") {
|
if ($this->fn_link_title !== "") {
|
||||||
$title = $this->fn_link_title;
|
$title = $this->fn_link_title;
|
||||||
$title = $this->encodeAttribute($title);
|
$title = $this->encodeAttribute($title);
|
||||||
$attr .= " title=\"$title\"";
|
$attr .= " title=\"$title\"";
|
||||||
|
@ -1717,6 +1778,23 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
return "[^" . $matches[1] . "]";
|
return "[^" . $matches[1] . "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build footnote label by evaluating any placeholders.
|
||||||
|
* - ^^ footnote number
|
||||||
|
* - %% footnote reference number (Nth reference to footnote number)
|
||||||
|
* @param string $label
|
||||||
|
* @param int $footnote_number
|
||||||
|
* @param int $reference_number
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function parseFootnotePlaceholders($label, $footnote_number, $reference_number) {
|
||||||
|
return str_replace(
|
||||||
|
array('^^', '%%'),
|
||||||
|
array($footnote_number, $reference_number),
|
||||||
|
$label
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abbreviations - strips abbreviations from text, stores titles in hash
|
* Abbreviations - strips abbreviations from text, stores titles in hash
|
||||||
|
@ -1783,12 +1861,10 @@ class MarkdownExtra extends \Michelf\Markdown {
|
||||||
$desc = $this->abbr_desciptions[$abbr];
|
$desc = $this->abbr_desciptions[$abbr];
|
||||||
if (empty($desc)) {
|
if (empty($desc)) {
|
||||||
return $this->hashPart("<abbr>$abbr</abbr>");
|
return $this->hashPart("<abbr>$abbr</abbr>");
|
||||||
} else {
|
|
||||||
$desc = $this->encodeAttribute($desc);
|
|
||||||
return $this->hashPart("<abbr title=\"$desc\">$abbr</abbr>");
|
|
||||||
}
|
}
|
||||||
} else {
|
$desc = $this->encodeAttribute($desc);
|
||||||
return $matches[0];
|
return $this->hashPart("<abbr title=\"$desc\">$abbr</abbr>");
|
||||||
}
|
}
|
||||||
|
return $matches[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* @package php-markdown
|
* @package php-markdown
|
||||||
* @author Michel Fortin <michel.fortin@michelf.com>
|
* @author Michel Fortin <michel.fortin@michelf.com>
|
||||||
* @copyright 2004-2018 Michel Fortin <https://michelf.com/projects/php-markdown/>
|
* @copyright 2004-2021 Michel Fortin <https://michelf.com/projects/php-markdown/>
|
||||||
* @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
|
* @copyright (Original Markdown) 2004-2006 John Gruber <https://daringfireball.net/projects/markdown/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
PHP Markdown
|
PHP Markdown
|
||||||
============
|
============
|
||||||
|
|
||||||
PHP Markdown Lib 1.8.0 - 14 Jan 2018
|
![ci.yml](https://github.com/michelf/php-markdown/actions/workflows/ci.yml/badge.svg)
|
||||||
|
|
||||||
|
PHP Markdown Lib 1.9.0 - 1 Dec 2019
|
||||||
|
|
||||||
by Michel Fortin
|
by Michel Fortin
|
||||||
<https://michelf.ca/>
|
<https://michelf.ca/>
|
||||||
|
@ -34,15 +36,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
|
||||||
|
@ -163,26 +164,54 @@ potential side effects, and future extensibility -- before deciding on
|
||||||
acceptance or rejection.
|
acceptance or rejection.
|
||||||
|
|
||||||
If you make a pull request that includes changes to the parser please add
|
If you make a pull request that includes changes to the parser please add
|
||||||
tests for what is being changed to [MDTest][] and make a pull request there
|
tests for what is being changed to the `test/` directory. This can be as
|
||||||
too.
|
simple as adding a `.text` (input) file with a corresponding `.xhtml`
|
||||||
|
(output) file to proper category under `./test/resources/`.
|
||||||
|
|
||||||
[MDTest]: https://github.com/michelf/mdtest/
|
Traditionally tests were in a separate repository, [MDTest](https://github.com/michelf/mdtest)
|
||||||
|
but they are now located here, alongside the source code.
|
||||||
|
|
||||||
|
|
||||||
Donations
|
Donations
|
||||||
---------
|
---------
|
||||||
|
|
||||||
If you wish to make a donation that will help me devote more time to
|
If you wish to make a donation that will help me devote more time to
|
||||||
PHP Markdown, please visit [michelf.ca/donate] or send Bitcoin to
|
PHP Markdown, please visit [michelf.ca/donate].
|
||||||
[1HiuX34czvVPPdhXbUAsAu7pZcesniDCGH].
|
|
||||||
|
|
||||||
[michelf.ca/donate]: https://michelf.ca/donate/#!Thanks%20for%20PHP%20Markdown
|
[michelf.ca/donate]: https://michelf.ca/donate/#!Thanks%20for%20PHP%20Markdown
|
||||||
[1HiuX34czvVPPdhXbUAsAu7pZcesniDCGH]: bitcoin:1HiuX34czvVPPdhXbUAsAu7pZcesniDCGH
|
|
||||||
|
|
||||||
|
|
||||||
Version History
|
Version History
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
PHP Markdown Lib 1.9.0 (1 Dec 2019)
|
||||||
|
|
||||||
|
* Added `fn_backlink_label` configuration variable to put some text in the
|
||||||
|
`aria-label` attribute.
|
||||||
|
(Thanks to Sunny Walker for the implementation.)
|
||||||
|
|
||||||
|
* Occurances of "`^^`" in `fn_backlink_html`, `fn_backlink_class`,
|
||||||
|
`fn_backlink_title`, and `fn_backlink_label` will be replaced by the
|
||||||
|
corresponding footnote number in the HTML output. Occurances of "`%%`" will be
|
||||||
|
replaced by a number for the reference (footnotes can have multiple references).
|
||||||
|
(Thanks to Sunny Walker for the implementation.)
|
||||||
|
|
||||||
|
* Added configuration variable `omit_footnotes`. When `true` footnotes are not
|
||||||
|
appended at the end of the generated HTML and the `footnotes_assembled`
|
||||||
|
variable will contain the HTML for the footnote list, allowing footnotes to be
|
||||||
|
moved somewhere else on the page.
|
||||||
|
(Thanks to James K. for the implementation.)
|
||||||
|
|
||||||
|
Note: when placing the content of `footnotes_assembled` on the page, consider
|
||||||
|
adding the attribute `role="doc-endnotes"` to the `<div>` or `<section>` that will
|
||||||
|
enclose the list of footnotes so they are reachable to accessibility tools the
|
||||||
|
same way they would be with the default HTML output.
|
||||||
|
|
||||||
|
* Fixed deprecation warnings from PHP about usage of curly braces to access
|
||||||
|
characters in text strings.
|
||||||
|
(Thanks to Remi Collet and Frans-Willem Post.)
|
||||||
|
|
||||||
|
|
||||||
PHP Markdown Lib 1.8.0 (14 Jan 2018)
|
PHP Markdown Lib 1.8.0 (14 Jan 2018)
|
||||||
|
|
||||||
* Autoloading with Composer now uses PSR-4.
|
* Autoloading with Composer now uses PSR-4.
|
||||||
|
@ -371,7 +400,7 @@ Copyright and License
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
PHP Markdown Lib
|
PHP Markdown Lib
|
||||||
Copyright (c) 2004-2016 Michel Fortin
|
Copyright (c) 2004-2019 Michel Fortin
|
||||||
<https://michelf.ca/>
|
<https://michelf.ca/>
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ spl_autoload_register(function($class){
|
||||||
require str_replace('\\', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
|
require str_replace('\\', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
|
||||||
});
|
});
|
||||||
// If using Composer, use this instead:
|
// If using Composer, use this instead:
|
||||||
//require 'vendor/autoloader.php';
|
//require 'vendor/autoload.php';
|
||||||
|
|
||||||
// Get Markdown class
|
// Get Markdown class
|
||||||
use Michelf\Markdown;
|
use Michelf\Markdown;
|
||||||
|
@ -21,13 +21,13 @@ $html = Markdown::defaultTransform($text);
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>PHP Markdown Lib - Readme</title>
|
<title>PHP Markdown Lib - Readme</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<?php
|
<?php
|
||||||
// Put HTML content in the document
|
// Put HTML content in the document
|
||||||
echo $html;
|
echo $html;
|
||||||
?>
|
?>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -18,9 +18,27 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.0"
|
"php": ">=7.4"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": { "Michelf\\": "Michelf/" }
|
"psr-4": { "Michelf\\": "Michelf/" }
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpspec/prophecy": "^1.6",
|
||||||
|
"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"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@ class serendipity_event_markdown extends serendipity_event
|
||||||
$propbag->add('requirements', array(
|
$propbag->add('requirements', array(
|
||||||
'serendipity' => '0.7',
|
'serendipity' => '0.7',
|
||||||
'smarty' => '2.6.7',
|
'smarty' => '2.6.7',
|
||||||
'php' => '5.3.0'
|
'php' => '7.4.0'
|
||||||
));
|
));
|
||||||
$propbag->add('version', '1.30.1');
|
$propbag->add('version', '1.31');
|
||||||
$propbag->add('cachable_events', array('frontend_display' => true));
|
$propbag->add('cachable_events', array('frontend_display' => true));
|
||||||
$propbag->add('event_hooks', array(
|
$propbag->add('event_hooks', array(
|
||||||
'frontend_display' => true,
|
'frontend_display' => true,
|
||||||
|
|
Loading…
Reference in a new issue