Цветные и стилизованные строки для терминалов.
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
от 0 до 255. При этом будут использоваться 256-цветные escape-коды ANSI. Чтобы узнать, какое число соответствует какому цвету и поддерживает ли ваш терминал 256 цветов, используйте Crayons.test_256_colors(codes=true)
.Tuple
из трех Integer
чисел, все от 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>
для различных стилей (обратите внимание на прописные буквы). Вызов using
модуля Crayons.Box
выведет все это в глобальную область видимости.
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
. В качестве альтернативы, если существует переменная среды FORCE_COLOR
или включен Crayons.force_color(::Bool)
, последовательности цветов печатаются несмотря ни на что. Кроме того, поскольку относительно немногие терминалы поддерживают полные 24-битные цвета, можно активировать 256-цветный режим, который преобразует 24-битный карандаш в 256-цветный карандаш при печати. Это делается либо определением переменной среды FORCE_256_COLORS
, либо вызовом Crayons.force_256_colors(::Bool)
. Кроме того, в некоторых системах возникают проблемы даже с 256 цветами, их можно преобразовать в один из 16 системных цветов, определив переменную FORCE_SYSTEM_COLORS
или вызвав Crayons.force_system_colors(::Bool)
. Обратите внимание, что 16 цветов (8 + 8 светлых версий) — это довольно маленькое цветовое пространство, поэтому преобразование вряд ли будет очень хорошим.
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! "
))
Функция inv
для Crayon
возвращает Crayon
, который отменяет то, что делает Crayon
в аргументе inv
. Например, 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
режиме, вызвав CrayonStack(incremental = true)
. В этом случае 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