Skip to content

Commit

Permalink
Merge pull request #13090 from cakephp/console-table
Browse files Browse the repository at this point in the history
Fix width calculation on formatted cells.
  • Loading branch information
markstory committed Apr 4, 2019
2 parents a594dea + 9fc0363 commit 3256439
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/Console/ConsoleIo.php
Expand Up @@ -398,7 +398,7 @@ public function outputAs($mode)
*/
public function styles($style = null, $definition = null)
{
$this->_out->styles($style, $definition);
return $this->_out->styles($style, $definition);
}

/**
Expand Down
22 changes: 20 additions & 2 deletions src/Shell/Helper/TableHelper.php
Expand Up @@ -44,7 +44,7 @@ protected function _calculateWidths($rows)
$widths = [];
foreach ($rows as $line) {
foreach (array_values($line) as $k => $v) {
$columnLength = mb_strwidth($v);
$columnLength = $this->_cellWidth($v);
if ($columnLength >= (isset($widths[$k]) ? $widths[$k] : 0)) {
$widths[$k] = $columnLength;
}
Expand All @@ -54,6 +54,24 @@ protected function _calculateWidths($rows)
return $widths;
}

/**
* Get the width of a cell exclusive of style tags.
*
* @param string $text The text to calculate a width for.
* @return int The width of the textual content in visible characters.
*/
protected function _cellWidth($text)
{
if (strpos($text, '<') === false && strpos($text, '>') === false) {
return mb_strwidth($text);
}
$styles = array_keys($this->_io->styles());
$tags = implode('|', $styles);
$text = preg_replace('#</?(?:' . $tags . ')>#', '', $text);

return mb_strwidth($text);
}

/**
* Output a row separator.
*
Expand Down Expand Up @@ -86,7 +104,7 @@ protected function _render(array $row, $widths, $options = [])

$out = '';
foreach (array_values($row) as $i => $column) {
$pad = $widths[$i] - mb_strwidth($column);
$pad = $widths[$i] - $this->_cellWidth($column);
if (!empty($options['style'])) {
$column = $this->_addStyle($column, $options['style']);
}
Expand Down
27 changes: 25 additions & 2 deletions tests/TestCase/Shell/Helper/TableHelperTest.php
@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* CakePHP : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
Expand Down Expand Up @@ -270,6 +271,28 @@ public function testOutputWithoutHeaders()
$this->assertEquals($expected, $this->stub->messages());
}

/**
* Test output with formatted cells
*
* @return void
*/
public function testOutputWithFormattedCells()
{
$data = [
['short', 'Longish thing', '<info>short</info>'],
['Longer thing', 'short', '<warning>Longest</warning> <error>Value</error>'],
];
$this->helper->setConfig(['headers' => false]);
$this->helper->output($data);
$expected = [
'+--------------+---------------+---------------+',
'| short | Longish thing | <info>short</info> |',
'| Longer thing | short | <warning>Longest</warning> <error>Value</error> |',
'+--------------+---------------+---------------+',
];
$this->assertEquals($expected, $this->stub->messages());
}

/**
* Test output with row separator
*
Expand All @@ -280,7 +303,7 @@ public function testOutputWithRowSeparator()
$data = [
['Header 1', 'Header', 'Long Header'],
['short', 'Longish thing', 'short'],
['Longer thing', 'short', 'Longest Value']
['Longer thing', 'short', 'Longest Value'],
];
$this->helper->setConfig(['rowSeparator' => true]);
$this->helper->output($data);
Expand Down Expand Up @@ -337,7 +360,7 @@ public function testOutputWithNoData()
public function testOutputWithHeaderAndNoData()
{
$data = [
['Header 1', 'Header', 'Long Header']
['Header 1', 'Header', 'Long Header'],
];
$this->helper->output($data);
$expected = [
Expand Down

0 comments on commit 3256439

Please sign in to comment.