zoukankan      html  css  js  c++  java
  • Latex 公式在线可视化编辑器

    寻觅

    最近的一个demo需要用到Latex公式在线编辑器,从搜索引擎一般会得到类似http://latex.codecogs.com/eqneditor/editor.php的结果,这个编辑器的问题在于使用成本高,并且界面不美观。
    codecogs

    继续探寻,发现了wiris Editor
    wiris Editor

    支持mathml和latex:
    wiris Editor

    那么就它了!

    选型

    首先,我们不会直接使用这个编辑器,只是在编辑公式的时候才使用,所以要选择合适的版本。
    wiris Editor
    以前用过CKEditor,所以就这它了!选用java版本
    我们的数据已经是latex的,在wiris 编辑器显示需要注意latex需要用两个$$包括起来
    例如:

    The history of $$sqrt(2)$$.
    

    但是CK版本的wiris对latex的支持是非可视化支持,在编辑器里输入latex还是显示为latex:
    enter description here

    将焦点移动到$$内部,再点击按钮出现wiris的公式编辑器:

    enter description here
    这种设计适合对latex熟悉的人员,可以裸写latex,同时对不熟悉的人来说,可以使用公式编辑器。但是,这样不直观啊!你让不会latex的看到的就一堆符号!

    适配

    简单试用可以发现,如果直接使用公式编辑器插入公式,是直观显示的:
    enter description here

    可以看到保存的时候,mathml是:

    <math class="wrs_chemistry" xmlns="http://www.w3.org/1998/Math/MathML">
    	<msqrt>
    		<mn>2</mn>
    	</msqrt>
    </math>
    

    那么在latex输入情况下呢:

    <math xmlns="http://www.w3.org/1998/Math/MathML">
    	<semantics>
    		<mrow>
    			<msqrt><mo>(</mo></msqrt><mn>2</mn><mo>)</mo>
    		</mrow>
    		<annotation encoding="LaTeX">sqrt(2)</annotation>
    	</semantics>
    </math>
    

    原来问题在这里,正是mathML的区别导致处理的区别。也就是说一开始就生成不带LaTeX的mathML,然后再放入编辑器。简单查看代码,可以知道先调用wrs_endParse,再wrs_initParse就可以了。

    CKEDITOR.on("instanceReady", function(event)
    	{
    		CKEDITOR.instances.example.focus();
    		var mathxml = wrs_endParse("已知向量$$\vec{a}=(\sqrt{3},2)$$,$$\vec{b}=(0,-2)$$,向量$$\vec{c}=(k,\sqrt{2})$$.$$\vec{a}-1\vec{b}$$与$$\vec{d}$$共线,$$k=$$__.");
    		CKEDITOR.instances.example.setData(wrs_initParse(mathxml));
    		// 等待完成
    		window.setTimeout(updateFunction,0);
    	});
    

    Latex

    直观显示没问题了,但是mathml如何再转换成Latex呢?core.js里的wrs_parseMathmlToLatex函数是直接从mathml里将。。。里的内容提取出来:

    function wrs_parseMathmlToLatex(content, characters){
        ....
        var openTarget = characters.tagOpener + 'annotation encoding=' + characters.doubleQuote + 'LaTeX' + characters.doubleQuote + characters.tagCloser;
     
            mathml = content.substring(start, end);
    
            startAnnotation = mathml.indexOf(openTarget);
    		// 包含 encoding=latex,保留latex
            if (startAnnotation != -1){
                startAnnotation += openTarget.length;
                closeAnnotation = mathml.indexOf(closeTarget);
                var latex = mathml.substring(startAnnotation, closeAnnotation);
                if (characters == _wrs_safeXmlCharacters) {
                    latex = wrs_mathmlDecode(latex);
                }
                output += '$$' + latex + '$$';
                // Populate latex into cache.
                wrs_populateLatexCache(latex, mathml);
            }else{
                output += mathml;
            }
       ......
    }
    

    但是现在的mathml不包含这个信息,如何处理?查看官方文档,发现有一个mathml2latex的服务,查看官方给的java demo里servlet并不包含这个服务,但是jar包里存在代码,于是自己封装一个servlet即可:

    public class ServiceServlet extends com.wiris.plugin.dispatchers.MainServlet {
    
        @Override
        public void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
                throws ServletException, IOException {
            PluginBuilder pb = newPluginBuilder(request);
            String origin = request.getHeader("origin");
            HttpResponse res = new HttpResponse(response);
            pb.addCorsHeaders(res, origin);
            String pathInfo = request.getServletPath();
            if (pathInfo.equals("/mathml2latex")) {
                response.setContentType("text/plain; charset=utf-8");
                ParamsProvider provider = pb.getCustomParamsProvider();
                String mml = provider.getParameter("mml", (String)null);
                String r = pb.newTextService().mathml2latex(mml);
                PrintWriter out = response.getWriter();
                out.print(r);
                out.close();
            }
    

    js里,调用这个服务:

    var _wrs_mathmlCache = {};
    function wrs_getLatexFromMathML(mml) {
        if (_wrs_mathmlCache.hasOwnProperty(mml)) {
            return _wrs_mathmlCache[mml];
        }
        var data = {
            'service': 'mathml2latex',
            'mml': mml
        };
    
        var latex = wrs_getContent(_wrs_conf_servicePath, data);
        // Populate LatexCache.
        if (!_wrs_mathmlCache.hasOwnProperty(mml)) {
            _wrs_mathmlCache[mml] = latex;
        }
        return latex.split("
    ").join('').split("
    ").join(' ');
    }
    

    wrs_getLatexFromMathML只能将一个mathml转换为latex,对于编辑器里的内容来说,需要将mathML抽取出来逐一转换:

    function wrs_parseRawMathmlToLatex(content, characters){
        var output = '';
        var mathTagBegin = characters.tagOpener + 'math';
        var mathTagEnd = characters.tagOpener + '/math' + characters.tagCloser;
        var start = content.indexOf(mathTagBegin);
        var end = 0;
        var mathml, startAnnotation, closeAnnotation;
    
        while (start != -1) {
            output += content.substring(end, start);
            end = content.indexOf(mathTagEnd, start);
    
            if (end == -1) {
                end = content.length - 1;
            }
            else {
                end += mathTagEnd.length;
            }
    
            mathml = content.substring(start, end);
    
            output += wrs_getLatexFromMathML(mathml);
    
            start = content.indexOf(mathTagBegin, end);
        }
    
        output += content.substring(end, content.length);
        return output;
    }
    function wrs_getLatex(code) {
        return wrs_parseRawMathmlToLatex(code, _wrs_xmlCharacters);
    }
    

    末了,为了方便获取,可以将latex放到_current_latex变量里:

    	// 获取数据
    	editor.on('getData', function (e) {
    		e.data.dataValue = wrs_endParse(e.data.dataValue || "");
    		_current_latex = wrs_getLatex(e.data.dataValue || "");
    	});
    
    

    再简单修改下网页,显示latex:
    enter description here

    收官!

  • 相关阅读:
    【已解决】github中git push origin master出错:error: failed to push some refs to
    好记心不如烂笔头,ssh登录 The authenticity of host 192.168.0.xxx can't be established. 的问题
    THINKPHP 5.0目录结构
    thinkphp5.0入口文件
    thinkphp5.0 生命周期
    thinkphp5.0 架构
    Django template
    Django queryset
    Django model
    Python unittest
  • 原文地址:https://www.cnblogs.com/xiaoqi/p/latex-editor.html
Copyright © 2011-2022 走看看