给Ghost博客增加Latex支持

测试:
$ x=\frac {-b\pm\sqrt{b^2-4ac}} {2a} $
$ x_1+x_2=-\frac b a, x_1x_2=\frac c a $

网上显然是有把Mathjax直接放进Code injection里的做法。但是

  1. 写的公式里的特殊字符会先被Markdown渲染,再传给Mathjax。所以写的时候还得处理这种问题。
  2. 评论里的latex。
  3. 编辑博客的时候无法预览效果。

于是...

为了摆脱特殊字符的麻烦,我把语法改了一下。一般都是$$包围,这样和普通字符一样会被处理,还有空格这样的麻烦。所以我改成了inline-code里面的$$。如图:

然后因为mathjax太过臃肿所以用了katex。速度很快。

再然后解决什么时候渲染的问题。

  1. 页面加载完成后
  2. 每隔500ms
  3. 按下按键(输入)后

这样一来就很不错了。

需要嵌入到很多个地方。

首先是casper主题的default.hbs
然后是ghost-admin的静态文件default.html, default-prod.html

然后就能用了。

代码:

(function _zView() {
    if(!$) {
	console.log('no jquery support.');
	return;
    }
    
    (function _zView_Katex() {
	if(!katex) {
	    console.log('no katex support.');
	    return;
	}
	
	var texCache = {};

	function getRender(tex) {
	    try {
		if(tex in texCache) return texCache[tex];
		else return texCache[tex] = katex.renderToString(tex);
	    } catch(err) {
		return '<b>Latex Parse Error</b>';
	    }
	}

	function renderElements() {
	    $('code').each(function() {
		var $this = $(this), inner = $this.text();
		if(inner.length >= 3 && inner.slice(0, 1) == '$' && inner.slice(inner.length - 1, inner.length) == '$') {
		    $this.replaceWith(getRender(inner.slice(1, inner.length - 1)));
		}
	    });
	}

	$(function() {
	    renderElements();
	    setInterval(renderElements, 500);
	    $(document).keydown(function() {
		setTimeout(renderElements, 5);
		setTimeout(renderElements, 10);
		setTimeout(renderElements, 20);
	    });
	});
    })();
})();

jquery能注册的事件貌似都是注册成队列的,而不是后一个覆盖前一个。这个很不错,不过想要取消事件需要注意下。