ITPub博客

首页 > IT职业 > IT生活 > dp.SyntaxHighlighter代码分析

dp.SyntaxHighlighter代码分析

IT生活 作者:smanzheng 时间:2021-09-09 09:41:57 0 删除 编辑


文章截图 - 更好的排版
源代码下载

dp.SyntaxHighlighter代码分析


dp.SyntaxHighlighter作为一个最常用的JavaScript代码高亮工具受到广泛的欢迎。
那么你有没有想知道它的内部实现机制是什么,本文在对其分析后,抽取核心代码以重现其功能。
注:本文中的代码高亮使用的就是手工打造的dp.SyntaxHighlighter的简化版。

核心思想
1. 首先定义了一系列的正则表达式用来匹配所有的高亮代码,包括关键字、单行注释、多行注释、字符串, 如果你仔细观察高亮后的JavaScript代码,你会发现也只有这些代码被高亮显示了,是不是很简单。

var keywords = 'abstract boolean break byte case catch char class const continue debugger ' + 'default delete do double else enum export extends false final finally float ' + 'for function goto if implements import in instanceof int interface long native ' + 'new null package private protected public return short static super switch ' + 'synchronized this throw throws transient true try typeof var void volatile while with';var regexList = [{ regex: new RegExp('/\*[\s\S]*?\*/', 'gm'), css: 'comment' },{ regex: new RegExp('//.*$', 'gm'), css: 'comment' },{ regex: new RegExp('"(?:\.|(\\\")|[^\""\n])*"', 'g'), css: 'string' },{ regex: new RegExp("'(?:\.|(\\\')|[^\''\n])*'", 'g'), css: 'string' },{ regex: new RegExp(getKeywords(keywords), 'gm'), css: 'keyword'}];function getKeywords(str) {    return '\b' + str.replace(/ /g, '\b|\b') + '\b';}



2. 接下来我们需要通过JavaScript中的正则匹配来找到所有的匹配项。

for (var i = 0; i 



3. 然后对匹配项进行排序(按照其在原始代码中的顺序)

function sortCallback(m1, m2) {    if (m1.index  m2.index)        return 1;    else {        return 0;    }}matchs = matchs.sort(sortCallback);



4. 最后拿着这些排好顺序的匹配项,和原始代码进行整合就好了。


注意事项

在拿到排序后的匹配项列表后,还不能和原始代码整合,因为其中有重复项,比如:

    var keywords = 'abstract boolean break';

会找到如下匹配项:var,'abstract boolean break',abstract,boolean,break这五个匹配项,其中一个字符串,四个关键词。
对于这样的情况,我们还必须起初重复的匹配项。

function isInlcude(matchs, index) {    var match = matchs[index];    for (var i = index - 1; i >= 0; i--) {        if (matchs[i]) {            if (match.index > matchs[i].index && match.index 




修改后的源代码

这里只处理JavaScript的情况,对于其他语言的代码,只需要定义不同的正则匹配表达式就行了。

function hightLight(source) {    var keywords = 'abstract boolean break byte case catch char class const continue debugger ' +  'default delete do double else enum export extends false final finally float ' +  'for function goto if implements import in instanceof int interface long native ' +  'new null package private protected public return short static super switch ' +  'synchronized this throw throws transient true try typeof var void volatile while with';    var regexList = [{ regex: new RegExp('/\*[\s\S]*?\*/', 'gm'), css: 'comment' },    { regex: new RegExp('//.*$', 'gm'), css: 'comment' },    { regex: new RegExp('"(?:\.|(\\\")|[^\""\n])*"', 'g'), css: 'string' },    { regex: new RegExp("'(?:\.|(\\\')|[^\''\n])*'", 'g'), css: 'string' },    { regex: new RegExp(getKeywords(keywords), 'gm'), css: 'keyword'}];    var matchs = [], result = [];    function getKeywords(str) {        return '\b' + str.replace(/ /g, '\b|\b') + '\b';    }    function sortCallback(m1, m2) {        if (m1.index  m2.index)            return 1;        else {            return 0;        }    }    function isInlcude(matchs, index) {        var match = matchs[index];        for (var i = index - 1; i >= 0; i--) {            if (matchs[i]) {                if (match.index > matchs[i].index && match.index  i) {                    result.push('' + convertSpace(source.substr(i, match.index - i)) + '');                }                result.push('' + convertSpace(match.value) + '');                i = match.index + match.length;            }        }        if (i != source.length - 1) {            result.push(convertSpace(source.substr(i)));        }    }    var resultLines = result.join("").split("n");    var out = [], alt = false;    out.push('
    ');    for (var i = 0; i ' : '
  1. ');        out.push('');        out.push(resultLines[i] === "" ? " " : resultLines[i]);        out.push('');        out.push('
  2. ');        alt = !alt;    }    out.push('
');    return out.join("");}$(function() {    $("pre.js").each(function() {        var $this = $(this);        $this.hide().after(hightLight($this.html()));    });});



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4759/viewspace-2806207/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: String 的常用操作
请登录后发表评论 登录
全部评论

注册时间:2019-04-25

  • 博文量
    115
  • 访问量
    1241