Forum


Replies: 1   Views: 2171
Transformdocadvhtml and lists
Topic closed:
Please note this is an old forum thread. Information in this post may be out-to-date and/or erroneous.
Every phpdocx version includes new features and improvements. Previously unsupported features may have been added to newer releases, or past issues may have been corrected.
We encourage you to download the current phpdocx version and check the Documentation available.

Posted by IHD  · 27-01-2019 - 14:44

Hi, 

I'm using the TransformDocAdvHTML to transform a previously created docx to HTML. Consider the following word content: 

$itemList = array(
    'Line 1',
    array(
        'Line A',
        'Line B',
        'Line C'
    ),
    'Line 2',
    'Line 3',
);


$docx->addList($itemList, 2);
$docx->addText('ordinary text line');

When tranforming to HTML, it gives me a correct HTML structure, such as: 

<ol>
 <li>Line 1</li>
 <ol>
  <li>Line A</li>
  <li>Line B</li>
  <li>Line C</li>
 </ol>
 <li>Line 2</li>
 <li>Line 3</li>
<ol>
<p>ordinary text line</p>

 

HOWEVER, if the list ends with the nested list item, as follows:

$itemList = array(
    'Line 1',
    array(
        'Line A',
        'Line B',
        'Line C'
    ),
);


$docx->addList($itemList, 2);
$docx->addText('ordinary text line');

...then the <ol> tag is not closed properly and the resulting HTML looks like this:

<ol>
 <li>Line 1</li>
 <ol>
  <li>Line A</li>
  <li>Line B</li>
  <li>Line C</li>
 </ol>
 <p>ordinary text line</p>

 [AND ALL OTHER CONTENT ALSO SHOWS WITHIN THIS <ol> TAG]

<ol>

 

As you can see, the <p> tag and all other html comes before/within the closing </ol> tag. But it should come after.

Is there an easy "fix"?

Using version 8.0, advanced. 

Thanks!

Posted by admin  · 28-01-2019 - 07:54

Hello,

phpdocx 8.5 added changes to the internal algorithm to handle that kind of nested list correctly.

Although we recommend you to upgrade to phpdocx 8.5 to get the latest improvements in the DOCX to HTML transformation feature (https://www.phpdocx.com/news/post/phpdocx-v8-5-release-notes/217), you can apply the following patch to use the numbering styles with nested lists:

@@ -1882,7 +1882,18 @@
             // get w:numId to know the ID of the list
             $numIdTag = $numPrTag->item(0)->getElementsByTagNameNS('http://schemas.openxmlformats.org/wordprocessingml/2006/main', 'numId');
             if ($numIdTag->length > 0 && $numIdTag->item(0)->hasAttribute('w:val') && $numIdTag->item(0)->getAttribute('w:val') != '') {
+                // handle start list number
+                if (!isset($this->listStartValues[$numIdTag->item(0)->getAttribute('w:val')])) {
+                    $this->listStartValues[$numIdTag->item(0)->getAttribute('w:val')] = array();
+                }
                 $numberingLevel = (int)$numPrTag->item(0)->getElementsByTagNameNS('http://schemas.openxmlformats.org/wordprocessingml/2006/main', 'ilvl')->item(0)->getAttribute('w:val');
+                // handle start list number
+                if (!isset($this->listStartValues[$numIdTag->item(0)->getAttribute('w:val')][$numberingLevel])) {
+                    $this->listStartValues[$numIdTag->item(0)->getAttribute('w:val')][$numberingLevel] = 1;
+                } else {
+                    $this->listStartValues[$numIdTag->item(0)->getAttribute('w:val')][$numberingLevel] = $this->listStartValues[$numIdTag->item(0)->getAttribute('w:val')][$numberingLevel] + 1;
+                }
+
                 // get the numbering style based on the numbering ID and its level
                 $numberingStyle = $this->getNumberingType($numIdTag->item(0)->getAttribute('w:val'), $numberingLevel);
 
@@ -2007,6 +2018,9 @@
                 $closeNewList = true;
             }
 
+            // sets how many list levels must be closed
+            $iterationListClose = 1;
+
             if ($nextSiblingElement !== null) {
                 $numPrNextSiblingElement = $nextSiblingElement->getElementsByTagNameNS('http://schemas.openxmlformats.org/wordprocessingml/2006/main', 'numPr');
                 if ($numPrNextSiblingElement->length > 0) {
@@ -2017,6 +2031,11 @@
                         // get the numbering style based on the numbering ID and its level
                         $numberingStyleNextSiblingElementTag = $this->getNumberingType($numIdNextSiblingElementTag->item(0)->getAttribute('w:val'), $numberingLevelNextSiblingElementTag);
 
+                        // handle close list levels
+                        if ($numberingLevel > 0 && $numIdNextSiblingElementTag->item(0)->getAttribute('w:val') != $numIdTag->item(0)->getAttribute('w:val')) {
+                            $iterationListClose += $numberingLevel;
+                        }
+
                         if ($numIdNextSiblingElementTag->item(0)->getAttribute('w:val') != $numIdTag->item(0)->getAttribute('w:val')) {
                             $closeNewList = true;
                         }
@@ -2026,8 +2045,13 @@
                         }
                     }
                 } else {
-                    // the next element is not a numbering, then create a new list
+                    // the next element is not a numbering, then close the list
                     $closeNewList = true;
+
+                    // handle close list levels
+                    if ($numberingLevel > 0) {
+                        $iterationListClose += $numberingLevel;
+                    }
                 }
             }
 
@@ -2039,7 +2063,9 @@
                 $tagTypeList = $this->htmlPlugin->getTag('unorderedList');
             }
             if ($closeNewList === true) {
-                $this->html .= '</'.$tagTypeList.'>';
+                for ($iClose = 0; $iClose < $iterationListClose; $iClose++) { 
+                    $this->html .= '</'.$tagTypeList.'>';
+                }
             }
         }
     }

If you send to contact[at]phpdocx.com an e-mail sending if you are using the classic or namespaces package, the dev team will send you the class updated with these changes.

Regards.