feature #13438 [Console][Table] Add support for colspan/rowspan + multiple header lines (aitboudad)
This PR was squashed before being merged into the 2.7 branch (closes #13438).
Discussion
----------
[Console][Table] Add support for colspan/rowspan + multiple header lines
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Fixed tickets | #13368, #13369
| Tests pass? | yes
| License | MIT
This PR introduce a new feature described in #13368 and #13369,
I created a new class ```TableCell``` which can allow us to specify colspan/rowspan for each cell.
```php
$table->addRow([new TableCell("data", array('rowspan' => 1, 'colspan' => 2)), 'data']);
```
- [x] #13368 Add support for colspan/rowspan
- [x] #13369 Add support for multiple header lines
- [ ] add doc
Commits
-------
ed18767
[Console][Table] Add support for colspan/rowspan + multiple header lines
This commit is contained in:
commit
350f30b0e1
@ -18,6 +18,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Саша Стаменковић <umpirsky@gmail.com>
|
||||
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
|
||||
*/
|
||||
class Table
|
||||
{
|
||||
@ -139,7 +140,12 @@ class Table
|
||||
|
||||
public function setHeaders(array $headers)
|
||||
{
|
||||
$this->headers = array_values($headers);
|
||||
$headers = array_values($headers);
|
||||
if (!empty($headers) && !is_array($headers[0])) {
|
||||
$headers = array($headers);
|
||||
}
|
||||
|
||||
$this->headers = $headers;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -174,30 +180,6 @@ class Table
|
||||
|
||||
$this->rows[] = array_values($row);
|
||||
|
||||
end($this->rows);
|
||||
$rowKey = key($this->rows);
|
||||
reset($this->rows);
|
||||
|
||||
foreach ($row as $key => $cellValue) {
|
||||
if (!strstr($cellValue, "\n")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lines = explode("\n", $cellValue);
|
||||
$this->rows[$rowKey][$key] = $lines[0];
|
||||
unset($lines[0]);
|
||||
|
||||
foreach ($lines as $lineKey => $line) {
|
||||
$nextRowKey = $rowKey + $lineKey + 1;
|
||||
|
||||
if (isset($this->rows[$nextRowKey])) {
|
||||
$this->rows[$nextRowKey][$key] = $line;
|
||||
} else {
|
||||
$this->rows[$nextRowKey] = array($key => $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -222,10 +204,16 @@ class Table
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$this->calculateNumberOfColumns();
|
||||
$this->rows = $this->buildTableRows($this->rows);
|
||||
$this->headers = $this->buildTableRows($this->headers);
|
||||
|
||||
$this->renderRowSeparator();
|
||||
$this->renderRow($this->headers, $this->style->getCellHeaderFormat());
|
||||
if (!empty($this->headers)) {
|
||||
$this->renderRowSeparator();
|
||||
foreach ($this->headers as $header) {
|
||||
$this->renderRow($header, $this->style->getCellHeaderFormat());
|
||||
$this->renderRowSeparator();
|
||||
}
|
||||
}
|
||||
foreach ($this->rows as $row) {
|
||||
if ($row instanceof TableSeparator) {
|
||||
@ -248,7 +236,7 @@ class Table
|
||||
*/
|
||||
private function renderRowSeparator()
|
||||
{
|
||||
if (0 === $count = $this->getNumberOfColumns()) {
|
||||
if (0 === $count = $this->numberOfColumns) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -287,7 +275,7 @@ class Table
|
||||
}
|
||||
|
||||
$this->renderColumnSeparator();
|
||||
for ($column = 0, $count = $this->getNumberOfColumns(); $column < $count; $column++) {
|
||||
foreach ($this->getRowColumns($row) as $column) {
|
||||
$this->renderCell($row, $column, $cellFormat);
|
||||
$this->renderColumnSeparator();
|
||||
}
|
||||
@ -305,38 +293,215 @@ class Table
|
||||
{
|
||||
$cell = isset($row[$column]) ? $row[$column] : '';
|
||||
$width = $this->getColumnWidth($column);
|
||||
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
|
||||
// add the width of the following columns(numbers of colspan).
|
||||
foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
|
||||
$width += $this->getColumnSeparatorWidth() + $this->getColumnWidth($nextColumn);
|
||||
}
|
||||
}
|
||||
|
||||
// str_pad won't work properly with multi-byte strings, we need to fix the padding
|
||||
if (function_exists('mb_strwidth') && false !== $encoding = mb_detect_encoding($cell)) {
|
||||
$width += strlen($cell) - mb_strwidth($cell, $encoding);
|
||||
}
|
||||
|
||||
$width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
|
||||
|
||||
$content = sprintf($this->style->getCellRowContentFormat(), $cell);
|
||||
|
||||
$this->output->write(sprintf($cellFormat, str_pad($content, $width, $this->style->getPaddingChar(), $this->style->getPadType())));
|
||||
if ($cell instanceof TableSeparator) {
|
||||
$this->output->write(sprintf($this->style->getBorderFormat(), str_repeat($this->style->getHorizontalBorderChar(), $width)));
|
||||
} else {
|
||||
$width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
|
||||
$content = sprintf($this->style->getCellRowContentFormat(), $cell);
|
||||
$this->output->write(sprintf($cellFormat, str_pad($content, $width, $this->style->getPaddingChar(), $this->style->getPadType())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of columns for this table.
|
||||
*
|
||||
* @return int
|
||||
* Calculate number of columns for this table.
|
||||
*/
|
||||
private function getNumberOfColumns()
|
||||
private function calculateNumberOfColumns()
|
||||
{
|
||||
if (null !== $this->numberOfColumns) {
|
||||
return $this->numberOfColumns;
|
||||
return;
|
||||
}
|
||||
|
||||
$columns = array(count($this->headers));
|
||||
foreach ($this->rows as $row) {
|
||||
$columns[] = count($row);
|
||||
$columns = array(0);
|
||||
foreach (array_merge($this->headers, $this->rows) as $row) {
|
||||
if ($row instanceof TableSeparator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$columns[] = $this->getNumberOfColumns($row);
|
||||
}
|
||||
|
||||
return $this->numberOfColumns = max($columns);
|
||||
}
|
||||
|
||||
private function buildTableRows($rows)
|
||||
{
|
||||
$unmergedRows = array();
|
||||
for ($rowKey = 0; $rowKey < count($rows); $rowKey++) {
|
||||
$rows = $this->fillNextRows($rows, $rowKey);
|
||||
|
||||
// Remove any new line breaks and replace it with a new line
|
||||
foreach ($rows[$rowKey] as $column => $cell) {
|
||||
$rows[$rowKey] = $this->fillCells($rows[$rowKey], $column);
|
||||
if (!strstr($cell, "\n")) {
|
||||
continue;
|
||||
}
|
||||
$lines = explode("\n", $cell);
|
||||
foreach ($lines as $lineKey => $line) {
|
||||
if ($cell instanceof TableCell) {
|
||||
$line = new TableCell($line, array('colspan' => $cell->getColspan()));
|
||||
}
|
||||
if (0 === $lineKey) {
|
||||
$rows[$rowKey][$column] = $line;
|
||||
} else {
|
||||
$unmergedRows[$rowKey][$lineKey][$column] = $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tableRows = array();
|
||||
foreach ($rows as $rowKey => $row) {
|
||||
$tableRows[] = $row;
|
||||
if (isset($unmergedRows[$rowKey])) {
|
||||
$tableRows = array_merge($tableRows, $unmergedRows[$rowKey]);
|
||||
}
|
||||
}
|
||||
|
||||
return $tableRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* fill rows that contains rowspan > 1.
|
||||
*
|
||||
* @param array $rows
|
||||
* @param array $line
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function fillNextRows($rows, $line)
|
||||
{
|
||||
$unmergedRows = array();
|
||||
foreach ($rows[$line] as $column => $cell) {
|
||||
if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
|
||||
$nbLines = $cell->getRowspan()-1;
|
||||
$lines = array($cell);
|
||||
if (strstr($cell, "\n")) {
|
||||
$lines = explode("\n", $cell);
|
||||
$nbLines = count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines;
|
||||
|
||||
$rows[$line][$column] = new TableCell($lines[0], array('colspan' => $cell->getColspan()));
|
||||
unset($lines[0]);
|
||||
}
|
||||
|
||||
// create a two dimensional array (rowspan x colspan)
|
||||
$unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, ''), $unmergedRows);
|
||||
foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
|
||||
$value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : '';
|
||||
$unmergedRows[$unmergedRowKey][$column] = new TableCell($value, array('colspan' => $cell->getColspan()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
|
||||
// we need to know if $unmergedRow will be merged or inserted into $rows
|
||||
if (isset($rows[$unmergedRowKey]) && is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) {
|
||||
foreach ($unmergedRow as $cellKey => $cell) {
|
||||
// insert cell into row at cellKey position
|
||||
array_splice($rows[$unmergedRowKey], $cellKey, 0, array($cell));
|
||||
}
|
||||
} else {
|
||||
$row = $this->copyRow($rows, $unmergedRowKey-1);
|
||||
foreach ($unmergedRow as $column => $cell) {
|
||||
if (!empty($cell)) {
|
||||
$row[$column] = $unmergedRow[$column];
|
||||
}
|
||||
}
|
||||
array_splice($rows, $unmergedRowKey, 0, array($row));
|
||||
}
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* fill cells for a row that contains colspan > 1.
|
||||
*
|
||||
* @param array $row
|
||||
* @param array $column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function fillCells($row, $column)
|
||||
{
|
||||
$cell = $row[$column];
|
||||
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
|
||||
foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) {
|
||||
// insert empty value into rows at column position
|
||||
array_splice($row, $position, 0, '');
|
||||
}
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $rows
|
||||
* @param int $line
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function copyRow($rows, $line)
|
||||
{
|
||||
$row = $rows[$line];
|
||||
foreach ($row as $cellKey => $cellValue) {
|
||||
$row[$cellKey] = '';
|
||||
if ($cellValue instanceof TableCell) {
|
||||
$row[$cellKey] = new TableCell('', array('colspan' => $cellValue->getColspan()));
|
||||
}
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of columns by row.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getNumberOfColumns(array $row)
|
||||
{
|
||||
$columns = count($row);
|
||||
foreach ($row as $column) {
|
||||
$columns += $column instanceof TableCell ? ($column->getColspan()-1) : 0;
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets list of columns for the given row.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return array()
|
||||
*/
|
||||
private function getRowColumns($row)
|
||||
{
|
||||
$columns = range(0, $this->numberOfColumns-1);
|
||||
foreach ($row as $cellKey => $cell) {
|
||||
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
|
||||
// exclude grouped columns.
|
||||
$columns = array_diff($columns, range($cellKey+1, $cellKey + $cell->getColspan()-1));
|
||||
}
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets column width.
|
||||
*
|
||||
@ -350,8 +515,7 @@ class Table
|
||||
return $this->columnWidths[$column];
|
||||
}
|
||||
|
||||
$lengths = array($this->getCellWidth($this->headers, $column));
|
||||
foreach ($this->rows as $row) {
|
||||
foreach (array_merge($this->headers, $this->rows) as $row) {
|
||||
if ($row instanceof TableSeparator) {
|
||||
continue;
|
||||
}
|
||||
@ -362,6 +526,18 @@ class Table
|
||||
return $this->columnWidths[$column] = max($lengths) + strlen($this->style->getCellRowContentFormat()) - 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets column width.
|
||||
*
|
||||
* @param int $column
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getColumnSeparatorWidth()
|
||||
{
|
||||
return strlen(sprintf($this->style->getBorderFormat(), $this->style->getVerticalBorderChar()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets cell width.
|
||||
*
|
||||
@ -372,7 +548,17 @@ class Table
|
||||
*/
|
||||
private function getCellWidth(array $row, $column)
|
||||
{
|
||||
return isset($row[$column]) ? Helper::strlenWithoutDecoration($this->output->getFormatter(), $row[$column]) : 0;
|
||||
if (isset($row[$column])) {
|
||||
$cell = $row[$column];
|
||||
if ($cell instanceof TableCell && $cell->getColspan() > 1) {
|
||||
// we assume that cell value will be across more than one column.
|
||||
$cell = substr($cell, 0, strlen($cell)/$cell->getColspan());
|
||||
}
|
||||
|
||||
return Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
77
src/Symfony/Component/Console/Helper/TableCell.php
Normal file
77
src/Symfony/Component/Console/Helper/TableCell.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Helper;
|
||||
|
||||
/**
|
||||
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
|
||||
*/
|
||||
class TableCell
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options = array(
|
||||
'rowspan' => 1,
|
||||
'colspan' => 1,
|
||||
);
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($value = '', array $options = array())
|
||||
{
|
||||
$this->value = $value;
|
||||
|
||||
// check option names
|
||||
if ($diff = array_diff(array_keys($options), array_keys($this->options))) {
|
||||
throw new \InvalidArgumentException(sprintf('The TableCell does not support the following options: \'%s\'.', implode('\', \'', $diff)));
|
||||
}
|
||||
|
||||
$this->options = array_merge($this->options, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cell value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of colspan.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getColspan()
|
||||
{
|
||||
return (int) $this->options['colspan'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of rowspan.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getRowspan()
|
||||
{
|
||||
return (int) $this->options['rowspan'];
|
||||
}
|
||||
}
|
@ -16,6 +16,14 @@ namespace Symfony\Component\Console\Helper;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class TableSeparator
|
||||
class TableSeparator extends TableCell
|
||||
{
|
||||
/**
|
||||
* @param string $value
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
parent::__construct('', $options);
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Console\Tests\Helper;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Helper\TableStyle;
|
||||
use Symfony\Component\Console\Helper\TableSeparator;
|
||||
use Symfony\Component\Console\Helper\TableCell;
|
||||
use Symfony\Component\Console\Output\StreamOutput;
|
||||
|
||||
class TableTest extends \PHPUnit_Framework_TestCase
|
||||
@ -250,6 +251,214 @@ TABLE
|
||||
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
|
||||
+----------------------------------+----------------------+-----------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
'Cell with colspan' => array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
array(
|
||||
array('99921-58-10-7', 'Divine Comedy', 'Dante Alighieri'),
|
||||
new TableSeparator(),
|
||||
array(new TableCell('Divine Comedy(Dante Alighieri)', array('colspan' => 3))),
|
||||
new TableSeparator(),
|
||||
array(
|
||||
new TableCell('Arduino: A Quick-Start Guide', array('colspan' => 2)),
|
||||
'Mark Schmidt',
|
||||
),
|
||||
new TableSeparator(),
|
||||
array(
|
||||
'9971-5-0210-0',
|
||||
new TableCell("A Tale of \nTwo Cities", array('colspan' => 2)),
|
||||
),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+----------------+---------------+-----------------+
|
||||
| ISBN | Title | Author |
|
||||
+----------------+---------------+-----------------+
|
||||
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
|
||||
+----------------+---------------+-----------------+
|
||||
| Divine Comedy(Dante Alighieri) |
|
||||
+----------------+---------------+-----------------+
|
||||
| Arduino: A Quick-Start Guide | Mark Schmidt |
|
||||
+----------------+---------------+-----------------+
|
||||
| 9971-5-0210-0 | A Tale of |
|
||||
| | Two Cities |
|
||||
+----------------+---------------+-----------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
'Cell with rowspan' => array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
array(
|
||||
array(
|
||||
new TableCell('9971-5-0210-0', array('rowspan' => 3)),
|
||||
'Divine Comedy',
|
||||
'Dante Alighieri',
|
||||
),
|
||||
array('A Tale of Two Cities', 'Charles Dickens'),
|
||||
array("The Lord of \nthe Rings", "J. R. \nR. Tolkien"),
|
||||
new TableSeparator(),
|
||||
array('80-902734-1-6', new TableCell("And Then \nThere \nWere None", array('rowspan' => 3)), 'Agatha Christie'),
|
||||
array('80-902734-1-7', 'Test'),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+---------------+----------------------+-----------------+
|
||||
| ISBN | Title | Author |
|
||||
+---------------+----------------------+-----------------+
|
||||
| 9971-5-0210-0 | Divine Comedy | Dante Alighieri |
|
||||
| | A Tale of Two Cities | Charles Dickens |
|
||||
| | The Lord of | J. R. |
|
||||
| | the Rings | R. Tolkien |
|
||||
+---------------+----------------------+-----------------+
|
||||
| 80-902734-1-6 | And Then | Agatha Christie |
|
||||
| 80-902734-1-7 | There | Test |
|
||||
| | Were None | |
|
||||
+---------------+----------------------+-----------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
'Cell with rowspan and colspan' => array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
array(
|
||||
array(
|
||||
new TableCell('9971-5-0210-0', array('rowspan' => 2, 'colspan' => 2)),
|
||||
'Dante Alighieri',
|
||||
),
|
||||
array('Charles Dickens'),
|
||||
new TableSeparator(),
|
||||
array(
|
||||
'Dante Alighieri',
|
||||
new TableCell('9971-5-0210-0', array('rowspan' => 3, 'colspan' => 2)),
|
||||
),
|
||||
array('J. R. R. Tolkien'),
|
||||
array('J. R. R'),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+------------------+--------+-----------------+
|
||||
| ISBN | Title | Author |
|
||||
+------------------+--------+-----------------+
|
||||
| 9971-5-0210-0 | Dante Alighieri |
|
||||
| | Charles Dickens |
|
||||
+------------------+--------+-----------------+
|
||||
| Dante Alighieri | 9971-5-0210-0 |
|
||||
| J. R. R. Tolkien | |
|
||||
| J. R. R | |
|
||||
+------------------+--------+-----------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
'Cell with rowspan and colspan contains new line break' => array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
array(
|
||||
array(
|
||||
new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
|
||||
'Dante Alighieri',
|
||||
),
|
||||
array('Charles Dickens'),
|
||||
new TableSeparator(),
|
||||
array(
|
||||
'Dante Alighieri',
|
||||
new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
|
||||
),
|
||||
array('Charles Dickens'),
|
||||
new TableSeparator(),
|
||||
array(
|
||||
new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
|
||||
new TableCell("Dante \nAlighieri", array('rowspan' => 2, 'colspan' => 1)),
|
||||
),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+-----------------+-------+-----------------+
|
||||
| ISBN | Title | Author |
|
||||
+-----------------+-------+-----------------+
|
||||
| 9971 | Dante Alighieri |
|
||||
| -5- | Charles Dickens |
|
||||
| 021 | |
|
||||
| 0-0 | |
|
||||
+-----------------+-------+-----------------+
|
||||
| Dante Alighieri | 9971 |
|
||||
| Charles Dickens | -5- |
|
||||
| | 021 |
|
||||
| | 0-0 |
|
||||
+-----------------+-------+-----------------+
|
||||
| 9971 | Dante |
|
||||
| -5- | Alighieri |
|
||||
| 021 | |
|
||||
| 0-0 | |
|
||||
+-----------------+-------+-----------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
'Cell with rowspan and colspan without using TableSeparator' => array(
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
array(
|
||||
array(
|
||||
new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
|
||||
'Dante Alighieri',
|
||||
),
|
||||
array('Charles Dickens'),
|
||||
array(
|
||||
'Dante Alighieri',
|
||||
new TableCell("9971\n-5-\n021\n0-0", array('rowspan' => 2, 'colspan' => 2)),
|
||||
),
|
||||
array('Charles Dickens'),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+-----------------+-------+-----------------+
|
||||
| ISBN | Title | Author |
|
||||
+-----------------+-------+-----------------+
|
||||
| 9971 | Dante Alighieri |
|
||||
| -5- | Charles Dickens |
|
||||
| 021 | |
|
||||
| 0-0 | |
|
||||
| Dante Alighieri | 9971 |
|
||||
| Charles Dickens | -5- |
|
||||
| | 021 |
|
||||
| | 0-0 |
|
||||
+-----------------+-------+-----------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
'Cell with rowspan and colspan with separator inside a rowspan' => array(
|
||||
array('ISBN', 'Author'),
|
||||
array(
|
||||
array(
|
||||
new TableCell("9971-5-0210-0", array('rowspan' => 3, 'colspan' => 1)),
|
||||
'Dante Alighieri',
|
||||
),
|
||||
array(new TableSeparator()),
|
||||
array('Charles Dickens'),
|
||||
),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+---------------+-----------------+
|
||||
| ISBN | Author |
|
||||
+---------------+-----------------+
|
||||
| 9971-5-0210-0 | Dante Alighieri |
|
||||
| |-----------------|
|
||||
| | Charles Dickens |
|
||||
+---------------+-----------------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
'Multiple header lines' => array(
|
||||
array(
|
||||
array(new TableCell('Main title', array('colspan' => 3))),
|
||||
array('ISBN', 'Title', 'Author'),
|
||||
),
|
||||
array(),
|
||||
'default',
|
||||
<<<TABLE
|
||||
+------+-------+--------+
|
||||
| Main title |
|
||||
+------+-------+--------+
|
||||
| ISBN | Title | Author |
|
||||
+------+-------+--------+
|
||||
|
||||
TABLE
|
||||
),
|
||||
);
|
||||
|
Reference in New Issue
Block a user