diff --git a/MarkdownParse.php b/MarkdownParse.php index 4c7456c..ebff62a 100644 --- a/MarkdownParse.php +++ b/MarkdownParse.php @@ -21,6 +21,10 @@ use Wnx\CommonmarkMarkExtension\MarkExtension; use League\CommonMark\Extension\DefaultAttributes\DefaultAttributesExtension; use SimonVomEyser\CommonMarkExtension\LazyImageExtension; +use League\CommonMark\Event\DocumentPreRenderEvent; +use League\CommonMark\Node\Node; +use League\CommonMark\Node\Query; +use League\CommonMark\Node\Inline\Text; class MarkdownParse { @@ -77,6 +81,24 @@ public function parse(string $text, array $config = []): string $environment = new Environment(array_merge($this->getConfig(), $config)); + $environment->addEventListener(DocumentPreRenderEvent::class, function (DocumentPreRenderEvent $event) { + $document = $event->getDocument(); + $matchingNodes = (new Query()) + ->where(Query::type(FencedCode::class)) + ->andWhere(function (Node $node): bool { + return $node->getInfo() === 'mermaid'; + }) + ->findAll($document); + + foreach ($matchingNodes as $node) { + $divNode = new Text('
' . $node->getLiteral() . '
'); + // foreach ($node->children() as $child) { + // $divNode->appendChild($child); + // } + $node->replaceWith($divNode); + } + }); + $this->addCommonMarkExtensions($environment); $htmlContent = (new MarkdownConverter($environment))->convert($text)->getContent(); @@ -107,13 +129,13 @@ public function preParse(string $text, array $config = []): array // Check if LaTeX is needed by searching for $$ or $ in the text if (!$this->isNeedLaTex) { - $this->isNeedLaTex = (bool) preg_match('/\${1,2}[^`]*?\${1,2}/m', $text); + $this->isNeedLaTex = (bool)preg_match('/\${1,2}[^`]*?\${1,2}/m', $text); } // Replace double $$ at the beginning and end of the text with
tags - $count = 0; - $text = preg_replace('/(^\${2,})(.*)(\${2,}$)/ms', '
$1$2$3
', $text, -1, $count); - $this->isNeedLaTex = $this->isNeedLaTex || $count > 0; + if ($this->isNeedLaTex) { + $text = preg_replace('/(^\${2,})([\s\S]+?)(\${2,})/m', '
$1$2$3
', $text, -1); + } return [$text, $config]; } @@ -127,6 +149,8 @@ public function preParse(string $text, array $config = []): array */ public function postParse(string $htmlContent, array $config = []): array { + $htmlContent = htmlspecialchars_decode($htmlContent); + // If LaTeX is needed, remove
tags added during preParse if ($this->isNeedLaTex) { $htmlContent = str_replace(['
$$', '$$
'], '$$', $htmlContent); @@ -153,6 +177,9 @@ public function getConfig(): array 'internal_hosts' => [], 'open_in_new_window' => true, ], + 'heading_permalink' => [ + 'symbol' => '', + ], 'default_attributes' => [ FencedCode::class => [ 'class' => static function (FencedCode $node) use ($instance) { diff --git a/Plugin.php b/Plugin.php index 3e45b9c..6abcd83 100644 --- a/Plugin.php +++ b/Plugin.php @@ -13,7 +13,7 @@ * * @author mrgeneral * @package MarkdownParse - * @version 2.0.0 + * @version 2.1.0 * @link https://www.chengxiaobai.cn/ */ class Plugin implements PluginInterface @@ -24,10 +24,10 @@ class Plugin implements PluginInterface const CDN_SOURCE_DEFAULT = 'jsDelivr'; const CDN_SOURCE_MERMAID = [ - 'jsDelivr' => 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js', - 'cdnjs' => 'https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.7.0/mermaid.min.js', - 'baomitu' => 'https://lib.baomitu.com/mermaid/latest/mermaid.min.js', - 'bootcdn' => 'https://cdn.bootcdn.net/ajax/libs/mermaid/10.7.0/mermaid.min.js' + 'jsDelivr' => 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs', + 'cdnjs' => 'https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.7.0/mermaid.esm.min.mjs', + 'baomitu' => 'https://lib.baomitu.com/mermaid/10.7.0/mermaid.esm.min.mjs', + 'bootcdn' => 'https://cdn.bootcdn.net/ajax/libs/mermaid/10.7.0/mermaid.esm.min.mjs' ]; const CDN_SOURCE_MATHJAX = [ 'jsDelivr' => 'https://cdn.jsdelivr.net/npm/mathjax/es5/tex-mml-chtml.min.js', @@ -56,13 +56,16 @@ public static function config(Form $form) $elementMermaid = new Form\Element\Radio('is_available_mermaid', [self::RADIO_VALUE_DISABLE => _t('不开启'), self::RADIO_VALUE_AUTO => _t('开启(按需加载)'), self::RADIO_VALUE_FORCE => _t('开启(每次加载,pjax 主题建议选择此选项)')], self::RADIO_VALUE_AUTO, _t('是否开启 Mermaid 支持(支持自动识别,按需渲染,无需担心引入冗余资源)'), _t('开启后支持解析并渲染 Mermaid')); $form->addInput($elementMermaid); + $elementMermaidTheme = new Form\Element\Radio('mermaid_theme', ['default' => _t('默认(default)'), 'neutral' => _t('墨水(neutral)'), 'dark' => _t('暗黑(dark)'), 'forest' => _t('森林绿(forest)')], 'default', _t('Mermaid 主题颜色'), _t('可以去这里 实时编辑器调整主题配置看下效果')); + $form->addInput($elementMermaidTheme); + $elementMathJax = new Form\Element\Radio('is_available_mathjax', [self::RADIO_VALUE_DISABLE => _t('不开启'), self::RADIO_VALUE_AUTO => _t('开启(按需加载)'), self::RADIO_VALUE_FORCE => _t('开启(每次加载,pjax 主题建议选择此选项)')], self::RADIO_VALUE_AUTO, _t('是否开启 MathJax 支持(支持自动识别,按需渲染,无需担心引入冗余资源)'), _t('开启后支持解析并渲染 MathJax')); $form->addInput($elementMathJax); - $elementCDNSource = new Form\Element\Radio('cdn_source', array_combine(array_keys(self::CDN_SOURCE_MERMAID), array_map('_t', array_keys(self::CDN_SOURCE_MERMAID))), self::CDN_SOURCE_DEFAULT); + $elementCDNSource = new Form\Element\Radio('cdn_source', array_combine(array_keys(self::CDN_SOURCE_MERMAID), array_map('_t', array_keys(self::CDN_SOURCE_MERMAID))), self::CDN_SOURCE_DEFAULT, _t('静态资源 CDN'), _t('jsDelivr 默认使用最新版本')); $form->addInput($elementCDNSource); - $elementInternalHosts = new Form\Element\Text('internal_hosts', null, parse_url(Options::alloc()->siteUrl(), PHP_URL_HOST), _t('设置内部链接'), _t('默认为本站点地址,支持正则表达式("/(^|\.)example\.com$/"),多个可用英文逗号分隔。外部链接解析策略:默认在新窗口中打开,并加上 "noopener noreferrer" 属性')); + $elementInternalHosts = new Form\Element\Text('internal_hosts', null, '', _t('设置内部链接'), _t('默认为本站点地址,支持正则表达式("/(^|\.)example\.com$/"),多个可用英文逗号分隔。
外部链接解析策略:默认在新窗口中打开,并加上 "noopener noreferrer" 属性')); $form->addInput($elementInternalHosts); $elementHelper = new Form\Element\Radio('show_help_info', [], self::RADIO_VALUE_DISABLE, _t('点击查看更新信息'), _t('点击查看语法手册')); @@ -79,31 +82,31 @@ public static function parse($text) $markdownParser = MarkdownParse::getInstance(); $markdownParser->setIsTocEnable((bool)Options::alloc()->plugin('MarkdownParse')->is_available_toc); - $markdownParser->setInternalHosts((string)Options::alloc()->plugin('MarkdownParse')->internal_hosts); + $markdownParser->setInternalHosts((string)Options::alloc()->plugin('MarkdownParse')->internal_hosts ?: parse_url(Options::alloc()->siteUrl, PHP_URL_HOST)); return $markdownParser->parse($text); } public static function resourceLink() { + $markdownParser = MarkdownParse::getInstance(); $configMermaid = (int)Options::alloc()->plugin('MarkdownParse')->is_available_mermaid; $configLaTex = (int)Options::alloc()->plugin('MarkdownParse')->is_available_mathjax; $configCDN = (string)Options::alloc()->plugin('MarkdownParse')->cdn_source; - $markdownParser = MarkdownParse::getInstance(); $isAvailableMermaid = $configMermaid === self::RADIO_VALUE_FORCE || ($markdownParser->getIsNeedMermaid() && $configMermaid === self::RADIO_VALUE_AUTO); $isAvailableMathjax = $configLaTex === self::RADIO_VALUE_FORCE || ($markdownParser->getIsNeedLaTex() && $configLaTex === self::RADIO_VALUE_AUTO); - $resourceContent = ''; + $resourceContent = ''; if ($isAvailableMermaid) { - $resourceContent .= ''; - $resourceContent .= sprintf('', !empty(self::CDN_SOURCE_MERMAID[$configCDN]) ? self::CDN_SOURCE_MERMAID[$configCDN] : self::CDN_SOURCE_MERMAID[self::CDN_SOURCE_DEFAULT]); + $resourceContent .= sprintf('', (string)Options::alloc()->plugin('MarkdownParse')->mermaid_theme ?: 'default'); } if ($isAvailableMathjax) { $resourceContent .= ''; - $resourceContent .= ''; - $resourceContent .= sprintf('', !empty(self::CDN_SOURCE_MATHJAX[$configCDN]) ? self::CDN_SOURCE_MATHJAX[$configCDN] : self::CDN_SOURCE_MATHJAX[self::CDN_SOURCE_DEFAULT]); + $resourceContent .= ''; + $resourceContent .= sprintf('', self::CDN_SOURCE_MATHJAX[$configCDN] ?: self::CDN_SOURCE_MATHJAX[self::CDN_SOURCE_DEFAULT]); } echo $resourceContent; diff --git a/README.md b/README.md index eed02ea..16ee287 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ MarkdownParse 是一款基于 [league/commonmark](https://commonmark.thephpleagu 2. 修改文件夹的名字为 "MarkdownParse" 3. 添加到你的项目中并启用它 +## 配置页面 + +![MarkdownParse Config Page](./markdown-parse-config-page.png) + ## 报告问题 [你可以直接点击这里提出你的问题](https://github.com/mrgeneralgoo/typecho-markdown/issues/new) @@ -53,6 +57,10 @@ In addition to the functions mentioned in the CommonMark and GFM specifications 2. Rename the folder to "MarkdownParse" 3. Add it to your project and activate it +## Configuration + +![MarkdownParse Config Page](./markdown-parse-config-page.png) + ## Reporting Issues [You can click here directly to create an issue](https://github.com/mrgeneralgoo/typecho-markdown/issues/new) diff --git a/markdown-parse-config-page.png b/markdown-parse-config-page.png new file mode 100644 index 0000000..4f7fafb Binary files /dev/null and b/markdown-parse-config-page.png differ