寻觅

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

继续探寻,发现了wiris Editor

支持mathml和latex:

那么就它了!

选型

首先,我们不会直接使用这个编辑器,只是在编辑公式的时候才使用,所以要选择合适的版本。



以前用过CKEditor,所以就这它了!选用java版本

我们的数据已经是latex的,在wiris 编辑器显示需要注意latex需要用两个$$包括起来

例如:

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

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

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



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

适配

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

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

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

那么在latex输入情况下呢:

  1. <math xmlns="http://www.w3.org/1998/Math/MathML">
  2. <semantics>
  3. <mrow>
  4. <msqrt><mo>(</mo></msqrt><mn>2</mn><mo>)</mo>
  5. </mrow>
  6. <annotation encoding="LaTeX">\sqrt(2)</annotation>
  7. </semantics>
  8. </math>

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

  1. CKEDITOR.on("instanceReady", function(event)
  2. {
  3. CKEDITOR.instances.example.focus();
  4. 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=$$__.");
  5. CKEDITOR.instances.example.setData(wrs_initParse(mathxml));
  6. // 等待完成
  7. window.setTimeout(updateFunction,0);
  8. });

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

  1. function wrs_parseMathmlToLatex(content, characters){
  2. ....
  3. var openTarget = characters.tagOpener + 'annotation encoding=' + characters.doubleQuote + 'LaTeX' + characters.doubleQuote + characters.tagCloser;
  4. mathml = content.substring(start, end);
  5. startAnnotation = mathml.indexOf(openTarget);
  6. // 包含 encoding=latex,保留latex
  7. if (startAnnotation != -1){
  8. startAnnotation += openTarget.length;
  9. closeAnnotation = mathml.indexOf(closeTarget);
  10. var latex = mathml.substring(startAnnotation, closeAnnotation);
  11. if (characters == _wrs_safeXmlCharacters) {
  12. latex = wrs_mathmlDecode(latex);
  13. }
  14. output += '$$' + latex + '$$';
  15. // Populate latex into cache.
  16. wrs_populateLatexCache(latex, mathml);
  17. }else{
  18. output += mathml;
  19. }
  20. ......
  21. }

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

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

js里,调用这个服务:

  1. var _wrs_mathmlCache = {};
  2. function wrs_getLatexFromMathML(mml) {
  3. if (_wrs_mathmlCache.hasOwnProperty(mml)) {
  4. return _wrs_mathmlCache[mml];
  5. }
  6. var data = {
  7. 'service': 'mathml2latex',
  8. 'mml': mml
  9. };
  10. var latex = wrs_getContent(_wrs_conf_servicePath, data);
  11. // Populate LatexCache.
  12. if (!_wrs_mathmlCache.hasOwnProperty(mml)) {
  13. _wrs_mathmlCache[mml] = latex;
  14. }
  15. return latex.split("\r").join('').split("\n").join(' ');
  16. }

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

  1. function wrs_parseRawMathmlToLatex(content, characters){
  2. var output = '';
  3. var mathTagBegin = characters.tagOpener + 'math';
  4. var mathTagEnd = characters.tagOpener + '/math' + characters.tagCloser;
  5. var start = content.indexOf(mathTagBegin);
  6. var end = 0;
  7. var mathml, startAnnotation, closeAnnotation;
  8. while (start != -1) {
  9. output += content.substring(end, start);
  10. end = content.indexOf(mathTagEnd, start);
  11. if (end == -1) {
  12. end = content.length - 1;
  13. }
  14. else {
  15. end += mathTagEnd.length;
  16. }
  17. mathml = content.substring(start, end);
  18. output += wrs_getLatexFromMathML(mathml);
  19. start = content.indexOf(mathTagBegin, end);
  20. }
  21. output += content.substring(end, content.length);
  22. return output;
  23. }
  24. function wrs_getLatex(code) {
  25. return wrs_parseRawMathmlToLatex(code, _wrs_xmlCharacters);
  26. }

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

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

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

收官!

