From 108c1cdc558dc3e53f01526b7cd540e78d26a4b1 Mon Sep 17 00:00:00 2001 From: lubosdz Date: Sat, 11 Jul 2020 17:20:36 +0200 Subject: [PATCH] Html parser (addHtml) - support attributes start, type in ordered list
    --- src/PhpWord/Shared/Html.php | 48 ++++++++++++++++++++++++- tests/PhpWord/Shared/HtmlTest.php | 60 +++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/PhpWord/Shared/Html.php b/src/PhpWord/Shared/Html.php index 9e5d84b1..7e0848b1 100644 --- a/src/PhpWord/Shared/Html.php +++ b/src/PhpWord/Shared/Html.php @@ -447,7 +447,31 @@ class Html } else { $data['listdepth'] = 0; $styles['list'] = 'listStyle_' . self::$listIndex++; - $element->getPhpWord()->addNumberingStyle($styles['list'], self::getListStyle($isOrderedList)); + $style = $element->getPhpWord()->addNumberingStyle($styles['list'], self::getListStyle($isOrderedList)); + + // extract attributes start & type e.g.
      + $start = 0; + $type = ''; + foreach ($node->attributes as $attribute) { + switch ($attribute->name) { + case 'start': + $start = (int) $attribute->value; + break; + case 'type': + $type = $attribute->value; + break; + } + } + + $levels = $style->getLevels(); + /** @var \PhpOffice\PhpWord\Style\NumberingLevel */ + $level = $levels[0]; + if($start > 0){ + $level->setStart($start); + } + if($type && !!($type = self::mapListType($type))){ + $level->setFormat($type); + } } if ($node->parentNode->nodeName === 'li') { return $element->getParent(); @@ -818,6 +842,28 @@ class Html } } + /** + * Map list style for ordered list + * + * @param string $cssListType + */ + protected static function mapListType($cssListType) + { + switch ($cssListType) { + case 'a': + return NumberFormat::LOWER_LETTER; // a, b, c, .. + case 'A': + return NumberFormat::UPPER_LETTER; // A, B, C, .. + case 'i': + return NumberFormat::LOWER_ROMAN; // i, ii, iii, iv, .. + case 'I': + return NumberFormat::UPPER_ROMAN; // I, II, III, IV, .. + case '1': + default: + return NumberFormat::DECIMAL; // 1, 2, 3, .. + } + } + /** * Parse line break * diff --git a/tests/PhpWord/Shared/HtmlTest.php b/tests/PhpWord/Shared/HtmlTest.php index 52d641af..2c1e2d07 100644 --- a/tests/PhpWord/Shared/HtmlTest.php +++ b/tests/PhpWord/Shared/HtmlTest.php @@ -784,4 +784,64 @@ HTML; $this->assertEquals(240, $doc->getElement($xpath)->getAttribute('w:line')); } + /** + * Parse ordered list start & numbering style + */ + public function testParseOrderedList() + { + $phpWord = new \PhpOffice\PhpWord\PhpWord(); + $section = $phpWord->addSection(); + + // borders & backgrounds are here just for better visual comparison + $html = << +
    1. standard ordered list line 1
    2. +
    3. standard ordered list line 2
    4. +
    + +
      +
    1. ordered list alphabetical, line 5 => E
    2. +
    3. ordered list alphabetical, line 6 => F
    4. +
    + +
      +
    1. ordered list roman lower, line 3 => iii
    2. +
    3. ordered list roman lower, line 4 => iv
    4. +
    + +HTML; + + Html::addHtml($section, $html); + $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007'); + + // compare numbering file + $xmlFile = 'word/numbering.xml'; + + // default - decimal start = 1 + $xpath = '/w:numbering/w:abstractNum[1]/w:lvl[1]/w:start'; + $this->assertTrue($doc->elementExists($xpath, $xmlFile)); + $this->assertEquals('1', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val')); + + $xpath = '/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt'; + $this->assertTrue($doc->elementExists($xpath, $xmlFile)); + $this->assertEquals('decimal', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val')); + + // second list - start = 5, type A = upperLetter + $xpath = '/w:numbering/w:abstractNum[2]/w:lvl[1]/w:start'; + $this->assertTrue($doc->elementExists($xpath, $xmlFile)); + $this->assertEquals('5', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val')); + + $xpath = '/w:numbering/w:abstractNum[2]/w:lvl[1]/w:numFmt'; + $this->assertTrue($doc->elementExists($xpath, $xmlFile)); + $this->assertEquals('upperLetter', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val')); + + // third list - start = 3, type i = lowerRoman + $xpath = '/w:numbering/w:abstractNum[3]/w:lvl[1]/w:start'; + $this->assertTrue($doc->elementExists($xpath, $xmlFile)); + $this->assertEquals('3', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val')); + + $xpath = '/w:numbering/w:abstractNum[3]/w:lvl[1]/w:numFmt'; + $this->assertTrue($doc->elementExists($xpath, $xmlFile)); + $this->assertEquals('lowerRoman', $doc->getElement($xpath, $xmlFile)->getAttribute('w:val')); + } }