Hoa central
Text.php
Go to the documentation of this file.
1 <?php
2 
37 namespace Hoa\Console\Chrome;
38 
39 use Hoa\Console;
40 
49 class Text
50 {
56  const ALIGN_LEFT = 0;
57 
63  const ALIGN_RIGHT = 1;
64 
70  const ALIGN_CENTER = 2;
71 
72 
73 
83  public static function colorize(
84  $text,
85  $attributesBefore,
86  $attributesAfter = 'normal'
87  ) {
88  ob_start();
89  Console\Cursor::colorize($attributesBefore);
90  echo $text;
91  Console\Cursor::colorize($attributesAfter);
92  $out = ob_get_contents();
93  ob_end_clean();
94 
95  return $out;
96  }
97 
126  public static function columnize(
127  Array $line,
128  $alignement = self::ALIGN_LEFT,
129  $horizontalPadding = 2,
130  $verticalPadding = 0,
131  $separator = null
132  ) {
133  if (empty($line)) {
134  return '';
135  }
136 
137  $separator = explode('|', $separator);
138  $nbColumn = 0;
139  $nbLine = count($line);
140  $xtraWidth = 2 * ($verticalPadding + 2); // + separator
141 
142  // Get the number of column.
143  foreach ($line as $key => &$column) {
144  if (!is_array($column)) {
145  $column = [$column];
146  }
147 
148  $handle = count($column);
149  $handle > $nbColumn and $nbColumn = $handle;
150  }
151 
152  $xtraWidth += $horizontalPadding * $nbColumn;
153 
154  // Get the column width.
155  $columnWidth = array_fill(0, $nbColumn, 0);
156 
157  for ($e = 0; $e < $nbColumn; $e++) {
158  for ($i = 0; $i < $nbLine; $i++) {
159  if (!isset($line[$i][$e])) {
160  continue;
161  }
162 
163  $handle = self::getMaxLineWidth($line[$i][$e]);
164  $handle > $columnWidth[$e] and $columnWidth[$e] = $handle;
165  }
166  }
167 
168  // If the sum of each column is greater than the window width, we reduce
169  // all greaters columns.
170  $window = Console\Window::getSize();
171  $envWindow = $window['x'];
172 
173  while ($envWindow <= ($cWidthSum = $xtraWidth + array_sum($columnWidth))) {
174  $diff = $cWidthSum - $envWindow;
175  $max = max($columnWidth) - $xtraWidth;
176  $newWidth = $max - $diff;
177  $i = array_search(max($columnWidth), $columnWidth);
178  $columnWidth[$i] = $newWidth;
179 
180  foreach ($line as $key => &$c) {
181  if (isset($c[$i])) {
182  $c[$i] = self::wordwrap($c[$i], $newWidth);
183  }
184  }
185  }
186 
187  // Manage the horizontal right padding.
188  $columnWidth = array_map(
189  function ($x) use ($horizontalPadding) {
190  return $x + 2 * $horizontalPadding;
191  },
192  $columnWidth
193  );
194 
195  // Prepare the new table, i.e. a new line (\n) must be a new line in the
196  // array (structurally meaning).
197  $newLine = [];
198  foreach ($line as $key => $plpl) {
199  $i = self::getMaxLineNumber($plpl);
200  while ($i-- >= 0) {
201  $newLine[] = array_fill(0, $nbColumn, null);
202  }
203  }
204 
205  $yek = 0;
206  foreach ($line as $key => $col) {
207  foreach ($col as $kkey => $value) {
208  if (false === strpos($value, "\n")) {
209  $newLine[$yek][$kkey] = $value;
210 
211  continue;
212  }
213 
214  foreach (explode("\n", $value) as $foo => $oof) {
215  $newLine[$yek + $foo][$kkey] = $oof;
216  }
217  }
218 
219  $i = self::getMaxLineNumber($col);
220  $i > 0 and $yek += $i;
221  $yek++;
222  }
223 
224  // Place the column separator.
225  foreach ($newLine as $key => $col) {
226  foreach ($col as $kkey => $value) {
227  if (isset($separator[$kkey])) {
228  $newLine[$key][$kkey] =
229  $separator[$kkey] .
230  str_replace(
231  "\n",
232  "\n" . $separator[$kkey],
233  $value
234  );
235  }
236  }
237  }
238 
239  $line = $newLine;
240  unset($newLine);
241 
242  // Complete the table with empty cells.
243  foreach ($line as $key => &$column) {
244  $handle = count($column);
245 
246  if ($nbColumn - $handle > 0) {
247  $column += array_fill($handle, $nbColumn - $handle, null);
248  }
249  }
250 
251  // Built!
252  $out = null;
253  $dash = $alignement === self::ALIGN_LEFT ? '-' : '';
254  foreach ($line as $key => $handle) {
255  $format = null;
256 
257  foreach ($handle as $i => $hand) {
258  if (preg_match_all('#(\\e\[[0-9]+m)#', $hand, $match)) {
259  $a = $columnWidth[$i];
260 
261  foreach ($match as $m) {
262  $a += strlen($m[1]);
263  }
264 
265  $format .= '%' . $dash . ($a + floor(count($match) / 2)) . 's';
266  } else {
267  $format .= '%' . $dash . $columnWidth[$i] . 's';
268  }
269  }
270 
271  $format .= str_repeat("\n", $verticalPadding + 1);
272 
273  array_unshift($handle, $format);
274  $out .= call_user_func_array('sprintf', $handle);
275  }
276 
277  return $out;
278  }
279 
288  public static function align(
289  $text,
290  $alignement = self::ALIGN_LEFT,
291  $width = null
292  ) {
293  if (null === $width) {
294  $window = Console\Window::getSize();
295  $width = $window['x'];
296  }
297 
298  $out = null;
299 
300  switch ($alignement) {
301  case self::ALIGN_LEFT:
302  $out .= sprintf('%-' . $width . 's', self::wordwrap($text, $width));
303 
304  break;
305 
306  case self::ALIGN_CENTER:
307  foreach (explode("\n", self::wordwrap($text, $width)) as $key => $value) {
308  $out .= str_repeat(' ', ceil(($width - strlen($value)) / 2)) .
309  $value . "\n";
310  }
311 
312  break;
313 
314  case self::ALIGN_RIGHT:
315  default:
316  foreach (explode("\n", self::wordwrap($text, $width)) as $key => $value) {
317  $out .= sprintf('%' . $width . 's' . "\n", $value);
318  }
319 
320  break;
321  }
322 
323  return $out;
324  }
325 
332  protected static function getMaxLineWidth($lines)
333  {
334  if (!is_array($lines)) {
335  $lines = [$lines];
336  }
337 
338  $width = 0;
339 
340  foreach ($lines as $foo => $line) {
341  foreach (explode("\n", $line) as $fooo => $lin) {
342  $lin = preg_replace('#\\e\[[0-9]+m#', '', $lin);
343  strlen($lin) > $width and $width = strlen($lin);
344  }
345  }
346 
347  return $width;
348  }
349 
356  protected static function getMaxLineNumber($lines)
357  {
358  if (!is_array($lines)) {
359  $lines = [$lines];
360  }
361 
362  $number = 0;
363 
364  foreach ($lines as $foo => $line) {
365  substr_count($line, "\n") > $number and
366  $number = substr_count($line, "\n");
367  }
368 
369  return $number;
370  }
371 
380  public static function wordwrap($text, $width = null, $break = "\n")
381  {
382  if (null === $width) {
383  $window = Console\Window::getSize();
384  $width = $window['x'];
385  }
386 
387  return wordwrap($text, $width, $break, true);
388  }
389 
397  public static function underline($text, $pattern = '*')
398  {
399  $text = explode("\n", $text);
400  $card = strlen($pattern);
401 
402  foreach ($text as $key => &$value) {
403  $i = -1;
404  $max = strlen($value);
405  while ($value{++$i} == ' ' && $i < $max);
406 
407  $underline =
408  str_repeat(' ', $i) .
409  str_repeat($pattern, strlen(trim($value)) / $card) .
410  str_repeat(' ', strlen($value) - $i - strlen(trim($value)));
411 
412  $value .= "\n" . $underline;
413  }
414 
415  return implode("\n", $text);
416  }
417 }
static underline($text, $pattern= '*')
Definition: Text.php:397
static align($text, $alignement=self::ALIGN_LEFT, $width=null)
Definition: Text.php:288
static getMaxLineWidth($lines)
Definition: Text.php:332
static getMaxLineNumber($lines)
Definition: Text.php:356
static getSize()
Definition: Window.php:118
static colorize($attributes)
Definition: Cursor.php:379
static wordwrap($text, $width=null, $break="\n")
Definition: Text.php:380
static columnize(Array $line, $alignement=self::ALIGN_LEFT, $horizontalPadding=2, $verticalPadding=0, $separator=null)
Definition: Text.php:126
static colorize($text, $attributesBefore, $attributesAfter= 'normal')
Definition: Text.php:83