Open Littleor opened 3 years ago
首先感谢能开源如此方便的插件,使用体验和效果较好,但是目前在预览界面好像并不能进行LaTeX渲染?
我查阅了好多帖子,两种解决办法,都说可以在预览和网页中渲染数学公式:
但实际操作后,只能在网页中渲染,不能实时预览。 后来又发现一篇文章,有提到预览界面无法渲染LaTex:http://www.nohup.cc/article/88/ 想问一下您,经过一段时间的折腾,是否实现在预览界面渲染LaTex?或者是讲解一下不能渲染的原因
我查阅了好多帖子,两种解决办法,都说可以在预览和网页中渲染数学公式:
但实际操作后,只能在网页中渲染,不能实时预览。 后来又发现一篇文章,有提到预览界面无法渲染LaTex:http://www.nohup.cc/article/88/ 想问一下您,经过一段时间的折腾,是否实现在预览界面渲染LaTex?或者是讲解一下不能渲染的原因
你好,其实这个问题并不复杂,预览没有渲染的根本原因在于渲染时没有调用对应的LaTeX解析库进行解析渲染,而在文章中的时候会将内容调用LaTeX解析库进行渲染。
具体来讲,为什么我们可以在文章中进行渲染呢?首先来看看该插件的激活配置:
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
Typecho_Plugin::factory('Widget_Abstract_Contents')->markdown = array('MarkdownKatex_Plugin','parseDown');
Typecho_Plugin::factory('Widget_Archive')->footer = array('MarkdownKatex_Plugin','footer');
}
你可以看到这里做了两个插入点,一个是Widget_Abstract_Contents
另一个是Widget_Archive
,这里先找到Typecho源码中插件初始化的对应文件Init.php中根据对应关系找到这两个插入点对应的文件:Contents.php和Archive.php
可以看出为什么这个插件能渲染出文章的LaTeX呢?那就是这个行:
Typecho_Plugin::factory('Widget_Abstract_Contents')->markdown = array('MarkdownKatex_Plugin','parseDown');
也就是这里的markdown
调用了parseDown
函数进行解析做到的,具体到Content.php
就是这个函数的插入点(912行):
/**
* markdown
*
* @param string|null $text
* @return string|null
*/
public function markdown(?string $text): ?string
{
$html = Contents::pluginHandle()->trigger($parsed)->markdown($text);
if (!$parsed) {
$html = Markdown::convert($text);
}
return $html;
}
那么就很容易可以理解了,我们如果要在预览中渲染无外乎就是调用pareDown
这个函数而已,但是呢我看了下插件的插入点部分没有预览这部分的,那怎么解决呢?
可能现在你认为是直接在预览的地方也调用这个方法不就行了,按道理确实如此,但是事实并非如此。
为什么呢?首先我们对预览的时候是如何解析MD进行分析,Typecho是在editor-js.php来定义的编辑器,其中就有预览功能,具体是这个包HyperDown.js
实现的:
var converter = new HyperDown(),
editor = new Markdown.Editor(converter, '', options);
// 自动跟随
converter.enableHtml(true);
converter.enableLine(true);
reloadScroll = scrollableEditor(textarea, preview);
// 修正白名单
converter.hook('makeHtml', function (html) {
html = html.replace('<p><!--more--></p>', '<!--more-->');
if (html.indexOf('<!--more-->') > 0) {
var parts = html.split(/\s*<\!\-\-more\-\->\s*/),
summary = parts.shift(),
details = parts.join('');
html = '<div class="summary">' + summary + '</div>'
+ '<div class="details">' + details + '</div>';
}
// 替换block
html = html.replace(/<(iframe|embed)\s+([^>]*)>/ig, function (all, tag, src) {
if (src[src.length - 1] == '/') {
src = src.substring(0, src.length - 1);
}
return '<div class="embed"><strong>'
+ tag + '</strong> : ' + $.trim(src) + '</div>';
});
return DOMPurify.sanitize(html, {USE_PROFILES: {html: true}});
});
所以要解决这个问题并不能说通过我们的PHP模块进行解决,因为预览部分是通过HyperDown.js实现的,并不会请求后端,一切都在浏览器通过JS进行解析,然而这个插件只是做了个解析PHP的服务,所以肯定没有办法在预览中渲染啦。
事已至此,现在应该理顺了,如今相比要实现预览渲染的话其实不难,有两个大方向:
这里推荐使用第一种方法,引入MathJax
这个JS的LaTeX渲染引擎即可,具体的可以自行查找对应的Doc即可,相信现在你应该可以实现预览的渲染了,期待你的作品~
首先感谢能开源如此方便的插件,使用体验和效果较好,但是目前在预览界面好像并不能进行LaTeX渲染?