Javascript 如何计算各种字符的终端列宽?

Javascript 如何计算各种字符的终端列宽?,javascript,node.js,bash,terminal,ascii,Javascript,Node.js,Bash,Terminal,Ascii,我希望计算终端视图中各种打印和非打印ascii/unicode字符将占用的终端列数 例如,水平选项卡(\t)占用8列,颜色代码(即\x1b32m)占用0列,以及固定大小的宽字符串(即。한) 可能占用2列。当然,在主要ASCII集合中,有许多只占用1列(即a-Z/0-9、标点符号等) 我遇到了node.js模块,它似乎有助于计算宽字符串,但没有达到我对其他字符(如颜色代码和选项卡)的预期 例如: var wcwidth = require('wcwidth'); console.log("TAB

我希望计算终端视图中各种打印和非打印ascii/unicode字符将占用的终端列数

例如,水平选项卡(
\t
)占用8列,颜色代码(即
\x1b32m
)占用0列,以及固定大小的宽字符串(即。한) 可能占用2列。当然,在主要ASCII集合中,有许多只占用1列(即
a-Z/0-9
、标点符号等)

我遇到了node.js模块,它似乎有助于计算宽字符串,但没有达到我对其他字符(如颜色代码和选项卡)的预期

例如:

var wcwidth = require('wcwidth');

console.log("TAB WIDTH", wcwidth('\t'));
console.log("한 WIDTH", wcwidth('한'));
console.log("Color Code WIDTH", wcwidth('\x1b32m'));
console.log("X WIDTH", wcwidth('X'));
产出:

TAB WIDTH 0
한 WIDTH 2
Color Code WIDTH 3
X WIDTH 1
我似乎在任何地方都找不到关于这个问题的任何信息,尽管我认为这在古代是人们必须解决的常见问题

如果有一种方法可以使用bash脚本,或者任何库、应用程序或工具,我也完全愿意这样做

非常感谢您的帮助!:)
感谢

对于任何需要知道光标在屏幕上的位置的程序来说,这确实是一个问题,从ls中的表格输出到可编辑的命令行,再到全屏应用程序。正如您所注意到的,wcwidth或wcswidth并不能解决这个问题,它们仅为(字符串)可打印字符定义。此外,控制序列不仅可以改变颜色,还可以改变光标的位置,甚至在支持的情况下,还可以改变字体大小的效果

相反,有时会使用诸如[]之类的终端控制库。它们似乎也不会告诉您字符串的宽度,但因为它们分别跟踪文本属性(如颜色),并自行生成控制序列来定位和设置文本样式,所以它们在将内容放在给定位置的屏幕上时提供了一些帮助

不幸的是,我认为除此之外没有太多可用的应用程序,应用程序要么忽略复杂性,要么以特殊方式处理复杂性


为了澄清一个常见的误解:水平标签(HT,
\t
)本身没有宽度;它是一个“格式效应器”,就像回车符或换页符一样,根据特定规则重新定位光标

HT(水平制表):一种格式效应器,用于控制 在一系列操作中,将打印位置移动到下一个位置 沿着印刷线的预定位置。(也适用于 显示设备和穿孔卡上的跳过功能。)

-1968年美国信息交换标准代码[ASCII],重印于

最常见的实现是每八列有固定的制表位:

                                1       2
                1.......9.......7.......5.....

1\tXYZ          1       XYZ
12\tXYZ         12      XYZ
1234567\tXYZ    1234567 XYZ
12345678\tXYZ   12345678        XYZ
123456789\tXYZ  123456789       XYZ

尽管有些系统支持控制序列或其他方式来设置制表位在任意距离的位置,如某些文字处理器中的标尺栏。

对于任何需要知道光标在屏幕上的位置的程序来说,这确实是一个问题,从
ls
中的表格输出,通过可编辑的命令行到全屏应用程序。正如您所注意到的,wcwidth或wcswidth并不能解决这个问题,它们仅为(字符串)可打印字符定义。此外,控制序列不仅可以改变颜色,还可以改变光标的位置,甚至在支持的情况下,还可以改变字体大小的效果

相反,有时会使用诸如[]之类的终端控制库。它们似乎也不会告诉您字符串的宽度,但因为它们分别跟踪文本属性(如颜色),并自行生成控制序列来定位和设置文本样式,所以它们在将内容放在给定位置的屏幕上时提供了一些帮助

不幸的是,我认为除此之外没有太多可用的应用程序,应用程序要么忽略复杂性,要么以特殊方式处理复杂性


为了澄清一个常见的误解:水平标签(HT,
\t
)本身没有宽度;它是一个“格式效应器”,就像回车符或换页符一样,根据特定规则重新定位光标

HT(水平制表):一种格式效应器,用于控制 在一系列操作中,将打印位置移动到下一个位置 沿着印刷线的预定位置。(也适用于 显示设备和穿孔卡上的跳过功能。)

-1968年美国信息交换标准代码[ASCII],重印于

最常见的实现是每八列有固定的制表位:

                                1       2
                1.......9.......7.......5.....

1\tXYZ          1       XYZ
12\tXYZ         12      XYZ
1234567\tXYZ    1234567 XYZ
12345678\tXYZ   12345678        XYZ
123456789\tXYZ  123456789       XYZ

尽管有些系统支持控制序列或其他方式来设置制表位在任意距离的位置,如某些文字处理器中的标尺栏。

制表符不占用8列。它输出一个空格,然后输出足够的空格,以确保下一个字符将在索引为0 mod 8(或者如果从1开始计数,则为1 mod 8)的下一列中输出。换句话说,除非您知道行上的位置,否则无法判断制表符的宽度

颜色代码(
\x1b[32m
)可能占用零空间,但也可能不占用;这取决于控制台的终端仿真器的性质。大多数终端仿真器将识别
CSI[Pm
代码,但还有其他代码更为特殊。例如

printf $'\x1b]2;A window\x1b\\'
将在
xterm
中设置窗口标题,因此不会产生任何输出。但在Linux控制台中,将显示文本
;窗口
,占9个字符


简言之,这不是一个容易的问题,你只能在大量的上下文中回答,因为没有绝对的答案。

一个选项卡不占用8列。它输出一个空格,然后输出足够的空格,以确保下一个字符将在索引为0 mod 8(或1 mod 8,如果从1开始计数)的下一列中输出换句话说,除非您知道自己在线路上的位置,否则无法知道选项卡的宽度