涛之雨 发表于 2022-11-5 09:55

控制台(包括cmd,node,c,shell,console控制台之类的)特殊输出

本帖最后由 涛之雨 于 2022-11-5 10:08 编辑

## 效果:



> 注:
>
> 1. 图中所使用的分别为:
>
>    最上方为浏览器控制台(chrome)
>   
>    下方田字格按`z`字形分别为c语言控制台, `bat`, `nodejs`, `Ubuntu-shell(wsl)`
>
> 2. 此外理论上支持的包括且不限于`python`, `Perl`, `go`, `java` 等语言。
>
> 3. 图上方控制台除了`ansi`还支持`style`,非本文重点,不多赘述,可以查看【[为控制台定义样式](https://developer.mozilla.org/zh-CN/docs/Web/API/console#为控制台定义样式1)】
>
>    注:上方链接似乎有bug,不会自动跳转到锚点,请点击后手动到在地址栏里删除最后的`1`回车跳转
>   
>    小声逼逼,网上控制台放图片的办法好像都失效了,我在(https://gist.github.com/taozhiyu/9045d392340b7a21814ebe67d99d66e9)写了一个其他方式实现的。。。
>
>   

## 原理:

说白了就是一句话,标准ANSI 转义码(~~[维基](https://en.wikipedia.org/wiki/ANSI_escape_code)~~(不存在的网站))([百度百科](https://baike.baidu.com/item/ANSI%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97))

(即使是不存在的维基百科, 中文的内容也没有英文的多, 下图左为英文(谷歌机译), 右为中文站点)



我之前的帖子:[多人成行(双人成行-存档切换工具)](https://www.52pojie.cn/thread-1702620-1-1.html)也用到过这种输出。

![](https://attach.52pojie.cn/forum/202210/22/215358kjr2xbcxcy7cxvme.png)

当时是手动计算的,现在通过库进行输出。

## 实现代码

核心代码来自:(https://github.com/chalk/ansi-styles)

为了使用方便,给`String`添加了`colorful`函数。

### 源码

源码见:(https://gist.github.com/taozhiyu/cdf0cdbb927b334b28fb96e6ae2b5f3a)

这里贴上使用`uglify`压缩后的版本:((https://gist.github.com/taozhiyu/cdf0cdbb927b334b28fb96e6ae2b5f3a#file-colorful-prototype-min-js))

```js
String.prototype.colorful=function(...e){const r=["color","bgColor"],{styles:o,colorNames:t,modifierNames:n}=function(){const e=10,r=(e=0)=>r=>`\x1b[${r+e}m`,o=(e=0)=>r=>`\x1b[${38+e};5;${r}m`,t=(e=0)=>(r,o,t)=>`\x1b[${38+e};2;${r};${o};${t}m`,n={modifier:{reset:,bold:,dim:,italic:,underline:,overline:,inverse:,hidden:,strikethrough:},color:{black:,red:,green:,yellow:,blue:,magenta:,cyan:,white:,blackBright:,gray:,grey:,redBright:,greenBright:,yellowBright:,blueBright:,magentaBright:,cyanBright:,whiteBright:},bgColor:{bgBlack:,bgRed:,bgGreen:,bgYellow:,bgBlue:,bgMagenta:,bgCyan:,bgWhite:,bgBlackBright:,bgGray:,bgGrey:,bgRedBright:,bgGreenBright:,bgYellowBright:,bgBlueBright:,bgMagentaBright:,bgCyanBright:,bgWhiteBright:}},i=Object.keys(n.modifier),l=[...Object.keys(n.color),...Object.keys(n.bgColor)];return{styles:function(){const i=new Map;for(constof Object.entries(n)){for(constof Object.entries(r))n={open:`\x1b[${o}m`,close:`\x1b[${o}m`},r=n,i.set(o,o);Object.defineProperty(n,e,{value:r,enumerable:!1})}return Object.defineProperty(n,"codes",{value:i,enumerable:!1}),n.color.close="\x1b{6}|{3}/i.exec(e.toString(16));if(!r)return;let=r;3===o.length&&(o=[...o].map(e=>e+e).join(""));const t=Number.parseInt(o,16);return},enumerable:!1},hexToAnsi256:{value:e=>n.rgbToAnsi256(...n.hexToRgb(e)),enumerable:!1},ansi256ToAnsi:{value:e=>{if(e<8)return 30+e;if(e<16)return e-8+90;let r,o,t;if(e>=232)o=r=(10*(e-232)+8)/255,t=r;else{const n=(e-=16)%36;r=Math.floor(e/36)/5,o=Math.floor(n/6)/5,t=n%6/5}const n=2*Math.max(r,o,t);if(0===n)return 30;let i=30+(Math.round(t)<<2|Math.round(o)<<1|Math.round(r));return 2===n&&(i+=60),i},enumerable:!1},rgbToAnsi:{value:(e,r,o)=>n.ansi256ToAnsi(n.rgbToAnsi256(e,r,o)),enumerable:!1},hexToAnsi:{value:e=>n.ansi256ToAnsi(n.hexToAnsi256(e)),enumerable:!1}}),n}(),colorNames:l,modifierNames:i}}();if(e.find(e=>""!==Object.prototype.toString.call(e)))throw new Error("Invalid color");let i=this;return e.forEach((e,l)=>{[...t,...n].includes(e)?i=o.open+i+o.close:e.startsWith("#")&&(i=o].ansi(o.hexToAnsi(e))+i+o].close)}),i};
```

### 使用

`'字符串'.colorful(参数1, 参数2, ...)`

其中,参数支持

1. `#`开头的16进制RGB字符串
2. 下方列出的关键词

其中,允许RGB字符串和关键词允许混编,但是由于代码中的[骚操作](https://gist.github.com/taozhiyu/cdf0cdbb927b334b28fb96e6ae2b5f3a#file-colorful-prototype-js-L249-L261)

16进制输入时,只有作为第一个参数才作为前景色,否则均作为背景色处理(没错,特性)

因此`.colorful('bold','#123456','abcdef')`的最后一个参数是无意义的,

等价于`.colorful('bold','#123456')`,不过可以`.colorful('bold','#123456','redBright')`,其中`redBright`作为前景色

### 演示

```js
String.prototype.colorful=function(){xxxxxx(上面的一堆)xxxxxx}
console.log([...'吾爱破解论坛官网是&#120142;&#120168;&#120142;.&#120797;&#120794;ℙ&#120160;&#120129;&#120154;&#120150;.ℂ&#120159;\n'.repeat(40)].map(a=>a.colorful("#"+Math.random().toString(16).slice(2,8),"#"+Math.random().toString(16).slice(2,8))).join(""))
```

会生成`40行`强烈精神污染的随机颜色文本。。。就不放截图了=_=自己脑补吧

可以通过控制台执行`copy("这里是要复制的文本")`复制到剪贴板到外面使用(注:存在控制字符`\x1b`,有些编辑器可以显示,但是有些编辑器会显示`□`,请确保使用支持显示不可见控制字符的编辑器)



## 支持参数

### RGB(hex)

`#`开头的6位16进制颜色

非要说就是符合下方正则表达式的字符串

```js
/#[\da-f]{6}/
```

### 关键词

|                           特殊                           |               文本颜色               |                  背景颜色                  |
| :----------------------------------------------------------: | :----------------------------------: | :----------------------------------------: |
|                           `reset`                            |               `black`                |               `bgBlack`                  |
|                            `bold`                            |                `red`               |                  `bgRed`                   |
|                            `dim`                           |               `green`                |               `bgGreen`                  |
|               `italic` *(未得到广泛支持)*                  |               `yellow`               |               `bgYellow`               |
|                         `underline`                        |                `blue`                |                  `bgBlue`                  |
| `overline` *在基于VTE的终端、GNOME终端、mintty和Git Bash上支持。* |            `magenta`               |                `bgMagenta`               |
|                        `inverse`                           |                `cyan`                |                  `bgCyan`                  |
|                           `hidden`                           |               `white`                |               `bgWhite`                  |
|            `strikethrough` *(未得到广泛支持)*            | `blackBright` (别名: `gray`, `grey`) | `bgBlackBright` (别名: `bgGray`, `bgGrey`) |
|                                                            |             `redBright`            |               `bgRedBright`                |
|                                                            |            `greenBright`             |            `bgGreenBright`               |
|                                                            |            `yellowBright`            |            `bgYellowBright`            |
|                                                            |             `blueBright`             |               `bgBlueBright`               |
|                                                            |         `magentaBright`            |             `bgMagentaBright`            |
|                                                            |             `cyanBright`             |               `bgCyanBright`               |
|                                                            |            `whiteBright`             |            `bgWhiteBright`               |

好像也没什么意思。。。做个记录。。。

涛之雨 发表于 2022-11-5 17:50

luliucheng 发表于 2022-11-5 14:23
曾经我的oh-my-cmd关键部分就是特殊颜色输出,我自己还整理了一份完整点的bat:https://pan.baidu.com/s/1a ...

对的,原理都是一样的,不过连console控制台都支持我是没想到的。。。(虽然使用%c进行格式化输出更香。。。)

luliucheng 发表于 2022-11-5 14:23

本帖最后由 luliucheng 于 2022-11-5 14:25 编辑

曾经我的oh-my-cmd关键部分就是特殊颜色输出,我自己还整理了一份完整点的bat:https://pan.baidu.com/s/1aYfK_yDqa8ahFVv85p8dgA?pwd=52pj (网盘里直接看是乱码,因为bat使用ANSI编码而浏览器使用UTF-8编码,下载运行就没问题了)

rhci 发表于 2022-11-5 10:34

虽然不知道有啥用,但还是大为震撼。

冥界3大法王 发表于 2022-11-5 10:35

进来看看国际友人。{:301_986:}

正己 发表于 2022-11-5 10:46

看不懂,但是我大受震撼{:301_997:}

modesty88 发表于 2022-11-5 10:51

似懂非懂{:301_1009:}

vip1639253946 发表于 2022-11-5 11:46

这个还真没看明白

cowmaxs 发表于 2022-11-5 17:42

看着有点屌啊,,, 似懂非懂{:1_907:}

ljili2003 发表于 2022-11-5 22:22

看似大为震撼,实则一脸懵逼

页: [1] 2
查看完整版本: 控制台(包括cmd,node,c,shell,console控制台之类的)特殊输出