mirror of
https://github.com/Unstructured-IO/unstructured.git
synced 2025-06-27 02:30:08 +00:00

> This is POC change; not everything is working correctly and code quality could be improved significantly This ticket add parsing HTML to unstructured element and back. How is it working? HTML has a tree structure, Unstructured Elements is a list. HTML structure is traversed in DFS order, creating Elements and adding them to list. So the reading order from HTML is preserved. To be able to compose tree again all elements has IDs, and metadata.parent_id is leveraged How html is preserved if there are 'layout' without text, or there are deeply nested HTMLs that are just text from the point of view of Unstructured Element? Each element is parsed back to HTML using metadata.text_as_html field. For layout elements only html_tag are there, for long text elements there is everything required to recreate HTML - you can see examples in unit tests or .json file I attached. Pros of solution: - Nothing had to be changed in element types Cons: - There are elements without Text which may be confusing (they could be replaced by some special type) Core transformation logic can be found in 2 functions in `unstructured/documents/transformations.py` Knowns bugs (they are minor): - sometimes html tag is changed incorrectly - metadata.category_depth and metadata.page_number are not set - page break is not added between pages How to test. Generate HTML: ```python3 from pathlib import Path from vlm_partitioner.src.partition import partition if __name__ == "__main__": doc_dir = Path("out_dir") file_path = Path("example_doc.pdf") partition(str(file_path), provider="anthropic", output_dir=str(doc_dir)) ``` Then parse to unstructured elements and back to html ```python3 from pathlib import Path from unstructured.documents.html_utils import indent_html from unstructured.documents.transformations import parse_html_to_ontology, ontology_to_unstructured_elements, \ unstructured_elements_to_ontology from unstructured.staging.base import elements_to_json if __name__ == "__main__": output_dir = Path("out_dir/") output_dir.mkdir(exist_ok=True, parents=True) doc_path = Path("out_dir/example_doc.html") html_content = doc_path.read_text() ontology = parse_html_to_ontology(html_content) unstructured_elements = ontology_to_unstructured_elements(ontology) elements_to_json(unstructured_elements, str(output_dir / f"{doc_path.stem}_unstr.json")) parsed_ontology = unstructured_elements_to_ontology(unstructured_elements) html_to_save = indent_html(parsed_ontology.to_html()) Path(output_dir / f"{doc_path.stem}_parsed_unstr.html").write_text(html_to_save) ``` I attached example doc before and after running these scripts [outputs.zip](https://github.com/user-attachments/files/17438673/outputs.zip)
27 lines
1.0 KiB
Python
27 lines
1.0 KiB
Python
import pytest
|
|
|
|
from unstructured.partition.html.transformations import remove_empty_tags_from_html_content
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("html_content, expected_output"), # noqa PT006
|
|
[
|
|
("<div></div>", ""),
|
|
("<div><p></p></div>", "<div></div>"),
|
|
("<div><input/></div>", "<div><input/></div>"),
|
|
("<div><br/></div>", "<div><br/></div>"),
|
|
('<div><p id="1"></p></div>', '<div><p id="1"></p></div>'),
|
|
("<div><p>Content</p></div>", "<div><p>Content</p></div>"),
|
|
("<div><p> </p></div>", "<div></div>"),
|
|
("<div><p></p><span></span></div>", "<div></div>"),
|
|
("<div><p>Content</p><span></span></div>", "<div><p>Content</p></div>"),
|
|
("<div><p>Content</p><span> </span></div>", "<div><p>Content</p></div>"),
|
|
(
|
|
"<div><p>Content</p><span>Text</span></div>",
|
|
"<div><p>Content</p><span>Text</span></div>",
|
|
),
|
|
],
|
|
)
|
|
def test_removes_empty_tags(html_content, expected_output):
|
|
assert remove_empty_tags_from_html_content(html_content) == expected_output
|