annotate vendor/consolidation/output-formatters/src/Transformations/WordWrapper.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2 namespace Consolidation\OutputFormatters\Transformations;
Chris@0 3
Chris@0 4 use Consolidation\OutputFormatters\Transformations\Wrap\CalculateWidths;
Chris@0 5 use Consolidation\OutputFormatters\Transformations\Wrap\ColumnWidths;
Chris@0 6 use Symfony\Component\Console\Helper\TableStyle;
Chris@0 7
Chris@0 8 class WordWrapper
Chris@0 9 {
Chris@0 10 protected $width;
Chris@0 11 protected $minimumWidths;
Chris@0 12
Chris@0 13 // For now, hardcode these to match what the Symfony Table helper does.
Chris@0 14 // Note that these might actually need to be adjusted depending on the
Chris@0 15 // table style.
Chris@0 16 protected $extraPaddingAtBeginningOfLine = 0;
Chris@0 17 protected $extraPaddingAtEndOfLine = 0;
Chris@0 18 protected $paddingInEachCell = 3;
Chris@0 19
Chris@0 20 public function __construct($width)
Chris@0 21 {
Chris@0 22 $this->width = $width;
Chris@0 23 $this->minimumWidths = new ColumnWidths();
Chris@0 24 }
Chris@0 25
Chris@0 26 /**
Chris@0 27 * Calculate our padding widths from the specified table style.
Chris@0 28 * @param TableStyle $style
Chris@0 29 */
Chris@0 30 public function setPaddingFromStyle(TableStyle $style)
Chris@0 31 {
Chris@0 32 $verticalBorderLen = strlen(sprintf($style->getBorderFormat(), $style->getVerticalBorderChar()));
Chris@0 33 $paddingLen = strlen($style->getPaddingChar());
Chris@0 34
Chris@0 35 $this->extraPaddingAtBeginningOfLine = 0;
Chris@0 36 $this->extraPaddingAtEndOfLine = $verticalBorderLen;
Chris@0 37 $this->paddingInEachCell = $verticalBorderLen + $paddingLen + 1;
Chris@0 38 }
Chris@0 39
Chris@0 40 /**
Chris@0 41 * If columns have minimum widths, then set them here.
Chris@0 42 * @param array $minimumWidths
Chris@0 43 */
Chris@0 44 public function setMinimumWidths($minimumWidths)
Chris@0 45 {
Chris@0 46 $this->minimumWidths = new ColumnWidths($minimumWidths);
Chris@0 47 }
Chris@0 48
Chris@0 49 /**
Chris@0 50 * Set the minimum width of just one column
Chris@0 51 */
Chris@0 52 public function minimumWidth($colkey, $width)
Chris@0 53 {
Chris@0 54 $this->minimumWidths->setWidth($colkey, $width);
Chris@0 55 }
Chris@0 56
Chris@0 57 /**
Chris@0 58 * Wrap the cells in each part of the provided data table
Chris@0 59 * @param array $rows
Chris@0 60 * @return array
Chris@0 61 */
Chris@0 62 public function wrap($rows, $widths = [])
Chris@0 63 {
Chris@0 64 $auto_widths = $this->calculateWidths($rows, $widths);
Chris@0 65
Chris@0 66 // If no widths were provided, then disable wrapping
Chris@0 67 if ($auto_widths->isEmpty()) {
Chris@0 68 return $rows;
Chris@0 69 }
Chris@0 70
Chris@0 71 // Do wordwrap on all cells.
Chris@0 72 $newrows = array();
Chris@0 73 foreach ($rows as $rowkey => $row) {
Chris@0 74 foreach ($row as $colkey => $cell) {
Chris@0 75 $newrows[$rowkey][$colkey] = $this->wrapCell($cell, $auto_widths->width($colkey));
Chris@0 76 }
Chris@0 77 }
Chris@0 78
Chris@0 79 return $newrows;
Chris@0 80 }
Chris@0 81
Chris@0 82 /**
Chris@0 83 * Determine what widths we'll use for wrapping.
Chris@0 84 */
Chris@0 85 protected function calculateWidths($rows, $widths = [])
Chris@0 86 {
Chris@0 87 // Widths must be provided in some form or another, or we won't wrap.
Chris@0 88 if (empty($widths) && !$this->width) {
Chris@0 89 return new ColumnWidths();
Chris@0 90 }
Chris@0 91
Chris@0 92 // Technically, `$widths`, if provided here, should be used
Chris@0 93 // as the exact widths to wrap to. For now we'll just treat
Chris@0 94 // these as minimum widths
Chris@0 95 $minimumWidths = $this->minimumWidths->combine(new ColumnWidths($widths));
Chris@0 96
Chris@0 97 $calculator = new CalculateWidths();
Chris@0 98 $dataCellWidths = $calculator->calculateLongestCell($rows);
Chris@0 99
Chris@0 100 $availableWidth = $this->width - $dataCellWidths->paddingSpace($this->paddingInEachCell, $this->extraPaddingAtEndOfLine, $this->extraPaddingAtBeginningOfLine);
Chris@0 101
Chris@0 102 $this->minimumWidths->adjustMinimumWidths($availableWidth, $dataCellWidths);
Chris@0 103
Chris@0 104 return $calculator->calculate($availableWidth, $dataCellWidths, $minimumWidths);
Chris@0 105 }
Chris@0 106
Chris@0 107 /**
Chris@0 108 * Wrap one cell. Guard against modifying non-strings and
Chris@0 109 * then call through to wordwrap().
Chris@0 110 *
Chris@0 111 * @param mixed $cell
Chris@0 112 * @param string $cellWidth
Chris@0 113 * @return mixed
Chris@0 114 */
Chris@0 115 protected function wrapCell($cell, $cellWidth)
Chris@0 116 {
Chris@0 117 if (!is_string($cell)) {
Chris@0 118 return $cell;
Chris@0 119 }
Chris@0 120 return wordwrap($cell, $cellWidth, "\n", true);
Chris@0 121 }
Chris@0 122 }