From 115435a835829b1914df5323df88905d07d62466 Mon Sep 17 00:00:00 2001 From: Maxim Lysak Date: Tue, 15 Oct 2024 14:32:37 +0200 Subject: [PATCH 1/2] Fixes for lists handling in docx Signed-off-by: Maxim Lysak --- docling/backend/mspowerpoint_backend.py | 4 +- docling/backend/msword_backend.py | 91 ++++++++++++++++++++---- tests/data/word_sample.docx | Bin 103139 -> 103966 bytes 3 files changed, 80 insertions(+), 15 deletions(-) diff --git a/docling/backend/mspowerpoint_backend.py b/docling/backend/mspowerpoint_backend.py index bdf73c99..0849328d 100644 --- a/docling/backend/mspowerpoint_backend.py +++ b/docling/backend/mspowerpoint_backend.py @@ -88,7 +88,7 @@ class MsPowerpointDocumentBackend(DeclarativeDocumentBackend, PaginatedDocumentB ) doc = DoclingDocument( description=DescriptionItem(), name="name_without_extension", origin=origin - ) # TODO must add origin information + ) # must add origin information doc = self.walk_linear(self.pptx_obj, doc) return doc @@ -177,7 +177,7 @@ class MsPowerpointDocumentBackend(DeclarativeDocumentBackend, PaginatedDocumentB e_is_a_list_item = False if e_is_a_list_item: - # TODO: Set marker and enumerated arguments if this is an enumeration element. + # Set marker and enumerated arguments if this is an enumeration element. enum_marker = str(enum_list_item_value) + "." doc.add_list_item( marker=enum_marker, diff --git a/docling/backend/msword_backend.py b/docling/backend/msword_backend.py index a098db51..2974d1ff 100644 --- a/docling/backend/msword_backend.py +++ b/docling/backend/msword_backend.py @@ -44,6 +44,7 @@ class MsWordDocumentBackend(DeclarativeDocumentBackend): self.parents[i] = None self.level = 0 + self.listIter = 0 self.history = { "names": [None], @@ -115,6 +116,7 @@ class MsWordDocumentBackend(DeclarativeDocumentBackend): for element in body: tag_name = etree.QName(element).localname + # Check for Inline Images (drawings or blip elements) found_drawing = etree.ElementBase.xpath( element, ".//w:drawing", namespaces=self.xml_namespaces ) @@ -128,8 +130,7 @@ class MsWordDocumentBackend(DeclarativeDocumentBackend): self.handle_tables(element, docx_obj, doc) except Exception: _log.error("could not parse a table, broken docx table") - # Check for Inline Images (drawings or blip elements) - # elif element.xpath(".//w:drawing", namespaces = self.xml_namespaces) or element.xpath(".//w:pict", namespaces = self.xml_namespaces): + elif found_drawing or found_pict: self.handle_pictures(element, docx_obj, doc) # Check for Text @@ -157,7 +158,6 @@ class MsWordDocumentBackend(DeclarativeDocumentBackend): # Get the numId element and extract the value numId_elem = numPr.find("w:numId", namespaces=paragraph._element.nsmap) ilvl_elem = numPr.find("w:ilvl", namespaces=paragraph._element.nsmap) - numId = numId_elem.get(self.XML_KEY) if numId_elem is not None else None ilvl = ilvl_elem.get(self.XML_KEY) if ilvl_elem is not None else None @@ -206,15 +206,31 @@ class MsWordDocumentBackend(DeclarativeDocumentBackend): text = paragraph.text.strip() # if len(text)==0 # keep empty paragraphs, they seperate adjacent lists! + # Common styles for bullet and numbered lists. + # "List Bullet", "List Number", "List Paragraph" + # TODO: reliably identify wether list is a numbered list or not + # is_numbered = "List Bullet" not in paragraph.style.name + is_numbered = False + p_style_name, p_level = self.get_label_and_level(paragraph) numid, ilevel = self.get_numId_and_ilvl(paragraph) + # print("numid: {}, ilevel: {}, text: {}".format(numid, ilevel, text)) - # print("paragraph.text: {} | numid: {} | ilevel: {}".format(paragraph.text, numid, ilevel)) + if numid == 0: + numid = None # Handle lists if numid is not None and ilevel is not None: self.add_listitem( - element, docx_obj, doc, p_style_name, p_level, numid, ilevel, text + element, + docx_obj, + doc, + p_style_name, + p_level, + numid, + ilevel, + text, + is_numbered, ) self.update_history(p_style_name, p_level, numid, ilevel) return @@ -224,14 +240,12 @@ class MsWordDocumentBackend(DeclarativeDocumentBackend): self.parents[key] = None self.level = self.level_at_new_list - 1 self.level_at_new_list = None - if p_style_name in ["Title"]: for key, val in self.parents.items(): self.parents[key] = None self.parents[0] = doc.add_text( parent=None, label=DocItemLabel.TITLE, text=text ) - elif "Heading" in p_style_name: self.add_header(element, docx_obj, doc, p_style_name, p_level, text) @@ -303,8 +317,20 @@ class MsWordDocumentBackend(DeclarativeDocumentBackend): return def add_listitem( - self, element, docx_obj, doc, p_style_name, p_level, numid, ilevel, text: str + self, + element, + docx_obj, + doc, + p_style_name, + p_level, + numid, + ilevel, + text: str, + is_numbered=False, ): + # is_numbered = is_numbered + enum_marker = "" + level = self.get_level() if self.prev_numid() is None: # Open new list self.level_at_new_list = level @@ -314,7 +340,16 @@ class MsWordDocumentBackend(DeclarativeDocumentBackend): ) # TODO: Set marker and enumerated arguments if this is an enumeration element. - doc.add_list_item(parent=self.parents[level], text=text) + self.listIter += 1 + if is_numbered: + enum_marker = str(self.listIter) + "." + is_numbered = True + doc.add_list_item( + marker=enum_marker, + enumerated=is_numbered, + parent=self.parents[level], + text=text, + ) elif ( self.prev_numid() == numid and self.prev_indent() < ilevel @@ -325,12 +360,26 @@ class MsWordDocumentBackend(DeclarativeDocumentBackend): ): # TODO: determine if this is an unordered list or an ordered list. # Set GroupLabel.ORDERED_LIST when it fits. - self.parents[i] = doc.add_group( - label=GroupLabel.LIST, name="list", parent=self.parents[i - 1] - ) + self.listIter = 0 + if is_numbered: + self.parents[i] = doc.add_group( + label=GroupLabel.ORDERED_LIST, + name="list", + parent=self.parents[i - 1], + ) + else: + self.parents[i] = doc.add_group( + label=GroupLabel.LIST, name="list", parent=self.parents[i - 1] + ) # TODO: Set marker and enumerated arguments if this is an enumeration element. + self.listIter += 1 + if is_numbered: + enum_marker = str(self.listIter) + "." + is_numbered = True doc.add_list_item( + marker=enum_marker, + enumerated=is_numbered, parent=self.parents[self.level_at_new_list + ilevel], text=text, ) @@ -341,14 +390,30 @@ class MsWordDocumentBackend(DeclarativeDocumentBackend): self.parents[k] = None # TODO: Set marker and enumerated arguments if this is an enumeration element. + self.listIter += 1 + if is_numbered: + enum_marker = str(self.listIter) + "." + is_numbered = True doc.add_list_item( + marker=enum_marker, + enumerated=is_numbered, parent=self.parents[self.level_at_new_list + ilevel], text=text, ) + self.listIter = 0 elif self.prev_numid() == numid or self.prev_indent() == ilevel: # TODO: Set marker and enumerated arguments if this is an enumeration element. - doc.add_list_item(parent=self.parents[level - 1], text=text) + self.listIter += 1 + if is_numbered: + enum_marker = str(self.listIter) + "." + is_numbered = True + doc.add_list_item( + marker=enum_marker, + enumerated=is_numbered, + parent=self.parents[level - 1], + text=text, + ) return def handle_tables(self, element, docx_obj, doc): diff --git a/tests/data/word_sample.docx b/tests/data/word_sample.docx index b1889405865c5bfcc594a04de63ae20168e4a84c..69b09f5a3a72c6a7bbfe016ff71465f3ca66109c 100644 GIT binary patch delta 15668 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%0Dv(Ft9tu8I}{6I+U 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 delta 14819 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 Date: Tue, 15 Oct 2024 14:35:02 +0200 Subject: [PATCH 2/2] pin docling-core and glm Signed-off-by: Michele Dolfi --- poetry.lock | 17 +++++++++-------- pyproject.toml | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/poetry.lock b/poetry.lock index cefef5e6..4a868911 100644 --- a/poetry.lock +++ b/poetry.lock @@ -885,7 +885,7 @@ files = [] develop = false [package.dependencies] -docling-core = {git = "https://github.com/DS4SD/docling-core.git", rev = "6fee533a101ca08f62e88826218c33e0aab2f417"} +docling-core = {git = "https://github.com/DS4SD/docling-core.git", rev = "7c104d61aa5d003dd8d9711c37e23ce04799f4c9"} docutils = "!=0.21" matplotlib = "^3.7.1" networkx = "^3.1" @@ -909,8 +909,8 @@ toolkit = ["deepsearch-toolkit (>=0.31.0)"] [package.source] type = "git" url = "https://github.com/DS4SD/deepsearch-glm.git" -reference = "c13a6cdda25206911d63a5a28e990217ad823068" -resolved_reference = "c13a6cdda25206911d63a5a28e990217ad823068" +reference = "c185c4f985ccd29a470a1cddd3bec43880b739ee" +resolved_reference = "c185c4f985ccd29a470a1cddd3bec43880b739ee" [[package]] name = "dill" @@ -952,14 +952,15 @@ json-schema-for-humans = "^1.0.0" jsonref = "^1.1.0" jsonschema = "^4.16.0" pandas = "^2.1.4" +pillow = "^10.3.0" pydantic = "^2.6.0" tabulate = "^0.9.0" [package.source] type = "git" url = "https://github.com/DS4SD/docling-core.git" -reference = "6fee533a101ca08f62e88826218c33e0aab2f417" -resolved_reference = "6fee533a101ca08f62e88826218c33e0aab2f417" +reference = "7c104d61aa5d003dd8d9711c37e23ce04799f4c9" +resolved_reference = "7c104d61aa5d003dd8d9711c37e23ce04799f4c9" [[package]] name = "docling-ibm-models" @@ -3441,9 +3442,9 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] [[package]] @@ -3577,8 +3578,8 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, {version = ">=1.22.4", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2", markers = "python_version == \"3.11\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -7114,4 +7115,4 @@ tesserocr = ["tesserocr"] [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "46f6c1eb76034223f7d65760f6ebe0989ba9e8aff46fcdbce82c147030fcb8be" +content-hash = "14143d6cc79f4c2c8a4d021711198697e91ca01ecf290dd270b483984461c3d1" diff --git a/pyproject.toml b/pyproject.toml index 92225813..4914b903 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,9 +37,9 @@ torchvision = [ ###################### python = "^3.10" pydantic = "^2.0.0" -docling-core = {git = "https://github.com/DS4SD/docling-core.git", rev = "6fee533a101ca08f62e88826218c33e0aab2f417"} +docling-core = {git = "https://github.com/DS4SD/docling-core.git", rev = "7c104d61aa5d003dd8d9711c37e23ce04799f4c9"} docling-ibm-models = {git = "https://github.com/DS4SD/docling-ibm-models.git", rev = "1d2e2a2e6eb152c237f1383cdba20cf85db80b97"} -deepsearch-glm = {git = "https://github.com/DS4SD/deepsearch-glm.git", rev = "c13a6cdda25206911d63a5a28e990217ad823068"} +deepsearch-glm = {git = "https://github.com/DS4SD/deepsearch-glm.git", rev = "c185c4f985ccd29a470a1cddd3bec43880b739ee"} docling-parse = "^1.5.1" filetype = "^1.2.0"