• 091128日志(博客园博客显示数学公式的方法!)


    这两天我把 blog 的数学公式显示的支持方案修改了下。

    之前采用的是 ASCIIMathML.js 的方式来支持博客页面上的数学公式显示(这里有说明),但这个方法有几个不足之处:

    • 首先是 JS 脚本的大小问题,ASCIIMathML.js 这个脚本有 150K 左右,如果在 blog 中使用这个 JS 脚本的话,那么无论是否需要支持数学公式,访问者打开我的博客的页面的时候,都需要承受这 150K 的下载负担,对于网速好的访问者来说也许问题不大,但毕竟不少地方网速还不行(想起一年前十几户人共用 1M 网络的日子了,唉),所以这个脚本还是有点大了。
    • 使用 ASCIIMathML.js 脚本,会将页面上的数学公式转换成 ML 标签,要求浏览器必须要有支持,FireFox 等自然是没问题,但 IE 的用户则必须安装 MathPlayer 才能“正常”查看。
    • 最终产生的公式样子比较丑……

    综上,感觉 ASCIIMathML.js 比较符合本机使用,嘿嘿,比如自己的 TW ……

    新的方案是使用 MathTran 提供的公式转图片的服务,最初知道这个方法是因为我想在 TiddlyWiki 中使用数学公式显示,结果查到这么一篇文章,里面就有对 MathTran 的一些说明,按他说的方法试了试,确实很不错,显示的公式很漂亮。而且速度也很快。但原始的方法中有一个不足之处:必须在自己的页面中插入 <img> 标签,才能使用 mathtran 提供的脚本来转换。这很不方便,因为现在我基本上都是用 WLW 离线写文章,然后再进行发布,WLW 中直接编辑 html 代码当然是没问题的,但在“所见即所得”的编辑器中使用起来就很不爽了(你会看到文章中插入了一陀很难看的东西),如果公式的数量非常多的话,修改和编辑都不舒服,并且,评论栏要添加数学公式也不方便。要是能像 ASCIIMathML.js 那样多好啊。顺着这个想法,结合那篇文章中的作者也提到的“不过通过研究那个js可以再简化一点,直接使用端口 "http://www.mathtran.org/cgi-bin/mathtran?tex="+encodeURIComponent(expr),省去查错的环节。”于是我照虎画猫,抄了 ASCIIMathML.js 的一些代码,自己写了一点 JS 脚本,让这个脚本寻找正文和评论中两个反单引号之间的内容,自动生成 img 标签,这样,我在 WLW 中写东西时候就可以直接在编辑窗口写公式,发布后自然会被转成图片来显示,下面是这个 JS 的脚本的代码(12月1日更新):

    // 将letax公式的文字生成一个img标签
    function GenerateMathImg(formula) {
        var mi =document.createElement("img");    
        mi.src = "http://www.mathtran.org/cgi-bin/mathtran?tex=" 
            + encodeURIComponent(formula);
        mi.alt = formula;
        return mi;
    }
    
    function ProcessFormula(str, newFrag) {
        while (1) {
        // 将含有公式的文字块变换成= 文字块+公式img+文字块
            var re = str.match(/([^\`]*)\`(.*?)\`(.*)/);  
            if (re != null) {
                newFrag.appendChild(document.createTextNode(re[1]));
                newFrag.appendChild(GenerateMathImg(
                    re[2].replace(/^\s+|\s+$/, '')));
                str = re[3];
            }
            else {
                newFrag.appendChild(document.createTextNode(str));
                break;
            }
        }
    }
    
    function processTextNode() {
        var nodeText = this.nodeValue;   
        if (nodeText.indexOf('`') != -1) {
            var strAry = nodeText.split("\\`");
            var newHtmlFrag = document.createDocumentFragment();
            for (var i = 0; i < strAry.length; ++i) {
                if (i > 0) {
                    newHtmlFrag.appendChild(document.createTextNode("`"));
                }
                ProcessFormula(strAry[i], newHtmlFrag);            
            }
            this.parentNode.replaceChild(newHtmlFrag, this);  
        }   
        
    }
    
    function StartConvert() {
        var bConv = ($(document.body).html().indexOf('`') != -1);
        if (bConv) {
        // 找出页面上所有的text-node,对每个text-node调用processTextNode
        var allText = $(document.body).find("*").
            contents().filter(function(){
                return (this.nodeType == 3);
            }).each(processTextNode); 
        }
    }
    
    $(StartConvert)
    
    

    不过现在这个脚本确实很简陋,也不知道有多少 bug,呵,先试着用着吧,等出了 bug 或是新需求再进一步调整。至少单行的公式显示应该是没有问题的,比如:

    `f(x) = a_0 + \sum_{n=1}^\infty\left[a_n\cos(nx)+b_n\sin(nx)\right]`

    傅立叶级数展开式,嘿嘿,:P。感觉还是不错的。嗯,美中不足的是博客模板的背景与公式图片的背景不一致,另外,如果把页面保存在本地,而又在查看的时候又不在连网状态的话,那就显示不了了(不过把脚本的代码删掉,会直接显示数学公式的,勉强可以接受吧……)。

    记记别的。

    编译原理的学习进展不大,上周又把词法分析复习了一遍,看语法分析的时候第一遍愣是没把上下文无关方法和 BNF 理解清楚,应该说是一头雾水,唉,真羡慕那些天才们,随手就写一个语言的编译器出来,仰望……,仰望完之后,下周继续看,读书百遍,其意自见嘛,我就不信我搞不明白它。

    不过词法分析倒是理解得比较清楚了(毕竟这部分不太复杂嘛),哈哈,现在至少知道,如果要对 C/C++ 代码里的注释做些处理,用自动状态机的话其实也是很简单的。想以前用正则表达式来处理代码文件,处理的过程总是会出一些“意外”,毕竟正则表达式不懂“ C/C++ 语法”……表达能力也有限制。嗯,编译原理,继续学习,什么时候我也出个语言来玩玩,嘿嘿。

     

     

  • 相关阅读:
    BZOJ 1049: [HAOI2006]数字序列
    BZOJ 1048: [HAOI2007]分割矩阵
    BZOJ 1047: [HAOI2007]理想的正方形
    BZOJ 1046: [HAOI2007]上升序列
    BZOJ 1045: [HAOI2008] 糖果传递
    Flink学习(十三) Flink 常见核心概念分析
    Flink学习(十二) Sink到JDBC(可扩展到任何关系型数据库)
    Flink学习(十一) Sink到Elasticsearch
    Flink学习(十) Sink到Redis
    Flink学习(九) Sink到Kafka
  • 原文地址:https://www.cnblogs.com/muxue/p/1612732.html
Copyright © 2020-2023  润新知