2 namespace Consolidation\OutputFormatters\Transformations;
4 use Consolidation\OutputFormatters\Transformations\Wrap\CalculateWidths;
5 use Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths;
6 use Symfony\Component\Console\Helper\TableStyle;
11 protected $minimumWidths;
13 // For now, hardcode these to match what the Symfony Table helper does.
14 // Note that these might actually need to be adjusted depending on the
16 protected $extraPaddingAtBeginningOfLine = 0;
17 protected $extraPaddingAtEndOfLine = 0;
18 protected $paddingInEachCell = 3;
20 public function __construct($width)
22 $this->width = $width;
23 $this->minimumWidths = new ColumnWidths();
27 * Calculate our padding widths from the specified table style.
28 * @param TableStyle $style
30 public function setPaddingFromStyle(TableStyle $style)
32 $verticalBorderLen = strlen(sprintf($style->getBorderFormat(), $style->getVerticalBorderChar()));
33 $paddingLen = strlen($style->getPaddingChar());
35 $this->extraPaddingAtBeginningOfLine = 0;
36 $this->extraPaddingAtEndOfLine = $verticalBorderLen;
37 $this->paddingInEachCell = $verticalBorderLen + $paddingLen + 1;
41 * If columns have minimum widths, then set them here.
42 * @param array $minimumWidths
44 public function setMinimumWidths($minimumWidths)
46 $this->minimumWidths = new ColumnWidths($minimumWidths);
50 * Set the minimum width of just one column
52 public function minimumWidth($colkey, $width)
54 $this->minimumWidths->setWidth($colkey, $width);
58 * Wrap the cells in each part of the provided data table
62 public function wrap($rows, $widths = [])
64 $auto_widths = $this->calculateWidths($rows, $widths);
66 // If no widths were provided, then disable wrapping
67 if ($auto_widths->isEmpty()) {
71 // Do wordwrap on all cells.
73 foreach ($rows as $rowkey => $row) {
74 foreach ($row as $colkey => $cell) {
75 $newrows[$rowkey][$colkey] = $this->wrapCell($cell, $auto_widths->width($colkey));
83 * Determine what widths we'll use for wrapping.
85 protected function calculateWidths($rows, $widths = [])
87 // Widths must be provided in some form or another, or we won't wrap.
88 if (empty($widths) && !$this->width) {
89 return new ColumnWidths();
92 // Technically, `$widths`, if provided here, should be used
93 // as the exact widths to wrap to. For now we'll just treat
94 // these as minimum widths
95 $minimumWidths = $this->minimumWidths->combine(new ColumnWidths($widths));
97 $calculator = new CalculateWidths();
98 $dataCellWidths = $calculator->calculateLongestCell($rows);
100 $availableWidth = $this->width - $dataCellWidths->paddingSpace($this->paddingInEachCell, $this->extraPaddingAtEndOfLine, $this->extraPaddingAtBeginningOfLine);
102 $this->minimumWidths->adjustMinimumWidths($availableWidth, $dataCellWidths);
104 return $calculator->calculate($availableWidth, $dataCellWidths, $minimumWidths);
108 * Wrap one cell. Guard against modifying non-strings and
109 * then call through to wordwrap().
112 * @param string $cellWidth
115 protected function wrapCell($cell, $cellWidth)
117 if (!is_string($cell)) {
120 return wordwrap($cell, $cellWidth, "\n", true);