diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ed042704f..f2e7b21e06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ -## 0.27.27-dev0 +## 0.27.27-dev1 ### Fixes +- **Keep overlap category names intact from element 100 on.** `identify_overlapping_or_nesting_case()` split `{ix}. {category}` labels with a 3-character slice, so from index 100 the leftover digits leaked into `overlapping_elements` and `overlapping_case`. It now splits on the first `". "`. + - **Preserve serialized element identity when rehydrating JSON.** `partition_json()` no longer replaces element IDs or stored metadata with attributes from the JSON container. Explicit `metadata_filename`, `metadata_last_modified`, `url`, and `text_as_html` overrides remain supported, diff --git a/test_unstructured/test_utils.py b/test_unstructured/test_utils.py index abde59e22c..a74fc09a3e 100644 --- a/test_unstructured/test_utils.py +++ b/test_unstructured/test_utils.py @@ -7,7 +7,7 @@ from unstructured import utils from unstructured.documents.coordinates import PixelSpace -from unstructured.documents.elements import ElementMetadata, NarrativeText, Title +from unstructured.documents.elements import ElementMetadata, NarrativeText, Table, Title @pytest.fixture() @@ -312,6 +312,43 @@ def test_catch_overlapping_and_nested_bboxes_non_overlapping_case(): assert overlapping_cases == [] +@pytest.mark.parametrize("n_filler", [0, 100, 1000]) +def test_catch_overlapping_and_nested_bboxes_keeps_category_past_element_99(n_filler): + coordinate_system = PixelSpace(width=1000, height=1000) + fillers = [ + NarrativeText( + text=f"filler {i}", + coordinates=((0, i), (0, i + 1), (5, i + 1), (5, i)), + coordinate_system=coordinate_system, + metadata=ElementMetadata(page_number=1), + ) + for i in range(n_filler) + ] + elements = fillers + [ + Table( + text="cell a cell b", + coordinates=((0, 0), (0, 500), (500, 500), (500, 0)), + coordinate_system=coordinate_system, + metadata=ElementMetadata(page_number=2), + ), + Title( + text="cell a", + coordinates=((10, 10), (10, 50), (100, 50), (100, 10)), + coordinate_system=coordinate_system, + metadata=ElementMetadata(page_number=2), + ), + ] + + overlapping_flag, overlapping_cases = utils.catch_overlapping_and_nested_bboxes(elements) + + assert overlapping_flag is True + assert overlapping_cases[0]["overlapping_elements"] == [ + f"Table(ix={n_filler})", + f"Title(ix={n_filler + 1})", + ] + assert overlapping_cases[0]["overlapping_case"] == "nested Title in Table" + + def test_only_returns_singleton_iterable(): singleton_iterable = [42] result = utils.only(singleton_iterable) diff --git a/unstructured/__version__.py b/unstructured/__version__.py index 108230819e..5a9a5fb825 100644 --- a/unstructured/__version__.py +++ b/unstructured/__version__.py @@ -1 +1 @@ -__version__ = "0.27.27-dev0" # pragma: no cover +__version__ = "0.27.27-dev1" # pragma: no cover diff --git a/unstructured/utils.py b/unstructured/utils.py index ba87f63c01..2135cdbcb4 100644 --- a/unstructured/utils.py +++ b/unstructured/utils.py @@ -500,8 +500,9 @@ def identify_overlapping_or_nesting_case( type1, type2 = label_pair ix_element1 = "".join([ch for ch in type1 if ch.isnumeric()]) ix_element2 = "".join([ch for ch in type2 if ch.isnumeric()]) - type1 = type1[3:].strip() - type2 = type2[3:].strip() + # Labels are "{ix}. {category}", and ix can have any number of digits. + type1 = type1.split(". ", 1)[-1] + type2 = type2.split(". ", 1)[-1] box1_corners = _convert_coordinates_to_box(box1) box2_corners = _convert_coordinates_to_box(box2) x_bottom_left_1, y_bottom_left_1, x_top_right_1, y_top_right_1 = box1_corners