16 return rtrim($line,
"\r\n");
25 public static function prompt($message,$options = null,$default = null){
27 print($message . (is_array($options) ?
' [' . Record::implode($options,
',',
'=') .
']' :
'') . ($default ?
" ($default)" :
'') .
': ');
28 if(($result = self::readLine()) ===
'') $result = $default;
30 while($options && !(is_array($options) ? array_key_exists($result,$options) : preg_match($options,$result)));
41 public static function header($header,$width = 80,$font = null,$pad = null){
42 $length = strlen($header);
43 $image = imagecreate($width * 2,$width);
44 $background = imagecolorallocate($image,0,0,0);
45 $color = imagecolorallocate($image,0,0,255);
46 $check = imagecolorallocate($image,0,255,0);
47 for($font = $font ?: 5; $font; $font--){
48 $size= imagefontwidth($font);
49 imagefilledrectangle($image,0,0,$width * 2,$height = imagefontheight($font),$background);
51 for($i = 0; $i < $length; $i++)
if(trim($c = $header[$i])){
52 if($i && trim($header[$i - 1])){
54 imagestring($image,$font,--$x,0,$c,$check);
56 for($cx = max(0,$x - $size); $cx < min($width * 2,$x + $size); $cx++)
for($cy = 0; $cy < $height; $cy++)
57 if($touch = (!$cx || (imagecolorat($image,$cx - 1,$cy) == $color)) && (
58 (($cy > 0) && (($cx && (imagecolorat($image,$cx - 1,$cy - 1) == $check)) || (imagecolorat($image,$cx,$cy - 1) == $check))) ||
59 (imagecolorat($image,$cx,$cy) == $check) ||
60 (($cy < $height - 1) && (($cx && (imagecolorat($image,$cx - 1,$cy + 1) == $check)) || (imagecolorat($image,$cx,$cy + 1) == $check)))
62 imagestring($image,$font,$x,0,$c,$background);
67 imagestring($image,$font,$x,0,$c,$color);
68 if(($x += $size) > $width * 2)
break;
70 else $x += round($size / 2);
72 for($y = 0; $y < $height; $y++){
74 for($x = 0; $x < $width * 2; $x++) $line .= imagecolorat($image,$x,$y) ?
'#' :
' ';
75 if($line = rtrim($line)) $max = max($max,strlen($lines[] = $line));
77 if($max <= $width)
break;
85 case STR_PAD_RIGHT: $lines = Record::prefix($lines,str_repeat(
' ',$width - $max));
break;
86 case STR_PAD_BOTH: $lines = Record::prefix($lines,str_repeat(
' ',round(($width - $max) / 2)));
break;
88 return implode(
"\n",$lines);
97 public static function block($str,$width = 80,$pad = null){
98 $text = $border = str_repeat(
'*',$width);
99 foreach(Str::wrap($str,$width -= 8) as $line) $text .=
"\n** " . Str::pad($line,$width,
' ',$pad ?: STR_PAD_RIGHT) .
" **";
100 return $text .
"\n" . $border;
108 public static function gauge($perc = 0,$width = 80){
109 $done = round($perc * $width / 100);
110 $text = str_repeat(
'#',$done) . str_repeat(
'-',$width - $done);
111 $start = round(($width - ($length = strlen($perc =
' ' . round($perc) .
'% '))) / 2);
112 return substr($text,0,$start) . $perc . substr($text,$start + $length);
115 protected static function tableRow($record,$columns){
118 foreach($columns as $key => $column) $max_lines = max($max_lines,count($columns[$key][
'lines'] = Str::wrap($record[$key] ?? null,$column[
'width'])));
119 $last = Record::key($columns,-1);
120 for($i = 0; $i < $max_lines; $i++){
121 $text .= [
'|',
'/',
':',
'\\'][$border = $max_lines <= 1 ? 0 : ($i ? ($i == $max_lines - 1 ? 3 : 2) : 1)];
122 foreach($columns as $key => $column)
123 $text .=
' ' . \Rsi\Str::pad($column[
'lines'][$i] ?? null,$column[
'width'],
' ',$column[
'pad'] ?? STR_PAD_RIGHT) .
' ' . ($key == $last ? [
'|',
'\\',
':',
'/'][$border] :
'|');
136 public static function table($data,$columns = null,$width = 80){
138 if($count = count($data = array_values($data))){
139 if(!$columns) $columns = array_fill_keys(array_keys($data[0]),[]);
140 $headers = $footers = $max_length = [];
141 foreach($columns as $key => $column) $max_length[$key] = max(mb_strlen($headers[$key] = $column[
'header'] ?? $key),mb_strlen($footers[$key] = $column[
'footer'] ?? null));
142 $average_length = $max_length;
143 foreach($data as $record)
foreach($columns as $key => $column){
144 $length = mb_strlen($record[$key] ?? null);
145 if($column[
'width'] ?? null) $length = min($length,$column[
'width']);
146 $average_length[$key] += $length;
147 $max_length[$key] = max($max_length[$key],$length);
150 foreach($columns as $key => $column){
151 $average_length[$key] /= $count;
152 $total_width += ($columns[$key][
'width'] = $max_length[$key]) + 3;
154 if($total_width > $width){
155 $factor = ($width - 1 - count($columns) * 3) / array_sum($average_length);
157 foreach($columns as $key => $column) $total_width += ($columns[$key][
'width'] = min($max_length[$key],max(1,floor($factor * $average_length[$key])))) + 3;
158 while($total_width < $width){
159 $min_key = $min_width = null;
160 foreach($columns as $key => $column)
if((!$min_key || ($column[
'width'] < $min_width)) && ($column[
'width'] < $max_length[$key])){
162 $min_width = $column[
'width'];
164 $columns[$min_key][
'width']++;
169 foreach($columns as $key => $column) $border .= str_repeat(
'-',$column[
'width'] + 2) .
'+';
170 $text = $border .
"\n" . self::tableRow($headers,$columns) . $border .
"\n";
171 foreach($data as $record) $text .= self::tableRow($record,$columns);
173 if(array_filter($footers)) $text .=
"\n" . self::tableRow($footers,$columns) . $border;
static prompt($message, $options=null, $default=null)
Ask a question.
static readLine()
Read an input line.
static header($header, $width=80, $font=null, $pad=null)
Large header text.
static tableRow($record, $columns)
static gauge($perc=0, $width=80)
Text style gauge.
static block($str, $width=80, $pad=null)
Text block.
static table($data, $columns=null, $width=80)
Text style table.