From 9c235e7188effca26091e01928321f1a6da0b2fc Mon Sep 17 00:00:00 2001 From: Nikita Shevtsov Date: Mon, 20 Nov 2023 16:03:25 +0300 Subject: [PATCH] add new info to tutorial --- .../dedoc_creating_dedoc_document.py | 91 ++++++++++++-- .../_static/table_merged_horizontal.png | Bin 0 -> 11953 bytes .../tutorials/creating_document_classes.rst | 115 ++++++++++++++---- 3 files changed, 167 insertions(+), 39 deletions(-) create mode 100644 docs/source/_static/table_merged_horizontal.png diff --git a/docs/source/_static/code_examples/dedoc_creating_dedoc_document.py b/docs/source/_static/code_examples/dedoc_creating_dedoc_document.py index 2e2cb1cd..ffc910a7 100644 --- a/docs/source/_static/code_examples/dedoc_creating_dedoc_document.py +++ b/docs/source/_static/code_examples/dedoc_creating_dedoc_document.py @@ -1,5 +1,9 @@ +import uuid + from dedoc.data_structures import BoldAnnotation, CellWithMeta, HierarchyLevel, LineMetadata, LineWithMeta, \ - LinkedTextAnnotation, Table, TableMetadata, AttachedFile, UnstructuredDocument + LinkedTextAnnotation, Table, TableMetadata, AttachedFile, UnstructuredDocument, TableAnnotation, AttachAnnotation +from dedoc.structure_constructors import TreeConstructor + text = "Simple text line" simple_line = LineWithMeta(text) @@ -12,10 +16,7 @@ ) metadata = LineMetadata(page_id=0, line_id=1, tag_hierarchy_level=None, hierarchy_level=hierarchy_level, other_fields=None) -annotations = [ - LinkedTextAnnotation(0, 5, "Now it isn't so simple :)"), - BoldAnnotation(7, 10, "True") -] +annotations = [LinkedTextAnnotation(0, 5, "Now the line isn't so simple :)"), BoldAnnotation(7, 10, "True")] super_line = LineWithMeta(text, metadata=metadata, annotations=annotations) @@ -29,22 +30,86 @@ cells_row = [] for cell_text in row: line_with_meta = LineWithMeta(cell_text, metadata=LineMetadata(page_id=0, line_id=None), annotations=[]) - cell = CellWithMeta(lines=[line_with_meta]) + cell = CellWithMeta(lines=[line_with_meta]) # CellWithMeta contains list of LineWithMeta cells_row.append(cell) cells_with_meta.append(cells_row) -table_metadata = TableMetadata(page_id=0, uid="table 1") +table_metadata = TableMetadata(page_id=0, uid="table") table = Table(cells=cells_with_meta, metadata=table_metadata) -attached_file = AttachedFile(original_name="docx_example.png", tmp_file_path="test_dir/docx_example.png", need_content_analysis=True, uid='?') +table_line_metadata = LineMetadata( + page_id=0, + line_id=None, + hierarchy_level=HierarchyLevel( + level_1=1, + level_2=0, + can_be_multiline=False, + line_type="raw_text" + ), + ) +table_line = LineWithMeta("Line with simple table", metadata=table_line_metadata, annotations=[TableAnnotation("table", 0, 21)]) -unstructured_document = UnstructuredDocument(tables=[table], lines=[super_line], attachments=[attached_file]) +table_cells = [["Last name First name Patronymic", "Last name First name Patronymic", "Last name First name Patronymic"], + ["Ivanov", "Ivan", "Ivanovich"], + ["Petrov", "Petr", "Petrovich"]] -from dedoc.metadata_extractors import BaseMetadataExtractor -metadata = BaseMetadataExtractor().extract_metadata(directory="./", filename="example.docx", converted_filename="example.doc", original_filename="example.docx") -unstructured_document.metadata = metadata +for row in table_cells: + cells_row = [] + for cell_text in row: + line_with_meta = LineWithMeta(cell_text, metadata=LineMetadata(page_id=0, line_id=None), annotations=[]) + cell = CellWithMeta([line_with_meta]) # CellWithMeta contains list of LineWithMeta + cells_row.append(cell) + cells_with_meta.append(cells_row) + +cells_with_meta[0][0].colspan = 3 +cells_with_meta[0][1].invisible = True +cells_with_meta[0][2].invisible = True + +table_metadata = TableMetadata(page_id=0, uid="complicated_table") +complicated_table = Table(cells=cells_with_meta, metadata=table_metadata) + +complicated_table_line_metadata = LineMetadata( + page_id=0, + line_id=None, + hierarchy_level=HierarchyLevel( + level_1=1, + level_2=0, + can_be_multiline=False, + line_type="raw_text" + ), + ) +complicated_table_line = LineWithMeta("complicated table line", metadata=table_line_metadata, annotations=[TableAnnotation("complicated_table", 0, 21)]) + +attached_file = AttachedFile(original_name="docx_example.png", tmp_file_path="test_dir/docx_example.png", need_content_analysis=False, uid=str(uuid.uuid4())) + +attached_file_line_metadata = LineMetadata( + page_id=0, + line_id=None, + hierarchy_level=HierarchyLevel( + level_1=1, + level_2=0, + can_be_multiline=False, + line_type="raw_text" + ), + ) +attached_file_line = LineWithMeta("Line with attached file", metadata=attached_file_line_metadata, annotations=[AttachAnnotation("super table", 0, 21)]) + +unstructured_document = UnstructuredDocument( + tables=[table, complicated_table], + lines=[super_line, table_line, complicated_table_line], + attachments=[attached_file] +) + +unstructured_document.metadata = { + "file_name": "my_document.txt", + "temporary_file_name": "my_document.txt", + "file_type": "txt", + "size": 11111, # in bytes + "access_time": 1696381364, + "created_time": 1696316594, + "modified_time": 1696381364 + } -from dedoc.structure_constructors import TreeConstructor structure_constructor = TreeConstructor() parsed_document = structure_constructor.structure_document(document=unstructured_document, structure_type="tree") diff --git a/docs/source/_static/table_merged_horizontal.png b/docs/source/_static/table_merged_horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..b22dde0be25eeb853094c12dc0f011db915feee7 GIT binary patch literal 11953 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