diff --git a/CHANGELOG.md b/CHANGELOG.md index 762bf560be..406122b6af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). v0.15.0 (?? ??? 2018) ---------------------- ### Added -- Parsing of "align" HTML attribute - @troosan #1231 +- Parsing of `align` HTML attribute - @troosan #1231 - Parse formatting inside HTML lists - @troosan @samimussbach #1239 #945 #1215 #508 - Parsing of CSS `direction` instruction, HTML `lang` attribute, formatting inside table cell - @troosan #1273 #1252 #1254 - Add support for Track changes @Cip @troosan #354 #1262 - Add support for fixed Table Layout @aoloe @ekopach @troosan #841 #1276 +- Add support for Cell Spacing @dox07 @troosan #1040 ### Fixed - Fix reading of docx default style - @troosan #1238 @@ -19,6 +20,7 @@ v0.15.0 (?? ??? 2018) - Save PNG alpha information when using remote images. @samsullivan #779 - Fix parsing of `` tag. @troosan #1274 - Bookmark are not writton as internal link in html writer @troosan #1263 +- It should be possible to add a Footnote in a ListItemRun @troosan #1287 #1287 diff --git a/docs/styles.rst b/docs/styles.rst index 8e155ca295..0ec0ec38d5 100644 --- a/docs/styles.rst +++ b/docs/styles.rst @@ -103,7 +103,9 @@ Available Table style options: - ``border(Top|Right|Bottom|Left)Size``. Border size in *twip*. - ``cellMargin(Top|Right|Bottom|Left)``. Cell margin in *twip*. - ``width``. Table width in percent. +- ``unit``. The unit to use for the width. One of ``\PhpOffice\PhpWord\SimpleType\TblWidth``. Defaults to *auto*. - ``layout``. Table layout, either *fixed* or *autofit* See ``\PhpOffice\PhpWord\Style\Table`` for constants. +- ``cellSpacing`` Cell spacing in *twip* Available Row style options: diff --git a/samples/Sample_09_Tables.php b/samples/Sample_09_Tables.php index c4be7c9eaf..ba41aa5484 100644 --- a/samples/Sample_09_Tables.php +++ b/samples/Sample_09_Tables.php @@ -27,7 +27,7 @@ $section->addText('Fancy table', $header); $fancyTableStyleName = 'Fancy Table'; -$fancyTableStyle = array('borderSize' => 6, 'borderColor' => '006699', 'cellMargin' => 80, 'alignment' => \PhpOffice\PhpWord\SimpleType\JcTable::CENTER); +$fancyTableStyle = array('borderSize' => 6, 'borderColor' => '006699', 'cellMargin' => 80, 'alignment' => \PhpOffice\PhpWord\SimpleType\JcTable::CENTER, 'cellSpacing' => 50); $fancyTableFirstRowStyle = array('borderBottomSize' => 18, 'borderBottomColor' => '0000FF', 'bgColor' => '66BBFF'); $fancyTableCellStyle = array('valign' => 'center'); $fancyTableCellBtlrStyle = array('valign' => 'center', 'textDirection' => \PhpOffice\PhpWord\Style\Cell::TEXT_DIR_BTLR); diff --git a/samples/Sample_14_ListItem.php b/samples/Sample_14_ListItem.php index 689ac3d3eb..774fd284d0 100644 --- a/samples/Sample_14_ListItem.php +++ b/samples/Sample_14_ListItem.php @@ -67,6 +67,8 @@ $listItemRun = $section->addListItemRun(); $listItemRun->addText('List item 2'); $listItemRun->addText(' in italic', array('italic' => true)); +$footnote = $listItemRun->addFootnote(); +$footnote->addText('this is a footnote on a list item'); $listItemRun = $section->addListItemRun(); $listItemRun->addText('List item 3'); $listItemRun->addText(' underlined', array('underline' => 'dash')); diff --git a/src/PhpWord/Element/AbstractContainer.php b/src/PhpWord/Element/AbstractContainer.php index 4a5f83f536..507ff143e5 100644 --- a/src/PhpWord/Element/AbstractContainer.php +++ b/src/PhpWord/Element/AbstractContainer.php @@ -207,7 +207,7 @@ private function checkValidity($method) 'Table' => array('Section', 'Header', 'Footer', 'Cell', 'TextBox'), 'CheckBox' => array('Section', 'Header', 'Footer', 'Cell', 'TextRun'), 'TextBox' => array('Section', 'Header', 'Footer', 'Cell'), - 'Footnote' => array('Section', 'TextRun', 'Cell'), + 'Footnote' => array('Section', 'TextRun', 'Cell', 'ListItemRun'), 'Endnote' => array('Section', 'TextRun', 'Cell'), 'PreserveText' => array('Section', 'Header', 'Footer', 'Cell'), 'Title' => array('Section', 'Cell'), diff --git a/src/PhpWord/Reader/Word2007/AbstractPart.php b/src/PhpWord/Reader/Word2007/AbstractPart.php index 09d32dbb1e..511e90813d 100644 --- a/src/PhpWord/Reader/Word2007/AbstractPart.php +++ b/src/PhpWord/Reader/Word2007/AbstractPart.php @@ -426,6 +426,7 @@ protected function readTableStyle(XMLReader $xmlReader, \DOMElement $domNode) $styleDefs["border{$ucfSide}Style"] = array(self::READ_VALUE, "w:tblBorders/w:$side", 'w:val'); } $styleDefs['layout'] = array(self::READ_VALUE, 'w:tblLayout', 'w:type'); + $styleDefs['cellSpacing'] = array(self::READ_VALUE, 'w:tblCellSpacing', 'w:w'); $style = $this->readStyleDefs($xmlReader, $styleNode, $styleDefs); } } diff --git a/src/PhpWord/Shared/Html.php b/src/PhpWord/Shared/Html.php index 971776ff93..1841616ece 100644 --- a/src/PhpWord/Shared/Html.php +++ b/src/PhpWord/Shared/Html.php @@ -415,6 +415,10 @@ private static function parseList($node, $element, &$styles, &$data) } } + /** + * @param bool $isOrderedList + * @return array + */ private static function getListStyle($isOrderedList) { if ($isOrderedList) { @@ -547,13 +551,13 @@ private static function parseStyle($attribute, $styles) case 'width': if (preg_match('/([0-9]+[a-z]+)/', $cValue, $matches)) { $styles['width'] = Converter::cssToTwip($matches[1]); - $styles['unit'] = \PhpOffice\PhpWord\Style\Table::WIDTH_TWIP; + $styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::TWIP; } elseif (preg_match('/([0-9]+)%/', $cValue, $matches)) { $styles['width'] = $matches[1] * 50; - $styles['unit'] = \PhpOffice\PhpWord\Style\Table::WIDTH_PERCENT; + $styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::PERCENT; } elseif (preg_match('/([0-9]+)/', $cValue, $matches)) { $styles['width'] = $matches[1]; - $styles['unit'] = \PhpOffice\PhpWord\Style\Table::WIDTH_AUTO; + $styles['unit'] = \PhpOffice\PhpWord\SimpleType\TblWidth::AUTO; } break; case 'border': diff --git a/src/PhpWord/SimpleType/TblWidth.php b/src/PhpWord/SimpleType/TblWidth.php new file mode 100644 index 0000000000..3d947bce7c --- /dev/null +++ b/src/PhpWord/SimpleType/TblWidth.php @@ -0,0 +1,42 @@ +unit = $this->setEnumVal($value, array(Table::WIDTH_AUTO, Table::WIDTH_PERCENT, Table::WIDTH_TWIP), Table::WIDTH_TWIP); + $this->unit = $this->setEnumVal($value, array(TblWidth::AUTO, TblWidth::PERCENT, TblWidth::TWIP), TblWidth::TWIP); return $this; } diff --git a/src/PhpWord/Style/Table.php b/src/PhpWord/Style/Table.php index d0ff47ede2..8aba172a05 100644 --- a/src/PhpWord/Style/Table.php +++ b/src/PhpWord/Style/Table.php @@ -19,14 +19,21 @@ use PhpOffice\PhpWord\SimpleType\Jc; use PhpOffice\PhpWord\SimpleType\JcTable; +use PhpOffice\PhpWord\SimpleType\TblWidth; class Table extends Border { /** - * @const string Table width units http://www.schemacentral.com/sc/ooxml/t-w_ST_TblWidth.html + * @deprecated Use \PhpOffice\PhpWord\SimpleType\TblWidth::AUTO instead */ const WIDTH_AUTO = 'auto'; // Automatically determined width + /** + * @deprecated Use \PhpOffice\PhpWord\SimpleType\TblWidth::PERCENT instead + */ const WIDTH_PERCENT = 'pct'; // Width in fiftieths (1/50) of a percent (1% = 50 unit) + /** + * @deprecated Use \PhpOffice\PhpWord\SimpleType\TblWidth::TWIP instead + */ const WIDTH_TWIP = 'dxa'; // Width in twentieths (1/20) of a point (twip) //values for http://www.datypic.com/sc/ooxml/t-w_ST_TblLayoutType.html @@ -133,7 +140,12 @@ class Table extends Border /** * @var string Width unit */ - private $unit = self::WIDTH_AUTO; + private $unit = TblWidth::AUTO; + + /** + * @var int|float cell spacing value + */ + protected $cellSpacing = null; /** * @var string Table Layout @@ -152,7 +164,7 @@ public function __construct($tableStyle = null, $firstRowStyle = null) if ($firstRowStyle !== null && is_array($firstRowStyle)) { $this->firstRowStyle = clone $this; $this->firstRowStyle->isFirstRow = true; - unset($this->firstRowStyle->firstRowStyle, $this->firstRowStyle->borderInsideHSize, $this->firstRowStyle->borderInsideHColor, $this->firstRowStyle->borderInsideVSize, $this->firstRowStyle->borderInsideVColor, $this->firstRowStyle->cellMarginTop, $this->firstRowStyle->cellMarginLeft, $this->firstRowStyle->cellMarginRight, $this->firstRowStyle->cellMarginBottom); + unset($this->firstRowStyle->firstRowStyle, $this->firstRowStyle->borderInsideHSize, $this->firstRowStyle->borderInsideHColor, $this->firstRowStyle->borderInsideVSize, $this->firstRowStyle->borderInsideVColor, $this->firstRowStyle->cellMarginTop, $this->firstRowStyle->cellMarginLeft, $this->firstRowStyle->cellMarginRight, $this->firstRowStyle->cellMarginBottom, $this->firstRowStyle->cellSpacing); $this->firstRowStyle->setStyleByArray($firstRowStyle); } @@ -161,6 +173,22 @@ public function __construct($tableStyle = null, $firstRowStyle = null) } } + /** + * @param float|int $cellSpacing + */ + public function setCellSpacing($cellSpacing = null) + { + $this->cellSpacing = $cellSpacing; + } + + /** + * @return float|int + */ + public function getCellSpacing() + { + return $this->cellSpacing; + } + /** * Set first row * @@ -595,8 +623,8 @@ public function getUnit() */ public function setUnit($value = null) { - $enum = array(self::WIDTH_AUTO, self::WIDTH_PERCENT, self::WIDTH_TWIP); - $this->unit = $this->setEnumVal($value, $enum, $this->unit); + TblWidth::validate($value); + $this->unit = $value; return $this; } diff --git a/src/PhpWord/Writer/Word2007/Style/Table.php b/src/PhpWord/Writer/Word2007/Style/Table.php index e2e8f978dc..1422621251 100644 --- a/src/PhpWord/Writer/Word2007/Style/Table.php +++ b/src/PhpWord/Writer/Word2007/Style/Table.php @@ -18,6 +18,7 @@ namespace PhpOffice\PhpWord\Writer\Word2007\Style; use PhpOffice\Common\XMLWriter; +use PhpOffice\PhpWord\SimpleType\TblWidth; use PhpOffice\PhpWord\Style\Table as TableStyle; use PhpOffice\PhpWord\Writer\Word2007\Element\TableAlignment; @@ -49,7 +50,7 @@ public function write() $xmlWriter->writeAttribute('w:val', $style); $xmlWriter->endElement(); if (null !== $this->width) { - $this->writeWidth($xmlWriter, $this->width, 'pct'); + $this->writeTblWidth($xmlWriter, 'w:tblW', TblWidth::PERCENT, $this->width); } $xmlWriter->endElement(); } @@ -76,7 +77,8 @@ private function writeStyle(XMLWriter $xmlWriter, TableStyle $style) $xmlWriter->endElement(); } - $this->writeWidth($xmlWriter, $style->getWidth(), $style->getUnit()); + $this->writeTblWidth($xmlWriter, 'w:tblW', $style->getUnit(), $style->getWidth()); + $this->writeTblWidth($xmlWriter, 'w:tblCellSpacing', TblWidth::TWIP, $style->getCellSpacing()); $this->writeLayout($xmlWriter, $style->getLayout()); $this->writeMargin($xmlWriter, $style); $this->writeBorder($xmlWriter, $style); @@ -92,21 +94,6 @@ private function writeStyle(XMLWriter $xmlWriter, TableStyle $style) } } - /** - * Write width. - * - * @param \PhpOffice\Common\XMLWriter $xmlWriter - * @param int $width - * @param string $unit - */ - private function writeWidth(XMLWriter $xmlWriter, $width, $unit) - { - $xmlWriter->startElement('w:tblW'); - $xmlWriter->writeAttribute('w:w', $width); - $xmlWriter->writeAttribute('w:type', $unit); - $xmlWriter->endElement(); // w:tblW - } - /** * Enable/Disable automatic resizing of the table * @@ -159,6 +146,25 @@ private function writeBorder(XMLWriter $xmlWriter, TableStyle $style) } } + /** + * Writes a table width + * + * @param \PhpOffice\Common\XMLWriter $xmlWriter + * @param string $elementName + * @param string $unit + * @param int|float $width + */ + private function writeTblWidth(XMLWriter $xmlWriter, $elementName, $unit, $width = null) + { + if (null === $width) { + return; + } + $xmlWriter->startElement($elementName); + $xmlWriter->writeAttributeIf(null !== $width, 'w:w', $width); + $xmlWriter->writeAttribute('w:type', $unit); + $xmlWriter->endElement(); + } + /** * Write row style. * diff --git a/tests/PhpWord/Reader/Word2007/StyleTest.php b/tests/PhpWord/Reader/Word2007/StyleTest.php index ce59f4c3b4..4375df475a 100644 --- a/tests/PhpWord/Reader/Word2007/StyleTest.php +++ b/tests/PhpWord/Reader/Word2007/StyleTest.php @@ -18,6 +18,7 @@ namespace PhpOffice\PhpWord\Reader\Word2007; use PhpOffice\PhpWord\AbstractTestReader; +use PhpOffice\PhpWord\SimpleType\TblWidth; use PhpOffice\PhpWord\Style\Table; /** @@ -43,4 +44,26 @@ public function testReadTableLayout() $this->assertInstanceOf('PhpOffice\PhpWord\Style\Table', $elements[0]->getStyle()); $this->assertEquals(Table::LAYOUT_FIXED, $elements[0]->getStyle()->getLayout()); } + + /** + * Test reading of cell spacing + */ + public function testReadCellSpacing() + { + $documentXml = ' + + + + '; + + $phpWord = $this->getDocumentFromString($documentXml); + + $elements = $this->get($phpWord->getSections(), 0)->getElements(); + $this->assertInstanceOf('PhpOffice\PhpWord\Element\Table', $elements[0]); + $this->assertInstanceOf('PhpOffice\PhpWord\Style\Table', $elements[0]->getStyle()); + $this->assertEquals(TblWidth::AUTO, $elements[0]->getStyle()->getUnit()); + /** @var \PhpOffice\PhpWord\Style\Table $tableStyle */ + $tableStyle = $elements[0]->getStyle(); + $this->assertEquals(10.5, $tableStyle->getCellSpacing()); + } } diff --git a/tests/PhpWord/Style/TableTest.php b/tests/PhpWord/Style/TableTest.php index dafdeb31b8..9dec422e97 100644 --- a/tests/PhpWord/Style/TableTest.php +++ b/tests/PhpWord/Style/TableTest.php @@ -18,6 +18,7 @@ namespace PhpOffice\PhpWord\Style; use PhpOffice\PhpWord\SimpleType\JcTable; +use PhpOffice\PhpWord\SimpleType\TblWidth; /** * Test class for PhpOffice\PhpWord\Style\Table @@ -38,9 +39,6 @@ public function testConstruct() $styleTable = array('bgColor' => 'FF0000'); $styleFirstRow = array('borderBottomSize' => 3); - $object = new Table(); - $this->assertNull($object->getBgColor()); - $object = new Table($styleTable, $styleFirstRow); $this->assertEquals('FF0000', $object->getBgColor()); @@ -49,6 +47,18 @@ public function testConstruct() $this->assertEquals(3, $firstRow->getBorderBottomSize()); } + /** + * Test default values when passing no style + */ + public function testDefaultValues() + { + $object = new Table(); + + $this->assertNull($object->getBgColor()); + $this->assertEquals(Table::LAYOUT_AUTO, $object->getLayout()); + $this->assertEquals(TblWidth::AUTO, $object->getUnit()); + } + /** * Test setting style with normal value */ @@ -77,6 +87,7 @@ public function testSetGetNormal() 'alignment' => JcTable::CENTER, 'width' => 100, 'unit' => 'pct', + 'layout' => Table::LAYOUT_FIXED, ); foreach ($attributes as $key => $value) { $set = "set{$key}"; @@ -174,13 +185,14 @@ public function testSetStyleValue() } /** - * Tests table layout + * Tests table cell spacing */ - public function testTableLayout() + public function testTableCellSpacing() { $object = new Table(); - $this->assertEquals(Table::LAYOUT_AUTO, $object->getLayout()); - $object->setLayout(Table::LAYOUT_FIXED); - $this->assertEquals(Table::LAYOUT_FIXED, $object->getLayout()); + $this->assertNull($object->getCellSpacing()); + + $object = new Table(array('cellSpacing' => 20)); + $this->assertEquals(20, $object->getCellSpacing()); } } diff --git a/tests/PhpWord/Writer/Word2007/Style/TableTest.php b/tests/PhpWord/Writer/Word2007/Style/TableTest.php index a89dd61048..c0a0b3ad13 100644 --- a/tests/PhpWord/Writer/Word2007/Style/TableTest.php +++ b/tests/PhpWord/Writer/Word2007/Style/TableTest.php @@ -55,4 +55,25 @@ public function testTableLayout() $this->assertTrue($doc->elementExists($path)); $this->assertEquals(Table::LAYOUT_FIXED, $doc->getElementAttribute($path, 'w:type')); } + + /** + * Test write styles + */ + public function testCellSpacing() + { + $tableStyle = new Table(); + $tableStyle->setCellSpacing(10.3); + + $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $section = $phpWord->addSection(); + $table = $section->addTable($tableStyle); + $table->addRow(); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + $path = '/w:document/w:body/w:tbl/w:tblPr/w:tblCellSpacing'; + $this->assertTrue($doc->elementExists($path)); + $this->assertEquals(10.3, $doc->getElementAttribute($path, 'w:w')); + $this->assertEquals(\PhpOffice\PhpWord\SimpleType\TblWidth::TWIP, $doc->getElementAttribute($path, 'w:type')); + } }