diff --git a/Michelf/Markdown.php b/Michelf/Markdown.php
index 746a2d0..bb86414 100644
--- a/Michelf/Markdown.php
+++ b/Michelf/Markdown.php
@@ -29,16 +29,19 @@ class Markdown implements MarkdownInterface {
* @param string $text
* @return string
*/
- public static function defaultTransform(string $text): string {
+ public static function defaultTransform(string $text): string
+ {
// Take parser class on which this function was called.
$parser_class = static::class;
// Try to take parser from the static parser list
static $parser_list;
+
$parser =& $parser_list[$parser_class];
// Create the parser it not already set
- if (!$parser) {
+ if (!$parser)
+ {
$parser = new $parser_class;
}
@@ -46,6 +49,8 @@ class Markdown implements MarkdownInterface {
return $parser->transform($text);
}
+ private int $debug_depth = 0;
+
/**
* Configuration variables
*/
@@ -142,7 +147,10 @@ class Markdown implements MarkdownInterface {
* Constructor function. Initialize appropriate member variables.
* @return void
*/
- public function __construct() {
+ public function __construct()
+ {
+ $this->enter(__FUNCTION__);
+
$this->_initDetab();
$this->prepareItalicsAndBold();
@@ -160,6 +168,8 @@ class Markdown implements MarkdownInterface {
asort($this->document_gamut);
asort($this->block_gamut);
asort($this->span_gamut);
+
+ $this->exit(__FUNCTION__);
}
@@ -184,13 +194,18 @@ class Markdown implements MarkdownInterface {
* Called before the transformation process starts to setup parser states.
* @return void
*/
- protected function setup() {
+ protected function setup()
+ {
+ $this->enter(__FUNCTION__);
+
// Clear global hashes.
$this->urls = $this->predef_urls;
$this->titles = $this->predef_titles;
$this->html_hashes = array();
$this->in_anchor = false;
$this->in_emphasis_processing = false;
+
+ $this->exit(__FUNCTION__);
}
/**
@@ -204,6 +219,21 @@ class Markdown implements MarkdownInterface {
$this->html_hashes = array();
}
+ public function enter(string $text)
+ {
+ // printf("%*s<%s>\n", $this->debug_depth, "", $text); $this->debug_depth += 1;
+ }
+
+ public function exit(string $text)
+ {
+ // $this->debug_depth -= 1; printf("%*s%s>\n", $this->debug_depth, "", $text);
+ }
+
+ public function zprint(string $text)
+ {
+ // printf("%*s%s\n", $this->debug_depth, "", $text);
+ }
+
/**
* Main function. Performs some preprocessing on the input text and pass
* it through the document gamut.
@@ -213,7 +243,10 @@ class Markdown implements MarkdownInterface {
* @param string $text
* @return string
*/
- public function transform(string $text): string {
+ public function transform(string $text): string
+ {
+ $this->enter(__FUNCTION__);
+
$this->setup();
# Remove UTF-8 BOM and marker character in input, if present.
@@ -229,7 +262,6 @@ class Markdown implements MarkdownInterface {
# Convert all tabs to spaces.
$text = $this->detab($text);
- # Turn block-level HTML blocks into hash entries
$text = $this->hashHTMLBlocks($text);
# Strip any lines consisting only of spaces and tabs.
@@ -239,12 +271,15 @@ class Markdown implements MarkdownInterface {
$text = preg_replace('/^[ ]+$/m', '', $text);
# Run document gamut methods.
- foreach ($this->document_gamut as $method => $priority) {
+ foreach ($this->document_gamut as $method => $priority)
+ {
$text = $this->$method($text);
}
$this->teardown();
-
+
+ $this->exit(__FUNCTION__);
+
return $text . "\n";
}
@@ -264,7 +299,8 @@ class Markdown implements MarkdownInterface {
* @return string
*/
protected function stripLinkDefinitions($text) {
-
+ $this->enter(__FUNCTION__);
+
$less_than_tab = $this->tab_width - 1;
// Link defs are in the form: ^[id]: url "optional title"
@@ -293,6 +329,9 @@ class Markdown implements MarkdownInterface {
array($this, '_stripLinkDefinitions_callback'),
$text
);
+
+ $this->exit(__FUNCTION__);
+
return $text;
}
@@ -301,12 +340,19 @@ class Markdown implements MarkdownInterface {
* @param array $matches
* @return string
*/
- protected function _stripLinkDefinitions_callback($matches) {
+ protected function _stripLinkDefinitions_callback($matches)
+ {
+ $this->enter(__FUNCTION__);
$link_id = strtolower($matches[1]);
+
$url = $matches[2] == '' ? $matches[3] : $matches[2];
+
$this->urls[$link_id] = $url;
+
$this->titles[$link_id] =& $matches[4];
- return ''; // String that will replace the block
+
+ $this->exit(__FUNCTION__);
+ return '';
}
/**
@@ -314,8 +360,12 @@ class Markdown implements MarkdownInterface {
* @param string $text
* @return string
*/
- protected function hashHTMLBlocks($text) {
- if ($this->no_markup) {
+ protected function hashHTMLBlocks($text)
+ {
+ $this->enter(__FUNCTION__);
+ if ($this->no_markup)
+ {
+ $this->exit(__FUNCTION__);
return $text;
}
@@ -459,6 +509,7 @@ class Markdown implements MarkdownInterface {
$text
);
+ $this->exit(__FUNCTION__);
return $text;
}
@@ -496,6 +547,7 @@ class Markdown implements MarkdownInterface {
static $i = 0;
$key = "$boundary\x1A" . ++$i . $boundary;
$this->html_hashes[$key] = $text;
+
return $key; // String that will replace the tag.
}
@@ -532,9 +584,16 @@ class Markdown implements MarkdownInterface {
* @param string $text
* @return string
*/
- protected function runBlockGamut($text) {
+ protected function runBlockGamut($text)
+ {
+ $this->enter(__FUNCTION__);
+
$text = $this->hashHTMLBlocks($text);
- return $this->runBasicBlockGamut($text);
+
+ $retval = $this->runBasicBlockGamut($text);
+
+ $this->exit(__FUNCTION__);
+ return $retval;
}
/**
@@ -545,8 +604,10 @@ class Markdown implements MarkdownInterface {
* @param string $text
* @return string
*/
- protected function runBasicBlockGamut($text) {
-
+ protected function runBasicBlockGamut($text)
+ {
+ $this->enter(__FUNCTION__);
+
foreach ($this->block_gamut as $method => $priority) {
$text = $this->$method($text);
}
@@ -554,6 +615,8 @@ class Markdown implements MarkdownInterface {
// Finally form paragraph and restore hashed blocks.
$text = $this->formParagraphs($text);
+ $this->exit(__FUNCTION__);
+
return $text;
}
@@ -605,11 +668,15 @@ class Markdown implements MarkdownInterface {
* @param string $text
* @return string
*/
- protected function runSpanGamut($text) {
+ protected function runSpanGamut($text)
+ {
+ $this->enter(__FUNCTION__);
+
foreach ($this->span_gamut as $method => $priority) {
$text = $this->$method($text);
}
+ $this->exit(__FUNCTION__);
return $text;
}
@@ -618,14 +685,20 @@ class Markdown implements MarkdownInterface {
* @param string $text
* @return string
*/
- protected function doHardBreaks($text) {
+ protected function doHardBreaks($text)
+ {
+ $this->enter(__FUNCTION__);
+
if ($this->hard_wrap) {
- return preg_replace_callback('/ *\n/',
+ $retval = preg_replace_callback('/ *\n/',
array($this, '_doHardBreaks_callback'), $text);
} else {
- return preg_replace_callback('/ {2,}\n/',
+ $retval = preg_replace_callback('/ {2,}\n/',
array($this, '_doHardBreaks_callback'), $text);
}
+
+ $this->exit(__FUNCTION__);
+ return $retval;
}
/**
@@ -642,10 +715,15 @@ class Markdown implements MarkdownInterface {
* @param string $text
* @return string
*/
- protected function doAnchors($text) {
- if ($this->in_anchor) {
+ protected function doAnchors($text)
+ {
+ $this->enter(__FUNCTION__);
+
+ if ($this->in_anchor)
+ {
return $text;
}
+
$this->in_anchor = true;
// First, handle reference-style links: [link text] [id]
@@ -703,6 +781,8 @@ class Markdown implements MarkdownInterface {
array($this, '_doAnchors_reference_callback'), $text);
$this->in_anchor = false;
+
+ $this->exit(__FUNCTION__);
return $text;
}
@@ -711,7 +791,10 @@ class Markdown implements MarkdownInterface {
* @param array $matches
* @return string
*/
- protected function _doAnchors_reference_callback($matches) {
+ protected function _doAnchors_reference_callback($matches)
+ {
+ $this->enter(__FUNCTION__);
+
$whole_match = $matches[1];
$link_text = $matches[2];
$link_id =& $matches[3];
@@ -742,6 +825,9 @@ class Markdown implements MarkdownInterface {
} else {
$result = $whole_match;
}
+
+ $this->exit(__FUNCTION__);
+
return $result;
}
@@ -750,7 +836,10 @@ class Markdown implements MarkdownInterface {
* @param array $matches
* @return string
*/
- protected function _doAnchors_inline_callback($matches) {
+ protected function _doAnchors_inline_callback($matches)
+ {
+ $this->enter(__FUNCTION__);
+
$link_text = $this->runSpanGamut($matches[2]);
$url = $matches[3] === '' ? $matches[4] : $matches[3];
$title =& $matches[7];
@@ -773,6 +862,7 @@ class Markdown implements MarkdownInterface {
$link_text = $this->runSpanGamut($link_text);
$result .= ">$link_text";
+ $this->exit(__FUNCTION__);
return $this->hashPart($result);
}
@@ -781,7 +871,10 @@ class Markdown implements MarkdownInterface {
* @param string $text
* @return string
*/
- protected function doImages($text) {
+ protected function doImages($text)
+ {
+ $this->enter(__FUNCTION__);
+
// First, handle reference-style labeled images: ![alt text][id]
$text = preg_replace_callback('{
( # wrap whole match in $1
@@ -827,6 +920,7 @@ class Markdown implements MarkdownInterface {
}xs',
array($this, '_doImages_inline_callback'), $text);
+ $this->exit(__FUNCTION__);
return $text;
}
@@ -835,7 +929,9 @@ class Markdown implements MarkdownInterface {
* @param array $matches
* @return string
*/
- protected function _doImages_reference_callback($matches) {
+ protected function _doImages_reference_callback($matches)
+ {
+ $this->enter(__FUNCTION__);
$whole_match = $matches[1];
$alt_text = $matches[2];
$link_id = strtolower($matches[3]);
@@ -860,6 +956,7 @@ class Markdown implements MarkdownInterface {
$result = $whole_match;
}
+ $this->exit(__FUNCTION__);
return $result;
}
@@ -891,7 +988,10 @@ class Markdown implements MarkdownInterface {
* @param string $text
* @return string
*/
- protected function doHeaders($text) {
+ protected function doHeaders($text)
+ {
+ $this->enter(__FUNCTION__);
+
/**
* Setext-style headers:
* Header 1
@@ -921,6 +1021,7 @@ class Markdown implements MarkdownInterface {
}xm',
array($this, '_doHeaders_callback_atx'), $text);
+ $this->exit(__FUNCTION__);
return $text;
}
@@ -929,7 +1030,10 @@ class Markdown implements MarkdownInterface {
* @param array $matches
* @return string
*/
- protected function _doHeaders_callback_setext($matches) {
+ protected function _doHeaders_callback_setext($matches)
+ {
+ $this->enter(__FUNCTION__);
+
// Terrible hack to check we haven't found an empty list item.
if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1])) {
return $matches[0];
@@ -941,6 +1045,8 @@ class Markdown implements MarkdownInterface {
$idAtt = $this->_generateIdFromHeaderValue($matches[1]);
$block = "
tags
* @return string
*/
- protected function formParagraphs($text, $wrap_in_p = true) {
+ protected function formParagraphs($text, $wrap_in_p = true)
+ {
+ $this->enter(__FUNCTION__);
+
// Strip leading and trailing lines:
$text = preg_replace('/\A\n+|\n+\z/', '', $text);
@@ -1535,6 +1656,7 @@ class Markdown implements MarkdownInterface {
}
}
+ $this->exit(__FUNCTION__);
return implode("\n\n", $grafs);
}
@@ -1717,7 +1839,10 @@ class Markdown implements MarkdownInterface {
* @param string $str
* @return string
*/
- protected function parseSpan($str) {
+ protected function parseSpan($str)
+ {
+ $this->enter(__FUNCTION__);
+
$output = '';
$span_re = '{
@@ -1766,6 +1891,7 @@ class Markdown implements MarkdownInterface {
}
}
+ $this->exit(__FUNCTION__);
return $output;
}
diff --git a/Michelf/MarkdownExtra.php b/Michelf/MarkdownExtra.php
index 78e265d..3dc59b6 100644
--- a/Michelf/MarkdownExtra.php
+++ b/Michelf/MarkdownExtra.php
@@ -106,7 +106,10 @@ class MarkdownExtra extends \Michelf\Markdown {
* Constructor function. Initialize the parser object.
* @return void
*/
- public function __construct() {
+ public function __construct()
+ {
+ $this->enter(__FUNCTION__);
+
// Add extra escapable characters before parent constructor
// initialize the table.
$this->escape_chars .= ':|';
@@ -116,21 +119,27 @@ class MarkdownExtra extends \Michelf\Markdown {
$this->document_gamut += array(
"doFencedCodeBlocks" => 5,
"stripFootnotes" => 15,
+ "stripTomCells" => 16,
"stripAbbreviations" => 25,
"appendFootnotes" => 50,
);
+
$this->block_gamut += array(
"doFencedCodeBlocks" => 5,
"doTables" => 15,
"doDefLists" => 45,
);
+
$this->span_gamut += array(
"doFootnotes" => 5,
"doAbbreviations" => 70,
);
$this->enhanced_ordered_list = true;
+
parent::__construct();
+
+ $this->exit(__FUNCTION__);
}
@@ -144,6 +153,10 @@ class MarkdownExtra extends \Michelf\Markdown {
protected array $abbr_desciptions = array();
protected string $abbr_word_re = '';
+ protected array $tom_cells = array();
+ protected array $tom_cells_type = array();
+ protected array $tom_cells_stack = array();
+
/**
* Give the current footnote number.
*/
@@ -157,7 +170,10 @@ class MarkdownExtra extends \Michelf\Markdown {
/**
* Setting up Extra-specific variables.
*/
- protected function setup() {
+ protected function setup()
+ {
+ $this->enter(__FUNCTION__);
+
parent::setup();
$this->footnotes = array();
@@ -169,18 +185,26 @@ class MarkdownExtra extends \Michelf\Markdown {
$this->footnote_counter = 1;
$this->footnotes_assembled = null;
+ $this->tom_cells = array();
+ $this->tom_cells_type = array();
+ $this->tom_cells_stack = array();
+
foreach ($this->predef_abbr as $abbr_word => $abbr_desc) {
if ($this->abbr_word_re)
$this->abbr_word_re .= '|';
$this->abbr_word_re .= preg_quote($abbr_word);
$this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
}
+
+ $this->exit(__FUNCTION__);
}
/**
* Clearing Extra-specific variables.
*/
protected function teardown() {
+ $this->enter(__FUNCTION__);
+
$this->footnotes = array();
$this->footnotes_ordered = array();
$this->footnotes_ref_count = array();
@@ -192,6 +216,8 @@ class MarkdownExtra extends \Michelf\Markdown {
$this->footnotes_assembled = null;
parent::teardown();
+
+ $this->exit(__FUNCTION__);
}
@@ -270,7 +296,10 @@ class MarkdownExtra extends \Michelf\Markdown {
* @param string $text
* @return string
*/
- protected function stripLinkDefinitions($text) {
+ protected function stripLinkDefinitions($text)
+ {
+ $this->enter(__FUNCTION__);
+
$less_than_tab = $this->tab_width - 1;
// Link defs are in the form: ^[id]: url "optional title"
@@ -299,6 +328,9 @@ class MarkdownExtra extends \Michelf\Markdown {
}xm',
array($this, '_stripLinkDefinitions_callback'),
$text);
+
+ $this->exit(__FUNCTION__);
+
return $text;
}
@@ -307,12 +339,18 @@ class MarkdownExtra extends \Michelf\Markdown {
* @param array $matches
* @return string
*/
- protected function _stripLinkDefinitions_callback($matches) {
+ protected function _stripLinkDefinitions_callback($matches)
+ {
+ $this->enter(__FUNCTION__);
+
$link_id = strtolower($matches[1]);
$url = $matches[2] == '' ? $matches[3] : $matches[2];
$this->urls[$link_id] = $url;
$this->titles[$link_id] =& $matches[4];
$this->ref_attr[$link_id] = $this->doExtraAttributes("", $dummy =& $matches[5]);
+
+ $this->exit(__FUNCTION__);
+
return ''; // String that will replace the block
}
@@ -1055,6 +1093,7 @@ class MarkdownExtra extends \Michelf\Markdown {
* @return string
*/
protected function doHeaders($text) {
+ $this->enter(__FUNCTION__);
// Setext-style headers:
// Header 1 {#header1}
// ========
@@ -1089,6 +1128,8 @@ class MarkdownExtra extends \Michelf\Markdown {
}xm',
array($this, '_doHeaders_callback_atx'), $text);
+ $this->exit(__FUNCTION__);
+
return $text;
}
@@ -1104,7 +1145,8 @@ class MarkdownExtra extends \Michelf\Markdown {
$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;
$attr = $this->doExtraAttributes("h$level", $dummy =& $matches[2], $defaultId);
$block = "
| " . $this->runSpanGamut(trim($header)) . " | \n"; + foreach ($headers as $n => $header) + { + if (preg_match('/\[([a-zA-Z]+)\]/', $header, $matches)) + { + $label = $matches[1]; + + if ( !in_array($label, $this->tom_cells_stack) + && array_key_exists($label, $this->tom_cells)) + { + array_push($this->tom_cells_stack, $label); + + $local_content = $this->tom_cells[$label]; + + if ($this->tom_cells_type[$label] == "span") + { + $processed = $this->runSpanGamut($local_content); + } + else + { + $processed = $this->runBasicBlockGamut($local_content); + } + + array_pop($this->tom_cells_stack); + + $text .= "" . $processed . " | \n"; + } + else + { + $text .= "" . $header . " | \n"; + } + } + else + { + $text .= "" . $this->runSpanGamut(trim($header)) . " | \n"; + } } $text .= "
|---|---|---|---|
| " . $this->runSpanGamut(trim($cell)) . " | \n"; + foreach ($row_cells as $n => $cell) + { + if (preg_match('/ *\[([a-zA-Z]+)\] */', $cell, $matches)) + { + $label = $matches[1]; + + if ( !in_array($label, $this->tom_cells_stack) + && array_key_exists($label, $this->tom_cells)) + { + array_push($this->tom_cells_stack, $label); + + $local_content = $this->tom_cells[$label]; + + if ($this->tom_cells_type[$label] == "span") + { + $processed = $this->runSpanGamut($local_content); + } + else + { + $processed = $this->runBasicBlockGamut($local_content); + } + + array_pop($this->tom_cells_stack); + + $text .= " <{$column_tags[$n]}$attr[$n]>" . $processed . "\n"; + } + else + { + $text .= " <{$column_tags[$n]}$attr[$n]>" . $cell . "\n"; + } + } + else + { + $text .= " <{$column_tags[$n]}$attr[$n]>" . $this->runSpanGamut(trim($cell)) . "\n"; + } } + $text .= "
`. - (Thanks to Thomas Hochstein for the fix.) - -* Fix for unintended blank title attribute when adding supplementary attributes - to a link in Markdown Extra. - (Thanks to Richie Black for the fix.) - - -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 `
`
- where the element expects only span-level content.
-
-* In the parser code, switched to PHPDoc comment format. Thanks to
- Robbie Averill for the help.
-
-
-PHP Markdown Lib 1.6.0 (23 Dec 2015)
-
-Note: this version was incorrectly released as 1.5.1 on Dec 22, a number
-that contradicted the versioning policy.
-
-* For fenced code blocks in Markdown Extra, can now set a class name for the
- code block's language before the special attribute block. Previously, this
- class name was only allowed in the absence of the special attribute block.
-
-* Added a `code_block_content_func` configuration variable which takes a
- function that will convert the content of the code block to HTML. This is
- most useful for syntax highlighting. For fenced code blocks in Markdown
- Extra, the function has access to the language class name (the one outside
- of the special attribute block). Credits to Mario Konrad for providing the
- implementation.
-
-* The curled arrow character for the backlink in footnotes is now followed
- by a Unicode variant selector to prevent it from being displayed in emoji
- form on iOS.
-
- Note that in older browsers the variant selector is often interpreted as a
- separate character, making it visible after the arrow. So there is now a
- also a `fn_backlink_html` configuration variable that can be used to set
- the link text to something else. Credits to Dana for providing the
- implementation.
-
-* Fixed an issue in MarkdownExtra where long header lines followed by a
- special attribute block would hit the backtrack limit an cause an empty
- string to be returned.
-
-
-PHP Markdown Lib 1.5.0 (1 Mar 2015)
-
-* Added the ability start ordered lists with a number different from 1 and
- and have that reflected in the HTML output. This can be enabled with
- the `enhanced_ordered_lists` configuration variable for the Markdown
- parser; it is enabled by default for Markdown Extra.
- Credits to Matt Gorle for providing the implementation.
-
-* Added the ability to insert custom HTML attributes with simple values
- everywhere an extra attribute block is allowed (links, images, headers).
- The value must be unquoted, cannot contains spaces and is limited to
- alphanumeric ASCII characters.
- Credits to Peter Droogmans for providing the implementation.
-
-* Added a `header_id_func` configuration variable which takes a function
- that can generate an `id` attribute value from the header text.
- Credits to Evert Pot for providing the implementation.
-
-* Added a `url_filter_func` configuration variable which takes a function
- that can rewrite any link or image URL to something different.
-
-
-PHP Markdown Lib 1.4.1 (4 May 2014)
-
-* The HTML block parser will now treat ` ` or parse it's content with
- the as Markdown syntax (although with Extra you can use `markdown="1"`
- if you wish to use the Markdown syntax inside it).
-
-* The content of `