#终端 #ANSI #ANSI 代码 #terminfo #颜色

color-print

使用类似 HTML 的语法在编译时为终端着色和添加样式

6 个版本

0.3.6 2024年4月23日
0.3.5 2023年9月3日
0.3.4 2022年10月13日
0.3.2 2021年8月29日
0.1.0 2021年8月25日

#20 in 命令行界面

Download history 57876/week @ 2024-05-03 59154/week @ 2024-05-10 52710/week @ 2024-05-17 61279/week @ 2024-05-24 57208/week @ 2024-05-31 54018/week @ 2024-06-07 54002/week @ 2024-06-14 58437/week @ 2024-06-21 51247/week @ 2024-06-28 54806/week @ 2024-07-05 61664/week @ 2024-07-12 63027/week @ 2024-07-19 62173/week @ 2024-07-26 57226/week @ 2024-08-02 72017/week @ 2024-08-09 58085/week @ 2024-08-16

每月下载量 259,660
100 包中使用 (57 个直接使用)

MIT/Apache

46KB
418

color-print

使用类似 HTML 的语法在编译时为终端着色和添加样式。

此库提供了以下宏

  • cformat!(<FORMAT_STRING> [, ARGS...])
  • cprint!(<FORMAT_STRING> [, ARGS...])
  • cprintln!(<FORMAT_STRING> [, ARGS...])
  • cstr!(<FORMAT_STRING>)
  • untagged!(<FORMAT_STRING>)

cformat!(), cprint!()cprintln!() 的语法与 format!(), print!()println!() 分别相同,但它们在格式字符串中接受额外的语法:编译时添加 ANSI 颜色/样式的类似 HTML 的标签。

cstr!() 只将给定的字符串字面量转换成另一个字符串字面量,而不格式化任何其他颜色标签。

untagged!() 从给定的字符串字面量中移除所有标签。

它做什么?

默认情况下,提供的宏将用 ANSI 十六进制转义码替换格式字符串中找到的标签。例如:

cprintln!("HELLO <green>WORLD</green>")
cprintln!("HELLO <green>WORLD</>"); // Alternative, shorter syntax

将被替换为:

println!("HELLO \u{1b}[31mWORLD\u{1b}[39m")

注意:可以通过激活功能 terminfo 来更改此行为。然后它将在运行时查询 terminfo 数据库,以了解为每种样式/着色写入哪个序列(下面将详细介绍)。

此包的优点/缺点

优点

  • 样式在编译时处理,因此运行时负载不存在(除非激活了功能 terminfo);
  • 嵌套标签处理良好,例如 "<green>...<blue>...</blue>...</green>"
  • 执行了一些优化,以避免冗余的 ANSI 序列,因为这些优化可以在编译时完成,而不会影响运行时;
  • 几乎每个标签都有一个简短的名字,因此可以快速地进行着色:"my <b>blue</> word";
  • 每个提供的宏都可以像标准 format! 类型的宏一样使用;例如,可以使用位置参数和命名参数,就像通常一样;
  • 支持16、256和16M种颜色;
  • 细粒度错误处理(错误将在编译时给出)。

缺点

  • 不兼容非ANSI终端。

简介

基本示例

use color_print::cprintln;
cprintln!("Hello <green>world</green>!");

更简单地关闭标签:使用 </> 标签

基本上,标签必须使用与其匹配的打开标签完全相同的颜色/样式来关闭(在开头使用斜杠 /),例如: <blue,bold>...</blue,bold>。但这可能很繁琐!

因此,也可以简单地使用 </> 关闭最后一个打开的标签

cprintln!("Hello <green>world</>!");

组合颜色和样式

可以通过使用逗号字符 , 分隔来将多个样式和颜色组合成一个单独的标签

cprintln!("This a <green,bold>green and bold text</green,bold>.");
// The same, but closing with the </> tag:
cprintln!("This a <green,bold>green and bold text</>.");

嵌套标签

任何标签都可以与任何其他标签嵌套。

注意:关闭标签必须正确匹配(遵循HTML标签嵌套的基本规则),但可以使用标签 </> 简化。

嵌套标签的示例

cprintln!("<green>This is green, <bold>then green and bold</bold>, then green again</green>");
cprintln!("<green>This is green, <bold>then green and bold</>, then green again</>");

// Colors can be nested as well:
cprintln!("<green>This is green, <blue>then blue</blue>, then green again</green>");
cprintln!("<green>This is green, <blue>then blue</>, then green again</>");

未关闭的标签将在格式字符串的末尾自动关闭

未手动关闭的标签将自动关闭,这意味着将添加ANSI序列以返回到原始状态

// The two following lines are strictly equivalent:
cprintln!("<green><bold>Hello");
cprintln!("<green><bold>Hello</></>");

如何显示字符 <> 的字面意义

对于标准格式字符串中的 {},字符 <> 必须加倍才能显示其字面意义

cprintln!("This is an angle bracket character: <<, and here is another one: >>");

优化:没有冗余的ANSI代码

扩展的格式字符串将只包含 需要的 ANSI代码。这是通过在每次遇到标签时,通过比较不同的样式属性来完成的,而不是机械地添加ANSI代码。

