fix: account for Phred tags in TableAdapter width calculation and alignment
This commit is contained in:
parent
da1efaba55
commit
a657802c70
|
|
@ -86,12 +86,12 @@ class TableAdapter implements TableInterface
|
|||
$widths = [];
|
||||
|
||||
foreach ($this->headers as $index => $header) {
|
||||
$widths[$index] = mb_strlen((string)$header);
|
||||
$widths[$index] = $this->getContentLength((string)$header);
|
||||
}
|
||||
|
||||
foreach ($this->rows as $row) {
|
||||
foreach ($row as $index => $value) {
|
||||
$width = mb_strlen((string)$value);
|
||||
$width = $this->getContentLength((string)$value);
|
||||
if (!isset($widths[$index]) || $width > $widths[$index]) {
|
||||
$widths[$index] = $width;
|
||||
}
|
||||
|
|
@ -118,11 +118,54 @@ class TableAdapter implements TableInterface
|
|||
default => STR_PAD_RIGHT,
|
||||
};
|
||||
|
||||
$formatted .= ' ' . str_pad($value, $width, ' ', $padType) . ' |';
|
||||
// We need to account for tags in the value when padding
|
||||
$displayValue = $this->stripTags($value);
|
||||
$displayLength = mb_strlen($displayValue);
|
||||
$paddingLength = $width - $displayLength;
|
||||
|
||||
if ($paddingLength < 0) {
|
||||
$paddingLength = 0;
|
||||
}
|
||||
|
||||
$leftPadding = 0;
|
||||
$rightPadding = 0;
|
||||
|
||||
if ($padType === STR_PAD_LEFT) {
|
||||
$leftPadding = $paddingLength;
|
||||
} elseif ($padType === STR_PAD_BOTH) {
|
||||
$leftPadding = (int) floor($paddingLength / 2);
|
||||
$rightPadding = (int) ceil($paddingLength / 2);
|
||||
} else {
|
||||
$rightPadding = $paddingLength;
|
||||
}
|
||||
|
||||
$formatted .= ' ' . str_repeat(' ', $leftPadding) . $value . str_repeat(' ', $rightPadding) . ' |';
|
||||
}
|
||||
$this->output->writeln($formatted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips Phred console tags from a string.
|
||||
*
|
||||
* @param string $text
|
||||
* @return string
|
||||
*/
|
||||
private function stripTags(string $text): string
|
||||
{
|
||||
return preg_replace('/<[a-z]+>(.*?)<\/.*?>/i', '$1', $text) ?? $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the length of a string without console tags.
|
||||
*
|
||||
* @param string $text
|
||||
* @return int
|
||||
*/
|
||||
private function getContentLength(string $text): int
|
||||
{
|
||||
return mb_strlen($this->stripTags($text));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, int> $widths
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -71,6 +71,27 @@ class PhredBridgeTest extends TestCase
|
|||
$this->assertStringContainsString('| Active |', $content);
|
||||
}
|
||||
|
||||
public function testTableAdapterWithTags(): void
|
||||
{
|
||||
$output = new OutputAdapter(false);
|
||||
$table = new TableAdapter($output);
|
||||
|
||||
// Header with tags (8 chars displayed, more in raw string)
|
||||
$table->setHeaders(['<info>ID</info>', 'Name']);
|
||||
$table->addRow(['1', 'John']);
|
||||
|
||||
ob_start();
|
||||
$table->render();
|
||||
$content = ob_get_clean();
|
||||
|
||||
// If bug exists, the ID column width will be 13 (mb_strlen('<info>ID</info>'))
|
||||
// but it should be 2 (length of 'ID')
|
||||
// The separator line will have '-' x (width + 2)
|
||||
// Correct width 2 -> "+----+"
|
||||
// Buggy width 13 -> "+---------------+"
|
||||
$this->assertStringContainsString('+----+', $content);
|
||||
}
|
||||
|
||||
public function testMarkdownConverter(): void
|
||||
{
|
||||
$output = new OutputAdapter(false);
|
||||
|
|
|
|||
Loading…
Reference in a new issue