about summary refs log tree commit diff stats
path: root/wiki/vendor/splitbrain/php-cli/src/TableFormatter.php
diff options
context:
space:
mode:
authorahriman <ahriman@falte.red>2018-12-03 19:22:25 -0500
committerahriman <ahriman@falte.red>2018-12-03 19:22:25 -0500
commit0ae8cbf5c0b1a198b963490985b7738392ebcb97 (patch)
treeb2c77ae72c6b717e2b97492065196ac5ffb2d9e2 /wiki/vendor/splitbrain/php-cli/src/TableFormatter.php
parentf57f6cc5a2d159f90168d292437dc4bd8cd7f934 (diff)
downloadsite-0ae8cbf5c0b1a198b963490985b7738392ebcb97.tar.gz
installed dokuwiki, added to navbar, updated news
Diffstat (limited to 'wiki/vendor/splitbrain/php-cli/src/TableFormatter.php')
-rw-r--r--wiki/vendor/splitbrain/php-cli/src/TableFormatter.php307
1 files changed, 307 insertions, 0 deletions
diff --git a/wiki/vendor/splitbrain/php-cli/src/TableFormatter.php b/wiki/vendor/splitbrain/php-cli/src/TableFormatter.php
new file mode 100644
index 0000000..73fd6b3
--- /dev/null
+++ b/wiki/vendor/splitbrain/php-cli/src/TableFormatter.php
@@ -0,0 +1,307 @@
+<?php
+
+namespace splitbrain\phpcli;
+
+/**
+ * Class TableFormatter
+ *
+ * Output text in multiple columns
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @license MIT
+ */
+class TableFormatter
+{
+    /** @var string border between columns */
+    protected $border = ' ';
+
+    /** @var int the terminal width */
+    protected $max = 74;
+
+    /** @var Colors for coloring output */
+    protected $colors;
+
+    /**
+     * TableFormatter constructor.
+     *
+     * @param Colors|null $colors
+     */
+    public function __construct(Colors $colors = null)
+    {
+        // try to get terminal width
+        $width = 0;
+        if (isset($_SERVER['COLUMNS'])) {
+            // from environment
+            $width = (int)$_SERVER['COLUMNS'];
+        }
+        if (!$width) {
+            // via tput command
+            $width = @exec('tput cols');
+        }
+        if ($width) {
+            $this->max = $width - 1;
+        }
+
+        if ($colors) {
+            $this->colors = $colors;
+        } else {
+            $this->colors = new Colors();
+        }
+    }
+
+    /**
+     * The currently set border (defaults to ' ')
+     *
+     * @return string
+     */
+    public function getBorder()
+    {
+        return $this->border;
+    }
+
+    /**
+     * Set the border. The border is set between each column. Its width is
+     * added to the column widths.
+     *
+     * @param string $border
+     */
+    public function setBorder($border)
+    {
+        $this->border = $border;
+    }
+
+    /**
+     * Width of the terminal in characters
+     *
+     * initially autodetected
+     *
+     * @return int
+     */
+    public function getMaxWidth()
+    {
+        return $this->max;
+    }
+
+    /**
+     * Set the width of the terminal to assume (in characters)
+     *
+     * @param int $max
+     */
+    public function setMaxWidth($max)
+    {
+        $this->max = $max;
+    }
+
+    /**
+     * Takes an array with dynamic column width and calculates the correct width
+     *
+     * Column width can be given as fixed char widths, percentages and a single * width can be given
+     * for taking the remaining available space. When mixing percentages and fixed widths, percentages
+     * refer to the remaining space after allocating the fixed width
+     *
+     * @param array $columns
+     * @return int[]
+     * @throws Exception
+     */
+    protected function calculateColLengths($columns)
+    {
+        $idx = 0;
+        $border = $this->strlen($this->border);
+        $fixed = (count($columns) - 1) * $border; // borders are used already
+        $fluid = -1;
+
+        // first pass for format check and fixed columns
+        foreach ($columns as $idx => $col) {
+            // handle fixed columns
+            if ((string)intval($col) === (string)$col) {
+                $fixed += $col;
+                continue;
+            }
+            // check if other colums are using proper units
+            if (substr($col, -1) == '%') {
+                continue;
+            }
+            if ($col == '*') {
+                // only one fluid
+                if ($fluid < 0) {
+                    $fluid = $idx;
+                    continue;
+                } else {
+                    throw new Exception('Only one fluid column allowed!');
+                }
+            }
+            throw new Exception("unknown column format $col");
+        }
+
+        $alloc = $fixed;
+        $remain = $this->max - $alloc;
+
+        // second pass to handle percentages
+        foreach ($columns as $idx => $col) {
+            if (substr($col, -1) != '%') {
+                continue;
+            }
+            $perc = floatval($col);
+
+            $real = (int)floor(($perc * $remain) / 100);
+
+            $columns[$idx] = $real;
+            $alloc += $real;
+        }
+
+        $remain = $this->max - $alloc;
+        if ($remain < 0) {
+            throw new Exception("Wanted column widths exceed available space");
+        }
+
+        // assign remaining space
+        if ($fluid < 0) {
+            $columns[$idx] += ($remain); // add to last column
+        } else {
+            $columns[$fluid] = $remain;
+        }
+
+        return $columns;
+    }
+
+    /**
+     * Displays text in multiple word wrapped columns
+     *
+     * @param int[] $columns list of column widths (in characters, percent or '*')
+     * @param string[] $texts list of texts for each column
+     * @param array $colors A list of color names to use for each column. use empty string for default
+     * @return string
+     * @throws Exception
+     */
+    public function format($columns, $texts, $colors = array())
+    {
+        $columns = $this->calculateColLengths($columns);
+
+        $wrapped = array();
+        $maxlen = 0;
+
+        foreach ($columns as $col => $width) {
+            $wrapped[$col] = explode("\n", $this->wordwrap($texts[$col], $width, "\n", true));
+            $len = count($wrapped[$col]);
+            if ($len > $maxlen) {
+                $maxlen = $len;
+            }
+
+        }
+
+        $last = count($columns) - 1;
+        $out = '';
+        for ($i = 0; $i < $maxlen; $i++) {
+            foreach ($columns as $col => $width) {
+                if (isset($wrapped[$col][$i])) {
+                    $val = $wrapped[$col][$i];
+                } else {
+                    $val = '';
+                }
+                $chunk = $this->pad($val, $width);
+                if (isset($colors[$col]) && $colors[$col]) {
+                    $chunk = $this->colors->wrap($chunk, $colors[$col]);
+                }
+                $out .= $chunk;
+
+                // border
+                if ($col != $last) {
+                    $out .= $this->border;
+                }
+            }
+            $out .= "\n";
+        }
+        return $out;
+
+    }
+
+    /**
+     * Pad the given string to the correct length
+     *
+     * @param string $string
+     * @param int $len
+     * @return string
+     */
+    protected function pad($string, $len)
+    {
+        $strlen = $this->strlen($string);
+        if ($strlen > $len) return $string;
+
+        $pad = $len - $strlen;
+        return $string . str_pad('', $pad, ' ');
+    }
+
+    /**
+     * Measures char length in UTF-8 when possible
+     *
+     * @param $string
+     * @return int
+     */
+    protected function strlen($string)
+    {
+        // don't count color codes
+        $string = preg_replace("/\33\\[\\d+(;\\d+)?m/", '', $string);
+
+        if (function_exists('mb_strlen')) {
+            return mb_strlen($string, 'utf-8');
+        }
+
+        return strlen($string);
+    }
+
+    /**
+     * @param string $string
+     * @param int $start
+     * @param int|null $length
+     * @return string
+     */
+    protected function substr($string, $start = 0, $length = null)
+    {
+        if (function_exists('mb_substr')) {
+            return mb_substr($string, $start, $length);
+        } else {
+            return substr($string, $start, $length);
+        }
+    }
+
+    /**
+     * @param string $str
+     * @param int $width
+     * @param string $break
+     * @param bool $cut
+     * @return string
+     * @link http://stackoverflow.com/a/4988494
+     */
+    protected function wordwrap($str, $width = 75, $break = "\n", $cut = false)
+    {
+        $lines = explode($break, $str);
+        foreach ($lines as &$line) {
+            $line = rtrim($line);
+            if ($this->strlen($line) <= $width) {
+                continue;
+            }
+            $words = explode(' ', $line);
+            $line = '';
+            $actual = '';
+            foreach ($words as $word) {
+                if ($this->strlen($actual . $word) <= $width) {
+                    $actual .= $word . ' ';
+                } else {
+                    if ($actual != '') {
+                        $line .= rtrim($actual) . $break;
+                    }
+                    $actual = $word;
+                    if ($cut) {
+                        while ($this->strlen($actual) > $width) {
+                            $line .= $this->substr($actual, 0, $width) . $break;
+                            $actual = $this->substr($actual, $width);
+                        }
+                    }
+                    $actual .= ' ';
+                }
+            }
+            $line .= trim($actual);
+        }
+        return implode($break, $lines);
+    }
+}
\ No newline at end of file