Feat: Native hierarchies for docx element types#1505
Conversation
…into newelh/hierarchy-fast/post-processor
new document_to_element_list location
…into newelh/hierarchy-fast/post-processor
…into newelh/hierarchy-fast/post-processor
and execution to metadata cleaning in filetype
non-deterministic hierachy check
…into newelh/hierarchy-fast/post-processor
add more robust test for checking depth
…into newelh/hierarchy-fast/post-processor
* The file used in one of the getting-started examples has moved, update the code-block so it works. * Remedy bulleted list that was rendering in-line. Bulletted list start needs to be separated by blank line. Bullet-paragraph continuation lines need to be indented to align with text of first line.
Project-specific Black configuration like line-length cannot be specified in setup.cfg, only the more modern pyproject.toml. Since we probably need to move to pyproject.toml soon for building and distribution anyway, add a `pyproject.toml` file and add our project's Black configuration values to it. This is only line-length for now but is likely to grow.
…into newelh/hierarchy-fast/post-processor
…tructured into newelh/hierarchy-fast/docx
…into newelh/hierarchy-fast/docx
…into newelh/hierarchy-fast/docx
… document to illustrate hierarchy among headers and list items in a docx file
…into newelh/hierarchy-fast/docx
…into newelh/hierarchy-fast/docx
scanny
left a comment
There was a problem hiding this comment.
LGTM Newel :)
A couple of remarks to consider.
|
|
||
| # Remember that category depths are 0-indexed and relative to the category type | ||
| # Title, list item, bullet, narrative text, etc. | ||
| paragraph = partitioner._document.paragraphs[0] |
There was a problem hiding this comment.
You might extracting paragraphs = partitioner._document.paragraphs to a line at the top here just to reduce the word-count below. The repeated dereferencings don't buy you anything as far as I can see. They're also expensive, but of course that only matters at scale; still, as a matter of style you wouldn't want repeated identical dereferencings (say more than two; each dot is a dict lookup) in your production code so consistent style would be to apply the same to test code.
You could also consider a more compact structure like:
test_cases = [
(0, "Some text before any heading"),
(0, "A Heading 1"),
# etc. ...
]
partitioner = _DocxPartitioner("example-docs/category-level.docx", None, None, False, None)
paragraphs = partitioner._document.paragraphs
for idx, (depth, text) in enumerate(test_cases):
paragraph = paragraphs[idx]
actual_depth = partitioner._parse_category_depth_by_style(paragraph)
assert (
actual_depth == depth
), f"expected paragraph[{idx}] to have depth=={depth}, got {actual_depth}"
assert text in paragraph.text, f"paragraph[{idx}].text does not contain {text}"Then you could probably see the whole test without scrolling. This also has the benefit being able to produce nice test-failure messages without repeating yourself a lot.
Your call though, just an idea :)
There was a problem hiding this comment.
Much more elegant. Thank you!
Summary
Improves hierarchy from docx files by leveraging natural hierarchies built into docx documents. Hierarchy can now be detected from an indentation level for list bullets/numbers and by style name (e.g. Heading 1, List Bullet 2, List Number).
Hierarchy detection is improved by determining category depth via the following:
Testing
This PR adds an additional docx file to example-docs: category-level.docx. This document illustrates heading and bullet hierarchies in a docx file.
Unit tests
test_unstructured/partition/docx/test_docx::test_parse_category_depth_by_style-- Verifies that a paragraph correctly returns the expected category depth.test_unstructured/partition/docx/test_docx::test_parse_category_depth_by_style_name-- Verifies that the category depth for the majority of style names work correctly.test_unstructured/partition/docx/test_docx::test_parse_category_depth_by_style_ilvl-- Verifies the stubbed out implementation returns 0 for category depth.Example
Sample document:

Before
After