ANSI helper


1Presentation

Helper used to format texts written to standard output in console mode.


2Formatting functions

The \Temma\Utils\Ansi object offers several static methods. These methods add markers interpreted by ANSI-compatible terminals, to modify the way text appears.

Some examples:

use \Temma\Utils\Ansi as TµAnsi;

// write text in bold (thicker than normal style)
print(TµAnsi::bold("blah blah blah"));

// write "thin" text (thinner than normal style)
print(TµAnsi::faint("blah blah blah"));

// write text in italic
print(TµAnsi::italic("blah blah blah"));

// write underlined text
print(TµAnsi::underline("blah blah blah"));

// write blinking text
print(TµAnsi::blink("blah blah blah"));

// write text in video inversion (black on white background)
print(TµAnsi::negative("blah blah blah"));

// write striked out text
print(TµAnsi::strikeout("blah blah blah"));

// write text in red
print(TµAnsi::color('red', "blah blah blah"));

// write text in red on blue background
print(TµAnsi::backColor('blue', 'red', "blah blah blah"));

// write an hypertext link
print(TµAnsi::link('https://www.temma.net', 'Site Temma'));

3Colors

Colors can be defined by a string or by a numerical value.

Strings (in brackets the corresponding numerical value) :

  • default: Default value defined by the 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)

Numerical values start with the 17 values listed above, and end with 24 levels of grey:


4Blocks

You can easily create boxes displaying titles, with three different levels.

Example:

use \Temma\Utils\Ansi as TµAnsi;

print(TµAnsi::title1("First level title"));
print(TµAnsi::title2("Second level title"));
print(TµAnsi::title3("Third level title"));
print(TµAnsi::title4("Fourth level title"));

Result:

It is also possible to insert specific text blocks:

  • code: Green text on black background.
  • pre: Text in black on gray background.
  • comment: Text in italics, black on blue background.
  • success: Text in black on green background.
  • info: Text in black on yellow background.
  • alert: Text in white on red background.

Exemple:

use \Temma\Utils\Ansi as TµAnsi;

print(TµAnsi::block('code', "Code block."));
print(TµAnsi::block('pre', "Raw text block."));
print(TµAnsi::block('comment', "Comment."));
print(TµAnsi::block('success', "Success message."));
print(TµAnsi::block('info', "Information message."));
print(TµAnsi::block('alert', "Alert message."));

Result:


5XML streams

The style() method is used to format an XML stream containing tags similar to HTML tags.


5.1Inline tags

The easiest way is to use tags to modify text directly:

use \Temma\Utils\Ansi as TµAnsi;

