Compare commits
10 commits
932cbc7760
...
c7c8b4929b
| Author | SHA1 | Date | |
|---|---|---|---|
| c7c8b4929b | |||
|
|
98b12b84b1 | ||
|
|
dbb995733d | ||
|
|
51613168d7 | ||
|
|
b9604e39bd | ||
|
|
fbc3604077 | ||
|
|
eb176f173f | ||
|
|
da48f4ac04 | ||
|
|
7c68ff4d7b | ||
|
|
86b59575e7 |
8 changed files with 658 additions and 466 deletions
|
|
@ -1,5 +1,5 @@
|
|||
PHP Markdown Lib
|
||||
Copyright (c) 2004-2021 Michel Fortin
|
||||
Copyright (c) 2004-2022 Michel Fortin
|
||||
<https://michelf.ca/>
|
||||
All rights reserved.
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class Markdown implements MarkdownInterface {
|
|||
* Define the package version
|
||||
* @var string
|
||||
*/
|
||||
const MARKDOWNLIB_VERSION = "1.10.0";
|
||||
const MARKDOWNLIB_VERSION = "2.0.0";
|
||||
|
||||
/**
|
||||
* Simple function interface - Initialize the parser and return the result
|
||||
|
|
@ -29,16 +29,19 @@ class Markdown implements MarkdownInterface {
|
|||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public static function defaultTransform($text) {
|
||||
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($text) {
|
||||
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,6 +299,7 @@ class Markdown implements MarkdownInterface {
|
|||
* @return string
|
||||
*/
|
||||
protected function stripLinkDefinitions($text) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$less_than_tab = $this->tab_width - 1;
|
||||
|
||||
|
|
@ -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,7 +604,9 @@ 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</a>";
|
||||
|
||||
$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 = "<h$level$idAtt>".$this->runSpanGamut($matches[1])."</h$level>";
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
return "\n" . $this->hashBlock($block) . "\n\n";
|
||||
}
|
||||
|
||||
|
|
@ -949,7 +1055,10 @@ class Markdown implements MarkdownInterface {
|
|||
* @param array $matches
|
||||
* @return string
|
||||
*/
|
||||
protected function _doHeaders_callback_atx($matches) {
|
||||
protected function _doHeaders_callback_atx($matches)
|
||||
{
|
||||
print("_doHeaders_callback_atx\n");
|
||||
|
||||
// ID attribute generation
|
||||
$idAtt = $this->_generateIdFromHeaderValue($matches[2]);
|
||||
|
||||
|
|
@ -985,7 +1094,10 @@ class Markdown implements MarkdownInterface {
|
|||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
protected function doLists($text) {
|
||||
protected function doLists($text)
|
||||
{
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$less_than_tab = $this->tab_width - 1;
|
||||
|
||||
// Re-usable patterns to match list item bullets and number markers:
|
||||
|
|
@ -1044,6 +1156,7 @@ class Markdown implements MarkdownInterface {
|
|||
}
|
||||
}
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
|
@ -1052,7 +1165,8 @@ class Markdown implements MarkdownInterface {
|
|||
* @param array $matches
|
||||
* @return string
|
||||
*/
|
||||
protected function _doLists_callback($matches) {
|
||||
protected function _doLists_callback($matches)
|
||||
{
|
||||
// Re-usable patterns to match list item bullets and number markers:
|
||||
$marker_ul_re = '[*+-]';
|
||||
$marker_ol_re = '\d+[\.]';
|
||||
|
|
@ -1420,7 +1534,10 @@ class Markdown implements MarkdownInterface {
|
|||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
protected function doBlockQuotes($text) {
|
||||
protected function doBlockQuotes($text)
|
||||
{
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$text = preg_replace_callback('/
|
||||
( # Wrap whole match in $1
|
||||
(?>
|
||||
|
|
@ -1433,6 +1550,7 @@ class Markdown implements MarkdownInterface {
|
|||
/xm',
|
||||
array($this, '_doBlockQuotes_callback'), $text);
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
|
@ -1474,7 +1592,10 @@ class Markdown implements MarkdownInterface {
|
|||
* @param boolean $wrap_in_p Whether paragraphs should be wrapped in <p> 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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__);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -229,7 +255,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
}
|
||||
|
||||
// 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);
|
||||
$elements = $matches[0];
|
||||
|
||||
// Handle classes and IDs (only first ID taken into account)
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
@ -499,7 +537,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
$parsed .= $parts[0]; // Text before current tag.
|
||||
|
||||
// If end of $text has been reached. Stop loop.
|
||||
if (count($parts) < 3) {
|
||||
if ($parts === false || count($parts) < 3) {
|
||||
$text = "";
|
||||
break;
|
||||
}
|
||||
|
|
@ -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 = "<h$level$attr>" . $this->runSpanGamut($matches[1]) . "</h$level>";
|
||||
|
|
@ -1116,10 +1158,12 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @param array $matches
|
||||
* @return string
|
||||
*/
|
||||
protected function _doHeaders_callback_atx($matches) {
|
||||
protected function _doHeaders_callback_atx($matches)
|
||||
{
|
||||
$level = strlen($matches[1]);
|
||||
|
||||
$defaultId = is_callable($this->header_id_func) ? call_user_func($this->header_id_func, $matches[2]) : null;
|
||||
$defaultId = is_callable($this->header_id_func) ?
|
||||
call_user_func($this->header_id_func, $matches[2]) : null;
|
||||
$attr = $this->doExtraAttributes("h$level", $dummy =& $matches[3], $defaultId);
|
||||
$block = "<h$level$attr>" . $this->runSpanGamut($matches[2]) . "</h$level>";
|
||||
return "\n" . $this->hashBlock($block) . "\n\n";
|
||||
|
|
@ -1130,7 +1174,10 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
protected function doTables($text) {
|
||||
protected function doTables($text)
|
||||
{
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$less_than_tab = $this->tab_width - 1;
|
||||
// Find tables with leading pipe.
|
||||
//
|
||||
|
|
@ -1154,6 +1201,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
[|] .* \n # Row content.
|
||||
)*
|
||||
)
|
||||
('.$this->id_class_attr_catch_re.')? # $4 = id/class attributes
|
||||
(?=\n|\Z) # Stop at final double newline.
|
||||
}xm',
|
||||
array($this, '_doTable_leadingPipe_callback'), $text);
|
||||
|
|
@ -1178,10 +1226,13 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
.* [|] .* \n # Row content
|
||||
)*
|
||||
)
|
||||
('.$this->id_class_attr_catch_re.')? # $4 = id/class attributes
|
||||
(?=\n|\Z) # Stop at final double newline.
|
||||
}xm',
|
||||
array($this, '_DoTable_callback'), $text);
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
|
@ -1194,10 +1245,11 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
$head = $matches[1];
|
||||
$underline = $matches[2];
|
||||
$content = $matches[3];
|
||||
$id_class = $matches[4] ?? null;
|
||||
|
||||
$content = preg_replace('/^ *[|]/m', '', $content);
|
||||
|
||||
return $this->_doTable_callback(array($matches[0], $head, $underline, $content));
|
||||
return $this->_doTable_callback(array($matches[0], $head, $underline, $content, $id_class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1205,12 +1257,15 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @param string $alignname
|
||||
* @return string
|
||||
*/
|
||||
protected function _doTable_makeAlignAttr($alignname) {
|
||||
if (empty($this->table_align_class_tmpl)) {
|
||||
return " align=\"$alignname\"";
|
||||
protected function _doTable_makeAlignAttr($alignname)
|
||||
{
|
||||
if (empty($this->table_align_class_tmpl))
|
||||
{
|
||||
return " style='text-align: $alignname'";
|
||||
}
|
||||
|
||||
$classname = str_replace('%%', $alignname, $this->table_align_class_tmpl);
|
||||
|
||||
return " class=\"$classname\"";
|
||||
}
|
||||
|
||||
|
|
@ -1219,10 +1274,17 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @param array $matches
|
||||
* @return string
|
||||
*/
|
||||
protected function _doTable_callback($matches) {
|
||||
protected function _doTable_callback($matches)
|
||||
{
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
// array_shift($matches);
|
||||
|
||||
$head = $matches[1];
|
||||
$underline = $matches[2];
|
||||
$content = $matches[3];
|
||||
$id_class = $matches[4] ?? null;
|
||||
$column_tags = [];
|
||||
$attr = [];
|
||||
|
||||
// Remove any tailing pipes for each line.
|
||||
|
|
@ -1232,16 +1294,49 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
|
||||
// Reading alignement from header underline.
|
||||
$separators = preg_split('/ *[|] */', $underline);
|
||||
foreach ($separators as $n => $s) {
|
||||
foreach ($separators as $n => $s)
|
||||
{
|
||||
if (preg_match('/^ *-+: *$/', $s))
|
||||
{
|
||||
$column_tags[$n] = "td";
|
||||
$attr[$n] = $this->_doTable_makeAlignAttr('right');
|
||||
}
|
||||
else if (preg_match('/^ *:-+: *$/', $s))
|
||||
{
|
||||
$column_tags[$n] = "td";
|
||||
$attr[$n] = $this->_doTable_makeAlignAttr('center');
|
||||
}
|
||||
else if (preg_match('/^ *:-+ *$/', $s))
|
||||
{
|
||||
$column_tags[$n] = "td";
|
||||
$attr[$n] = $this->_doTable_makeAlignAttr('left');
|
||||
else
|
||||
}
|
||||
else if (preg_match('/^ *=+: *$/', $s))
|
||||
{
|
||||
$column_tags[$n] = "th";
|
||||
$attr[$n] = $this->_doTable_makeAlignAttr('right');
|
||||
}
|
||||
else if (preg_match('/^ *:=+: *$/', $s))
|
||||
{
|
||||
$column_tags[$n] = "th";
|
||||
$attr[$n] = $this->_doTable_makeAlignAttr('center');
|
||||
}
|
||||
else if (preg_match('/^ *:=+ *$/', $s))
|
||||
{
|
||||
$column_tags[$n] = "th";
|
||||
$attr[$n] = $this->_doTable_makeAlignAttr('left');
|
||||
}
|
||||
else if (preg_match('/^ *=+ *$/', $s))
|
||||
{
|
||||
$column_tags[$n] = "th";
|
||||
$attr[$n] = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$column_tags[$n] = "td";
|
||||
$attr[$n] = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Parsing span elements, including code spans, character escapes,
|
||||
// and inline HTML tags, so that pipes inside those gets ignored.
|
||||
|
|
@ -1251,12 +1346,46 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
$attr = array_pad($attr, $col_count, '');
|
||||
|
||||
// Write column headers.
|
||||
$text = "<table>\n";
|
||||
$table_attr_str = $this->doExtraAttributes('table', $id_class, null, []);
|
||||
$text = "<table$table_attr_str>\n";
|
||||
$text .= "<thead>\n";
|
||||
$text .= "<tr>\n";
|
||||
foreach ($headers as $n => $header) {
|
||||
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 .= " <th$attr[$n]>" . $processed . "</th>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$text .= " <th$attr[$n]>" . $header . "</th>\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$text .= " <th$attr[$n]>" . $this->runSpanGamut(trim($header)) . "</th>\n";
|
||||
}
|
||||
}
|
||||
$text .= "</tr>\n";
|
||||
$text .= "</thead>\n";
|
||||
|
||||
|
|
@ -1264,7 +1393,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
$rows = explode("\n", trim($content, "\n"));
|
||||
|
||||
$text .= "<tbody>\n";
|
||||
foreach ($rows as $row) {
|
||||
foreach ($rows as $row)
|
||||
{
|
||||
// Parsing span elements, including code spans, character escapes,
|
||||
// and inline HTML tags, so that pipes inside those gets ignored.
|
||||
$row = $this->parseSpan($row);
|
||||
|
|
@ -1274,14 +1404,50 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
$row_cells = array_pad($row_cells, $col_count, '');
|
||||
|
||||
$text .= "<tr>\n";
|
||||
foreach ($row_cells as $n => $cell) {
|
||||
$text .= " <td$attr[$n]>" . $this->runSpanGamut(trim($cell)) . "</td>\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 . "</td>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$text .= " <{$column_tags[$n]}$attr[$n]>" . $cell . "</td>\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$text .= " <{$column_tags[$n]}$attr[$n]>" . $this->runSpanGamut(trim($cell)) . "</td>\n";
|
||||
}
|
||||
}
|
||||
|
||||
$text .= "</tr>\n";
|
||||
}
|
||||
$text .= "</tbody>\n";
|
||||
$text .= "</table>";
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $this->hashBlock($text) . "\n";
|
||||
}
|
||||
|
||||
|
|
@ -1290,7 +1456,10 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
protected function doDefLists($text) {
|
||||
protected function doDefLists($text)
|
||||
{
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$less_than_tab = $this->tab_width - 1;
|
||||
|
||||
// Re-usable pattern to match any entire dl list:
|
||||
|
|
@ -1327,6 +1496,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
}mx',
|
||||
array($this, '_doDefLists_callback'), $text);
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
|
@ -1336,6 +1507,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @return string
|
||||
*/
|
||||
protected function _doDefLists_callback($matches) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
// Re-usable patterns to match list item bullets and number markers:
|
||||
$list = $matches[1];
|
||||
|
||||
|
|
@ -1343,6 +1516,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
// paragraph for the last item in a list, if necessary:
|
||||
$result = trim($this->processDefListItems($list));
|
||||
$result = "<dl>\n" . $result . "\n</dl>";
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $this->hashBlock($result) . "\n\n";
|
||||
}
|
||||
|
||||
|
|
@ -1353,6 +1529,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @return string
|
||||
*/
|
||||
protected function processDefListItems($list_str) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
|
||||
$less_than_tab = $this->tab_width - 1;
|
||||
|
||||
|
|
@ -1390,6 +1568,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
}xm',
|
||||
array($this, '_processDefListItems_callback_dd'), $list_str);
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $list_str;
|
||||
}
|
||||
|
||||
|
|
@ -1399,12 +1579,17 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @return string
|
||||
*/
|
||||
protected function _processDefListItems_callback_dt($matches) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$terms = explode("\n", trim($matches[1]));
|
||||
$text = '';
|
||||
foreach ($terms as $term) {
|
||||
$term = $this->runSpanGamut(trim($term));
|
||||
$text .= "\n<dt>" . $term . "</dt>";
|
||||
}
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $text . "\n";
|
||||
}
|
||||
|
||||
|
|
@ -1414,6 +1599,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @return string
|
||||
*/
|
||||
protected function _processDefListItems_callback_dd($matches) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$leading_line = $matches[1];
|
||||
$marker_space = $matches[2];
|
||||
$def = $matches[3];
|
||||
|
|
@ -1429,6 +1616,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
$def = $this->runSpanGamut($this->outdent($def));
|
||||
}
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return "\n<dd>" . $def . "</dd>\n";
|
||||
}
|
||||
|
||||
|
|
@ -1443,6 +1632,7 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @return string
|
||||
*/
|
||||
protected function doFencedCodeBlocks($text) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$text = preg_replace_callback('{
|
||||
(?:\n|\A)
|
||||
|
|
@ -1473,6 +1663,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
}xm',
|
||||
array($this, '_doFencedCodeBlocks_callback'), $text);
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
|
@ -1584,6 +1776,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @return string
|
||||
*/
|
||||
protected function stripFootnotes($text) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$less_than_tab = $this->tab_width - 1;
|
||||
|
||||
// Link defs are in the form: [^id]: url "optional title"
|
||||
|
|
@ -1604,6 +1798,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
}xm',
|
||||
array($this, '_stripFootnotes_callback'),
|
||||
$text);
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
|
@ -1612,12 +1809,85 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @param array $matches
|
||||
* @return string
|
||||
*/
|
||||
protected function _stripFootnotes_callback($matches) {
|
||||
protected function _stripFootnotes_callback($matches)
|
||||
{
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$note_id = $this->fn_id_prefix . $matches[1];
|
||||
$this->footnotes[$note_id] = $this->outdent($matches[2]);
|
||||
$content = $this->footnotes[$note_id] = $this->outdent($matches[2]);
|
||||
|
||||
$this->zprint("note_id = $note_id");
|
||||
$this->zprint("content = $content");
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return ''; // String that will replace the block
|
||||
}
|
||||
|
||||
protected function stripTomCells($text) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$less_than_tab = $this->tab_width - 1;
|
||||
|
||||
$text = preg_replace_callback('{
|
||||
^[ ]{0,' . $less_than_tab . '}\[(.+?)\][ ]?: [ ]* \n
|
||||
|
||||
(
|
||||
(?>
|
||||
(?!^\[\1\])
|
||||
.*\n+
|
||||
)+
|
||||
)
|
||||
|
||||
# Closing marker.
|
||||
\[\1\][ ]* (?= \n )
|
||||
}xm',
|
||||
array($this, '_stripTomCells_block_callback'),
|
||||
$text);
|
||||
|
||||
$text = preg_replace_callback('{
|
||||
^[ ]{0,' . $less_than_tab . '}\[(.+?)\][ ]?: (.+) \[\1\][ ]* (?= \n )
|
||||
}xm',
|
||||
array($this, '_stripTomCells_span_callback'),
|
||||
$text);
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
protected function _stripTomCells_span_callback($matches)
|
||||
{
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$this->zprint("matches[1] = {$matches[1]}");
|
||||
$this->zprint("matches[2] = {$matches[2]}");
|
||||
|
||||
$this->tom_cells[$matches[1]] = trim($matches[2]);
|
||||
|
||||
$this->tom_cells_type[$matches[1]] = "span";
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function _stripTomCells_block_callback($matches)
|
||||
{
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$this->zprint("matches[1] = {$matches[1]}");
|
||||
$this->zprint("matches[2] = {$matches[2]}");
|
||||
|
||||
$this->tom_cells[$matches[1]] = $this->outdent($matches[2]);
|
||||
|
||||
$this->tom_cells_type[$matches[1]] = "block";
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace footnote references in $text [^id] with a special text-token
|
||||
* which will be replaced by the actual footnote marker in appendFootnotes.
|
||||
|
|
@ -1637,11 +1907,14 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @return string
|
||||
*/
|
||||
protected function appendFootnotes($text) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}',
|
||||
array($this, '_appendFootnotes_callback'), $text);
|
||||
|
||||
if ( ! empty( $this->footnotes_ordered ) ) {
|
||||
$this->_doFootnotes();
|
||||
|
||||
if ( ! $this->omit_footnotes ) {
|
||||
$text .= "\n\n";
|
||||
$text .= "<div class=\"footnotes\" role=\"doc-endnotes\">\n";
|
||||
|
|
@ -1650,6 +1923,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
$text .= "</div>";
|
||||
}
|
||||
}
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
|
@ -1660,6 +1936,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @return void
|
||||
*/
|
||||
protected function _doFootnotes() {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$attr = array();
|
||||
if ($this->fn_backlink_class !== "") {
|
||||
$class = $this->fn_backlink_class;
|
||||
|
|
@ -1729,6 +2007,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
$text .= "</ol>\n";
|
||||
|
||||
$this->footnotes_assembled = $text;
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1804,6 +2084,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @return string
|
||||
*/
|
||||
protected function stripAbbreviations($text) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$less_than_tab = $this->tab_width - 1;
|
||||
|
||||
// Link defs are in the form: [id]*: url "optional title"
|
||||
|
|
@ -1813,6 +2095,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
}xm',
|
||||
array($this, '_stripAbbreviations_callback'),
|
||||
$text);
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
|
@ -1822,6 +2107,8 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
* @return string
|
||||
*/
|
||||
protected function _stripAbbreviations_callback($matches) {
|
||||
$this->enter(__FUNCTION__);
|
||||
|
||||
$abbr_word = $matches[1];
|
||||
$abbr_desc = $matches[2];
|
||||
if ($this->abbr_word_re) {
|
||||
|
|
@ -1829,6 +2116,9 @@ class MarkdownExtra extends \Michelf\Markdown {
|
|||
}
|
||||
$this->abbr_word_re .= preg_quote($abbr_word);
|
||||
$this->abbr_desciptions[$abbr_word] = trim($abbr_desc);
|
||||
|
||||
$this->exit(__FUNCTION__);
|
||||
|
||||
return ''; // String that will replace the block
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ interface MarkdownInterface {
|
|||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public static function defaultTransform($text);
|
||||
public static function defaultTransform(string $text): string;
|
||||
|
||||
/**
|
||||
* Main function. Performs some preprocessing on the input text
|
||||
|
|
@ -34,5 +34,5 @@ interface MarkdownInterface {
|
|||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
public function transform($text);
|
||||
public function transform(string $text): string;
|
||||
}
|
||||
|
|
|
|||
455
Readme.md
455
Readme.md
|
|
@ -1,458 +1,121 @@
|
|||
PHP Markdown
|
||||
============
|
||||
|
||||

|
||||
<style>
|
||||
table
|
||||
{
|
||||
border-collapse: collapse;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
by Michel Fortin
|
||||
<https://michelf.ca/>
|
||||
th, td
|
||||
{
|
||||
border: thin solid grey;
|
||||
padding: 0.5em;
|
||||
}
|
||||
</style>
|
||||
|
||||
based on Markdown by John Gruber
|
||||
<https://daringfireball.net/>
|
||||
|
||||
Hello, world!
|
||||
|
||||
Introduction
|
||||
------------
|
||||
| Header 1 | [foo]
|
||||
| :------: | :-----:
|
||||
| Cell 1 | Cell 2
|
||||
| [bar] | Cell 4
|
||||
| Cell 3 | [gar]
|
||||
|
||||
This is a library package that includes the PHP Markdown parser and its
|
||||
sibling PHP Markdown Extra with additional features.
|
||||
|
||||
Markdown is a text-to-HTML conversion tool for web writers. Markdown
|
||||
allows you to write using an easy-to-read, easy-to-write plain text
|
||||
format, then convert it to structurally valid XHTML (or HTML).
|
||||
|
||||
"Markdown" is actually two things: a plain text markup syntax, and a
|
||||
software tool, originally written in Perl, that converts the plain text
|
||||
markup to HTML. PHP Markdown is a port to PHP of the original Markdown
|
||||
program by John Gruber.
|
||||
[foo]:
|
||||
There are multiple paragraphs
|
||||
|
||||
* [Full documentation of the Markdown syntax](<https://daringfireball.net/projects/markdown/>)
|
||||
— Daring Fireball (John Gruber)
|
||||
* [Markdown Extra syntax additions](<https://michelf.ca/projects/php-markdown/extra/>)
|
||||
— Michel Fortin
|
||||
I'm another one!
|
||||
[foo]
|
||||
|
||||
[bar]: something clever without paragraphs [bar]
|
||||
|
||||
Requirement
|
||||
-----------
|
||||
[gar]:
|
||||
just one paragraph here
|
||||
[gar]
|
||||
|
||||
This library package requires PHP 7.4 or later.
|
||||
[bar]: something clever clever without paragraphs [bar]
|
||||
|
||||
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
|
||||
later.
|
||||
[gar]:
|
||||
just one paragraph here here
|
||||
[gar]
|
||||
|
||||
You might need to set pcre.backtrack_limit higher than 1 000 000
|
||||
(the default), though the default is usually fine.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
To use this library with Composer, first install it with:
|
||||
|
||||
$ composer require michelf/php-markdown
|
||||
<!--- Table header:-->
|
||||
<!-- - If explicit HTML tag, use that-->
|
||||
<!-- - Default to `<th>`-->
|
||||
<!--- Table body:-->
|
||||
<!-- - If explicit HTML tag, use that-->
|
||||
<!-- - Use `<td>` for hypen columns, and `<th>` for equal-sign columns.-->
|
||||
|
||||
Then include Composer's generated vendor/autoload.php to [enable autoloading]:
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
Without Composer, for autoloading to work, your project needs an autoloader
|
||||
compatible with PSR-4 or PSR-0. See the included Readme.php file for a minimal
|
||||
autoloader setup. (If you cannot use autoloading, see below.)
|
||||
|
||||
With class autoloading in place:
|
||||
<!--| Header 1 | Header 2-->
|
||||
<!--| :------: | :-----:-->
|
||||
<!--| [q] | Cell 2-->
|
||||
<!--| [w] | Cell 2-->
|
||||
|
||||
use Michelf\Markdown;
|
||||
$my_html = Markdown::defaultTransform($my_text);
|
||||
|
||||
Markdown Extra syntax is also available the same way:
|
||||
<!--[q]: a [q] [q]: b [q]-->
|
||||
|
||||
use Michelf\MarkdownExtra;
|
||||
$my_html = MarkdownExtra::defaultTransform($my_text);
|
||||
<!--[w]: [w]: a [w] [w]-->
|
||||
|
||||
If you wish to use PHP Markdown with another text filter function
|
||||
built to parse HTML, you should filter the text *after* the `transform`
|
||||
function call. This is an example with [PHP SmartyPants]:
|
||||
|
||||
use Michelf\Markdown, Michelf\SmartyPants;
|
||||
$my_html = Markdown::defaultTransform($my_text);
|
||||
$my_html = SmartyPants::defaultTransform($my_html);
|
||||
|
||||
All these examples are using the static `defaultTransform` static function
|
||||
found inside the parser class. If you want to customize the parser
|
||||
configuration, you can also instantiate it directly and change some
|
||||
configuration variables:
|
||||
|
||||
use Michelf\MarkdownExtra;
|
||||
$parser = new MarkdownExtra;
|
||||
$parser->fn_id_prefix = "post22-";
|
||||
$my_html = $parser->transform($my_text);
|
||||
|
||||
To learn more, see the full list of [configuration variables].
|
||||
|
||||
[enable autoloading]: https://getcomposer.org/doc/01-basic-usage.md#autoloading
|
||||
[PHP SmartyPants]: https://michelf.ca/projects/php-smartypants/
|
||||
[configuration variables]: https://michelf.ca/projects/php-markdown/configuration/
|
||||
|
||||
|
||||
### Usage without an autoloader
|
||||
|
||||
If you cannot use class autoloading, you can still use `include` or `require`
|
||||
to access the parser. To load the `Michelf\Markdown` parser, do it this way:
|
||||
<!--[a] | [b] | [c]-->
|
||||
<!------|-----|------>
|
||||
<!--[d] | [a] | [f]-->
|
||||
<!--[g] | [h] | [a]-->
|
||||
|
||||
require_once 'Michelf/Markdown.inc.php';
|
||||
|
||||
Or, if you need the `Michelf\MarkdownExtra` parser:
|
||||
<!--[a] | [b] | [c]-->
|
||||
<!------|-----|------>
|
||||
<!--[d] | [e] | [f]-->
|
||||
<!--[g] | [h] | [i]-->
|
||||
|
||||
require_once 'Michelf/MarkdownExtra.inc.php';
|
||||
|
||||
While the plain `.php` files depend on autoloading to work correctly, using the
|
||||
`.inc.php` files instead will eagerly load the dependencies that would be
|
||||
loaded on demand if you were using autoloading.
|
||||
<!--[a]: A [a]-->
|
||||
<!--[b]: B [b]-->
|
||||
<!--[c]: C [c]-->
|
||||
<!--[d]: D [d]-->
|
||||
<!--[e]: E [e]-->
|
||||
<!--[f]: F [f]-->
|
||||
<!--[g]: G [g]-->
|
||||
<!--[h]: H [h]-->
|
||||
<!--[i]: I [i]-->
|
||||
|
||||
|
||||
Public API and Versioning Policy
|
||||
---------------------------------
|
||||
|
||||
Version numbers are of the form *major*.*minor*.*patch*.
|
||||
|
||||
The public API of PHP Markdown consist of the two parser classes `Markdown`
|
||||
and `MarkdownExtra`, their constructors, the `transform` and `defaultTransform`
|
||||
functions and their configuration variables. The public API is stable for
|
||||
a given major version number. It might get additions when the minor version
|
||||
number increments.
|
||||
|
||||
**Protected members are not considered public API.** This is unconventional
|
||||
and deserves an explanation. Incrementing the major version number every time
|
||||
the underlying implementation of something changes is going to give
|
||||
nonessential version numbers for the vast majority of people who just use the
|
||||
parser. Protected members are meant to create parser subclasses that behave in
|
||||
different ways. Very few people create parser subclasses. I don't want to
|
||||
discourage it by making everything private, but at the same time I can't
|
||||
guarantee any stable hook between versions if you use protected members.
|
||||
|
||||
**Syntax changes** will increment the minor number for new features, and the
|
||||
patch number for small corrections. A *new feature* is something that needs a
|
||||
change in the syntax documentation. Note that since PHP Markdown Lib includes
|
||||
two parsers, a syntax change for either of them will increment the minor
|
||||
number. Also note that there is nothing perfectly backward-compatible with the
|
||||
Markdown syntax: all inputs are always valid, so new features always replace
|
||||
something that was previously legal, although generally nonsensical to do.
|
||||
|
||||
|
||||
Bugs
|
||||
----
|
||||
|
||||
To file bug reports please send email to:
|
||||
<michel.fortin@michelf.ca>
|
||||
|
||||
Please include with your report: (1) the example input; (2) the output you
|
||||
expected; (3) the output PHP Markdown actually produced.
|
||||
|
||||
If you have a problem where Markdown gives you an empty result, first check
|
||||
that the backtrack limit is not too low by running `php --info | grep pcre`.
|
||||
See Installation and Requirement above for details.
|
||||
|
||||
|
||||
Development and Testing
|
||||
-----------------------
|
||||
|
||||
Pull requests for fixing bugs are welcome. Proposed new features are
|
||||
going to be meticulously reviewed -- taking into account backward compatibility,
|
||||
potential side effects, and future extensibility -- before deciding on
|
||||
acceptance or rejection.
|
||||
|
||||
If you make a pull request that includes changes to the parser please add
|
||||
tests for what is being changed to the `test/` directory. This can be as
|
||||
simple as adding a `.text` (input) file with a corresponding `.xhtml`
|
||||
(output) file to proper category under `./test/resources/`.
|
||||
|
||||
Traditionally tests were in a separate repository, [MDTest](https://github.com/michelf/mdtest)
|
||||
but they are now located here, alongside the source code.
|
||||
|
||||
|
||||
Donations
|
||||
---------
|
||||
|
||||
If you wish to make a donation that will help me devote more time to
|
||||
PHP Markdown, please visit [michelf.ca/donate].
|
||||
|
||||
[michelf.ca/donate]: https://michelf.ca/donate/#!Thanks%20for%20PHP%20Markdown
|
||||
|
||||
|
||||
Version History
|
||||
---------------
|
||||
|
||||
PHP Markdown Lib 1.10.0 (26 Sep 2022)
|
||||
|
||||
* Now requiring PHP version 7.4 or later.
|
||||
|
||||
* Added type annotations to configuration properties of the parser.
|
||||
(Thanks to Tac Tacelosky.)
|
||||
|
||||
* Fixing a TypeError in PHP 8 caused by invalid counter variable.
|
||||
(Thanks to Alexey Kopytko.)
|
||||
|
||||
|
||||
PHP Markdown Lib 1.9.1 (23 Nov 2021)
|
||||
|
||||
* Now treating `<details>` and `<summary>` as block level so they don't
|
||||
get wrapped in `<p>`.
|
||||
(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 `<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)
|
||||
|
||||
* Autoloading with Composer now uses PSR-4.
|
||||
|
||||
* HTML output for Markdown Extra footnotes now include `role` attributes
|
||||
with values from [WAI-ARIA](https://www.w3.org/TR/dpub-aria/) to
|
||||
make them more accessible.
|
||||
(Thanks to Tobias Bengfort)
|
||||
|
||||
* In Markdown Extra, added the `hashtag_protection` configuration variable.
|
||||
When set to `true` it prevents ATX-style headers with no space after the initial
|
||||
hash from being interpreted as headers. This way your precious hashtags
|
||||
are preserved.
|
||||
(Thanks to Jaussoin Timothée for the implementation.)
|
||||
|
||||
|
||||
PHP Markdown Lib 1.7.0 (29 Oct 2016)
|
||||
|
||||
* Added a `hard_wrap` configuration variable to make all newline characters
|
||||
in the text become `<br>` tags in the HTML output. By default, according
|
||||
to the standard Markdown syntax these newlines are ignored unless they a
|
||||
preceded by two spaces. Thanks to Jonathan Cohlmeyer for the implementation.
|
||||
|
||||
* Improved the parsing of list items to fix problematic cases that came to
|
||||
light with the addition of `hard_wrap`. This should have no effect on the
|
||||
output except span-level list items that ended with two spaces (and thus
|
||||
ended with a line break).
|
||||
|
||||
* Added a `code_span_content_func` configuration variable which takes a
|
||||
function that will convert the content of the code span to HTML. This can
|
||||
be useful to implement syntax highlighting. Although contrary to its
|
||||
code block equivalent, there is no syntax for specifying a language.
|
||||
Credits to styxit for the implementation.
|
||||
|
||||
* Fixed a Markdown Extra issue where two-space-at-end-of-line hard breaks
|
||||
wouldn't work inside of HTML block elements such as `<p markdown="1">`
|
||||
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 `<figure>` as a block-level element
|
||||
(as it should) and no longer wrap it in `<p>` 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 `<style>` elements will now be left alone, its content
|
||||
won't be interpreted as Markdown.
|
||||
|
||||
* Corrected an bug where some inline links with spaces in them would not
|
||||
work even when surounded with angle brackets:
|
||||
|
||||
[link](<s p a c e s>)
|
||||
|
||||
* Fixed an issue where email addresses with quotes in them would not always
|
||||
have the quotes escaped in the link attribute, causing broken links (and
|
||||
invalid HTML).
|
||||
|
||||
* Fixed the case were a link definition following a footnote definition would
|
||||
be swallowed by the footnote unless it was separated by a blank line.
|
||||
|
||||
|
||||
PHP Markdown Lib 1.4.0 (29 Nov 2013)
|
||||
|
||||
* Added support for the `tel:` URL scheme in automatic links.
|
||||
|
||||
<tel:+1-111-111-1111>
|
||||
|
||||
It gets converted to this (note the `tel:` prefix becomes invisible):
|
||||
|
||||
<a href="tel:+1-111-111-1111">+1-111-111-1111</a>
|
||||
|
||||
* Added backtick fenced code blocks to MarkdownExtra, originally from
|
||||
Github-Flavored Markdown.
|
||||
|
||||
* Added an interface called MarkdownInterface implemented by both
|
||||
the Markdown and MarkdownExtra parsers. You can use the interface if
|
||||
you want to create a mockup parser object for unit testing.
|
||||
|
||||
* For those of you who cannot use class autoloading, you can now
|
||||
include `Michelf/Markdown.inc.php` or `Michelf/MarkdownExtra.inc.php` (note
|
||||
the `.inc.php` extension) to automatically include other files required
|
||||
by the parser.
|
||||
|
||||
|
||||
PHP Markdown Lib 1.3 (11 Apr 2013)
|
||||
|
||||
This is the first release of PHP Markdown Lib. This package requires PHP
|
||||
version 5.3 or later and is designed to work with PSR-0 autoloading and,
|
||||
optionally with Composer. Here is a list of the changes since
|
||||
PHP Markdown Extra 1.2.6:
|
||||
|
||||
* Plugin interface for WordPress and other systems is no longer present in
|
||||
the Lib package. The classic package is still available if you need it:
|
||||
<https://michelf.ca/projects/php-markdown/classic/>
|
||||
|
||||
* Added `public` and `protected` protection attributes, plus a section about
|
||||
what is "public API" and what isn't in the Readme file.
|
||||
|
||||
* Changed HTML output for footnotes: now instead of adding `rel` and `rev`
|
||||
attributes, footnotes links have the class name `footnote-ref` and
|
||||
backlinks `footnote-backref`.
|
||||
|
||||
* Fixed some regular expressions to make PCRE not shout warnings about POSIX
|
||||
collation classes (dependent on your version of PCRE).
|
||||
|
||||
* Added optional class and id attributes to images and links using the same
|
||||
syntax as for headers:
|
||||
|
||||
[link](url){#id .class}
|
||||
{#id .class}
|
||||
|
||||
It work too for reference-style links and images. In this case you need
|
||||
to put those attributes at the reference definition:
|
||||
|
||||
[link][linkref] or [linkref]
|
||||
![img][linkref]
|
||||
|
||||
[linkref]: url "optional title" {#id .class}
|
||||
|
||||
* Fixed a PHP notice message triggered when some table column separator
|
||||
markers are missing on the separator line below column headers.
|
||||
|
||||
* Fixed a small mistake that could cause the parser to retain an invalid
|
||||
state related to parsing links across multiple runs. This was never
|
||||
observed (that I know of), but it's still worth fixing.
|
||||
|
||||
|
||||
Copyright and License
|
||||
---------------------
|
||||
|
||||
PHP Markdown Lib
|
||||
Copyright (c) 2004-2022 Michel Fortin
|
||||
<https://michelf.ca/>
|
||||
All rights reserved.
|
||||
|
||||
Based on Markdown
|
||||
Copyright (c) 2003-2005 John Gruber
|
||||
<https://daringfireball.net/>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name "Markdown" nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
This software is provided by the copyright holders and contributors "as
|
||||
is" and any express or implied warranties, including, but not limited
|
||||
to, the implied warranties of merchantability and fitness for a
|
||||
particular purpose are disclaimed. In no event shall the copyright owner
|
||||
or contributors be liable for any direct, indirect, incidental, special,
|
||||
exemplary, or consequential damages (including, but not limited to,
|
||||
procurement of substitute goods or services; loss of use, data, or
|
||||
profits; or business interruption) however caused and on any theory of
|
||||
liability, whether in contract, strict liability, or tort (including
|
||||
negligence or otherwise) arising in any way out of the use of this
|
||||
software, even if advised of the possibility of such damage.
|
||||
|
|
|
|||
|
|
@ -8,15 +8,16 @@
|
|||
spl_autoload_register(function($class) {
|
||||
require str_replace('\\', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
|
||||
});
|
||||
|
||||
// If using Composer, use this instead:
|
||||
//require 'vendor/autoload.php';
|
||||
|
||||
// Get Markdown class
|
||||
use Michelf\Markdown;
|
||||
use Michelf\MarkdownExtra;
|
||||
|
||||
// Read file and pass content through the Markdown parser
|
||||
$text = file_get_contents('Readme.md');
|
||||
$html = Markdown::defaultTransform($text);
|
||||
$html = MarkdownExtra::defaultTransform($text);
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
|
|
|
|||
77
flake.lock
Normal file
77
flake.lock
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1761588595,
|
||||
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1762708072,
|
||||
"narHash": "sha256-Z1IGLq5IPJ7Yl9Y+X+0eMnEWnckIRiLA75tBWUPLQh0=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "adb5147f66533a1c84c6218f1998fca1ece9092b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
35
flake.nix
Normal file
35
flake.nix
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
# vim: set sw=2 ts=2 et: #
|
||||
|
||||
{
|
||||
description = "An example project using flutter";
|
||||
|
||||
inputs.nixpkgs = { url = "github:NixOS/nixpkgs"; };
|
||||
|
||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
inputs.flake-compat = {
|
||||
url = "github:edolstra/flake-compat";
|
||||
flake = false;
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, ... }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
in {
|
||||
devShells.default =
|
||||
pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
php
|
||||
gedit
|
||||
python3
|
||||
meld
|
||||
];
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
Reference in a new issue