Helper ANSI
1Apresentação
Helper usado para formatar textos escritos na saída padrão em modo console.
2Funções de formatação
O objeto \Temma\Utils\Ansi oferece vários métodos estáticos. Esses métodos adicionam marcadores interpretados por terminais compatíveis com ANSI, para modificar a forma como o texto aparece.
Alguns exemplos:
use \Temma\Utils\Ansi as TµAnsi;
// escreve texto em negrito (mais espesso que o estilo normal)
print(TµAnsi::bold("blah blah blah"));
// escreve texto "fino" (mais fino que o estilo normal)
print(TµAnsi::faint("blah blah blah"));
// escreve texto em itálico
print(TµAnsi::italic("blah blah blah"));
// escreve texto sublinhado
print(TµAnsi::underline("blah blah blah"));
// escreve texto piscante
print(TµAnsi::blink("blah blah blah"));
// escreve texto em inversão de vídeo (preto sobre fundo branco)
print(TµAnsi::negative("blah blah blah"));
// escreve texto riscado
print(TµAnsi::strikeout("blah blah blah"));
// escreve texto em vermelho
print(TµAnsi::color('red', "blah blah blah"));
// escreve texto em vermelho sobre fundo azul
print(TµAnsi::backColor('blue', 'red', "blah blah blah"));
// escreve um link de hipertexto
print(TµAnsi::link('https://www.temma.net', 'Site Temma'));
3Cores
As cores podem ser definidas por uma string ou por um valor numérico.
Strings (entre parênteses o valor numérico correspondente):
- default: Valor padrão definido pelo terminal.
- light-black (0)
- red (1)
- dark-green (2)
- olive (3)
- blue (4)
- purple (5)
- teal (6)
- silver (7)
- gray (8)
- light-red (9)
- green (10)
- yellow (11)
- light-blue (12)
- magenta (13)
- cyan (14)
- white (15)
- black (16)
Os valores numéricos começam com os 17 valores listados acima, e terminam com 24 níveis de cinza:
4Blocos
Você pode criar facilmente caixas exibindo títulos, com quatro níveis diferentes.
Exemplo:
use \Temma\Utils\Ansi as TµAnsi;
print(TµAnsi::title1("Título de nível 1"));
print(TµAnsi::title2("Título de nível 2"));
print(TµAnsi::title3("Título de nível 3"));
print(TµAnsi::title4("Título de nível 4"));
Resultado:
Também é possível inserir blocos de texto específicos:
- code: Texto verde sobre fundo preto.
- pre: Texto preto sobre fundo cinza.
- comment: Texto em itálico, preto sobre fundo azul.
- success: Texto preto sobre fundo verde.
- info: Texto preto sobre fundo amarelo.
- alert: Texto branco sobre fundo vermelho.
Exemplo:
use \Temma\Utils\Ansi as TµAnsi;
print(TµAnsi::block('code', "Bloco de código."));
print(TµAnsi::block('pre', "Bloco de texto bruto."));
print(TµAnsi::block('comment', "Comentário."));
print(TµAnsi::block('success', "Mensagem de sucesso."));
print(TµAnsi::block('info', "Mensagem de informação."));
print(TµAnsi::block('alert', "Mensagem de alerta."));
Resultado:
5Fluxos XML
O método style() é usado para formatar um fluxo XML contendo tags semelhantes a tags HTML.
5.1Tags inline
A forma mais simples é usar tags para modificar o texto diretamente:
use \Temma\Utils\Ansi as TµAnsi;
print(TµAnsi::style("<i>itálico</i> <u>sublinhado</u> <b>negrito</b><br />
<s>riscado</s> <tt>invertido</tt>"));
Resultado:
As tags existentes são:
- <b>: negrito
- <u>: sublinhado
- <i>: itálico
- <s>: riscado
- <tt>: vídeo invertido
- <br />: inserção de uma quebra de linha
- <color>: para definir a cor (atributo t para definir a cor do texto, atributo b para definir a cor de fundo)
- a: para criar um link de hipertexto (atributo href para definir a URL do link)
5.2Tags de bloco
Também é possível usar tags que representam os blocos correspondentes:
use \Temma\Utils\Ansi as TµAnsi;
$s = <<<EOF
<h1>Título de nível 1</h1>
<h2>Título de nível 2</h2>
<h3>Título de nível 3</h3>
<h4>Título de nível 4</h4>
<code>Bloco de código.</code>
<pre>Bloco de texto bruto.</pre>
<comment>Comentário.</comment>
<success>Mensagem de sucesso.</success>
<info>Mensagem de informação.</info>
<alert>Mensagem de alerta.</alert>
EOF;
print(TµAnsi::style($s));
Resultado:
5.3Gerenciamento de quebras de linha
As quebras de linha são preservadas dentro dos blocos.
Fora dos blocos, porém, as quebras de linha não são interpretadas. Se você quiser inserir uma quebra de linha, deve usar a tag <br />.
5.4Personalização
Cada tag XML pode receber atributos que podem ser usados para modificar o estilo do bloco:
- label: Texto do rótulo adicionado acima do bloco.
- labelColor: Cor de fundo do rótulo.
- backColor: Cor de fundo.
- textColor: Cor do texto.
- borderColor: Cor da borda.
- bold: Defina como true para deixar o texto em negrito.
- italic: true para texto em itálico.
- underline: true para texto sublinhado.
- faint: true para o texto aparecer com menos intensidade
- strikeout: true para riscar o texto.
- blink: true para o texto piscar.
- reverse: true para o texto aparecer em inversão de vídeo.
- line: String contendo os símbolos a serem usados para compor a borda. É uma string de 8 caracteres: canto superior esquerdo, linha horizontal superior, canto superior direito, linha vertical direita, canto inferior direito, linha horizontal inferior, canto inferior esquerdo, linha vertical esquerda.
- padding: Tamanho do espaçamento interno (número de linhas vazias acima e abaixo do texto, dentro do bloco).
- marginTop: Tamanho da margem externa superior (número de linhas vazias acima do bloco).
- marginBottom: Tamanho da margem externa inferior (número de linhas vazias abaixo do bloco).
Exemplo:
use \Temma\Utils\Ansi as TµAnsi;
// bloco com fundo cinza, rótulo acima,
// e margem inferior de 5 linhas
print(TµAnsi::style("<code backColor='gray' label='Título'
marginBottom='5'>código estilizado.</code>"));
Resultado:
6Criação e modificação de estilos
Você pode modificar o estilo de um bloco, alterando sua cor de fundo, a cor do texto, a cor da borda, os caracteres usados para desenhar a borda, e o tamanho da caixa ao redor do texto (em número de linhas).
O método setStyle() recebe como parâmetro o nome do bloco a ser modificado. Se não existir nenhum bloco com esse nome, ele é criado. Todos os outros parâmetros são opcionais, e são usados para definir uma característica do bloco.
Assinatura do método:
setStyle(
string $tag,
?string $display=null,
null|int|string $backColor=null,
null|int|string $textColor=null,
null|int|string $borderColor=null,
?string $labelColor=null,
?bool $bold=null,
?bool $italic=null,
?bool $underline=null,
?bool $faint=null,
?bool $strikeout=null,
?bool $blink=null,
?bool $reverse=null,
?string $label=null,
?string $line=null,
?int $padding=null,
?int $marginTop=null,
?int $marginBottom=null
) : array
Parâmetros:
- $tag: Nome do estilo a ser modificado ou criado.
- $display: Defina como 'block' para criar um novo bloco.
- $backColor: Cor de fundo.
- $textColor: Cor do texto.
- $borderColor: Cor da borda.
- $labelColor: Cor de fundo do rótulo (veja abaixo).
- $bold: Defina como true para deixar o texto em negrito.
- $italic: true para texto em itálico.
- $underline: true para texto sublinhado
- $faint: true para o texto aparecer com menos intensidade.
- $strikeout: true para riscar o texto.
- $blink: true para o texto piscar.
- $reverse: true para o texto aparecer em inversão de vídeo.
- $line: String contendo os símbolos a serem usados para compor a borda. É uma string de 8 caracteres: canto superior esquerdo, linha horizontal superior, canto superior direito, linha vertical direita, canto inferior direito, linha horizontal inferior, canto inferior esquerdo, linha vertical esquerda.
- $padding: Tamanho do espaçamento interno (número de linhas vazias acima e abaixo do texto, dentro do bloco).
- $marginTop: Tamanho da margem externa superior (número de linhas vazias acima do bloco).
- $marginBottom: Tamanho da margem externa inferior (número de linhas vazias abaixo do bloco).
Valor de retorno: Array associativo contendo a definição anterior do estilo (array vazio se o estilo não existia).
Exemplo:
use \Temma\Utils\Ansi as TµAnsi;
// cria o estilo "eighties"
TµAnsi::setStyle(
tag: 'eighties',
display: 'block',
backColor: 'cyan',
textColor: 'magenta',
borderColor: 'white',
bold: true,
line: '+-+|+-+|',
padding: 1,
marginBottom: 1,
);
// usa o bloco
print(TµAnsi::block('eighties', "Texto especial"));
// modifica o estilo (remove o negrito, define a cor do rótulo)
TµAnsi::setStyle('eighties', bold: false, labelColor: 'red');
// usa o estilo adicionando um rótulo
print(TµAnsi::style("<eighties label='Rótulo do bloco'>Outro texto</eighties>"));
Resultado:
7Indicador de atividade
Quando um script precisa realizar um processamento demorado, pode ser útil fornecer ao usuário uma indicação visual de que o programa ainda está em execução.
use \Temma\Utils\Ansi as TµAnsi;
// inicia o indicador de atividade
TµAnsi::throbberStart("Processando...");
// processamento
while (condition) {
// processando...
// avança os símbolos
TµAnsi::throbberGo();
}
// fim do processamento
TµAnsi::throbberEnd("Concluído");
Resultado:
Você pode modificar a animação fornecendo uma string ou um array contendo os elementos da animação.
use \Temma\Utils\Ansi as TµAnsi;
TµAnsi::throbberStart("Processando...", "/−\\|");
while (condition) {
// processando...
TµAnsi::throbberGo();
}
TµAnsi::throbberEnd("Concluído");
Resultado:
8Barra de progresso
Para alguns tipos de processamento, é preferível mostrar ao usuário o estado de progresso até a conclusão. Nesse caso, uma barra de progresso pode ser usada para representar graficamente esse progresso.
use \Temma\Utils\Ansi as TµAnsi;
// inicia a barra de progresso
TµAnsi::progressStart("Processando...");
// processamento
while (condition) {
// processando...
// avança a barra
TµAnsi::progressGo();
}
// fim do processamento
TµAnsi::progressEnd("Concluído");
Resultado:
O método estático progressStart() pode receber dois parâmetros (opcionais):
- $text (string): Texto padrão a ser exibido acima da barra de progresso. (valor padrão: string vazia)
- $units (int): Número de unidades que representam a conclusão total. (valor padrão: 100)
O método estático progressGo() pode receber dois parâmetros (opcionais):
- $units (int): Número de unidades de progresso. Pode receber um valor negativo. (valor padrão: 1)
- $text (string): Texto a ser exibido acima da barra de progresso. (padrão: string vazia, para usar o valor definido na chamada de progressStart())
Também existe um método estático progressSet(), que permite definir diretamente o valor de progresso (e não o incremento de progresso, como faz o método progressGo()). O primeiro parâmetro é o valor de progresso, e o segundo (opcional) é o texto a ser exibido.
A exibição da barra de progresso pode ser modificada com o método estático setProgressStyle(), que pode receber cinco parâmetros (todos opcionais):
- $backColor (string): cor da parte não concluída da barra de progresso.
- $frontColor (string): cor da parte concluída da barra de progresso.
- $percentage (bool): true para exibir uma porcentagem de conclusão, false para exibir o número de unidades concluídas e o número total. (valor padrão: true)
- $width (int): Divisor da largura da tela. Por exemplo, se o valor for 3, a barra de progresso ocupará um terço da largura da tela. (valor padrão: 1, para ocupar toda a largura da tela)
- $bold (string): false para impedir que o texto fique em negrito.
use \Temma\Utils\Ansi as TµAnsi;
// cor: amarelo sobre fundo azul
// exibição em unidades (não em porcentagem) em metade da tela
TµAnsi::setProgressStyle(
backColor: 'blue',
frontColor: 'yellow',
percentage: false,
width: 2,
bold: false
);
// exibição com 120 unidades
TµAnsi::progressStart("Processando...", 120);
while (condition) {
// processando...
TµAnsi::progressGo();
}
TµAnsi::progressEnd("Concluído");
Resultado:
9Métodos utilitários
O objeto \Temma\Utils\Ansi também oferece duas funções estáticas que podem ser usadas para manipular strings contendo caracteres de controle ANSI.
9.1strlen()
Este método estático retorna o número de caracteres imprimíveis em uma string UTF-8.
Assinatura do método:
strlen(string $string) : int
Exemplo:
use \Temma\Utils\Ansi as TµAnsi;
$s = TµAnsi::bold('hello');
$length = TµAnsi::strlen($s); // 5
9.2wordwrap()
Este método estático realiza o mesmo processamento que a função PHP wordwrap(), cortando strings de forma que cada linha não ultrapasse o número de caracteres passado como parâmetro, mantendo as palavras inteiras, mas contando apenas os caracteres imprimíveis. Ele preserva, no entanto, os caracteres não imprimíveis, como as sequências de controle ANSI.
Assinatura do método:
wordwrap(string $string, int $width) : string
Parâmetros:
- $string: String a ser cortada.
- $width: Número máximo de caracteres por linha.
Exemplo:
use \Temma\Utils\Ansi as TµAnsi;
$s = TµAnsi::bold('hello') . ' ' . TµAnsi::italic('world');
$s = TµAnsi::wordwrap($s, 8);
// equivalente a:
// $s = TµAnsi::bold('hello') . "\n" . TµAnsi::italic('world');