在控制台中显示带有删除线效果的文本是否可能?

12

我已经查看了 ANSI 转义码,但似乎只支持下划线。

我有什么遗漏吗?还有其他选项吗?

如果不可能的话,是否有类似“此已弃用”的含义等效的选项?

6个回答

16
根据终端的ECMA-48标准,SGR(选择图形呈现)代码编号9应该启用删除线文本。然而,ANSI转义码维基百科页面表示它并不广泛支持,并且我不知道有任何一个支持它。我猜测这是因为DEC的VTxxx系列不支持它

3
我的libvterm/pangoterm可以很好地完成它。请参见链接中的第二张截图。 - LeoNerd
6
实际上,许多主要的Shell终端都支持它(包括“guake”,“terminator”,“gnome-terminal”等)。http://misc.flogisoft.com/bash/tip_colors_and_formatting#terminals_compatibility。快速测试:``echo -e "\e[9mtest\e[0m"``。 - vaab
Kitty支持SGR代码9来实现删除线文本(以及其他一些不常用的模式)。大多数常见的Linux终端使用libvterm,因此在Linux上,这种模式得到了广泛支持。然而,Putty不支持它。 - NoelProf
我发现在Windows上,Windows终端支持它,而VS Code的终端仿真器也支持它。PowerShell和CMD无法在没有终端仿真器的情况下执行转义代码,因此似乎非常兼容。 - KetZoomer

6

对于使用C11或C++11编写的应用程序,一种替代方案是使用Unicode 组合长划线覆盖 字符。

在C++11中,您可以编写类似以下代码:

#include <iostream>
#include <string>

std::string strikethrough(const std::string& text) {
  std::string result;
  for (auto ch : text) {
    result.append(u8"\u0336");
    result.push_back(ch);
  }
  return result;
}

int main() {
  std::cout << strikethrough("strikethrough") << std::endl;
}

代码会在输入的文本text中的每个字符前添加笔画叠加符\u0336。请注意,该函数假设text编码为单字节编码,如ASCII或Latin。如果输入为UTF-8,则必须首先转换为UTF-32以获取字符边界。
输出结果是一个带有删除线的s̶t̶r̶i̶k̶e̶t̶h̶r̶o̶u̶g̶h,在支持UTF-8的终端上显示。我不知道为什么第一个字符没有被划掉,可能是终端问题。我可以通过在调用删除线函数之前打印至少一个字符来解决这个问题。
Unicode解决方案在我的终端(terminator)中生成与上面提到的ANSI转义序列略有不同的锁定效果。前者将行正好呈现在文本中间,而后者则稍微低于中间位置。

1
如果您在每个字符之后添加\u0336,而不是之前,有时会产生“拉直”字符的效果,并且应该划掉每个字符。 - jonschlinkert

4

这个对我有效。

$ echo -e `echo "这是一段删除线文本" | sed 's/.\{1\}/&\\\u0336/g'`


2

使用SGR(9)进行划掉

功能 序列
开始打击文字 Esc [ 9 m
停止打击文字 Esc [ 2 9 m
返回正常文字 Esc [ m

您可以使用选择图形修饰符(SGR)序列来进行划掉文本。SGR允许您指定一个数字来启用或禁用“方面”,例如粗体、斜体和下划线。参数9可以启用“划掉”的方面。

如果您希望停止划掉文本但不影响其他活动方面,例如粗体或斜体,请使用SGR(29)。然而,更常见的是程序使用参数0,通常通过省略数字来将所有样式重置为默认值(普通文本)。

示例用法

printf "\e[9m"
printf "Casey"
printf "\e[m\n"

这里是XTerm的屏幕截图。

Screenshot of terminal using SGR aspect 9 to strikeout text

这就是你需要了解的使用它的全部。如果你想更详细地了解,可以继续阅读。


完整说明

回想过去,每种计算机终端型号都有自己独特的“转义序列”来控制它。ECMA-48[^1] 是一个尝试制定跨平台标准的努力。1994年版的ECMA-48首次包含了“划掉”的方面。然而,即使在24年后的2008年,Thomas Dickey - terminfo和xterm的维护者,因此是该主题上最有知识的人之一 - 声明他从未见过支持它的终端。幸运的是,自那时以来,软件终端仿真已经提高到了可以广泛使用ECMA-48提出的许多其他想法,“划掉”和其他想法。

其他文本方面

其他文本方面可以同时使用或取代划掉方面。以下是现代终端最有可能支持的方面。[^2]

    SGR(Ps) ⇐ Esc [ Ps m

    Ps 方面 Ps 方面
    0 正常(默认)
    1 加粗 21 双下划线
    2 微弱(虚淡,低强度) 22 正常(既不加粗也不虚淡)
    3 斜体 23 不是斜体
    4 下划线 24 没有下划线
    5 闪烁 25 持续(不闪烁)
    7 反相显示 27 正常(不反相)
    8 隐形,即隐藏 28 可见,即不隐藏
    9 被划掉的字符 29 没有被划掉

    关于所有可能的文本方面的完整列表,包括Fraktur和慢闪等奇怪的内容,请参见ECMA-48标准的第8.3.117节:SGR - 选择图形呈现

    已知可用的终端

    ncurses terminfo数据库跟踪哪些终端支持哪些功能。以下是已知支持“ecma+strikeout”[^3]的终端列表:

      alacritty foot hterm kitty konsole mintty mlterm
      ms-terminal screen st terminology tmux vte xterm

    请注意,一些终端项目不会及时更新其terminfo条目。例如,Gnome终端没有列出,但实际上它可以工作,因为它基于vte。




    [^1]: "ECMA-48"通常被称为"ANSI转义序列"。这两个术语都是正确的,因为ECMA-48和ANSI X3.64几乎相同,并随后合并为ISO 6429。然而,ANSI和ISO要收取费用才能查看其标准,因此我使用免费的ECMA出版物。

    [^2]: 实际上,这是XTerm支持的序列列表(截至2023年),记录在Thomas Dickey的Control Sequences for XTerm中的CSI函数m部分,参见pdfhtml。没有完美的最常支持的序列列表,但XTerm被广泛模仿,许多其他终端试图“兼容xterm”。

    [^3] 截至ncurses 6.4-dev 2023,通过$ toe -u terminfo.src | grep strike | cut -d: -f1 | sort | column

    Ps 方面 Ps 方面
    30 将前景色设置为黑色 40 将背景色设置为黑色
    31 将前景色设置为红色 41 将背景色设置为红色
    32 将前景色设置为绿色 42 将背景色设置为绿色
    33 将前景色设置为黄色 43 将背景色设置为黄色
    34 将前景色设置为蓝色 44 将背景色设置为蓝色
    35 将前景色设置为品红色 45 将背景色设置为品红色
    36 将前景色设置为青色 46 将背景色设置为青色
    37 将前景色设置为白色 47 将背景色设置为白色

0

找不到比这更简单的了:

$ echo -e "\e[9myour text goes here\e"

0
是的,就像这样:
console.log("\x1b[9m" + "STRIKE THROUGH" + "\x1b[29m" + " NOT STRIKE THROUGH");

// OR
const text = "STRIKE THROUGH";
console.log(`\x1b[9m${text}\x1b[29m`);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接