例如,几个嵌套的 <bold> 标签将只产生一个加粗的ANSI序列

cprintln!("<bold><bold> A <bold,blue> B </> C </></>")

将被替换为:

println!("\u{1b}[1m A \u{1b}[34m B \u{1b}[39m C \u{1b}[22m")
//        ^-------^   ^--------^   ^--------^   ^--------^
//          bold         blue         color        bold
//                                    reset        reset

terminfo 功能

不是直接将ANSI序列插入到格式字符串中,而是可以通过激活功能 terminfo:这将通过查询 terminfo 数据库在运行时添加格式序列。

这有一个优点和几个缺点

优点
  • 这为某些终端添加了一层兼容性。
缺点
  • 这添加了一点点运行时负载;
  • 这添加了两个依赖项:lazy_staticterminfo
  • 样式 <strike><conceal> 未处理;
  • 使用 terminfo,许多样式无法单独重置,这意味着相同结果的格式序列会更长;
  • 目前,提供的宏只能在单个线程中使用。

lazy_static: https://crates.io/crates/lazy_static terminfo: https://crates.io/crates/terminfo

标签的命名规则

每个标签至少有一个 长名,如 <magenta><underline>

直接与 颜色 相关的标签(如 <red><bg:blue><bg:bright-green>...,与 样式 标签(如 <bold><italics>...)相比)有一些共同的命名规则

  • 每个标签有四种变体
    • <mycolor>:正常的前景色;
    • <bright-mycolor><mycolor!>:明亮的前景色;
    • <bg:mycolor><MYCOLOR>:正常的背景色;
    • <bg:bright-mycolor><bg:mycolor!><BRIGHT-MYCOLOR><MYCOLOR!>:明亮的背景色;
  • 每个标签都有一个 快捷方式,每个颜色都有一个基本字母;以下是用 x 字母的示例
    • <x>:正常的背景色;
    • <x!>:明亮的背景色;
    • <bg:x><X>:正常背景色;
    • <bg:x!><X!>:明亮背景色;
  • 每种颜色的快捷字母就是其名称的第一个字母(除了 <k>,它是 <black> 的快捷键),例如 <y><yellow> 的快捷键;
  • 每个大写标签都是 背景色
  • 每个带有尾随感叹号 ! 的标签都是 明亮色

接受的标签列表

前两列显示支持哪些样式,分别使用默认的 crate 功能(ANSI 列)和启用 terminfo 功能。

ANSI Terminfo 快捷键 长名称 别名
X X <s> <strong> <em> <bold>
X X <dim>
X X <u> <underline>
X <strike>
X X <reverse> <rev>
X <conceal> <hide>
X X <i> <italics> <italic>
X X <blink>
X X <k> <black>
X X <r> <red>
X X <g> <green>
X X <y> <yellow>
X X <b> <blue>
X X <m> <magenta>
X X <c> <cyan>
X X <w> <white>
X X <k!> <bright-black> <black!>
X X <r!> <bright-red> <red!>
X X <g!> <bright-green> <green!>
X X <y!> <bright-yellow> <yellow!>
X X <b!> <bright-blue> <blue!>
X X <m!> <bright-magenta> <magenta!>
X X <c!> <bright-cyan> <cyan!>
X X <w!> <bright-white> <white!>
X X <K> <bg:black> <BLACK>
X X <R> <bg:red> <RED>
X X <G> <bg:green> <GREEN>
X X <Y> <bg:yellow> <YELLOW>
X X <B> <bg:blue> <BLUE>
X X <M> <bg:magenta> <MAGENTA>
X X <C> <bg:cyan> <CYAN>
X X <W> <bg:white> <WHITE>
X X <K!> <bg:bright-black> <BLACK!> <bg:black!> <BRIGHT-BLACK>
X X <R!> <bg:bright-red> <RED!> <bg:red!> <BRIGHT-RED>
X X <G!> <bg:bright-green> <GREEN!> <bg:green!> <BRIGHT-GREEN>
X X <Y!> <bg:bright-yellow> <YELLOW!> <bg:yellow!> <BRIGHT-YELLOW>
X X <B!> <bg:bright-blue> <BLUE!> <bg:blue!> <BRIGHT-BLUE>
X X <M!> <bg:bright-magenta> <MAGENTA!> <bg:magenta!> <BRIGHT-MAGENTA>
X X <C!> <bg:bright-cyan> <CYAN!> <bg:cyan!> <BRIGHT-CYAN>
X X <W!> <bg:bright-white> <WHITE!> <bg:white!> <BRIGHT-WHITE>
X <rgb(r,g,b)> <#RRGGBB>
X <bg:rgb(r,g,b)> <bg:#RRGGBB> <RGB(r,g,b)>
X <0>...<255> <调色板(...)> <p(...)> <pal(...)>
X <P(...)> <bg:调色板(...)> <PALETTE(...)> <PAL(...)> <bg:p(...)> <bg:pal(...)>

许可: MIT 或 Apache-2.0

依赖项

~1–2.1MB
~40K SLoC