Page rendering using ANSI support

This commit is contained in:
Deon George
2021-10-02 10:02:21 +10:00
parent a24bba0481
commit b35655a163
5 changed files with 511 additions and 42 deletions

View File

@@ -38,22 +38,24 @@ class ANSI
/* MAGIC METHODS */
public function __construct(string $file)
public function __construct(string $file='')
{
$this->width = collect();
$this->ansi = collect();
$f = fopen($file,'r');
while (! feof($f)) {
$line = stream_get_line($f,self::BUFREAD,"\r");
if ($file) {
$f = fopen($file,'r');
while (! feof($f)) {
$line = stream_get_line($f,self::BUFREAD,"\r");
// If the last line is blank, we'll ignore it
if ((! feof($f)) || $line) {
$this->width->push(self::line_width($line,FALSE));
$this->ansi->push(array_map(function($item) { return ord($item); },str_split($line,1)));
// If the last line is blank, we'll ignore it
if ((! feof($f)) || $line) {
$this->width->push(self::line_width($line,FALSE));
$this->ansi->push(array_map(function($item) { return ord($item); },str_split($line,1)));
}
}
fclose($f);
}
fclose($f);
return $this->ansi;
}
@@ -85,6 +87,33 @@ class ANSI
return static::bin_to_ansi((new self($file))->ansi->toArray());
}
/**
* Convert an array of ANSI codes into a binary equivalent
*
* @param array $code
* @return string
*/
public static function ansi_code(array $code): string
{
if (!$code)
return '';
return "\x1b".chr(self::code($code));
}
/**
* Render an ANSI binary code into an ANSI string
*
* @param int $code
* @return string
*/
public static function ansi_color(int $code): string
{
static $current = [];
return "\x1b[".self::color($code,$current);
}
/**
* Convert a binary ANS file to ANSI text
*
@@ -230,7 +259,10 @@ class ANSI
foreach ($code as $item) {
switch ($item) {
// Color Reset
case 0: $result = 0; break;
case 0:
// Low Intensity
case 2: $result = 0; break;
// High Intensity
case 1: $result |= self::COLOR_HIGH; break;
@@ -262,18 +294,8 @@ class ANSI
return $result;
}
/**
* Convert binary code to ANSI escape code
*
* @param int $code
* @param array $current
* @return string
*/
private static function color(int $code,array &$current): string
public static function color_array(int $code): array
{
if (! $current)
$current = static::reset();
$h = ($code&0x01);
switch ($x=(($code>>1)&0x07)) {
@@ -301,28 +323,45 @@ class ANSI
default:
dump(['unknown color'=>$x]);
}
$return = '';
$highlight_changed = false;
if ($h !== $current['h']) {
$return .= $h;
$current['h'] = $h;
return ['h'=>$h,'f'=>$f,'b'=>$b];
}
/**
* Convert binary code to ANSI escape code
*
* @param int $code
* @param array $current
* @return string
*/
private static function color(int $code,array &$current): string
{
if (! $current)
$current = static::reset();
$return = '';
$color = self::color_array($code);
$highlight_changed = FALSE;
if ($color['h'] !== $current['h']) {
$return .= $color['h'] ?: ($code != 0x0e ? 2 : 0);
$current['h'] = $color['h'];
$highlight_changed = TRUE;
}
if ($f !== $current['f']) {
if (! $highlight_changed || $h || (($f != self::DEFAULT_FORE) || ($b != self::DEFAULT_BACK)))
$return .= (strlen($return) ? ';' : '').$f;
if ($color['f'] !== $current['f']) {
if (! $highlight_changed || $color['h'] || (($color['f'] != self::DEFAULT_FORE) || ($color['b'] != self::DEFAULT_BACK)))
$return .= (strlen($return) ? ';' : '').$color['f'];
$x = $f;
$current['f'] = $f;
$x = $color['f'];
$current['f'] = $color['f'];
}
if ($b !== $current['b']) {
if (! $highlight_changed || $h || (($x != self::DEFAULT_FORE) || ($b != self::DEFAULT_BACK)))
$return .= (strlen($return) ? ';' : '').$b;
if ($color['b'] !== $current['b']) {
if (! $highlight_changed || $color['h'] || (($x != self::DEFAULT_FORE) || ($color['b'] != self::DEFAULT_BACK)))
$return .= (strlen($return) ? ';' : '').$color['b'];
$current['b'] = $b;
$current['b'] = $color['b'];
}
return ($return !== '') ? $return.'m' : '';
@@ -354,6 +393,19 @@ class ANSI
];
}
/**
* Show a line with embedded color codes in ANSI
*
* @param string $text
* @return string
*/
public static function text_to_ansi(string $text): string
{
$ansi = preg_match('/\x1b./',$text);
return self::bin_to_ansi([array_map(function($item) {return ord($item); },str_split($text))],FALSE).((strlen($text) && $ansi) ? "\x1b[0m" : '');
}
/* METHODS */
/**