Helper ANSI
1Presentación
Helper utilizado para dar formato a los textos escritos en la salida estándar en modo consola.
2Funciones de formato
El objeto \Temma\Utils\Ansi ofrece varios métodos estáticos. Estos métodos añaden marcadores interpretados por los terminales compatibles con ANSI, para modificar la forma en que aparece el texto.
Algunos ejemplos:
use \Temma\Utils\Ansi as TµAnsi;
// escribe texto en negrita (más grueso que el estilo normal)
print(TµAnsi::bold("bla bla bla"));
// escribe texto "tenue" (más fino que el estilo normal)
print(TµAnsi::faint("bla bla bla"));
// escribe texto en cursiva
print(TµAnsi::italic("bla bla bla"));
// escribe texto subrayado
print(TµAnsi::underline("bla bla bla"));
// escribe texto parpadeante
print(TµAnsi::blink("bla bla bla"));
// escribe texto en inversión de vídeo (negro sobre fondo blanco)
print(TµAnsi::negative("bla bla bla"));
// escribe texto tachado
print(TµAnsi::strikeout("bla bla bla"));
// escribe texto en rojo
print(TµAnsi::color('red', "bla bla bla"));
// escribe texto en rojo sobre fondo azul
print(TµAnsi::backColor('blue', 'red', "bla bla bla"));
// escribe un enlace de hipertexto
print(TµAnsi::link('https://www.temma.net', 'Sitio Temma'));
3Colores
Los colores pueden definirse mediante una cadena de caracteres o mediante un valor numérico.
Cadenas de caracteres (entre paréntesis el valor numérico correspondiente):
- default: Valor por defecto definido por el 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)
Los valores numéricos comienzan con los 17 valores listados arriba, y terminan con 24 niveles de gris:
4Bloques
Puedes crear fácilmente cajas que muestran títulos, con cuatro niveles diferentes.
Ejemplo:
use \Temma\Utils\Ansi as TµAnsi;
print(TµAnsi::title1("Título de nivel 1"));
print(TµAnsi::title2("Título de nivel 2"));
print(TµAnsi::title3("Título de nivel 3"));
print(TµAnsi::title4("Título de nivel 4"));
Resultado:
También es posible insertar bloques de texto específicos:
- code: Texto verde sobre fondo negro.
- pre: Texto negro sobre fondo gris.
- comment: Texto en cursiva, negro sobre fondo azul.
- success: Texto negro sobre fondo verde.
- info: Texto negro sobre fondo amarillo.
- alert: Texto blanco sobre fondo rojo.
Ejemplo:
use \Temma\Utils\Ansi as TµAnsi;
print(TµAnsi::block('code', "Bloque de código."));
print(TµAnsi::block('pre', "Bloque de texto en bruto."));
print(TµAnsi::block('comment', "Comentario."));
print(TµAnsi::block('success', "Mensaje de éxito."));
print(TµAnsi::block('info', "Mensaje de información."));
print(TµAnsi::block('alert', "Mensaje de alerta."));
Resultado:
5Flujos XML
El método style() se usa para dar formato a un flujo XML que contiene etiquetas similares a las etiquetas HTML.
5.1Etiquetas en línea
La forma más sencilla es usar etiquetas para modificar el texto directamente:
use \Temma\Utils\Ansi as TµAnsi;
print(TµAnsi::style("<i>cursiva</i> <u>subrayado</u> <b>negrita</b><br />
<s>tachado</s> <tt>invertido</tt>"));
Resultado:
Las etiquetas existentes son:
- <b>: negrita
- <u>: subrayado
- <i>: cursiva
- <s>: tachado
- <tt>: vídeo invertido
- <br />: inserción de un salto de línea
- <color>: para definir el color (atributo t para definir el color del texto, atributo b para definir el color de fondo)
- a: para crear un enlace de hipertexto (atributo href para definir la URL del enlace)
5.2Etiquetas de bloque
También es posible usar etiquetas que representan los bloques correspondientes:
use \Temma\Utils\Ansi as TµAnsi;
$s = <<<EOF
<h1>Título de nivel 1</h1>
<h2>Título de nivel 2</h2>
<h3>Título de nivel 3</h3>
<h4>Título de nivel 4</h4>
<code>Bloque de código.</code>
<pre>Bloque de texto en bruto.</pre>
<comment>Comentario.</comment>
<success>Mensaje de éxito.</success>
<info>Mensaje de información.</info>
<alert>Mensaje de alerta.</alert>
EOF;
print(TµAnsi::style($s));
Resultado:
5.3Gestión de saltos de línea
Los saltos de línea se conservan dentro de los bloques.
Fuera de los bloques, sin embargo, los saltos de línea no se interpretan. Si deseas insertar un salto de línea, debes usar la etiqueta <br />.
5.4Personalización
Cada etiqueta XML puede recibir atributos que permiten modificar el estilo del bloque:
- label: Texto de la etiqueta añadida encima del bloque.
- labelColor: Color de fondo de la etiqueta.
- backColor: Color de fondo.
- textColor: Color del texto.
- borderColor: Color del borde.
- bold: Pon el valor true para que el texto aparezca en negrita.
- italic: true para texto en cursiva.
- underline: true para texto subrayado.
- faint: true para que el texto aparezca con menos intensidad
- strikeout: true para tachar el texto.
- blink: true para que el texto parpadee.
- reverse: true para que el texto aparezca en inversión de vídeo.
- line: Cadena de caracteres que contiene los símbolos que se usarán para componer el borde. Es una cadena de 8 caracteres: esquina superior izquierda, línea horizontal superior, esquina superior derecha, línea vertical derecha, esquina inferior derecha, línea horizontal inferior, esquina inferior izquierda, línea vertical izquierda.
- padding: Tamaño del margen inferior (número de líneas vacías por encima y por debajo del texto, dentro del bloque).
- marginTop: Tamaño del margen exterior superior (número de líneas vacías por encima del bloque).
- marginBottom: Tamaño del margen exterior inferior (número de líneas vacías por debajo del bloque).
Ejemplo:
use \Temma\Utils\Ansi as TµAnsi;
// bloque con fondo gris, etiqueta encima,
// y margen inferior de 5 líneas
print(TµAnsi::style("<code backColor='gray' label='Título'
marginBottom='5'>código estilizado.</code>"));
Resultado:
6Creación y modificación de estilos
Puedes modificar el estilo de un bloque, cambiando su color de fondo, el color del texto, el color del borde, los caracteres usados para dibujar el borde, y el tamaño de la caja alrededor del texto (en número de líneas).
El método setStyle() recibe como parámetro el nombre del bloque a modificar. Si no existe ningún bloque con ese nombre, se crea. Todos los demás parámetros son opcionales, y sirven para definir una característica del bloque.
Firma del 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: Nombre del estilo a modificar o crear.
- $display: Pon el valor 'block' para crear un nuevo bloque.
- $backColor: Color de fondo.
- $textColor: Color del texto.
- $borderColor: Color del borde.
- $labelColor: Color de fondo de la etiqueta (ver más abajo).
- $bold: Pon el valor true para que el texto aparezca en negrita.
- $italic: true para texto en cursiva.
- $underline: true para texto subrayado
- $faint: true para que el texto aparezca con menos intensidad.
- $strikeout: true para tachar el texto.
- $blink: true para que el texto parpadee.
- $reverse: true para que el texto aparezca en inversión de vídeo.
- $line: Cadena de caracteres que contiene los símbolos que se usarán para componer el borde. Es una cadena de 8 caracteres: esquina superior izquierda, línea horizontal superior, esquina superior derecha, línea vertical derecha, esquina inferior derecha, línea horizontal inferior, esquina inferior izquierda, línea vertical izquierda.
- $padding: Tamaño del margen inferior (número de líneas vacías por encima y por debajo del texto, dentro del bloque).
- $marginTop: Tamaño del margen exterior superior (número de líneas vacías por encima del bloque).
- $marginBottom: Tamaño del margen exterior inferior (número de líneas vacías por debajo del bloque).
Valor de retorno: Array asociativo que contiene la definición anterior del estilo (array vacío si el estilo no existía).
Ejemplo:
use \Temma\Utils\Ansi as TµAnsi;
// crea el estilo "eighties"
TµAnsi::setStyle(
tag: 'eighties',
display: 'block',
backColor: 'cyan',
textColor: 'magenta',
borderColor: 'white',
bold: true,
line: '+-+|+-+|',
padding: 1,
marginBottom: 1,
);
// usa el bloque
print(TµAnsi::block('eighties', "Texto especial"));
// modifica el estilo (quita la negrita, define el color de la etiqueta)
TµAnsi::setStyle('eighties', bold: false, labelColor: 'red');
// usa el estilo añadiendo una etiqueta
print(TµAnsi::style("<eighties label='Etiqueta del bloque'>Otro texto</eighties>"));
Resultado:
7Indicador de actividad
Cuando un script necesita realizar un procesamiento largo, puede ser útil proporcionar al usuario una indicación visual de que el programa sigue en ejecución.
use \Temma\Utils\Ansi as TµAnsi;
// inicia el indicador de actividad
TµAnsi::throbberStart("Procesando...");
// procesamiento
while (condition) {
// procesamiento...
// hace avanzar los símbolos
TµAnsi::throbberGo();
}
// fin del procesamiento
TµAnsi::throbberEnd("Completado");
Resultado:
Puedes modificar la animación proporcionando una cadena de caracteres o un array que contenga los elementos de la animación.
use \Temma\Utils\Ansi as TµAnsi;
TµAnsi::throbberStart("Procesando...", "/−\\|");
while (condition) {
// procesamiento...
TµAnsi::throbberGo();
}
TµAnsi::throbberEnd("Completado");
Resultado:
8Barra de progreso
Para algunos tipos de procesamiento, es preferible mostrar al usuario el estado de avance hasta su finalización. En este caso, se puede usar una barra de progreso para representar gráficamente este avance.
use \Temma\Utils\Ansi as TµAnsi;
// inicia la barra de progreso
TµAnsi::progressStart("Procesando...");
// procesamiento
while (condition) {
// procesamiento...
// hace avanzar la barra
TµAnsi::progressGo();
}
// fin del procesamiento
TµAnsi::progressEnd("Completado");
Resultado:
El método estático progressStart() puede recibir dos parámetros (opcionales):
- $text (string): Texto por defecto que se mostrará encima de la barra de progreso. (valor por defecto: cadena vacía)
- $units (int): Número de unidades que representan la finalización total. (valor por defecto: 100)
El método estático progressGo() puede recibir dos parámetros (opcionales):
- $units (int): Número de unidades de avance. Puede tomar un valor negativo. (valor por defecto: 1)
- $text (string): Texto que se mostrará encima de la barra de progreso. (valor por defecto: cadena vacía, para usar el valor definido al llamar a progressStart())
También existe un método estático progressSet(), que permite definir directamente el valor de avance (y no el incremento de avance, como hace el método progressGo()). El primer parámetro es el valor de avance, y el segundo (opcional) es el texto que se mostrará.
La visualización de la barra de progreso puede modificarse con el método estático setProgressStyle(), que puede recibir cinco parámetros (todos opcionales):
- $backColor (string): color de la parte no completada de la barra de progreso.
- $textColor (string): color de la parte completada de la barra de progreso.
- $percentage (bool): true para mostrar un porcentaje de finalización, false para mostrar el número de unidades completadas y el número total. (valor por defecto: true)
- $width (int): Divisor del ancho de la pantalla. Por ejemplo, si el valor es 3, la barra de progreso ocupará un tercio del ancho de la pantalla. (valor por defecto: 1, para ocupar todo el ancho de la pantalla)
- $bold (bool): false para evitar que el texto aparezca en negrita.
use \Temma\Utils\Ansi as TµAnsi;
// color: amarillo sobre fondo azul
// visualización en unidades (no en porcentaje) en la mitad de la pantalla
TµAnsi::setProgressStyle(
backColor: 'blue',
textColor: 'yellow',
percentage: false,
width: 2,
bold: false
);
// visualización sobre 120 unidades
TµAnsi::progressStart("Procesando...", 120);
while (condition) {
// procesamiento...
TµAnsi::progressGo();
}
TµAnsi::progressEnd("Completado");
Resultado:
9Métodos utilitarios
El objeto \Temma\Utils\Ansi también ofrece dos funciones estáticas que se pueden usar para manipular cadenas de caracteres que contienen caracteres de control ANSI.
9.1strlen()
Este método estático devuelve el número de caracteres imprimibles en una cadena UTF-8.
Firma del método:
strlen(string $string) : int
Ejemplo:
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 el mismo procesamiento que la función PHP wordwrap(), cortando las cadenas de manera que cada línea no supere el número de caracteres pasado como parámetro, manteniendo las palabras completas, pero contando solo los caracteres imprimibles. Sin embargo, preserva los caracteres no imprimibles, como las secuencias de control ANSI.
Firma del método:
wordwrap(string $string, int $width) : string
Parámetros:
- $string: Cadena a cortar.
- $width: Número máximo de caracteres por línea.
Ejemplo:
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');