diff --git a/docs/changes/1.x/1.5.0.md b/docs/changes/1.x/1.5.0.md
index b96865bada..3d3aca119e 100644
--- a/docs/changes/1.x/1.5.0.md
+++ b/docs/changes/1.x/1.5.0.md
@@ -7,6 +7,7 @@
### Bug fixes
- Set writeAttribute return type by [@radarhere](https://github.com/radarhere) fixing [#2204](https://github.com/PHPOffice/PHPWord/issues/2204) in [#2776](https://github.com/PHPOffice/PHPWord/pull/2776)
+- Writer HTML: ListItemRun render as unordered lists by [@andomiell](https://github.com/andomiell) partially fixing [#1462](https://github.com/PHPOffice/PHPWord/issues/1462)
### Miscellaneous
diff --git a/src/PhpWord/Writer/HTML/Element/Container.php b/src/PhpWord/Writer/HTML/Element/Container.php
index 6e2569f3c6..06f607b4af 100644
--- a/src/PhpWord/Writer/HTML/Element/Container.php
+++ b/src/PhpWord/Writer/HTML/Element/Container.php
@@ -50,7 +50,22 @@ public function write()
$content = '';
$elements = $container->getElements();
- foreach ($elements as $element) {
+ foreach ($elements as $index => $element) {
+ if ($element instanceof \PhpOffice\PhpWord\Element\ListItemRun) {
+ $prevElement = $elements[$index - 1] ?? null;
+
+ if ($prevElement === null) {
+ $content .= '
';
+ } elseif (!$prevElement instanceof \PhpOffice\PhpWord\Element\ListItemRun) {
+ $content .= '';
+ } elseif ($prevElement->getDepth() < $element->getDepth()) {
+ if (str_ends_with($content, '')) {
+ $content = substr($content, 0, -5);
+ }
+ $content .= '';
+ }
+ }
+
$elementClass = get_class($element);
$writerClass = str_replace('PhpOffice\\PhpWord\\Element', $this->namespace, $elementClass);
if (class_exists($writerClass)) {
@@ -58,6 +73,20 @@ public function write()
$writer = new $writerClass($this->parentWriter, $element, $withoutP);
$content .= $writer->write();
}
+
+ if ($element instanceof \PhpOffice\PhpWord\Element\ListItemRun) {
+ $nextElement = $elements[$index + 1] ?? null;
+
+ if ($nextElement === null) {
+ $content .= '
';
+ } elseif (!$nextElement instanceof \PhpOffice\PhpWord\Element\ListItemRun) {
+ $content .= '
';
+ } elseif ($nextElement->getDepth() < $element->getDepth()) {
+ for ($i = $element->getDepth() - $nextElement->getDepth(); $i !== 0; --$i) {
+ $content .= '
';
+ }
+ }
+ }
}
return $content;
diff --git a/src/PhpWord/Writer/HTML/Element/ListItemRun.php b/src/PhpWord/Writer/HTML/Element/ListItemRun.php
index a708868c3d..2515d6cc55 100644
--- a/src/PhpWord/Writer/HTML/Element/ListItemRun.php
+++ b/src/PhpWord/Writer/HTML/Element/ListItemRun.php
@@ -36,9 +36,22 @@ public function write()
return '';
}
- $writer = new Container($this->parentWriter, $this->element);
- $content = $writer->write() . PHP_EOL;
+ $content = '';
- return $content;
+ foreach ($this->element->getElements() as $element) {
+ $namespace = 'PhpOffice\\PhpWord\\Writer\\HTML\\Element';
+ $elementClass = get_class($element);
+ $writerClass = str_replace('PhpOffice\\PhpWord\\Element', $namespace, $elementClass);
+
+ if (!class_exists($writerClass)) {
+ continue;
+ }
+
+ /** @var AbstractElement $writer */
+ $writer = new $writerClass($this->parentWriter, $element, true);
+ $content .= $writer->write();
+ }
+
+ return "$content";
}
}
diff --git a/tests/PhpWordTests/Writer/HTML/ElementTest.php b/tests/PhpWordTests/Writer/HTML/ElementTest.php
index 3b2580381f..d3706f7a55 100644
--- a/tests/PhpWordTests/Writer/HTML/ElementTest.php
+++ b/tests/PhpWordTests/Writer/HTML/ElementTest.php
@@ -20,6 +20,8 @@
use DateTime;
use DOMDocument;
+use DOMNode;
+use DOMNodeList;
use DOMXPath;
use PhpOffice\PhpWord\Element\Text as TextElement;
use PhpOffice\PhpWord\Element\TextRun;
@@ -200,15 +202,35 @@ public function testWriteTitleTextRun(): void
*/
public function testListItemRun(): void
{
- $expected1 = 'List item run 1';
- $expected2 = 'List item run 1 in bold';
+ $expected11 = 'List item run 1.1';
+ $expected11InBold = 'List item run 1.1 in bold';
+ $expected12 = 'List item run 1.2';
+ $expected21 = 'List item run 2.1';
+ $expected22 = 'List item run 2.2';
+ $expected31 = 'List item run 3.1';
+ $expected13 = 'List item run 1.3';
$phpWord = new PhpWord();
$section = $phpWord->addSection();
- $listItemRun = $section->addListItemRun(0, null, 'MyParagraphStyle');
- $listItemRun->addText($expected1);
- $listItemRun->addText($expected2, ['bold' => true]);
+ $listItemRun11 = $section->addListItemRun(0, null, 'MyParagraphStyle');
+ $listItemRun11->addText($expected11);
+ $listItemRun11->addText($expected11InBold, ['bold' => true]);
+
+ $listItemRun12 = $section->addListItemRun(0);
+ $listItemRun12->addText($expected12);
+
+ $listItemRun21 = $section->addListItemRun(1);
+ $listItemRun21->addText($expected21);
+
+ $listItemRun22 = $section->addListItemRun(1);
+ $listItemRun22->addText($expected22);
+
+ $listItemRun31 = $section->addListItemRun(2);
+ $listItemRun31->addText($expected31);
+
+ $listItemRun13 = $section->addListItemRun(0);
+ $listItemRun13->addText($expected13);
$htmlWriter = new HTML($phpWord);
$content = $htmlWriter->getContent();
@@ -216,8 +238,32 @@ public function testListItemRun(): void
$dom = new DOMDocument();
$dom->loadHTML($content);
- self::assertEquals($expected1, $dom->getElementsByTagName('p')->item(0)->textContent);
- self::assertEquals($expected2, $dom->getElementsByTagName('p')->item(1)->textContent);
+ $xpath = new DOMXPath($dom);
+
+ /** @var DOMNodeList $list */
+ $list = $xpath->query('//body/div/ul/li');
+
+ $item11 = $list->item(0);
+ $item12 = $list->item(1);
+ $item13 = $list->item(2);
+
+ self::assertEquals($expected11, $item11->childNodes->item(0)->textContent);
+ self::assertEquals('span', $item11->childNodes->item(1)->nodeName);
+ self::assertEquals($expected11InBold, $item11->childNodes->item(1)->textContent);
+
+ self::assertEquals($expected12, $item12->childNodes->item(0)->textContent);
+ self::assertEquals('ul', $item12->childNodes->item(1)->nodeName);
+
+ self::assertEquals($expected21, $item12->childNodes->item(1)->childNodes->item(0)->textContent);
+
+ $item22 = $item12->childNodes->item(1)->childNodes->item(1);
+
+ self::assertEquals($expected22, $item22->childNodes->item(0)->textContent);
+ self::assertEquals('ul', $item22->childNodes->item(1)->nodeName);
+
+ self::assertEquals($expected31, $item22->childNodes->item(1)->childNodes->item(0)->textContent);
+
+ self::assertEquals($expected13, $item13->childNodes->item(0)->textContent);
}
/**