Latex 公式在线可视化编辑器的更多相关文章

  1. LaTex公式在线转图片

    Reference https://latex.codecogs.com/gif.latex?THE_FORMULAR 注: 请不要包含空格 或者 将整段url放到浏览器里, 会产生空格等字符的替换, ...

  2. 在线可视化设计网站 & 在线编辑器

    在线可视化设计网站 在线编辑器:海报编辑器.H5 编辑器.视频编辑器.音频编辑器.抠图编辑器 在线 拖拽 可视化 编辑器 Canvas WebGL Canva With Canva, anyone c ...

  3. 后端程序员之路 17、LaTeX公式

    之前的文章写了两个公式:d(x,y)=\sqrt{\sum_{i=1}^{n}(x_i-y_i)^2} H_x=-\sum_{i=1}^{n}p(x_i)\log_{2}{p(x_i)} LaTex ...

  4. LaTex公式语法教程及手册(附emlogpro公式显示插件katex说明)

    目录 第一列 第二列 第三列 效果 求和(使用\sum标签) 文本效果 本插件简介 积分(使用\int标签) 文本大小 LaTex是什么 空格 特殊符号 LaTex公式使用教程及手册 定界符 LaTe ...

  5. 很好用的在线markdown编辑器

    # 欢迎使用 Cmd Markdown 编辑阅读器 基本符号 *,-,+ 3个符号效果都一样,这3个符号被称为 Markdown符号 空白行表示另起一个段落 `是表示inline代码,tab是用来标记 ...

  6. TexFormula2Word: 将Latex公式转换为MathML的Chrome扩展

    前言 因为学校要求对毕业论文进行格式检查,而格式检查又必须上传Word文件,这就导致只能使用Word写毕业论文.但Word公式输入实在是太难用,加之我在小论文中已经用Latex写过大部分公式,所以就希 ...

  7. 为WLW开发Latex公式插件

    WLW是写博客的利器,支持离线.格式排版等,而且拥有众多的插件.博客园推荐了代码插入插件,但是没有提供WLW的公式编译插件.目前我的一般做法是:先在Word下使用MathType编辑好公式,然后将公式 ...

  8. 在线web编辑器

    真正在线编辑的在线web编辑器 最近正在研究开发一款在线web编辑器架构,这是一款真正傻瓜式的web编辑器,可以在正常浏览页面的情况进行编辑,经过测试,对于一般网页页面来说非常好用方便,操作更简单. ...

  9. xml可视化编辑器

    ——业内首创的在线可视化XML结构化数据编辑方法 Boxth Visual XML Web Editor (Boxth XWE) 是专为在线处理XML结构化数据而设计的在线(Web).可视化(WYSW ...

随机推荐

  1. mvc4中的过滤器

    过滤器(Filter)把附加逻辑注入到MVC框架的请求处理.实现了交叉关注. 交叉关注:用于整个应用程序,又不适合放在某个局部位置的功能. 过滤器是.NET的注解属性(Attribute),它们对请求 ...

  2. python学习笔记(一)元组tuple

    元组由简单的对象组构成,元组与列表相似,但是元组不能在原处修改.元组位置有序的对象集合,元组通过偏移来访问. 为什么有了列表还要元组?元组的不变性提供了某种完整性,可以确保元组在程序中不被另一个引用修 ...

  3. 用C#来学习唐诗三百首

    Begin 最近把项目做完了,闲来无事,就想做点好玩的事情,刚好前几天下载了[唐诗三百首]和[全唐诗]这两个txt文件,正好用C#来整理一下. [唐诗三百首]文件格式 [全唐诗]文件格式 目标 将每一 ...

  4. wemall app商城源码android开发MD5加密工具类

    wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享android开发MD5加密工具类主要代码,供 ...

  5. python + selenium <三>

    sql 数据库连接 引用pymssql模块 import pymssqldef getDB(name,psw,dbname,sql): conn=pymssql.connect(HOST=host,N ...

  6. 10分钟精通SharePoint - SharePoint发展历程

    SharePoint 2001: SharePoint Team Service(STS) SharePoint Portal Server(SPS) SharePoint 2003: Windows ...

  7. RequireJS基础知识

    RequireJS解决代码依赖问题,异步加载js,避免页面失去相应 RequireJS的目标是鼓励代码的模块化,它使用了不同于传统<script>标签的脚本加载步骤.可以用它来加速.优化代 ...

  8. querySlector

    在传统的 JavaScript 开发中,查找 DOM 往往是开发人员遇到的第一个头疼的问题,原生的 JavaScript 所提供的 DOM 选择方法并不多,仅仅局限于通过 tag, name, id ...

  9. Unity 3D Framework Designing(1)—— MVVM 模式的设计和实施(Part 1)

    初识 MVVM 谈起 MVVM 设计模式,可能第一映像你会想到 WPF/Sliverlight,他们提供了的数据绑定(Data Binding),命令(Command)等功能,这让 MVVM 模式得到 ...

  10. nodeJS之eventproxy源码解读

    1.源码缩影 !(function (name, definition) { var hasDefine = typeof define === 'function', //检查上下文环境是否为AMD ...