前沿拓展:
命令行选项语法错误
命令行的意思是按住winkey+R键,弹出的运行中输入CMD,确定后跳出一个黑色窗口,这就是命令行。
命令行里有许多命令,有的是系统自带,有的是下载的。你可以输入命令/?查看如何用这个命令。
比如输入 del/?,就会出现del这个命令的用法。
命令行选项语法错误,就是命令用错了。弹出来关掉就好了。
本文,将实现命令行输出带有语法高亮、带行号的JS代码。
效果如下图所示:
对于JS程序员而言,这个效果是有些惊喜的。
而实现起来,却似乎是出乎意料的简单。
直接上源码:
var js_code = `
function get_copyright(){
var domain = "jshaman.com";
var from_year = 2017;
var copyright = "(c)" + from_year + "-" + (new Date).getFullYear() + "," + domain;
return copyright;
}
console.log(get_copyright());
`;
//高亮显示代码
const { codeFrameColumns } = require('@babel/code-frame');
const res = codeFrameColumns(js_code, {}, {
highlightCode: true,
});
console.log(res);
由代码可见,仅仅是使用@babel/code-frame这个NodeJS模块即可直接实现高亮语法。
本着“知其然,知其所以然”的理念,我们再深入探究一下实现语法高亮的原理。
第一,是进行语法分析,从JS代码分离出不同的关键字。
在这一步,可以使用babel的parser获得代码的AST(抽象语法树),再遍历AST进行分析取词。
例如获得变量名、函数名的方式如下:
var parser = require('@babel/parser');
var traverse = require('@babel/traverse').default;
//获得抽象语法树
var ast = parser.parse(js_code);
//遍历语法树
traverse(ast, traverse(ast,{
//函数
"FunctionDeclaration"(path){
var fun_name = path.node.id.name;
console.log("函数名:",fun_name);
},
//变量
"VariableDeclaration"(path){
var var_name = path.node.declarations[0].id.name;
console.log("变量名:",var_name);
},
}));
console.log(js_code)
注:语法分析也有其它办法,比如用正则等。
接着上面的思路,当获得变量名、函数名之后,接下来即可对其进行着色。
写着色功能之前,先来看行代码:
console.log('u001b[31m JShaman专注于JS代码混淆加密 u001b[0m');
它会输出带颜色的信息,如下图:
为什么看似有些乱码的console执行时会出现彩色的文字呢?
解释是这样的:
The original specification only had 8 colors, and just gave them names. The SGR parameters 30-37 selected the foreground color, while 40-47 selected the background. Quite a few terminals implemented "bold" (SGR code 1) as a brighter color rather than a different font, thus providing 8 additional foreground colors. Usually you could not get these as background colors, though sometimes inverse video (SGR code 7) would allow that. Examples: to get black letters on white background use ESC[30;47m, to get red use ESC[31m, to get bright red use ESC[31;1m. To reset colors to their defaults, use ESC[39;49m (not supported on some terminals), or reset all attributes with ESC[0m.
大意是:“u001b”是一个特殊的转意字符,遵从一定的规则,可以用来设置文字或背景颜色。
上面代码中,前面的u001b[31m用于设定SGR颜色,后面的u001b[0m相当于一个封闭标签作为前面SGR颜色的作用范围的结束点标记。
有了这个知识储备后,我们就可以继续前面的工作。
当从JS代码中进行分词之后,将代码用此方法进行改造,即可使语法高亮。
运行效果:
至此,便已得知了命令行语法高亮的全部秘密。
最后,奉上本示例完整源码:
var js_code = `
function demo(){
var domain = "jshaman.com";
var from_year = 2017;
var copyright = "(c)" + from_year + "-" + (new Date).getFullYear() + "," + domain;
return copyright;
}
console.log(demo());
`;
//高亮显示代码
const { codeFrameColumns } = require('@babel/code-frame');
const res = codeFrameColumns(js_code, {}, {
highlightCode: true,
});
console.log(res);
var parser = require('@babel/parser');
var traverse = require('@babel/traverse').default;
//获得抽象语法树
var ast = parser.parse(js_code);
//遍历语法树
traverse(ast, traverse(ast,{
//函数
"FunctionDeclaration"(path){
var fun_name = path.node.id.name;
console.log("函数名:",fun_name);
js_code = js_code.replace(fun_name,"u001b[32m" + fun_name + "u001b[0m");
},
//变量
"VariableDeclaration"(path){
var var_name = path.node.declarations[0].id.name;
console.log("变量名:",var_name);
js_code = js_code.replace(var_name,"u001b[31m" + var_name + "u001b[0m");
},
}));
console.log(js_code)
JavaScript奇淫技巧:按键精灵
JavaScript奇淫技巧:收缩控制流
JavaScript奇淫技巧:变速齿轮
JavaScript奇淫技巧:隐写术
JavaScript奇淫技巧:压缩并加密图片
JavaScript奇淫技巧:用try、catch实现JS代码加密解密
拓展知识:
命令行选项语法错误
安装时可能会遇到其他软件占用某个安装可能会修改或占用的程序而造成的,或者是杀毒软件或防火墙所造成的,你只要试着在安装时关闭其他程序再安装一遍应该就可以了。
原创文章,作者:九贤生活小编,如若转载,请注明出处:http://www.wangguangwei.com/22101.html