我的个人博客:www.moonkite.cn
大家好,我是风筝
要在网页上做代码高亮的话,都要借助 SyntaxHighlighter
、Prism
这样的第三方库。
这个我是深有体会的,之前写 VsCode 插件版的 ChatGPT 这个插件。
以及前些天写的这个网页AI助手的浏览器插件。
这两个不同平台的插件,都有展示 Markdown 格式的需求,并且 Markdown 格式中如果有程序代码的话,需要加高亮显示,一个是原生 JS 写的,一个是 React 写的,在做和 Markdown 结合的代码高亮时是比较大的一块儿功能了,过程中碰到了不少问题。
SyntaxHighlighter
这一类代码高亮的逻辑都是一样的。
首先把你的代码用高亮库提供的方法包裹起来,比如放到一个<pre>
块中,或者用一个指定的 class
修饰,并指定语言, 然后在网页运行之后,高量库会根据不同的语言将代码段转换成一段 html。将每一行甚至每一个单词都拆成一个元素,然后用不同的样式和颜色区分。
如果要用第三方库的话,就要按照其规则进行一通配置,引入 JavaScript、引入CSS,然后调用其方法,错一点儿就没效果。
国外的一哥们儿做了一款字体,直接用字体做代码高亮。也就是说如果你用了这个字体的话,你只需要引入字体,然后在 <pre><code>
标签下贴代码就好了,这里面的代码就会高亮显示。引入 JavaScript、引入CSS、调用方法这些统统都省掉了。
可以在这儿看一下效果:https://codepen.io/argyleink/pen/GRbyNNv
作者是利用OpenType字体技术中的COLR(彩色)表和上下文替代功能来实现内置的语法高亮。这样,字体本身就包含了彩色字符,可以通过CSS来应用。
这个技术有两个关键点:第一,就是说在制作字体的时候就要给每个字做好几套不同颜色的,所谓高亮不就是用不同的颜色来区分吗。在使用的时候简单,但是制作字体的时候倒是有点麻烦,不过英文字母就那么几个,做起来倒也没那么复杂。
另外一个就是使用上下文替代功能,举个例子,字体可以在上下文查找 if
这个单词是,发现 i
后面跟的是 f
,就把i
和f
替换为同样一种颜色的字符。
使用这种方式,你在最终的网页上就不会看到被高亮插件转出来的那一堆 html 元素了,原本是什么样子的就是什么样子,代码会保持原始干净的样子。
但是这种方式有个缺点,就是字体模式匹配能力有限,不如正则表达式灵活,所以有些关键词可能匹配不到。如果是支持正则表达式的话, 那这样直接用字体控制高亮的方式应该就是最优方案了,
还可以看看风筝往期文章
用这个方法,免费、无限期使用 SSL(HTTPS)证书,从此实现证书自由了
古时的风筝,一个程序员,一个写作者。