|
<?php
declare(strict_types=1);
namespace app\utils;
class ParsedownExtension extends \Parsedown
{
protected $isTocEnabled = false;
protected $rawTocList = [];
protected $findTocSyntaxRule = '#^<p> *\[TOC\]\s*</p>$#m';
public function setTocEnabled($isTocEnable)
{
$this->isTocEnabled = $isTocEnable;
return $this;
}
public function setTocSyntaxRule($findTocSyntaxRule)
{
$this->findTocSyntaxRule = $findTocSyntaxRule;
return $this;
}
public function text($text)
{
$content = parent::text($text);
if (!$this->isTocEnabled || empty($this->rawTocList) || !preg_match($this->findTocSyntaxRule, $content)) {
return ["toc"=>"","content"=>$content];
}
$content = preg_replace($this->findTocSyntaxRule, "", $content);
return ["toc"=>$this->buildToc(), "content"=>$content];
}
protected function buildToc()
{
$tocMarkdownContent = '';
$topHeadLevel = min(array_column($this->rawTocList, 'level'));
foreach ($this->rawTocList as $id => $tocItem) {
$tocMarkdownContent .= sprintf('%s- [%s](#%s)' . PHP_EOL, str_repeat(' ', $tocItem['level'] - $topHeadLevel), $this->line($tocItem['text']), $tocItem['id']);
}
return parent::text($tocMarkdownContent);
}
protected function blockHeader($line)
{
$block = parent::blockHeader($line);
$text = $block['element']['handler']['argument'];
$no = 0;
foreach ($this->rawTocList as $key => $value) {
if ($text == $value['text']) {
$no = $value['no'] + 1;
}
}
$id = urlencode($this->line($text));
if ($no != 0) {
$id .= '-' . $no;
}
$block['element']['attributes'] = [
'id' => $id,
];
$this->rawTocList[] = [
'id' => $id,
'text' => $text,
'level' => str_replace('h', '', $block['element']['name']),
'no'=> $no,
];
return $block;
}
}
|