先看效果:
1 2 3 |
|
上面的源码被分成了 token 数组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
token 怎么分的呢?
一般来说词法分析就是有限状态自动机(DFA),但是这里实现比较简单,是通过正则匹配的:
js-tokens 这个包暴露出来一个正则,一个函数,正则是用来识别 token 的,其中有很多个分组,而函数里面是对不同的分组下标返回了不同的类型,这样就能完成 token 的识别和分类。
在 @babel/highlight 包里也是这样用的:
(正则来做词法分析有很多限制条件,比如不能处理递归的情况,所以这种方式不是通用的,通用词法分析还是得用状态机 DFA。)
有了分类之后,不同 token 显示不同颜色,建立个 map 就行了。
@babel/highlight 也是这么做的:
我们知道了怎么做语法高亮,使用 chalk 的 api 就可以打印颜色,那控制台打印颜色的原理是什么呢?
如何在控制台打印颜色
控制台打印的是 ASCII 码,并不是所有的编码都对应可见字符,ASCII 码有一部分字符是对应控制字符的,比如 27 是 ESC,就是我们键盘上的 ESC 键,是 escape 的缩写,按下它可以完成一些控制功能,这里我们可以通过打印 ESC 的 ASCII 码来进入控制打印颜色的状态。
格式是这样的:
打印一个 ESC
的 ASCII 码,之后是 [
代表开始,m
代表结束,中间是用 ;
分隔的 n 个控制字符,可以控制很多样式,比如前景色、背景色、加粗、下划线等等。
ESC 的 ASCII 码是 27,有好几种写法:一种是字符表示的 \e
,一种是 16 进制的 \0x1b
(27 对应的 16进制),一种是 8 进制的 \033
,这三种都表示 ESC。
我们来试验一下: 1 表示加粗、36 表示前景色为青色、4 表示下划线,下面三种写法等价:
1 2 3 |
|
我们来试一下:
都打印了正确的样式!
当然,加了样式还要去掉,可以加一个 \e[0m
就可以了(\033[0m
,\0x1b[0m
等价)。
chalk(nodejs 的在终端打印颜色的库)的不同方法就是封装了这些 ASCII 码的颜色控制字符。
上面每行代码被高亮过以后的代码是:
这样也就实现了不同颜色的打印。
总结
至此,我们能实现开头的效果了:支持 code frame 的打印,支持语法高亮,能够打印颜色
本文我们探究了这种效果的实现原理,先从 code frame 是怎么拼接的,然后每一行的代码是怎么做高亮的,之后是高亮具体是怎么打印颜色的。
不管是 code frame 的打印,还是语法高亮或者控制台打印颜色,都是特别常见的功能,希望这篇文章能够帮你彻底掌握这 3 方面的原理。
更多编程相关知识,请访问:编程视频!!
以上就是详解nodejs在控制台打印高亮代码的方法的详细内容,更多文章请关注木庄网络博客!
相关阅读 >>
浅谈nodejs利用node-xlsx模块读取excel数据的方法
更多相关阅读请进入《nodejs》频道 >>

Vue.js 设计与实现 基于Vue.js 3 深入解析Vue.js 设计细节
本书对 Vue.js 3 技术细节的分析非常可靠,对于需要深入理解 Vue.js 3 的用户会有很大的帮助。——尤雨溪,Vue.js作者