diff --git a/docs/elements.rst b/docs/elements.rst index 124f4431..e27b45d9 100644 --- a/docs/elements.rst +++ b/docs/elements.rst @@ -414,7 +414,7 @@ Line elements can be added to sections by using ``addLine``. .. code-block:: php - $linestyle = array('weight' => 1, 'width' => 100, 'height' => 0, 'color' => 635552); + $lineStyle = array('weight' => 1, 'width' => 100, 'height' => 0, 'color' => 635552); $section->addLine($lineStyle) Available line style attributes: diff --git a/src/PhpWord/Element/AbstractContainer.php b/src/PhpWord/Element/AbstractContainer.php index d7171798..cb42cf3d 100644 --- a/src/PhpWord/Element/AbstractContainer.php +++ b/src/PhpWord/Element/AbstractContainer.php @@ -23,7 +23,7 @@ namespace PhpOffice\PhpWord\Element; * @method Text addText(string $text, mixed $fStyle = null, mixed $pStyle = null) * @method TextRun addTextRun(mixed $pStyle = null) * @method Bookmark addBookmark(string $name) - * @method Link addLink(string $target, string $text = null, mixed $fStyle = null, mixed $pStyle = null) + * @method Link addLink(string $target, string $text = null, mixed $fStyle = null, mixed $pStyle = null, boolean $internal = false) * @method PreserveText addPreserveText(string $text, mixed $fStyle = null, mixed $pStyle = null) * @method void addTextBreak(int $count = 1, mixed $fStyle = null, mixed $pStyle = null) * @method ListItem addListItem(string $txt, int $depth = 0, mixed $font = null, mixed $list = null, mixed $para = null) diff --git a/src/PhpWord/Shared/Html.php b/src/PhpWord/Shared/Html.php index 670ba6e5..620839b4 100644 --- a/src/PhpWord/Shared/Html.php +++ b/src/PhpWord/Shared/Html.php @@ -18,6 +18,7 @@ namespace PhpOffice\PhpWord\Shared; use PhpOffice\PhpWord\Element\AbstractContainer; +use PhpOffice\PhpWord\SimpleType\Jc; /** * Common Html functions @@ -117,9 +118,13 @@ class Html 'h6' => array('Heading', null, $element, $styles, null, 'Heading6', null), '#text' => array('Text', $node, $element, $styles, null, null, null), 'strong' => array('Property', null, null, $styles, null, 'bold', true), + 'b' => array('Property', null, null, $styles, null, 'bold', true), 'em' => array('Property', null, null, $styles, null, 'italic', true), + 'i' => array('Property', null, null, $styles, null, 'italic', true), + 'u' => array('Property', null, null, $styles, null, 'underline', 'single'), 'sup' => array('Property', null, null, $styles, null, 'superScript', true), 'sub' => array('Property', null, null, $styles, null, 'subScript', true), + 'span' => array('Property', null, null, $styles, null, 'span', $node), 'table' => array('Table', $node, $element, $styles, null, 'addTable', true), 'tr' => array('Table', $node, $element, $styles, null, 'addRow', true), 'td' => array('Table', $node, $element, $styles, null, 'addCell', true), @@ -233,8 +238,6 @@ class Html // if (method_exists($element, 'addText')) { $element->addText($node->nodeValue, $styles['font'], $styles['paragraph']); // } - - return null; } /** @@ -246,9 +249,16 @@ class Html */ private static function parseProperty(&$styles, $argument1, $argument2) { - $styles['font'][$argument1] = $argument2; - - return null; + if ($argument1 !== 'span') { + $styles['font'][$argument1] = $argument2; + } else { + if (!is_null($argument2->attributes)) { + $nodeAttr = $argument2->attributes->getNamedItem('style'); + if (!is_null($nodeAttr) && property_exists($nodeAttr, 'value')) { + $styles['font'] = self::parseStyle($nodeAttr, $styles['font']); + } + } + } } /** @@ -298,8 +308,6 @@ class Html $data['listdepth'] = 0; } $styles['list']['listType'] = $argument1; - - return null; } /** @@ -325,8 +333,6 @@ class Html } $element->addListItem($text, $data['listdepth'], $styles['font'], $styles['list'], $styles['paragraph']); } - - return null; } /** @@ -354,7 +360,20 @@ class Html } break; case 'text-align': - $styles['alignment'] = $cValue; // todo: any mapping? + switch ($cValue) { + case 'left': + $styles['alignment'] = Jc::START; + break; + case 'right': + $styles['alignment'] = Jc::END; + break; + case 'center': + $styles['alignment'] = Jc::CENTER; + break; + case 'justify': + $styles['alignment'] = Jc::BOTH; + break; + } break; case 'color': $styles['color'] = trim($cValue, '#'); @@ -362,6 +381,20 @@ class Html case 'background-color': $styles['bgColor'] = trim($cValue, '#'); break; + case 'font-weight': + $tValue = false; + if (preg_match('#bold#', $cValue)) { + $tValue = true; // also match bolder + } + $styles['bold'] = $tValue; + break; + case 'font-style': + $tValue = false; + if (preg_match('#(?:italic|oblique)#', $cValue)) { + $tValue = true; + } + $styles['italic'] = $tValue; + break; } } diff --git a/tests/PhpWord/Reader/MsDocTest.php b/tests/PhpWord/Reader/MsDocTest.php index 12d50247..e407547d 100644 --- a/tests/PhpWord/Reader/MsDocTest.php +++ b/tests/PhpWord/Reader/MsDocTest.php @@ -56,4 +56,24 @@ class MsDocTest extends \PHPUnit\Framework\TestCase $phpWord = IOFactory::load($filename, 'MsDoc'); $this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $phpWord); } + + /** + * Test exception on not existing file + * @expectedException \Exception + */ + public function testFailIfFileNotReadable() + { + $filename = __DIR__ . '/../_files/documents/not_existing_reader.doc'; + IOFactory::load($filename, 'MsDoc'); + } + + /** + * Test exception on non OLE document + * @expectedException \Exception + */ + public function testFailIfFileNotOle() + { + $filename = __DIR__ . '/../_files/documents/reader.odt'; + IOFactory::load($filename, 'MsDoc'); + } } diff --git a/tests/PhpWord/Shared/HtmlTest.php b/tests/PhpWord/Shared/HtmlTest.php index 0ba7717f..8ec6840f 100644 --- a/tests/PhpWord/Shared/HtmlTest.php +++ b/tests/PhpWord/Shared/HtmlTest.php @@ -18,9 +18,12 @@ namespace PhpOffice\PhpWord\Shared; use PhpOffice\PhpWord\Element\Section; +use PhpOffice\PhpWord\SimpleType\Jc; +use PhpOffice\PhpWord\TestHelperDOCX; /** * Test class for PhpOffice\PhpWord\Shared\Html + * @coversDefaultClass \PhpOffice\PhpWord\Shared\Html */ class HtmlTest extends \PHPUnit\Framework\TestCase { @@ -43,7 +46,7 @@ class HtmlTest extends \PHPUnit\Framework\TestCase // Styles $content .= '
'; + . 'text-align: center; color: #999; background-color: #000; font-weight: bold; font-style: italic;">'; foreach ($styles as $style) { $content .= "<{$style}>{$style}{$style}>"; } @@ -67,4 +70,110 @@ class HtmlTest extends \PHPUnit\Framework\TestCase $content .= '– ²³¼½¾'; Html::addHtml($section, $content); } + + /** + * Test that html already in body element can be read + * @ignore + */ + public function testParseFullHtml() + { + $section = new Section(1); + Html::addHtml($section, '
test paragraph1
test paragraph2
', true); + + $this->assertCount(2, $section->getElements()); + } + + /** + * Test underline + */ + public function testParseUnderline() + { + $html = 'test'; + $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $section = $phpWord->addSection(); + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + $this->assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:u')); + $this->assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p/w:r/w:rPr/w:u', 'w:val')); + } + + /** + * Test text-decoration style + */ + public function testParseTextDecoration() + { + $html = 'test'; + $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $section = $phpWord->addSection(); + Html::addHtml($section, $html); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + $this->assertTrue($doc->elementExists('/w:document/w:body/w:p/w:r/w:rPr/w:u')); + $this->assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p/w:r/w:rPr/w:u', 'w:val')); + } + + /** + * Test text-align style + */ + public function testParseTextAlign() + { + $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $section = $phpWord->addSection(); + Html::addHtml($section, 'test
'); + Html::addHtml($section, 'test
'); + Html::addHtml($section, 'test
'); + Html::addHtml($section, 'test
'); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + $this->assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:jc')); + $this->assertEquals('start', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:jc', 'w:val')); + $this->assertEquals('end', $doc->getElementAttribute('/w:document/w:body/w:p[2]/w:pPr/w:jc', 'w:val')); + $this->assertEquals('center', $doc->getElementAttribute('/w:document/w:body/w:p[3]/w:pPr/w:jc', 'w:val')); + $this->assertEquals('both', $doc->getElementAttribute('/w:document/w:body/w:p[4]/w:pPr/w:jc', 'w:val')); + } + + /** + * Test parsing paragraph and span styles + */ + public function testParseParagraphAndSpanStyle() + { + $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $section = $phpWord->addSection(); + Html::addHtml($section, 'test
'); + + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + $this->assertTrue($doc->elementExists('/w:document/w:body/w:p/w:pPr/w:jc')); + $this->assertEquals('center', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:pPr/w:jc', 'w:val')); + $this->assertEquals('single', $doc->getElementAttribute('/w:document/w:body/w:p[1]/w:r/w:rPr/w:u', 'w:val')); + } + + /** + * Test parsing table + */ + public function testParseTable() + { + $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $section = $phpWord->addSection(); + $html = ' +| a | +b | +c | +
|---|---|---|
| 1 | 2 | |
| 4 | 5 | 6 |