[ 
https://issues.apache.org/jira/browse/TIKA-4943?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18125631#comment-18125631
 ] 

ASF GitHub Bot commented on TIKA-4943:
--------------------------------------

henry-lindeman-glean commented on code in PR #3277:
URL: https://github.com/apache/tika/pull/3277#discussion_r4232796206


##########
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/onenote/fsshttpb/MSOneStorePackage.java:
##########
@@ -622,25 +627,471 @@ private void walkObject(RevisionStoreObject object,
         }
         int objectType = jcidIndex(object);
         recordEntityGuid(object, objectType);
-        // The title structure of a page (StructureElementChildNodes) appears 
above the page
-        // body on screen, but is declared after the body child nodes. Emit it 
first so the
-        // text comes out in visual order.
-        for (PropertyAction action : actions) {
-            if (action.oneNotePropertyEnum == 
OneNotePropertyEnum.StructureElementChildNodes) {
-                processAction(action, objectsById, visited, authorRole, 
options, metadata, xhtml,
-                        depth, resourceInfo);
+        ListStyle listStyle = listStyleForObject(object, actions, objectsById);
+        startObjectStructure(objectType, listStyle, xhtml);
+        try {
+            // Emit the title structure before page body nodes to preserve 
visual order.
+            List<PropertyAction> structureActions = new ArrayList<>();
+            for (PropertyAction action : actions) {
+                if (action.oneNotePropertyEnum == 
OneNotePropertyEnum.StructureElementChildNodes) {
+                    structureActions.add(action);
+                }
             }
+            processStructureChildActions(structureActions, objectsById, 
visited, authorRole,
+                    options, metadata, xhtml, depth, resourceInfo);
+            List<PropertyAction> remainingActions = new ArrayList<>();
+            for (PropertyAction action : actions) {
+                if (hasPrimaryPicture &&
+                        action.oneNotePropertyEnum == 
OneNotePropertyEnum.WebPictureContainer14) {
+                    continue;
+                }
+                if (action.oneNotePropertyEnum != 
OneNotePropertyEnum.StructureElementChildNodes) {
+                    remainingActions.add(action);
+                }
+            }
+            processStructureChildActions(remainingActions, objectsById, 
visited, authorRole,
+                    options, metadata, xhtml, depth, resourceInfo);
+        } finally {
+            endObjectStructure(objectType, listStyle, xhtml);
         }
-        for (PropertyAction action : actions) {
-            if (hasPrimaryPicture &&
-                    action.oneNotePropertyEnum == 
OneNotePropertyEnum.WebPictureContainer14) {
+    }
+
+    private void startObjectStructure(int objectType, ListStyle listStyle,
+                                      XHTMLContentHandler xhtml) throws 
SAXException {
+        switch (objectType) {
+            case OneNoteStructureJcid.TABLE_NODE:
+                xhtml.startElement("table");
+                break;
+            case OneNoteStructureJcid.TABLE_ROW_NODE:
+                xhtml.startElement("tr");
+                break;
+            case OneNoteStructureJcid.TABLE_CELL_NODE:
+                xhtml.startElement("td");
+                break;
+            case OneNoteStructureJcid.OUTLINE_ELEMENT_NODE:
+                if (listStyle != null) {
+                    if (listStyle.restartValue == null) {
+                        xhtml.startElement("li");
+                    } else {
+                        xhtml.startElement("li", "value", 
listStyle.restartValue.toString());
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void endObjectStructure(int objectType, ListStyle listStyle,
+                                    XHTMLContentHandler xhtml) throws 
SAXException {
+        switch (objectType) {
+            case OneNoteStructureJcid.TABLE_NODE:
+                xhtml.endElement("table");
+                break;
+            case OneNoteStructureJcid.TABLE_ROW_NODE:
+                xhtml.endElement("tr");
+                break;
+            case OneNoteStructureJcid.TABLE_CELL_NODE:
+                xhtml.endElement("td");
+                break;
+            case OneNoteStructureJcid.OUTLINE_ELEMENT_NODE:
+                if (listStyle != null) {
+                    xhtml.endElement("li");
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void walkObjectGroupRoots(List<RevisionStoreObjectGroup> 
objectGroups,
+                                      Map<ExGuid, RevisionStoreObject> 
objectsById,
+                                      Set<ExGuid> visited, 
OneNoteTreeWalkerOptions options,
+                                      Metadata metadata, XHTMLContentHandler 
xhtml)
+            throws SAXException, TikaException, IOException {
+        Set<ExGuid> structureDescendantIds = 
collectStructureDescendantIds(objectsById);
+        List<RevisionStoreObject> deferredObjects = new ArrayList<>();
+        for (RevisionStoreObjectGroup objectGroup : objectGroups) {
+            if (objectGroup == null || objectGroup.objects == null) {
                 continue;
             }
-            if (action.oneNotePropertyEnum != 
OneNotePropertyEnum.StructureElementChildNodes) {
+            for (RevisionStoreObject object : objectGroup.objects) {
+                if (object != null && object.objectID != null &&
+                        structureDescendantIds.contains(object.objectID)) {
+                    deferredObjects.add(object);
+                    continue;
+                }
+                walkRootObject(object, objectsById, visited, options, 
metadata, xhtml);
+            }
+        }
+        // Cyclic owners may have no independent root; start tables before 
list containers.
+        for (RevisionStoreObject object : deferredObjects) {
+            if (!visited.contains(object.objectID) &&
+                    jcidIndex(object) == OneNoteStructureJcid.TABLE_NODE) {
+                walkRootObject(object, objectsById, visited, options, 
metadata, xhtml);
+            }
+        }
+        for (RevisionStoreObject object : deferredObjects) {
+            if (!visited.contains(object.objectID) && isListContainer(object, 
objectsById)) {
+                walkRootObject(object, objectsById, visited, options, 
metadata, xhtml);
+            }
+        }
+        // Recover only depth-skipped objects, not intentionally suppressed 
renditions.
+        while (!depthSkippedObjects.isEmpty()) {
+            Map.Entry<RevisionStoreObject, Map<AuthorRole, 
EmbeddedResourceInfo>> skipped =
+                    depthSkippedObjects.entrySet().iterator().next();
+            depthSkippedObjects.remove(skipped.getKey());
+            for (Map.Entry<AuthorRole, EmbeddedResourceInfo> reference : 
skipped.getValue().entrySet()) {
+                walkRootObject(skipped.getKey(), objectsById, visited, 
reference.getKey(), options,
+                        metadata, xhtml, reference.getValue());
+            }
+        }
+    }
+
+    private boolean isListContainer(RevisionStoreObject object,
+                                    Map<ExGuid, RevisionStoreObject> 
objectsById) {
+        int type = jcidIndex(object);
+        if (type == OneNoteStructureJcid.OUTLINE_NODE ||
+                type == OneNoteStructureJcid.OUTLINE_ELEMENT_NODE) {
+            return true;
+        }
+        if (object == null || object.propertySet == null ||
+                object.propertySet.objectSpaceObjectPropSet == null) {
+            return false;
+        }
+        for (PropertyAction action : collectObjectActions(object)) {
+            if (action.isChildReference &&
+                    jcidIndex(objectsById.get(action.childReference)) ==
+                            OneNoteStructureJcid.OUTLINE_ELEMENT_NODE) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private Set<ExGuid> collectStructureDescendantIds(
+            Map<ExGuid, RevisionStoreObject> objectsById) {
+        Set<ExGuid> descendants = new HashSet<>();
+        Set<ExGuid> traversed = new HashSet<>();
+        List<RevisionStoreObject> pending = new ArrayList<>();
+        for (RevisionStoreObject object : objectsById.values()) {
+            if (jcidIndex(object) == OneNoteStructureJcid.TABLE_NODE ||
+                    isListContainer(object, objectsById)) {
+                traversed.add(object.objectID);
+                pending.add(object);
+            }
+        }
+        for (int index = 0; index < pending.size(); index++) {
+            RevisionStoreObject object = pending.get(index);
+            if (object.propertySet == null ||
+                    object.propertySet.objectSpaceObjectPropSet == null) {
+                continue;
+            }
+            for (PropertyAction action : collectObjectActions(object)) {
+                if (!action.isChildReference || action.childReference == null) 
{
+                    continue;
+                }
+                ExGuid childId = action.childReference;
+                descendants.add(childId);
+                RevisionStoreObject child = objectsById.get(childId);
+                if (child != null && traversed.add(childId)) {
+                    pending.add(child);
+                }
+            }
+        }
+        return descendants;
+    }
+
+    private void walkRootObject(RevisionStoreObject object,
+                                Map<ExGuid, RevisionStoreObject> objectsById, 
Set<ExGuid> visited,
+                                OneNoteTreeWalkerOptions options, Metadata 
metadata,
+                                XHTMLContentHandler xhtml)
+            throws SAXException, TikaException, IOException {
+        walkRootObject(object, objectsById, visited, AuthorRole.NONE, options, 
metadata, xhtml, null);
+    }
+
+    private void walkRootObject(RevisionStoreObject object,
+                                Map<ExGuid, RevisionStoreObject> objectsById, 
Set<ExGuid> visited,
+                                AuthorRole authorRole, 
OneNoteTreeWalkerOptions options, Metadata metadata,
+                                XHTMLContentHandler xhtml, 
EmbeddedResourceInfo resourceInfo)
+            throws SAXException, TikaException, IOException {
+        if (!canWalkObject(object, visited, 0)) {
+            walkObject(object, objectsById, visited, authorRole, options, 
metadata, xhtml, 0, resourceInfo);
+            return;
+        }

Review Comment:
   here's the first three lines of walkObject:
   ```java
       private void walkObject(RevisionStoreObject object,
                                Map<ExGuid, RevisionStoreObject> objectsById, 
Set<ExGuid> visited,
                                AuthorRole authorRole, OneNoteTreeWalkerOptions 
options,
                                Metadata metadata, XHTMLContentHandler xhtml, 
int depth,
                                EmbeddedResourceInfo inheritedResourceInfo)
               throws SAXException, TikaException, IOException {
           if (object == null) {
               return;
           }
   ```





> Emit onenote lists and tables as html lists and tables
> ------------------------------------------------------
>
>                 Key: TIKA-4943
>                 URL: https://issues.apache.org/jira/browse/TIKA-4943
>             Project: Tika
>          Issue Type: Improvement
>          Components: parser
>            Reporter: Henry Lindeman
>            Priority: Minor
>
> currently table cells and list items are emitted in p tags
> instead use <tr>/<td> and <ul>/<li>



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to