: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
# For the full license information, view the LICENSE file that was distributed
if (! class_exists( 'Redux_Parsedown' ) ) {
const version = '1.8.0-beta-7';
$Elements = $this->textElements($text);
$markup = $this->elements($Elements);
$markup = trim($markup, "\n");
protected function textElements($text)
# make sure no definitions are set
$this->DefinitionData = array();
# standardize line breaks
$text = str_replace(array("\r\n", "\r"), "\n", $text);
# remove surrounding line breaks
$text = trim($text, "\n");
$lines = explode("\n", $text);
# iterate through lines to identify blocks
return $this->linesElements($lines);
function setBreaksEnabled($breaksEnabled)
$this->breaksEnabled = $breaksEnabled;
protected $breaksEnabled;
function setMarkupEscaped($markupEscaped)
$this->markupEscaped = $markupEscaped;
protected $markupEscaped;
function setUrlsLinked($urlsLinked)
$this->urlsLinked = $urlsLinked;
protected $urlsLinked = true;
function setSafeMode($safeMode)
$this->safeMode = (bool) $safeMode;
function setStrictMode($strictMode)
$this->strictMode = (bool) $strictMode;
protected $safeLinksWhitelist = array(
'data:image/png;base64,',
'data:image/gif;base64,',
'data:image/jpeg;base64,',
protected $BlockTypes = array(
'*' => array('Rule', 'List'),
'-' => array('SetextHeader', 'Table', 'Rule', 'List'),
'<' => array('Comment', 'Markup'),
'=' => array('SetextHeader'),
'[' => array('Reference'),
'`' => array('FencedCode'),
'~' => array('FencedCode'),
protected $unmarkedBlockTypes = array(
protected function lines(array $lines)
return $this->elements($this->linesElements($lines));
protected function linesElements(array $lines)
foreach ($lines as $line)
if (isset($CurrentBlock))
$CurrentBlock['interrupted'] = (isset($CurrentBlock['interrupted'])
? $CurrentBlock['interrupted'] + 1 : 1
while (($beforeTab = strstr($line, "\t", true)) !== false)
$shortage = 4 - mb_strlen($beforeTab, 'utf-8') % 4;
. str_repeat(' ', $shortage)
. substr($line, strlen($beforeTab) + 1)
$indent = strspn($line, ' ');
$text = $indent > 0 ? substr($line, $indent) : $line;
$Line = array('body' => $line, 'indent' => $indent, 'text' => $text);
if (isset($CurrentBlock['continuable']))
$methodName = 'block' . $CurrentBlock['type'] . 'Continue';
$Block = $this->$methodName($Line, $CurrentBlock);
if ($this->isBlockCompletable($CurrentBlock['type']))
$methodName = 'block' . $CurrentBlock['type'] . 'Complete';
$CurrentBlock = $this->$methodName($CurrentBlock);
$blockTypes = $this->unmarkedBlockTypes;
if (isset($this->BlockTypes[$marker]))
foreach ($this->BlockTypes[$marker] as $blockType)
$blockTypes []= $blockType;
foreach ($blockTypes as $blockType)
$Block = $this->{"block$blockType"}($Line, $CurrentBlock);
$Block['type'] = $blockType;
if ( ! isset($Block['identified']))
if (isset($CurrentBlock))
$Elements[] = $this->extractElement($CurrentBlock);
$Block['identified'] = true;
if ($this->isBlockContinuable($blockType))
$Block['continuable'] = true;
if (isset($CurrentBlock) and $CurrentBlock['type'] === 'Paragraph')
$Block = $this->paragraphContinue($Line, $CurrentBlock);
if (isset($CurrentBlock))
$Elements[] = $this->extractElement($CurrentBlock);
$CurrentBlock = $this->paragraph($Line);
$CurrentBlock['identified'] = true;
if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type']))
$methodName = 'block' . $CurrentBlock['type'] . 'Complete';
$CurrentBlock = $this->$methodName($CurrentBlock);
if (isset($CurrentBlock))
$Elements[] = $this->extractElement($CurrentBlock);
protected function extractElement(array $Component)
if ( ! isset($Component['element']))
if (isset($Component['markup']))
$Component['element'] = array('rawHtml' => $Component['markup']);
elseif (isset($Component['hidden']))
$Component['element'] = array();
return $Component['element'];
protected function isBlockContinuable($Type)
return method_exists($this, 'block' . $Type . 'Continue');
protected function isBlockCompletable($Type)
return method_exists($this, 'block' . $Type . 'Complete');
protected function blockCode($Line, $Block = null)
if (isset($Block) and $Block['type'] === 'Paragraph' and ! isset($Block['interrupted']))
if ($Line['indent'] >= 4)
$text = substr($Line['body'], 4);
protected function blockCodeContinue($Line, $Block)
if ($Line['indent'] >= 4)
if (isset($Block['interrupted']))
$Block['element']['element']['text'] .= str_repeat("\n", $Block['interrupted']);
unset($Block['interrupted']);
$Block['element']['element']['text'] .= "\n";
$text = substr($Line['body'], 4);
$Block['element']['element']['text'] .= $text;
protected function blockCodeComplete($Block)
protected function blockComment($Line)
if ($this->markupEscaped or $this->safeMode)
if (strpos($Line['text'], '<!--') === 0)
'rawHtml' => $Line['body'],
if (strpos($Line['text'], '-->') !== false)
protected function blockCommentContinue($Line, array $Block)
if (isset($Block['closed']))
$Block['element']['rawHtml'] .= "\n" . $Line['body'];
if (strpos($Line['text'], '-->') !== false)
protected function blockFencedCode($Line)
$marker = $Line['text'][0];
$openerLength = strspn($Line['text'], $marker);
$infostring = trim(substr($Line['text'], $openerLength), "\t ");
if (strpos($infostring, '`') !== false)
* https://www.w3.org/TR/2011/WD-html5-20110525/elements.html#classes
* Every HTML element may have a class attribute specified.
* The attribute, if specified, must have a value that is a set
* of space-separated tokens representing the various classes
* that the element belongs to.
* The space characters, for the purposes of this specification,
* are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab),
* U+000A LINE FEED (LF), U+000C FORM FEED (FF), and
* U+000D CARRIAGE RETURN (CR).
$language = substr($infostring, 0, strcspn($infostring, " \t\n\f\r"));
$Element['attributes'] = array('class' => "language-$language");
'openerLength' => $openerLength,