print(TµAnsi::style("<i>italic</i> <u>underlined</u> <b>bold</b><br />
<s>striked out</s> <tt>inverted</tt>"));

Result:

The existing tags are:

  • <b>: bold
  • <u>: underlined
  • <i>: italic
  • <s>: striked out
  • <tt>: inverted video
  • <br />: insertion of a line break
  • <c>: to define the color (t attribute to define the text color, b attribute to define the background color)
  • a: to create a hypertext link (href attribute to define link URL)

5.2Block tags

It is also possible to use tags representing the corresponding blocks:

use \Temma\Utils\Ansi as TµAnsi;

$s = <<<EOF
<h1>Level 1 title</h1>
<h2>Level 2 title</h2>
<h3>Level 3 title</h3>
<h4>Level 4 title</h4>
<code>Code block.</code>
<pre>Raw text block.</pre>
<comment>Comment.</comment>
<success>Success message.</success>
<info>Information message.</info>
<alert>Alert message.</alert>
EOF;
print(TµAnsi::style($s));

Result:

Please note that inline tags (<b>, <i>, <u>, <s>, <tt>, <blink>, <color>, <a>) cannot be used inside a block.

5.3New lines management

New lines are preserved in blocks.

Outside blocks, however, carriage returns are not interpreted. If you wish to insert a line break, you must use the <br />tag.


5.4Customization

Each XML tag can be assigned attributes that can be used to modify the style of the block:

  • label: Label text added above the block.
  • labelColor: Label background color.
  • backColor: Background color.
  • textColor: Text color.
  • borderColor: Border color.
  • bold: Set to true to make text bold.
  • italic: true for italic text.
  • underline: true for underlined text.
  • faint: true for text to appear with less intensity
  • strikeout: true to make text strikethrough.
  • blink: true to make text blink.
  • reverse: true to make text appear in video inversion.
  • line: Character string containing the symbols to be used to compose the border. This is a string of 8 characters: top left corner, top horizontal line, top right corner, right vertical line, bottom right corner, bottom horizontal line, bottom left corner, left vertical line.
  • padding: Size of bottom margin (number of empty lines above and below the text, inside the block).
  • marginTop: Size of upper outer margin (number of empty lines above the block).
  • marginBottom: Size of lower outer margin (number of empty lines below the block).

Example:

use \Temma\Utils\Ansi as TµAnsi;

// block with gray background, label above,
// and 5-line bottom margin
print(TµAnsi::style("<code backColor='gray' label='Titre'
marginBottom='5'>stylized code.</code>"));

Result:


6Creating and modifying styles

You can modify the style of a block, changing its background color, the text color, the border color, the characters used to draw the border, and the size of the box around the text (in number of lines).

The setStyle() method takes as parameter the name of the block to be modified. If no block with this name exists, it is created. All other parameters are optional, and are used to define a block characteristic.

Method signature :

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 $marginiTop=null,
    ?int $marginBottom=null
) : array

Parameters:

  • $tag: Name of the style to be modified or created.
  • $display: Set to 'block' to create a new block.
  • $backColor: Background color.
  • $textColor: Text color.
  • $borderColor: Border color.
  • $labelColor: Label background color (see below).
  • $bold: Set to true to make text bold.
  • $italic: true for italic text.
  • $underline: true for underlined text
  • $faint: true for text to appear with less intensity.
  • $strikeout: true to make text strikethrough.
  • $blink: true to make text blink.
  • $reverse: true for text to appear in video inversion.
  • $line: String containing the symbols to be used to compose the border. This is a string of 8 characters: top left corner, top horizontal line, top right corner, right vertical line, bottom right corner, bottom horizontal line, bottom left corner, left vertical line.
  • $padding: Size of bottom margin (number of empty lines above and below the text, inside the block).
  • $marginTop: Size of upper outer margin (number of empty lines above the block).
  • $marginBottom: Lower outer margin size (number of empty lines below the block).

Return value: Associative array containing the old style definition (empty array if the style didn't exist).

Example:

use \Temma\Utils\Ansi as TµAnsi;

// create the "eighties" style
TµAnsi::setStyle(
    tag: 'eighties',
    display: 'block',
    backColor: 'cyan',
    textColor: 'magenta',
    borderColor: 'white',
    bold: true,
    line: '+-+|+-+|',
    padding: 1,
    marginBottom: 1,
);
// use block
print(TµAnsi::block('eighties', "Special text"));

// modify style (remove bold, set label color)
TµAnsi::setStyle('eighties', bold: false, labelColor: 'red');

// use the style by adding a label
print(TµAnsi::style("<eighties label='Block label'>Other text</eighties>"));

Result:


7Activity indicator

When a script needs to perform lengthy processing, it can be useful to provide the user with a visual indication that the program is still running.

use \Temma\Utils\Ansi as TµAnsi;

// start activity indicator
TµAnsi::throbberStart("Processing...");

// processing
while (condition) {
    // processing...

    // run symbols
    TµAnsi::throbberGo();
}
// end of processing
TµAnsi::throbberEnd("Completed");

Result:

You can modify the animation by supplying a string or an array containing the animation elements.

use \Temma\Utils\Ansi as TµAnsi;

TµAnsi::throbberStart("Processing...", "/−\\|");
while (condition) {
    // processing...
    TµAnsi::throbberGo();
}
TµAnsi::throbberEnd("Completed");

Result:


8Progress bar

For some types of processing, it is preferable to show the user the state of progress until completion. In this case, a progress bar can be used to graphically represent this progress.

use \Temma\Utils\Ansi as TµAnsi;

// start the progress bar
TµAnsi::progressStart("Processing...");

// processing
while (condition) {
    // processing...

    // move the bar forward
    TµAnsi::progressGo();
}
// en of processing
TµAnsi::progressEnd("Completed");

Result:

The progressStart() static method can take two (optional) parameters:

  • $text (string): Default text to be displayed above the progress bar. (default value&nbp;: empty string)
  • $units (int): Number of units representing total completion. (default value: 100)

The static progressGo() method can take two (optional) parameters:

  • $units (int): Number of progress units. Can take a negative value. (default value: 1)
  • $text (string): Text to be displayed above the progress bar. (default: empty string, to use the value defined when calling progressStart())

There's also a static progressSet() method, which allows you to directly define the progress value (and not the progress increment, as the progressGo() method does). The first parameter is the progress value, and the second (optional) is the text to be displayed.

The progress bar display can be modified with the static method setProgressStyle(), which can take five parameters (all optional):

  • $backColor (string): color of the uncompleted progress bar.
  • $frontColor (string): color of the completed progress bar.
  • $percentage (bool): true to display a percentage of completion, false to display the number of units completed and the total number. (default value: true)
  • $width (int): Screen width divisor. For example, if the value is 3, the progress bar will occupy a third of the screen width. (default value: 1, to occupy the entire screen width)
  • $bold (string): false to prevent text from being bolded.
use \Temma\Utils\Ansi as TµAnsi;

// color: yellow on blue background
// display in units (not percentages) on one half of the screen
TµAnsi::setProgressStyle(
    backColor: 'blue',
    frontColor: 'yellow',
    percentage: false,
    width: 2,
    bold: false
);

// display on 120 units
TµAnsi::progressStart("Processing...", 120);

while (condition) {
    // processing...
    TµAnsi::progressGo();
}
TµAnsi::progressEnd("Completed");

Result:


9Utility methods

The \Temma\Utils\Ansi object also features two static functions that can be used to manipulate strings containing ANSI control characters.


9.1strlen()

This static method returns the number of printable characters in a UTF-8 string.

Method signature:

strlen(string $string) : int

Example:

use \Temma\Utils\Ansi as TµAnsi;

$s = TµAnsi::bold('hello');
$length = TµAnsi::strlen($s); // 5

9.2wordwrap()

This static method performs the same processing as the PHP function wordwrap(), cutting strings so that each line is no longer than the number of characters passed as a parameter, keeping words whole, but counting only printable characters. It does, however, preserve non-printable characters such as ANSI control sequences.

Method signature:

wordwrap(string $string, int $width) : string

Parameters:

  • $string: String to be cut.
  • $width: Maximum number of characters per line.

Example:

use \Temma\Utils\Ansi as TµAnsi;

$s = TµAnsi::bold('hello') . ' ' . TµAnsi::italic('world');
$s = TµAnsi::wordwrap($s, 8);
// equivalent to:
// $s = TµAnsi::bold('hello') . "\n" . TµAnsi::italic('world');