终端的彩色和样式字符串。
Crayons是一个包,可以轻松地将不同颜色和样式的字符串写入终端。它支持 16 种系统颜色、256 色和 24 位真彩色扩展,以及终端可用的不同文本样式。该包的设计目标是性能良好、无依赖性且加载速度快(预编译后加载时间约为 10 毫秒)。
import Pkg; Pkg . add ( " Crayons " )
Crayon
Crayon
是使用仅关键字构造函数创建的:
Crayon (foreground,
background,
reset,
bold,
faint,
italics,
underline,
blink,
negative,
conceal,
strikethrough)
foreground
和background
参数可以分为三种类型:
Symbol
。可用的颜色有black
、 red
、 green
、 yellow
、 blue
、 magenta
、 cyan
、 light_gray
、 default
、 dark_gray
、 light_red
、 light_green
、 light_yellow
、 light_blue
、 light_magenta
洋红色、 light_cyan
和white
。要查看实际颜色,请尝试Crayons.test_system_colors()
。几乎所有终端都支持这些颜色。Integer
。这将使用 256 色 ANSI 转义码。要查看什么数字对应什么颜色以及您的终端是否支持 256 种颜色,请使用Crayons.test_256_colors(codes=true)
。Integer
的Tuple
,全部在 0 到 255 之间。这将被解释为(r, g, b)
24 位颜色。要测试终端对 24 位颜色的支持,请使用Crayons.test_24bit_colors(codes=false)
。目前对此的支持相当有限,但终端正在不断改进,请参见此处。UInt32
。将会转换为相应的RGB格式。其他关键字参数都是Bool
类型,并确定是否应显式启用或禁用相应的样式:
reset
— 将所有样式和颜色重置为默认值bold
— 粗体文本,也使某些终端上的颜色变亮faint
——微弱的文本,没有得到广泛支持italics
— 斜体文本,未得到广泛支持underline
— 带下划线的文本blink
— 闪烁的文本negative
— 交换前景和背景conceal
— 隐藏文本,未得到广泛支持strikethrough
— 穿过文本中间的水平线,未得到广泛支持。要查看具有不同样式的文本,请使用Crayons.test_styles()
通过对任何关键字参数nothing
使用任何内容,该颜色或样式将处于非活动状态,因此既不会主动启用也不会主动禁用。
为了方便起见, Crayon
前/后台版本的 16 种系统颜色以及不同的样式都是预先制作好的,可以在Crayons.Box
模块中找到。它们的前景色/背景色名称为<COLOR_NAME>_<BG/FG>
,不同样式的名称为<STYLE>
(注意大写)。在Crayons.Box
模块上调用using
会将所有这些都带入全局范围。
还可以使用字符串宏crayon
以更简洁的方式创建Crayon
。这些是使用crayon"[[fg:]<col>] [bg:<col>] ([[!]<style>] ...)"
编写的,其中:
<col>
是一种颜色,以十六进制数字、 (r,g,b)
元组(无空格)、数字 0-255 或 16 种命名颜色之一的形式给出。<style>
是其中一种样式。!
意味着该样式被明确禁用。(<style> ...)
表示重复的多个样式,以空格分隔。下面显示了使用字符串宏和等效构造函数的几个示例
crayon " red " # Crayon(foreground = :red)
crayon " bg:(255,0,255) " # Crayon(background = (255, 0, 255))
crayon " !bold underline 0xff00ff " # Crayon(bold = false, underline = true, foreground = 0xff00ff)
crayon " #0000ff " # Crayon(foreground = 0x0000ff)
Crayon
使用蜡笔打印彩色和样式文本的过程很简单。通过将Crayon
打印到终端,正确的代码序列会发送到终端,以便后续打印的文本呈现打印的Crayon
的颜色和样式。例如,尝试在 REPL 中运行以下代码:
print ( Crayon (foreground = :red ), " In red. " , Crayon (bold = true ), " Red and bold " )
print ( Crayon (foreground = 208 , background = :red , bold = true ), " Orange bold on red " )
print ( Crayon (negative = true , underline = true , bold = true ), " Underlined inverse bold " )
print ( Crayon (foreground = ( 100 , 100 , 255 ), background = ( 255 , 255 , 0 )), " Bluish on yellow " )
using Crayons . Box
print (GREEN_FG, " This is in green " )
print (BOLD, GREEN_FG, BLUE_BG, " Bold green on blue " )
还可以在创建的Crayon
上使用调用重载。可以使用字符串和其他Crayon
来调用Crayon
,并且颜色和样式将正确嵌套。还将打印正确的结束序列,以便在调用范围之外禁用颜色和样式。通过一些示例可能会更清楚地显示此功能:
using Crayons . Box
print ( UNDERLINE ( " This is underlined. " ), " But this is not " )
print ( RED_FG ( " Hello " , BLUE_BG ( " world " ), " !!! " ), " !!! " )
print ( GREEN_BG ( " We " ,
UNDERLINE ( " are " ,
MAGENTA_FG ( " nesting " ),
" some " ),
" colors " )
)
注意:为了打印颜色序列,Julia REPL 需要激活颜色,可以通过 Julia 自动检测终端支持,也可以通过使用--color=yes
参数启动 Julia。或者,如果环境变量FORCE_COLOR
存在,或者Crayons.force_color(::Bool)
已启用,则无论如何都会打印颜色序列。此外,由于支持完整 24 位颜色的终端相对较少,因此可以激活 256 色模式,在打印时将 24 位蜡笔转换为 256 色蜡笔。这是通过定义变量环境FORCE_256_COLORS
或调用Crayons.force_256_colors(::Bool)
来完成的。此外,某些系统即使使用 256 种颜色也会出现问题,可以通过定义变量FORCE_SYSTEM_COLORS
或调用Crayons.force_system_colors(::Bool)
转换为 16 种系统颜色之一。请注意,16 种颜色(8 + 8 光版本)是一个相当小的色彩空间,因此转换不太可能很好。
Crayon
两个或多个Crayon
可以合并,从而生成一个具有合并后的 Crayon 的所有属性的新Crayon
。这是通过函数merge(crayons::Crayon...)
或通过使用*
乘以Crayon
来完成的。如果两个Crayon
指定相同的属性,则使用参数列表中最后一个Crayon
的属性:
using Crayons . Box
r_fg = Crayon (foreground = :red )
g_bg = Crayon (background = :green )
merged = merge (r_fg, g_bg)
print (merged, " Red foreground on green background! " )
print (r_fg * g_bg * Crayons . Box . BOLD, " Bold Red foreground on green background! " )
# Also with call overloading and nesting
print ( GREEN_FG (
" I am a green line " ,
BOLD * BLUE_FG * UNDERLINE (
" with a bold underlined blue substring "
),
" that becomes green again! "
))
Crayon
上的函数inv
返回一个Crayon
,该 Crayon 撤消inv
参数中的Crayon
所做的操作。例如, inv(Crayon(bold = true))
返回禁用粗体的Crayon
。
如果您想通过函数调用嵌套颜色和样式,可以使用CrayonStack
类型。只需push!
将Crayon
放入堆栈中,将文本打印到堆栈中,然后pop!
Crayons
关闭。该堆栈将跟踪Crayon
当前处于活动状态的内容。它的使用就像Crayon
一样:
stack = CrayonStack ()
print (stack, " normal text " )
print ( push! (stack, Crayon (foreground = :red )), " in red " )
print ( push! (stack, Crayon (foreground = :blue )), " in blue " )
print ( pop! (stack), " in red again " )
print ( pop! (stack), " normal text " )
还可以通过调用CrayonStack(incremental = true)
以incremental
模式创建CrayonStack
。在这种情况下, CrayonStack
将仅打印从之前的文本状态变为新状态所需的更改,这会导致打印的颜色代码较少。但是,请注意,这意味着需要将CrayonStack
打印到输出缓冲区,以了解对其所做的所有更改(即使用push!
和pop!
时)。下面的示例显示了一个工作示例,其中打印了对堆栈的所有更改,而另一个示例则给出了错误的结果,因为未打印一项更改。如果incremental = false
下面的两个示例都可以正常工作。
# Does work
io = IOBuffer ()
stack = CrayonStack (incremental = true )
print (io, push! (stack, Crayon (foreground = :red )))
print (io, push! (stack, Crayon (foreground = :red )))
print (io, stack, " This will be red " )
print ( String ( take! (io)))
# Does not work
io = IOBuffer ()
stack = CrayonStack (incremental = true )
push! (stack, Crayon (foreground = :red )) # <- not printing the stack even though we modify it!
print (io, push! (stack, Crayon (foreground = :red )))
print (io, stack, " This will not be red " )
print ( String ( take! (io)))
最后一个例子不起作用的原因是因为堆栈注意到第二次调用push!
,因为前景只是保持红色。第一次push!
意味着最终状态和堆栈状态不同步。
https://github.com/Aerlinger/AnsiColor.jl
克里斯托弗·卡尔森 — @KristofferC