Cordas coloridas e estilizadas para terminais.
Crayons é um pacote que simplifica a escrita de strings em diferentes cores e estilos nos terminais. Ele suporta as 16 cores do sistema, as extensões true color de 256 cores e 24 bits e os diferentes estilos de texto disponíveis para terminais. O pacote foi projetado para ter um bom desempenho, não ter dependências e carregar rapidamente (cerca de 10 ms de tempo de carregamento após a pré-compilação).
import Pkg; Pkg . add ( " Crayons " )
Crayon
de cera Um Crayon
é criado apenas com a palavra-chave construtor:
Crayon (foreground,
background,
reset,
bold,
faint,
italics,
underline,
blink,
negative,
conceal,
strikethrough)
O argumento foreground
e background
pode ser de três tipos:
Symbol
que representa uma cor. As cores disponíveis são black
, red
, green
, yellow
, blue
, magenta
, cyan
, light_gray
, default
, dark_gray
, light_red
, light_green
, light_yellow
, light_blue
, light_magenta
, light_cyan
e white
. Para ver as cores em ação, experimente Crayons.test_system_colors()
. Essas cores são suportadas por quase todos os terminais.Integer
entre 0 e 255. Isso usará os códigos de escape ANSI de 256 cores. Para ver qual número corresponde a qual cor e se o seu terminal suporta 256 cores, use Crayons.test_256_colors(codes=true)
.Tuple
de três Integer
, todos entre 0 e 255. Isso será interpretado como uma cor (r, g, b)
de 24 bits. Para testar o suporte de seus terminais para cores de 24 bits, use Crayons.test_24bit_colors(codes=false)
. O suporte para isso é atualmente bastante limitado, mas está sendo continuamente melhorado nos terminais, veja aqui.UInt32
representando uma cor fornecida em formato hexadecimal. Será convertido para o formato RGB correspondente. Os outros argumentos de palavras-chave são todos do tipo Bool
e determinam se o estilo correspondente deve ser explicitamente habilitado ou desabilitado:
reset
– redefine todos os estilos e cores para o padrãobold
– texto em negrito, também ilumina as cores em alguns terminaisfaint
— texto fraco, não amplamente suportadoitalics
— texto em itálico, sem amplo suporteunderline
– texto sublinhadoblink
– texto piscandonegative
– troque o primeiro plano e o plano de fundoconceal
— oculta o texto, não é amplamente suportadostrikethrough
— linha horizontal no meio do texto, não amplamente apoiada. Para ver o texto com os diferentes estilos ativos, use Crayons.test_styles()
Ao não usar nothing
para nenhum dos argumentos de palavra-chave, essa cor ou estilo fica inativo e, portanto, não está nem ativado nem desativado ativamente.
Por conveniência, Crayon
para a versão de primeiro plano/fundo das 16 cores do sistema, bem como os diferentes estilos, são pré-fabricados e podem ser encontrados no módulo Crayons.Box
. Eles têm o nome <COLOR_NAME>_<BG/FG>
para as cores de primeiro plano/fundo e <STYLE>
para os diferentes estilos (observe as letras maiúsculas). Chamar using
no módulo Crayons.Box
trará tudo isso para um escopo global.
Crayon
s também podem ser criados de forma mais concisa usando a macro de string crayon
. Eles são escritos usando crayon"[[fg:]<col>] [bg:<col>] ([[!]<style>] ...)"
onde:
<col>
é uma cor dada como um número hexadecimal, tupla (r,g,b)
(sem espaços), um número de 0 a 255 ou uma das 16 cores nomeadas.<style>
é um dos estilos.!
significa que o estilo está explicitamente desabilitado.(<style> ...)
significa um número repetido de estilos, separados por espaços.Alguns exemplos de uso de macros de string e o construtor equivalente são mostrados abaixo
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
O processo de impressão de texto colorido e estilizado usando giz de cera é simples. Ao imprimir um Crayon
no terminal, as sequências de código corretas são enviadas ao terminal, de forma que o texto impresso subsequente assuma a cor e o estilo do Crayon
impresso. Por exemplo, tente executar o código abaixo no 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 " )
Também é possível usar a sobrecarga de chamadas em Crayon
criados. O Crayon
pode ser chamado com strings e outros Crayon
s e as cores e estilos serão aninhados corretamente. Sequências finais corretas também serão impressas para que as cores e estilos sejam desativados fora do escopo da chamada. Esta funcionalidade talvez seja mostrada mais claramente com alguns exemplos:
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 " )
)
Nota: Para que as sequências de cores sejam impressas, o Julia REPL precisa ter as cores ativadas, seja por Julia detectando automaticamente o suporte do terminal ou iniciando Julia com o argumento --color=yes
. Alternativamente, se a variável de ambiente FORCE_COLOR
existir, ou Crayons.force_color(::Bool)
tiver sido habilitado, as sequências de cores serão impressas de qualquer maneira. Além disso, como relativamente poucos terminais suportam cores completas de 24 bits, é possível ativar o modo de 256 cores, que converte o giz de cera de 24 bits em um giz de cera de 256 cores quando impresso. Isso é feito definindo a variável ambiente FORCE_256_COLORS
ou chamando Crayons.force_256_colors(::Bool)
. Além disso, alguns sistemas apresentam problemas mesmo com 256 cores, é possível converter para uma das 16 cores do sistema definindo a variável FORCE_SYSTEM_COLORS
ou chamando Crayons.force_system_colors(::Bool)
. Observe que 16 cores (8 + 8 versões claras) é um espaço de cores bastante pequeno, portanto é improvável que a conversão seja muito boa.
Crayon
Dois ou mais Crayon
podem ser mesclados, resultando em um novo Crayon
com todas as propriedades dos mesclados. Isso é feito com a função merge(crayons::Crayon...)
ou multiplicando Crayon
s usando *
. Se dois Crayon
s especificarem a mesma propriedade, então a propriedade do último Crayon
na lista de argumentos será usada:
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! "
))
A função inv
em um Crayon
retorna um Crayon
que desfaz o que o Crayon
no argumento para inv
faz. Por exemplo, inv(Crayon(bold = true))
retorna um Crayon
que desativa o negrito.
Se você deseja aninhar cores e estilos por meio de chamadas de função, existe o tipo CrayonStack
. Basta push!
Crayon
giz de cera na pilha, imprima o texto na pilha e depois pop!
os Crayons
fora. A pilha acompanhará o que Crayon
está ativo no momento. É usado como um 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 " )
Um CrayonStack
também pode ser criado em modo incremental
chamando CrayonStack(incremental = true)
. Nesse caso, o CrayonStack
imprimirá apenas as alterações necessárias para passar do estado de texto anterior para o novo estado, o que resulta na impressão de menos códigos de cores. Entretanto, observe que isso significa que o CrayonStack
precisa ser impresso no buffer de saída para todas as alterações feitas nele (ou seja, quando push!
e pop!
são usados). O exemplo abaixo mostra um exemplo prático onde todas as alterações na pilha são impressas e outro exemplo, que dá resultado errado, pois uma alteração não é impressa. Ambos os exemplos abaixo funcionam corretamente se 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)))
A razão pela qual o último exemplo não funcionou é porque a pilha percebe que não há mudança no estado do texto na segunda chamada para push!
, já que o primeiro plano foi mantido vermelho. Falha ao imprimir a pilha após o primeiro push!
significava que o estado do terminal e o estado da pilha ficaram fora de sincronia.
https://github.com/Aerlinger/AnsiColor.jl
Kristoffer Carlsson — @KristofferC