From 3066d47003e18461001828f513db3778a652a76f Mon Sep 17 00:00:00 2001 From: lubosdz Date: Sat, 11 Jul 2020 22:47:40 +0200 Subject: [PATCH] Html parser (addHtml) - support vertical-align, valign --- src/PhpWord/Shared/Html.php | 46 ++++++++++++++++++++++++++++--- tests/PhpWord/Shared/HtmlTest.php | 44 +++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/src/PhpWord/Shared/Html.php b/src/PhpWord/Shared/Html.php index 7e0848b1..bf1a688b 100644 --- a/src/PhpWord/Shared/Html.php +++ b/src/PhpWord/Shared/Html.php @@ -96,19 +96,19 @@ class Html $attributes = $node->attributes; // get all the attributes(eg: id, class) foreach ($attributes as $attribute) { + $val = trim($attribute->value); switch (strtolower($attribute->name)) { case 'style': $styles = self::parseStyle($attribute, $styles); break; case 'align': - $styles['alignment'] = self::mapAlign($attribute->value); + $styles['alignment'] = self::mapAlign($val); break; case 'lang': - $styles['lang'] = $attribute->value; + $styles['lang'] = $val; break; case 'width': // tables, cells - $val = trim($attribute->value); if(false !== strpos($val, '%')){ // e.g. or - $styles['bgColor'] = trim($attribute->value, '# '); + $styles['bgColor'] = trim($val, '# '); + break; + case 'valign': + // cells e.g. + + + + + + +
$styles['width'] = intval($val) * 50; @@ -126,7 +126,13 @@ class Html break; case 'bgcolor': // tables, rows, cells e.g.
+ if (preg_match('#(?:top|bottom|middle|baseline)#i', $val, $matches)) { + $styles['valign'] = self::mapAlignVertical($matches[0]); + } break; } } @@ -678,6 +684,12 @@ class Html $styles["border{$which}Style"] = self::mapBorderStyle($matches[3]); } break; + case 'vertical-align': + // https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align + if (preg_match('#(?:top|bottom|middle|sub|baseline)#i', $cValue, $matches)) { + $styles['valign'] = self::mapAlignVertical($matches[0]); + } + break; } } @@ -842,6 +854,32 @@ class Html } } + /** + * Transforms a HTML/CSS alignment into a \PhpOffice\PhpWord\SimpleType\Jc + * + * @param string $cssAlignment + * @return string|null + */ + protected static function mapAlignVertical($alignment) + { + $alignment = strtolower($alignment); + switch ($alignment) { + case 'top': + case 'baseline': + case 'bottom': + return $alignment; + case 'middle': + return 'center'; + case 'sub': + return 'bottom'; + case 'text-top': + case 'baseline': + return 'top'; + default: + return ''; + } + } + /** * Map list style for ordered list * diff --git a/tests/PhpWord/Shared/HtmlTest.php b/tests/PhpWord/Shared/HtmlTest.php index 2c1e2d07..67c9fcaa 100644 --- a/tests/PhpWord/Shared/HtmlTest.php +++ b/tests/PhpWord/Shared/HtmlTest.php @@ -844,4 +844,48 @@ HTML; $this->assertTrue($doc->elementExists($xpath, $xmlFile)); $this->assertEquals('lowerRoman', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val')); } + + /** + * Parse ordered list start & numbering style + */ + public function testParseVerticalAlign() + { + $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $section = $phpWord->addSection(); + + // borders & backgrounds are here just for better visual comparison + $html = << +
defaulttopmiddlebottom






+HTML; + + Html::addHtml($section, $html); + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + // uncomment to see results + file_put_contents('./table_src.html', $html); + file_put_contents('./table_result_'.time().'.docx', file_get_contents( TestHelperDOCX::getFile() ) ); + + $xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:tcPr/w:vAlign'; + $this->assertFalse($doc->elementExists($xpath)); + + $xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[2]/w:tcPr/w:vAlign'; + $this->assertTrue($doc->elementExists($xpath)); + $this->assertEquals('top', $doc->getElement($xpath)->getAttribute('w:val')); + + $xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[3]/w:tcPr/w:vAlign'; + $this->assertTrue($doc->elementExists($xpath)); + $this->assertEquals('center', $doc->getElement($xpath)->getAttribute('w:val')); + + $xpath = '/w:document/w:body/w:tbl/w:tr/w:tc[4]/w:tcPr/w:vAlign'; + $this->assertTrue($doc->elementExists($xpath)); + $this->assertEquals('bottom', $doc->getElement($xpath)->getAttribute('w:val')); + } }