LMLPHP后院

LMLJS之代码高亮插件highlight发布新闻

maybe yes 发表于 2016-02-15 22:14

很久之前就想写一个代码高亮的插件,要求非常短小精悍,让本站的代码看起来舒服些漂亮些。市面上的代码高亮 JS 动不动就是将近 1M 的代码量看起来实在可怕,并且配置超级麻烦,要求指定语言,感觉就是很难用。于是就动手写了一个前端代码高亮插件,用起来还过的去,也发现有一些小的地方可以继续优化,但是现在已经没有时间用在这方面了,以后再优化吧。下面分享本次高亮代码 JS 开发过程中遇到的问题。

我对代码高亮的要求比较简单,首选一定是有行号,并且自动换行,每一行代码对应的行号的高度和代码高度一致,然后让代码关键的地方高亮一下,比如括号啊,引号啊。为了达到这个要求,花费了好多时间,最难的就是行号和代码的行对应。这个我研究了下 GITHUB 的做法,发现人家用的是 table,然后关键样式是 white-space: pre-wrap;。但是人家根本不兼容 IE8。如果不兼容 IE8 及以下浏览器,随便闭着眼睛写也很容易就搞定啦,为了兼容 IE6 也是蛮拼的,像前面说的,就是花了好多时间,最后虽然有一点点毛病,但是依然在可以接受的范围之内。

在写的时候,留下了可以配置的部分,颜色对应正则和颜色对应关键词,两种配置的区别在于,第一种是正则;第二种是纯字符串,这样字符串在最终匹配的时候是会进行转义处理的。最后发现第二种意义不大,因为我把 if,else 这样的关键词当做字符串来替换了,这样导致一个单词里面含有它们会出现部分高亮的问题,但是最终结果是对的,所以可以接受。替换的过程中,出现一个问题,我把 ; (分号)以字符串的方式进行了替换高亮处理,最后发现这样做是错的,因为 HTML 的实体会含有分号,如果这样替换处理会毁坏实体,导致显示错乱,所以要替换分号必须使用正则的方式来配置,其实最终的替换用的还是正则,所以 keywords 的配置并没有多大的意思,只需要配置正则 regexp 的项来替换就 OK 了,但是我没有配置多少,因为太多性能会降低。

在正则匹配之前,进行的预处理是引号的处理,双引号和单引号的关系用正则处理大复杂,个人目前还没有能力写出这样的正则表达式,于是老老实实的一个一个字符的遍历来处理,所以当一行同时出现了双引号和单引号时暂时就不做处理了,实在太过于复杂。所有的正则替换使用的核心方式就是否定预查,达到不占用字符的效果,这个也是我之前做 SearchSuggestion 的时候写过的,这样就能保证已经在颜色标签里面的字符不会再次被颜色标签包裹。

最近实在太忙,天天加班。下班路上,一同事言道:当一个人想去做一些事情的时候,发现没有时间,是多么悲哀的事情。这个世界上还有认真做技术的吗?

示例:

<style>
.wbreak {
    white-space: normal;
    white-space: pre-wrap;
    white-space: -moz-pre-wrap;
    white-space: -pre-wrap;
    white-space: -o-pre-wrap;
    word-wrap: break-word;
    word-break: break-all;
}

.code {
    background-color: #fefefe;
    border: 2px solid #ddd;
    color: #222;
    padding: 10px;
    font-family: Monaco,"DejaVu Sans Mono","Courier New",monospace;
    font-size: 13px;
    margin: 10px 0;
    overflow: auto;
    text-indent: 0;
}
</style>


<pre class="code">
function hello_world() {
    echo 'ni hao!';
}
</pre>


<script>
lml.loadJs('<?php echo WEB_PATH.'static/js/lmljs/highlight.js';?>', function(){});
</script>

<script>
window.onload = function(){
	lml.run();
};
</script>

后记:发现有些网站(比如 MDN)对于代码行号的处理,使用的是 list-style-type: decimal; 这种做法也很不错,兼容性也非常好,唯一的缺点就是数字后面有个点。

LMLPHP,可爱滴WEB开发框架

2017-11-24 13:23:29 1511501009 0.005600