python-hwpx 6.7.0__tar.gz → 6.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_hwpx-6.7.0/src/python_hwpx.egg-info → python_hwpx-6.9.0}/PKG-INFO +9 -4
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/README.md +8 -3
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/pyproject.toml +7 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/__init__.py +84 -34
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/fields.py +1 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/layout.py +46 -25
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/media.py +45 -8
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/memos.py +3 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/shapes.py +2 -2
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/tables.py +49 -3
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/persistence.py +14 -2
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/shapes.py +15 -7
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/body_patch.py +27 -12
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/capabilities.py +1 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/data/contract_docs/support-matrix.md +4 -4
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/document.py +39 -3
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/equation/authoring.py +6 -3
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/equation/eqedit.py +7 -2
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/equation/measure.py +169 -73
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/errors.py +48 -1
- python_hwpx-6.9.0/src/hwpx/form_fit/_glyph_table.py +6951 -0
- python_hwpx-6.9.0/src/hwpx/form_fit/measure.py +2853 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/docinfo_writer.py +4 -3
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/errors.py +12 -22
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/header_xml.py +4 -3
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/package.py +70 -3
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/records.py +2 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/section_writer.py +6 -5
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/section_xml.py +69 -6
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/shape_xml.py +6 -4
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/shapes.py +22 -16
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/ingest/hwpx_converter.py +2 -1
- python_hwpx-6.9.0/src/hwpx/layout/line_cache.py +636 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/layout/lint.py +4 -3
- python_hwpx-6.9.0/src/hwpx/layout/pages.py +4412 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/__init__.py +4 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/_document_primitives.py +31 -20
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/_paragraph_text_edit.py +5 -11
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/body.py +3 -3
- python_hwpx-6.9.0/src/hwpx/oxml/container.py +377 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/curves.py +10 -3
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/document_parts.py +38 -5
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/dutmal_compose.py +1 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/header.py +4 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/header_compat.py +6 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/header_fonts.py +75 -4
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/header_part.py +1 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/memo.py +4 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/note_authoring.py +2 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/objects.py +145 -215
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/paragraph.py +54 -81
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/run.py +1 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/section.py +69 -15
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/section_format.py +185 -54
- python_hwpx-6.9.0/src/hwpx/oxml/shape_position.py +600 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/table.py +6 -4
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/table_sizes.py +82 -1
- python_hwpx-6.9.0/src/hwpx/oxml/table_structure.py +166 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/utils.py +46 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/patch.py +11 -8
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/table_patch.py +428 -56
- python_hwpx-6.9.0/src/hwpx/tools/__init__.py +277 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/package_validator.py +29 -6
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/toc_author.py +1 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0/src/python_hwpx.egg-info}/PKG-INFO +9 -4
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/python_hwpx.egg-info/SOURCES.txt +29 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_authoring_defaults.py +63 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_body_patch.py +28 -0
- python_hwpx-6.9.0/tests/test_cell_edit_holder_cache.py +101 -0
- python_hwpx-6.9.0/tests/test_column_widths_as_shares.py +119 -0
- python_hwpx-6.9.0/tests/test_container_members.py +216 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_coverage_ledger.py +14 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_curve_connector_authoring.py +19 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_document_formatting.py +49 -4
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_document_metadata.py +2 -2
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_documentation_code_fences.py +21 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_drop_cap_authoring.py +2 -2
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_dutmal_compose_authoring.py +2 -2
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_equation_authoring.py +5 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_equation_converter.py +13 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_equation_measure_hancom_saved.py +7 -5
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_equation_size.py +4 -2
- python_hwpx-6.9.0/tests/test_equation_width_hancom_boxes.py +73 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_existing_document_format_editing.py +31 -0
- python_hwpx-6.9.0/tests/test_form_fit_hancom_rules.py +1573 -0
- python_hwpx-6.9.0/tests/test_gap_and_new_number_values.py +143 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_header_compat_authoring.py +26 -0
- python_hwpx-6.9.0/tests/test_header_list_lookups.py +71 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_hwp5_hancom_files.py +10 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_hwp5_open.py +206 -7
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_hwp5_save.py +117 -16
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_image_object_workflow.py +60 -0
- python_hwpx-6.9.0/tests/test_insert_column_by_clone.py +200 -0
- python_hwpx-6.9.0/tests/test_insert_row_sides.py +193 -0
- python_hwpx-6.9.0/tests/test_layer_leak_guard.py +181 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_layout_cache_scope.py +95 -5
- python_hwpx-6.9.0/tests/test_layout_line_cache.py +658 -0
- python_hwpx-6.9.0/tests/test_layout_page_estimate.py +2448 -0
- python_hwpx-6.9.0/tests/test_lazy_hwp5_import.py +87 -0
- python_hwpx-6.9.0/tests/test_lazy_tools_import.py +91 -0
- python_hwpx-6.9.0/tests/test_lazy_tools_submodules.py +149 -0
- python_hwpx-6.9.0/tests/test_line_break_writing.py +86 -0
- python_hwpx-6.9.0/tests/test_list_level_range.py +53 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_memo_fields.py +31 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_namespace_hygiene.py +4 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_native_edit_contract.py +1 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_ns_tables.py +21 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_oxml_modularization.py +7 -3
- python_hwpx-6.9.0/tests/test_page_and_list_values.py +161 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_paragraph_property_lookup.py +32 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_paragraph_section_management.py +11 -0
- python_hwpx-6.9.0/tests/test_picture_adjustments.py +256 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_product_boundary.py +5 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_public_artifact_hygiene.py +14 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_release_workflow_safety.py +2 -2
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_run_choice_atom_authoring.py +7 -6
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_section_columns.py +91 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_set_column_widths_uniform_split.py +6 -5
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_shape_position_frames.py +35 -1
- python_hwpx-6.9.0/tests/test_shape_size_values.py +212 -0
- python_hwpx-6.9.0/tests/test_size_ratchet.py +102 -0
- python_hwpx-6.9.0/tests/test_split_cell.py +224 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_stale_layout_cache_sweep.py +13 -1
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_style_font_border_reads.py +51 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_tab_character_writing.py +8 -4
- python_hwpx-6.9.0/tests/test_table_clone_identities.py +91 -0
- python_hwpx-6.9.0/tests/test_table_column_floor.py +119 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_table_label.py +2 -2
- python_hwpx-6.9.0/tests/test_table_ops_cells_without_geometry.py +61 -0
- python_hwpx-6.9.0/tests/test_table_ops_delete_every_line.py +44 -0
- python_hwpx-6.9.0/tests/test_table_ops_delete_zones.py +74 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_table_patch.py +15 -2
- python_hwpx-6.9.0/tests/test_table_structure_edits.py +281 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_toc_author.py +1 -1
- python_hwpx-6.7.0/src/hwpx/form_fit/measure.py +0 -1546
- python_hwpx-6.7.0/src/hwpx/layout/pages.py +0 -2245
- python_hwpx-6.7.0/src/hwpx/oxml/shape_position.py +0 -282
- python_hwpx-6.7.0/src/hwpx/tools/__init__.py +0 -131
- python_hwpx-6.7.0/tests/test_form_fit_hancom_rules.py +0 -721
- python_hwpx-6.7.0/tests/test_layout_page_estimate.py +0 -758
- python_hwpx-6.7.0/tests/test_split_cell.py +0 -112
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/LICENSE +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/NOTICE +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/setup.cfg +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/__init__.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/_legacy.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/_resolve.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/_units.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/headings.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/highlight.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/__init__.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/_base.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/fields.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/media.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/notes.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/page.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/parts.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/refs.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/styles.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/text.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/ns/tracking.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_document/tracked.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/_moved_modules.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/data/Skeleton.hwpx +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/data/contract_docs/known-traps.md +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/data/contract_docs/mutation-semantics.md +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/data/contract_docs/recipes-traversal.md +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/equation/__init__.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/equation/mathml.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/equation/render.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/equation/tokens.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/experimental.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/form_fit/__init__.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/form_fit/apply.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/form_fit/engine.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/form_fit/policy.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/form_fit/report.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/__init__.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/binary.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/bodytext.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/cfb.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/controls.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/docinfo.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/fileheader.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/owpml.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/reader.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/section_common.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/summary.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/hwp5/writer.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/ingest/__init__.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/ingest/base.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/layout/__init__.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/layout/report.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/model.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/mutation_report.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/objects/__init__.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/objects/binary_item.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/objects/checkbox.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/objects/form_field.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/objects/highlight.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/objects/results.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/objects/tracked.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/opc/package.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/opc/relationships.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/opc/security.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/opc/xml_utils.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/_document_impl.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/canonical_defaults.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/color.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/common.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/document.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/document_metadata.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/drop_cap.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/field_marks.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/history_part.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/hyperlink_form.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/master_page.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/master_page_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/namespaces.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/numbering.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/numbering_kinds.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/paragraph_heading.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/parser.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/schema.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/section_layout.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/section_story.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/settings.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/simple_parts.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/table_merge.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/oxml/version_part.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/package.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/plan/__init__.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/plan/_execute.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/plan/_model.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/plan/_schema.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/plan/_validate.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/py.typed +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/quality/__init__.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/quality/ledger.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/quality/policy.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/quality/rendering.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/quality/report.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/quality/save_pipeline.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/templates.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/_schemas/header.xsd +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/_schemas/owpml-body.xsd +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/_schemas/owpml-core.xsd +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/_schemas/owpml-header.xsd +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/_schemas/owpml-paralist.xsd +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/_schemas/owpml-xml.xsd +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/_schemas/section.xsd +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/archive_cli.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/doc_diff.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/document_merge.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/document_viewer.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/exporter.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/generic_inventory.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/id_integrity.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/idempotence.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/ir_equality.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/layout_preview.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/mail_merge.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/markdown_export.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/object_finder.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/package_reconcile.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/page_guard.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/read_fidelity.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/recover.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/redline.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/repair.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/report_utils.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/roundtrip_diff.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/table_cleanup.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/table_navigation.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/template_analyzer.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/text_extract_cli.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/text_extractor.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/toc_fidelity.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/hwpx/tools/validator.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/python_hwpx.egg-info/dependency_links.txt +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/python_hwpx.egg-info/entry_points.txt +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/python_hwpx.egg-info/requires.txt +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/src/python_hwpx.egg-info/top_level.txt +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_add_control.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_add_heading.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_adoption_metrics_snapshot.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_arc_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_authoring_quality_corpus.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_blind_eval_fixture.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_border_fill_image_gradient.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_border_line_types.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_build_element_census.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_byte_patch_identity.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_capabilities_surface.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_cell_border_neighbors.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_cell_fields.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_cell_line_spacing.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_cell_margins.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_cell_text_rewrite_semantics.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_char_pr_child_order.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_character_width_ratio.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_chart_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_check_box_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_color_arguments.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_column_break.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_comment_node_robustness.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_container_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_contract_docs_sync.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_corpus_read_fidelity.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_coverage_promotion.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_coverage_targets.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_deviations_registry.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_doc_diff.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_document_context_manager.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_document_facade_surface.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_document_merge.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_document_ops_runtime_boundary.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_document_save_api.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_document_viewer.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_edit_fidelity_corpus.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_edit_plan.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_editor_surface_inventory.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_engine_surface_6_0.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_equalize_widths_per_row.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_equation_render.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_error_contract.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_error_messages.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_evalplan_core_primitives.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_export_captions_dutmal.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_export_cell_text_spaces.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_export_list_labels.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_export_notes.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_export_text_boxes.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_exporter_table_text.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_field_marks.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_field_type_ids.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_fill_image_hancom_modes.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_form_field_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_form_fields.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_form_fill_core_primitives.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_form_fit.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_form_fit_integration.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_fuzz_catalog_derive_expected.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_fuzz_loop.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_fuzz_regressions.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_gap_closure_tools.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_golden_api.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_header_control_before_field.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_heading_style_shapes.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_highlight_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_hp_tab_support.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_hwp5_container.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_hwpxlib_corpus_read.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_hyperlink_hancom_form.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_id_generator_range.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_id_integrity.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_index_mark.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_ingest.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_inline_models.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_insert_row_merged_cells.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_instid_attribute_case.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_integration_hwpx_compatibility.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_integration_roundtrip.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_internal_calls_skip_moved_names.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_layout_lint.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_layout_preview.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_library_boundary_closure.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_line_width_arguments.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_list_continue.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_list_defaults_vs_hancom.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_llms_txt.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_mail_merge_xlsx.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_manifest_resolve_once.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_markdown_export.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_markdown_export_shape_text.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_master_page_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_master_page_pages_taken.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_memo_and_style_editing.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_memo_shape_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_merge_cells_hancom_files.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_merge_cells_keeps_contents.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_moved_module_imports.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_moved_surface_hints.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_mutation_report.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_namespace_handling.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_namespace_normalization.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_new_features.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_note_authoring_contract.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_ns_fields.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_ns_media.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_ns_notes.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_ns_page.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_ns_refs.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_ns_shapes.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_ns_tracking.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_number_formats.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_opc_package.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_open_safety_corpus.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_outline_numbering.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_oxml_parsing.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_package_hygiene.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_packaging_license_metadata.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_packaging_py_typed.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_page_number_control.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_page_number_format.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_page_orientation.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_para_pr_dedup.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_paragraph_align_distribute_space.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_paragraph_border.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_paragraph_format_targets.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_paragraph_hyperlink_style.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_paragraph_keep_together.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_paragraph_margin_default_scale.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_paragraph_property_version_switch.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_paragraph_remove_in_containers.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_part_hierarchy_read_models.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_polygon_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_public_runtime_boundary.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_read_fidelity.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_recover_broken_zip.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_redline_authoring.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_redline_verify.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_remove_unused_charts.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_remove_unused_images.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_repair_repack.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_replace_text_barriers.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_report_utils.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_repr_snapshots.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_return_contract.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_roundtrip_fidelity.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_roundtrip_fidelity_corpus.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_row_heights.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_run_content_kinds.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_run_font_refs.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_run_style_base.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_safe_edit_example.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_save_keeps_inline_text_caches.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_save_pipeline.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_save_verifies_once.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_section_clear_body.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_section_headers.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_section_ids_order.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_section_properties_real_roundtrip.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_set_paragraph_format_keep.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_shape_geometry_contract.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_shape_open_safety_risk_check.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_shape_original_size.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_skeleton_template_ids.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_split_merged_cell.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_stable_surface.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_story_edits_reach_control_copy.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_style_resolution.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_tab_definition_version_switch.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_table_cell_equalize.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_table_cleanup.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_table_navigation.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_table_page_flow.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_table_patch_dryrun.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_table_patch_m105.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_table_patch_structure_fixes.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_table_split_merge.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_tables_default_border.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_template_analyzer_enrichment.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_text_box_fields.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_text_extractor_annotations.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_text_extractor_nested_once.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_text_extractor_run_choice_atoms.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_text_inline_elements.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_text_replace_everywhere.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_title_mark.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_toc_fidelity.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_tracked_overlap_render_smoke.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_tracked_paragraph_delete_break.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_validation_severity.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_validator_comment_nodes.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_validator_form_parameters.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_validator_full_schema.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_validator_hancom_open_rules.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_validator_section_ids.py +0 -0
- {python_hwpx-6.7.0 → python_hwpx-6.9.0}/tests/test_version_metadata.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-hwpx
|
|
3
|
-
Version: 6.
|
|
3
|
+
Version: 6.9.0
|
|
4
4
|
Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 문서 라이브러리
|
|
5
5
|
Author: python-hwpx Maintainers
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -216,9 +216,14 @@ GitHub Release에 첨부되는 `py3-none-any` wheel을 문서와 함께 올리
|
|
|
216
216
|
## 알려진 제약
|
|
217
217
|
|
|
218
218
|
- `add_shape()` / `add_control()`은 저수준 탈출구라, 그대로 저장하면 한/글이
|
|
219
|
-
열지 못하는 파일이 됩니다(호출 시 경고만 나옵니다). 도형은
|
|
220
|
-
`
|
|
221
|
-
|
|
219
|
+
열지 못하는 파일이 됩니다(호출 시 경고만 나옵니다). 도형은 한/글이 요구하는 하위
|
|
220
|
+
요소까지 만드는 전용 메서드를 쓰세요: `add_line()` / `add_rectangle()` /
|
|
221
|
+
`add_ellipse()` / `add_arc()` / `add_polygon()` / `add_curve()` /
|
|
222
|
+
`add_connector()` / `add_container()`(묶음). 컨트롤은 `add_column_definition()` /
|
|
223
|
+
`add_bookmark()` / `add_hyperlink()`가 있습니다.
|
|
224
|
+
- 그림은 단순 개체 생성과 묶음 안 그림까지 지원합니다. 밝기·대비·회색조·흑백·투명도와 실선 테두리는
|
|
225
|
+
`add_picture()` 인자로 줄 수 있고(자르기는 `crop`, 그림자·빛남·부드러운 가장자리·반사는 `shadow`·`glow`·`soft_edge`·
|
|
226
|
+
`reflection`), 뒤집기·회전은 아직 지원하지 않습니다.
|
|
222
227
|
- 암호화된 HWPX와 암호·배포용 HWP는 지원하지 않습니다.
|
|
223
228
|
|
|
224
229
|
## 기여하기
|
|
@@ -165,9 +165,14 @@ GitHub Release에 첨부되는 `py3-none-any` wheel을 문서와 함께 올리
|
|
|
165
165
|
## 알려진 제약
|
|
166
166
|
|
|
167
167
|
- `add_shape()` / `add_control()`은 저수준 탈출구라, 그대로 저장하면 한/글이
|
|
168
|
-
열지 못하는 파일이 됩니다(호출 시 경고만 나옵니다). 도형은
|
|
169
|
-
`
|
|
170
|
-
|
|
168
|
+
열지 못하는 파일이 됩니다(호출 시 경고만 나옵니다). 도형은 한/글이 요구하는 하위
|
|
169
|
+
요소까지 만드는 전용 메서드를 쓰세요: `add_line()` / `add_rectangle()` /
|
|
170
|
+
`add_ellipse()` / `add_arc()` / `add_polygon()` / `add_curve()` /
|
|
171
|
+
`add_connector()` / `add_container()`(묶음). 컨트롤은 `add_column_definition()` /
|
|
172
|
+
`add_bookmark()` / `add_hyperlink()`가 있습니다.
|
|
173
|
+
- 그림은 단순 개체 생성과 묶음 안 그림까지 지원합니다. 밝기·대비·회색조·흑백·투명도와 실선 테두리는
|
|
174
|
+
`add_picture()` 인자로 줄 수 있고(자르기는 `crop`, 그림자·빛남·부드러운 가장자리·반사는 `shadow`·`glow`·`soft_edge`·
|
|
175
|
+
`reflection`), 뒤집기·회전은 아직 지원하지 않습니다.
|
|
171
176
|
- 암호화된 HWPX와 암호·배포용 HWP는 지원하지 않습니다.
|
|
172
177
|
|
|
173
178
|
## 기여하기
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-hwpx"
|
|
7
|
-
version = "6.
|
|
7
|
+
version = "6.9.0"
|
|
8
8
|
description = "한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 문서 라이브러리"
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -295,6 +295,9 @@ files = [
|
|
|
295
295
|
# Table width/height distribution (distribute cell width row by row) moved out
|
|
296
296
|
# of table.py -- born in the gate, per the WP-A rule.
|
|
297
297
|
"src/hwpx/oxml/table_sizes.py",
|
|
298
|
+
# Row and column insertion and deletion and cell splits on the table object, moved
|
|
299
|
+
# out of table.py -- born in the gate, per the WP-A rule.
|
|
300
|
+
"src/hwpx/oxml/table_structure.py",
|
|
298
301
|
# A paragraph shape's heading (outline levels 8 to 10 in Hancom's hp:switch form),
|
|
299
302
|
# written and read in one place -- born in the gate, per the WP-A rule.
|
|
300
303
|
"src/hwpx/oxml/paragraph_heading.py",
|
|
@@ -504,6 +507,9 @@ include = [
|
|
|
504
507
|
# Table width/height distribution (distribute cell width row by row) moved out
|
|
505
508
|
# of table.py -- born in the gate, per the WP-A rule.
|
|
506
509
|
"src/hwpx/oxml/table_sizes.py",
|
|
510
|
+
# Row and column insertion and deletion and cell splits on the table object, moved
|
|
511
|
+
# out of table.py -- born in the gate, per the WP-A rule.
|
|
512
|
+
"src/hwpx/oxml/table_structure.py",
|
|
507
513
|
# A paragraph shape's heading (outline levels 8 to 10 in Hancom's hp:switch form),
|
|
508
514
|
# written and read in one place -- born in the gate, per the WP-A rule.
|
|
509
515
|
"src/hwpx/oxml/paragraph_heading.py",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import importlib
|
|
15
15
|
import warnings
|
|
16
16
|
from dataclasses import dataclass
|
|
17
|
-
from typing import Literal
|
|
17
|
+
from typing import TYPE_CHECKING, Literal
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def _resolve_version() -> str:
|
|
@@ -28,9 +28,9 @@ def _resolve_version() -> str:
|
|
|
28
28
|
|
|
29
29
|
# --- experimental / deprecated 최상위 표면 (지연 접근, 접근 시 경고) ---------------
|
|
30
30
|
#
|
|
31
|
-
# stable 이름은 아래에서 eager import
|
|
32
|
-
#
|
|
33
|
-
# 4.0.0에서 제거되는 이름은 0개 — 모두 계속 import 가능합니다.
|
|
31
|
+
# stable 이름은 경고 없이 해석됩니다. 대부분 아래에서 eager import 되고, ``hwpx.tools``의
|
|
32
|
+
# 이름은 ``_TOOLS_STABLE_EXPORTS``가 지연 해석합니다. 여기 등록된 이름만 지연 해석되어
|
|
33
|
+
# 경고를 냅니다. 4.0.0에서 제거되는 이름은 0개 — 모두 계속 import 가능합니다.
|
|
34
34
|
|
|
35
35
|
_EXPERIMENTAL_EXPORTS = {
|
|
36
36
|
# 문서 ingestion 프레임워크(임의 포맷 -> HWPX). 계약 유동.
|
|
@@ -293,8 +293,8 @@ class RetiredSurface(ImportError):
|
|
|
293
293
|
def __getattr__(name: str) -> object:
|
|
294
294
|
"""Resolve dynamic module attributes.
|
|
295
295
|
|
|
296
|
-
``__version__
|
|
297
|
-
해석 시 ``DeprecationWarning``을 냅니다.
|
|
296
|
+
``__version__``과 ``hwpx.tools``의 stable 이름은 경고 없이 지연 해석하고,
|
|
297
|
+
experimental/deprecated 이름은 해석 시 ``DeprecationWarning``을 냅니다.
|
|
298
298
|
"""
|
|
299
299
|
|
|
300
300
|
if name == "__version__":
|
|
@@ -318,6 +318,17 @@ def __getattr__(name: str) -> object:
|
|
|
318
318
|
warnings.warn(_deprecated_message(name), DeprecationWarning, stacklevel=2)
|
|
319
319
|
return getattr(importlib.import_module(module_name), name)
|
|
320
320
|
|
|
321
|
+
if name in _TOOLS_STABLE_EXPORTS or name == "tools":
|
|
322
|
+
# Not ``from . import tools``: that asks this module for ``tools`` first and
|
|
323
|
+
# re-enters this function.
|
|
324
|
+
import hwpx.tools as tools
|
|
325
|
+
|
|
326
|
+
if name == "tools":
|
|
327
|
+
return tools
|
|
328
|
+
value = getattr(tools, name)
|
|
329
|
+
globals()[name] = value
|
|
330
|
+
return value
|
|
331
|
+
|
|
321
332
|
moved = _MOVED_TO_COMPANION.get(name)
|
|
322
333
|
if moved is not None:
|
|
323
334
|
statement = moved.import_statement(name)
|
|
@@ -346,11 +357,76 @@ def __dir__() -> list[str]:
|
|
|
346
357
|
return sorted(
|
|
347
358
|
set(globals())
|
|
348
359
|
| set(__all__)
|
|
360
|
+
| {"tools"}
|
|
349
361
|
| set(_EXPERIMENTAL_EXPORTS)
|
|
350
362
|
| set(_DEPRECATED_EXPORTS)
|
|
351
363
|
)
|
|
352
364
|
|
|
353
365
|
|
|
366
|
+
# --- 지연 stable 최상위 표면 (첫 접근 때 해석, 경고 없음) ---------------------------
|
|
367
|
+
#
|
|
368
|
+
# ``hwpx.tools``에 사는 stable 이름은 첫 접근 때 ``__getattr__``이 그 모듈을 읽어
|
|
369
|
+
# 같은 객체를 돌려주고 모듈 전역에 둡니다(경고 없음). ``import hwpx``가 도구 모듈
|
|
370
|
+
# 전부(내보내기·비교·검증 등)를 읽지 않게 하려는 것입니다. ``__all__``·``dir()``·
|
|
371
|
+
# ``from hwpx import *``에는 그대로 있습니다.
|
|
372
|
+
|
|
373
|
+
#: ``hwpx.tools``의 하위 모듈이 정의하고 ``hwpx.tools``가 다시 내보내는 stable 이름(텍스트 추출·개체
|
|
374
|
+
#: 찾기·문서 비교·메일 머지·패키지 검증). 정적 import로 해석하므로 동적 import 지점은
|
|
375
|
+
#: 늘지 않는다.
|
|
376
|
+
_TOOLS_STABLE_EXPORTS = frozenset(
|
|
377
|
+
{
|
|
378
|
+
"DEFAULT_NAMESPACES",
|
|
379
|
+
"ParagraphInfo",
|
|
380
|
+
"SectionInfo",
|
|
381
|
+
"TextExtractor",
|
|
382
|
+
"FoundElement",
|
|
383
|
+
"ObjectFinder",
|
|
384
|
+
"DOC_DIFF_REPORT_VERSION",
|
|
385
|
+
"REFERENCE_CONSISTENCY_REPORT_VERSION",
|
|
386
|
+
"diff_paragraphs",
|
|
387
|
+
"doc_diff",
|
|
388
|
+
"inspect_reference_consistency",
|
|
389
|
+
"MAIL_MERGE_REPORT_VERSION",
|
|
390
|
+
"inspect_mail_merge_placeholders",
|
|
391
|
+
"load_mail_merge_rows",
|
|
392
|
+
"merge_template_rows",
|
|
393
|
+
"EditorOpenSafetyReport",
|
|
394
|
+
"PackageValidationReport",
|
|
395
|
+
"validate_editor_open_safety",
|
|
396
|
+
"validate_package",
|
|
397
|
+
}
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
if TYPE_CHECKING: # type checkers see the real objects; at runtime they load lazily
|
|
402
|
+
from .tools.doc_diff import (
|
|
403
|
+
DOC_DIFF_REPORT_VERSION,
|
|
404
|
+
REFERENCE_CONSISTENCY_REPORT_VERSION,
|
|
405
|
+
diff_paragraphs,
|
|
406
|
+
doc_diff,
|
|
407
|
+
inspect_reference_consistency,
|
|
408
|
+
)
|
|
409
|
+
from .tools.mail_merge import (
|
|
410
|
+
MAIL_MERGE_REPORT_VERSION,
|
|
411
|
+
inspect_mail_merge_placeholders,
|
|
412
|
+
load_mail_merge_rows,
|
|
413
|
+
merge_template_rows,
|
|
414
|
+
)
|
|
415
|
+
from .tools.object_finder import FoundElement, ObjectFinder
|
|
416
|
+
from .tools.package_validator import (
|
|
417
|
+
EditorOpenSafetyReport,
|
|
418
|
+
PackageValidationReport,
|
|
419
|
+
validate_editor_open_safety,
|
|
420
|
+
validate_package,
|
|
421
|
+
)
|
|
422
|
+
from .tools.text_extractor import (
|
|
423
|
+
DEFAULT_NAMESPACES,
|
|
424
|
+
ParagraphInfo,
|
|
425
|
+
SectionInfo,
|
|
426
|
+
TextExtractor,
|
|
427
|
+
)
|
|
428
|
+
|
|
429
|
+
|
|
354
430
|
# ``import hwpx.builder`` goes through the import system, not ``__getattr__``,
|
|
355
431
|
# so the moved module names get their destination from a finder instead.
|
|
356
432
|
from . import _moved_modules
|
|
@@ -359,35 +435,9 @@ _moved_modules.install(_MOVED_TO_COMPANION)
|
|
|
359
435
|
|
|
360
436
|
|
|
361
437
|
# --- stable 최상위 표면 (eager import) ------------------------------------------
|
|
362
|
-
|
|
363
|
-
DEFAULT_NAMESPACES,
|
|
364
|
-
ParagraphInfo,
|
|
365
|
-
SectionInfo,
|
|
366
|
-
TextExtractor,
|
|
367
|
-
)
|
|
368
|
-
from .tools.object_finder import FoundElement, ObjectFinder
|
|
369
|
-
from .tools.doc_diff import (
|
|
370
|
-
DOC_DIFF_REPORT_VERSION,
|
|
371
|
-
REFERENCE_CONSISTENCY_REPORT_VERSION,
|
|
372
|
-
diff_paragraphs,
|
|
373
|
-
doc_diff,
|
|
374
|
-
inspect_reference_consistency,
|
|
375
|
-
)
|
|
376
|
-
from .tools.mail_merge import (
|
|
377
|
-
MAIL_MERGE_REPORT_VERSION,
|
|
378
|
-
inspect_mail_merge_placeholders,
|
|
379
|
-
load_mail_merge_rows,
|
|
380
|
-
merge_template_rows,
|
|
381
|
-
)
|
|
382
|
-
from .tools.package_validator import (
|
|
383
|
-
EditorOpenSafetyReport,
|
|
384
|
-
PackageValidationReport,
|
|
385
|
-
validate_editor_open_safety,
|
|
386
|
-
validate_package,
|
|
387
|
-
)
|
|
438
|
+
# ``hwpx.tools``의 stable 이름은 위 ``_TOOLS_STABLE_EXPORTS``가 지연 해석한다.
|
|
388
439
|
from .ingest import HwpxMarkdownConverter
|
|
389
|
-
from .errors import HwpxError
|
|
390
|
-
from .hwp5.errors import Hwp5ConversionWarning, Hwp5Error
|
|
440
|
+
from .errors import Hwp5ConversionWarning, Hwp5Error, HwpxError
|
|
391
441
|
from .mutation_report import (
|
|
392
442
|
MutationReport,
|
|
393
443
|
PreservationDowngradeError,
|
|
@@ -663,7 +663,7 @@ def add_form_field(
|
|
|
663
663
|
"""Create a click-here (누름틀) form field and return it as a :class:`FormField`.
|
|
664
664
|
|
|
665
665
|
The emitted XML follows the real-Hancom CLICKHERE contract
|
|
666
|
-
(
|
|
666
|
+
(inferred from Hancom Office 12.0.0.3288 gold documents). The
|
|
667
667
|
prompt (안내문) is materialized as a screen-only red-italic run, exactly as
|
|
668
668
|
Hancom authors it. The created field is immediately re-read through the
|
|
669
669
|
standard ``list_form_fields`` matcher — creation fails loudly if the
|
|
@@ -19,7 +19,9 @@ from ..oxml._document_primitives import NEW_NUM_KINDS
|
|
|
19
19
|
from ..oxml.namespaces import HH, HP
|
|
20
20
|
from ..oxml.numbering_kinds import ensure_numbering_levels
|
|
21
21
|
from ..oxml.objects import HwpxOxmlInlineObject
|
|
22
|
-
from ..oxml.section_format import
|
|
22
|
+
from ..oxml.section_format import (
|
|
23
|
+
_PAGE_LANDSCAPE, _PAGE_PORTRAIT, _checked, _page_orientation_value, column_shares, validate_column_gap,
|
|
24
|
+
)
|
|
23
25
|
from ..oxml.table_sizes import cell_margins_of
|
|
24
26
|
from ._units import _mm_to_hwp_units, _pt_to_hwp_units
|
|
25
27
|
|
|
@@ -512,12 +514,12 @@ def set_list_format(
|
|
|
512
514
|
suggestion="A continued list numbers on in the format of the list before it: "
|
|
513
515
|
"leave out number_format and start, or continue_list to start a new list.",
|
|
514
516
|
)
|
|
515
|
-
if level
|
|
517
|
+
if isinstance(level, bool) or not isinstance(level, int) or not 1 <= level <= 10:
|
|
516
518
|
raise HwpxValueError(
|
|
517
|
-
"level must be 1
|
|
519
|
+
f"level must be an int from 1 to 10; got {level!r}",
|
|
518
520
|
code="style-list-level-invalid",
|
|
519
|
-
context={"requested": level},
|
|
520
|
-
suggestion="
|
|
521
|
+
context={"requested": repr(level)},
|
|
522
|
+
suggestion="Hancom lists have ten levels, 1 to 10; it cannot save a document using a deeper one.",
|
|
521
523
|
)
|
|
522
524
|
if not doc._root.headers:
|
|
523
525
|
raise HwpxValueError(
|
|
@@ -525,6 +527,13 @@ def set_list_format(
|
|
|
525
527
|
code="document-header-missing",
|
|
526
528
|
suggestion="Check that this is an intact HWPX package.",
|
|
527
529
|
)
|
|
530
|
+
if start is not None and (isinstance(start, bool) or not isinstance(start, int) or not 0 <= start <= 0xFFFF):
|
|
531
|
+
raise HwpxValueError( # Hancom keeps a list's start as 16 bits unsigned (0 drawn as 1)
|
|
532
|
+
f"start must be an int from 0 to 65535; got {start!r}",
|
|
533
|
+
code="style-list-start-value",
|
|
534
|
+
context={"requested": repr(start)},
|
|
535
|
+
suggestion="Pass the number the list starts at, from 0 to 65535.",
|
|
536
|
+
)
|
|
528
537
|
|
|
529
538
|
level_specs: list[dict[str, str]] = [{} for _ in range(level)]
|
|
530
539
|
if bullet_char:
|
|
@@ -532,7 +541,7 @@ def set_list_format(
|
|
|
532
541
|
if number_format:
|
|
533
542
|
level_specs[level - 1]["format"] = str(number_format).upper()
|
|
534
543
|
if start is not None:
|
|
535
|
-
level_specs[level - 1]["start"] = str(
|
|
544
|
+
level_specs[level - 1]["start"] = str(start)
|
|
536
545
|
|
|
537
546
|
targets = _resolve_paragraph_targets(doc,
|
|
538
547
|
paragraph_index=paragraph_index,
|
|
@@ -609,6 +618,8 @@ def set_page_setup(
|
|
|
609
618
|
"""
|
|
610
619
|
|
|
611
620
|
normalized_orientation = _normalize_page_orientation(orientation)
|
|
621
|
+
if columns is not None: # the gap checked before the page or its margins change
|
|
622
|
+
validate_column_gap(_mm_to_hwp_units(float(column_gap_mm or 0)))
|
|
612
623
|
target_width_mm = width_mm
|
|
613
624
|
target_height_mm = height_mm
|
|
614
625
|
if paper_size:
|
|
@@ -633,6 +644,24 @@ def set_page_setup(
|
|
|
633
644
|
|
|
634
645
|
width = _mm_to_hwp_units(float(target_width_mm)) if target_width_mm is not None else None
|
|
635
646
|
height = _mm_to_hwp_units(float(target_height_mm)) if target_height_mm is not None else None
|
|
647
|
+
margin_source = dict(margins_mm or {})
|
|
648
|
+
margin_values = {
|
|
649
|
+
"left": margin_left_mm if margin_left_mm is not None else margin_source.get("left"),
|
|
650
|
+
"right": margin_right_mm if margin_right_mm is not None else margin_source.get("right"),
|
|
651
|
+
"top": margin_top_mm if margin_top_mm is not None else margin_source.get("top"),
|
|
652
|
+
"bottom": margin_bottom_mm if margin_bottom_mm is not None else margin_source.get("bottom"),
|
|
653
|
+
"header": header_margin_mm if header_margin_mm is not None else margin_source.get("header"),
|
|
654
|
+
"footer": footer_margin_mm if footer_margin_mm is not None else margin_source.get("footer"),
|
|
655
|
+
"gutter": gutter_mm if gutter_mm is not None else margin_source.get("gutter"),
|
|
656
|
+
}
|
|
657
|
+
hwp_margins = {
|
|
658
|
+
name: _mm_to_hwp_units(float(value))
|
|
659
|
+
for name, value in margin_values.items()
|
|
660
|
+
if value is not None
|
|
661
|
+
}
|
|
662
|
+
for name, value in (("width", width), ("height", height), *hwp_margins.items()):
|
|
663
|
+
if value is not None: # checked before the page or its margins change
|
|
664
|
+
_checked(name, value, 2**31 - 1, "page-size-value")
|
|
636
665
|
if width is not None or height is not None or normalized_orientation is not None:
|
|
637
666
|
# Call the local primitives directly rather than `doc.set_page_size`/
|
|
638
667
|
# `doc.set_page_margins`/`doc.set_columns` below — all three names
|
|
@@ -649,21 +678,6 @@ def set_page_setup(
|
|
|
649
678
|
section_index=section_index,
|
|
650
679
|
)
|
|
651
680
|
|
|
652
|
-
margin_source = dict(margins_mm or {})
|
|
653
|
-
margin_values = {
|
|
654
|
-
"left": margin_left_mm if margin_left_mm is not None else margin_source.get("left"),
|
|
655
|
-
"right": margin_right_mm if margin_right_mm is not None else margin_source.get("right"),
|
|
656
|
-
"top": margin_top_mm if margin_top_mm is not None else margin_source.get("top"),
|
|
657
|
-
"bottom": margin_bottom_mm if margin_bottom_mm is not None else margin_source.get("bottom"),
|
|
658
|
-
"header": header_margin_mm if header_margin_mm is not None else margin_source.get("header"),
|
|
659
|
-
"footer": footer_margin_mm if footer_margin_mm is not None else margin_source.get("footer"),
|
|
660
|
-
"gutter": gutter_mm if gutter_mm is not None else margin_source.get("gutter"),
|
|
661
|
-
}
|
|
662
|
-
hwp_margins = {
|
|
663
|
-
name: _mm_to_hwp_units(float(value))
|
|
664
|
-
for name, value in margin_values.items()
|
|
665
|
-
if value is not None
|
|
666
|
-
}
|
|
667
681
|
if hwp_margins:
|
|
668
682
|
set_page_margins(
|
|
669
683
|
doc,
|
|
@@ -723,15 +737,18 @@ def set_columns(
|
|
|
723
737
|
) -> HwpxOxmlInlineObject:
|
|
724
738
|
"""Set the columns of a section, or start new columns at a paragraph.
|
|
725
739
|
|
|
726
|
-
Without ``paragraph
|
|
727
|
-
``hp:colPr`` next to ``hp:secPr``) in
|
|
728
|
-
out in ``col_count`` columns. With
|
|
729
|
-
|
|
740
|
+
Without ``paragraph``, or with a section's first one, this rewrites the
|
|
741
|
+
section's own column layout (the ``hp:colPr`` next to ``hp:secPr``) in
|
|
742
|
+
place, so the whole section is laid out in ``col_count`` columns. With a
|
|
743
|
+
later ``paragraph`` it adds a column definition there, used from it on.
|
|
730
744
|
|
|
731
745
|
Args:
|
|
732
746
|
col_count: Number of columns (1–255).
|
|
733
747
|
col_type: ``NEWSPAPER``, ``BALANCED_NEWSPAPER``, or ``PARALLEL``.
|
|
734
748
|
same_gap: Gap in HWPUNIT (7200 = 1 inch).
|
|
749
|
+
column_widths: With ``same_size=False``, a ``(width, gap)`` pair per
|
|
750
|
+
column, in HWPUNIT adding up to the text width or in plain
|
|
751
|
+
proportions; Hancom keeps them as shares of 32768 of the text width.
|
|
735
752
|
separator_type: Optional column separator line type (e.g. ``SOLID``).
|
|
736
753
|
"""
|
|
737
754
|
if not 1 <= col_count <= 255:
|
|
@@ -741,6 +758,10 @@ def set_columns(
|
|
|
741
758
|
context={"requested": col_count},
|
|
742
759
|
suggestion="Use columns=1 to remove columns.",
|
|
743
760
|
)
|
|
761
|
+
if same_size:
|
|
762
|
+
validate_column_gap(same_gap) # before a paragraph is added
|
|
763
|
+
elif column_widths:
|
|
764
|
+
column_shares(column_widths) # checked before a paragraph is added too
|
|
744
765
|
if paragraph is None:
|
|
745
766
|
target_section = _resolve_section(doc, section=section, section_index=section_index)
|
|
746
767
|
ctrl = target_section.properties.set_columns(
|
|
@@ -19,6 +19,11 @@ from ..opc.relationships import (
|
|
|
19
19
|
)
|
|
20
20
|
from ..oxml import HwpxOxmlInlineObject, HwpxOxmlParagraph
|
|
21
21
|
from ..oxml.namespaces import HC, HP
|
|
22
|
+
from ..oxml.color import normalize_color
|
|
23
|
+
from ..oxml.shape_position import PictureGlow, PictureReflection, PictureShadow, validate_picture_effects
|
|
24
|
+
from ..oxml.shape_position import (
|
|
25
|
+
validate_picture_align, validate_picture_border, validate_picture_crop, validate_picture_image, validate_shape_size,
|
|
26
|
+
)
|
|
22
27
|
from ._units import _mm_to_hwp_units
|
|
23
28
|
|
|
24
29
|
if TYPE_CHECKING:
|
|
@@ -106,23 +111,35 @@ def add_picture(
|
|
|
106
111
|
width_mm: float | None = None,
|
|
107
112
|
height_mm: float | None = None,
|
|
108
113
|
align: str | None = None,
|
|
114
|
+
brightness: int = 0,
|
|
115
|
+
contrast: int = 0,
|
|
116
|
+
effect: str = "REAL_PIC",
|
|
117
|
+
alpha: int = 0,
|
|
118
|
+
line_color: str | None = None,
|
|
119
|
+
line_width: int = 33,
|
|
120
|
+
crop: tuple[int, int, int, int] | None = None,
|
|
121
|
+
shadow: PictureShadow | None = None,
|
|
122
|
+
glow: PictureGlow | None = None,
|
|
123
|
+
soft_edge: int | None = None,
|
|
124
|
+
reflection: PictureReflection | None = None,
|
|
109
125
|
para_pr_id_ref: str | int | None = None,
|
|
110
126
|
style_id_ref: str | int | None = None,
|
|
111
127
|
char_pr_id_ref: str | int | None = None,
|
|
112
128
|
run_attributes: dict[str, str] | None = None,
|
|
113
129
|
**extra_attrs: str,
|
|
114
130
|
) -> HwpxOxmlInlineObject:
|
|
115
|
-
"""Embed image data and place a picture object in a new paragraph
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
#
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
131
|
+
"""Embed image data and place a picture object in a new paragraph, the image adjusted and bordered as
|
|
132
|
+
:meth:`HwpxOxmlParagraph.add_picture` takes it."""
|
|
133
|
+
|
|
134
|
+
validate_picture_align(align) # before anything is stored: Hancom reads an unknown one as LEFT
|
|
135
|
+
validate_picture_image(brightness, contrast, effect, alpha) # ... and draws no other adjustment
|
|
136
|
+
validate_picture_border(line_width)
|
|
137
|
+
if line_color is not None:
|
|
138
|
+
normalize_color(line_color)
|
|
123
139
|
resolved_width = width
|
|
124
140
|
if resolved_width is None:
|
|
125
141
|
resolved_width = _mm_to_hwp_units(width_mm) if width_mm is not None else 14400
|
|
142
|
+
validate_shape_size(resolved_width, 0) # validate before aspect-ratio arithmetic too
|
|
126
143
|
|
|
127
144
|
resolved_height = height
|
|
128
145
|
if resolved_height is None:
|
|
@@ -135,6 +152,15 @@ def add_picture(
|
|
|
135
152
|
resolved_height = round(resolved_width * source_height / source_width)
|
|
136
153
|
else:
|
|
137
154
|
resolved_height = resolved_width
|
|
155
|
+
validate_shape_size(resolved_width, resolved_height) # before anything is stored too
|
|
156
|
+
validate_picture_crop(crop, resolved_width, resolved_height)
|
|
157
|
+
validate_picture_effects(shadow, glow, soft_edge, reflection)
|
|
158
|
+
|
|
159
|
+
# Call the local primitive directly rather than `doc.add_image` — that
|
|
160
|
+
# facade name moved in 6.0 (design table row 33), and going through it
|
|
161
|
+
# would fire a DeprecationWarning on every `add_picture` call even though
|
|
162
|
+
# `add_picture` itself is a kept (unmoved) root method.
|
|
163
|
+
binary_item_id_ref = str(add_image(doc, image_data, image_format))
|
|
138
164
|
|
|
139
165
|
paragraph = doc.add_paragraph(
|
|
140
166
|
"",
|
|
@@ -158,6 +184,17 @@ def add_picture(
|
|
|
158
184
|
width=resolved_width,
|
|
159
185
|
height=resolved_height,
|
|
160
186
|
align=align,
|
|
187
|
+
brightness=brightness,
|
|
188
|
+
contrast=contrast,
|
|
189
|
+
effect=effect,
|
|
190
|
+
alpha=alpha,
|
|
191
|
+
line_color=line_color,
|
|
192
|
+
line_width=line_width,
|
|
193
|
+
crop=crop,
|
|
194
|
+
shadow=shadow,
|
|
195
|
+
glow=glow,
|
|
196
|
+
soft_edge=soft_edge,
|
|
197
|
+
reflection=reflection,
|
|
161
198
|
run_attributes=run_attributes,
|
|
162
199
|
char_pr_id_ref=char_pr_id_ref,
|
|
163
200
|
)
|
|
@@ -8,7 +8,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
8
8
|
|
|
9
9
|
from ..errors import HwpxValueError
|
|
10
10
|
|
|
11
|
-
from ..oxml._document_primitives import _object_id
|
|
11
|
+
from ..oxml._document_primitives import _clear_paragraph_layout_cache, _object_id
|
|
12
12
|
from ..oxml.namespaces import HP
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
@@ -189,6 +189,7 @@ def attach_memo_field(
|
|
|
189
189
|
"dirty": "0",
|
|
190
190
|
"zorder": order,
|
|
191
191
|
"fieldid": MEMO_FIELD_ID,
|
|
192
|
+
"metaTag": "",
|
|
192
193
|
},
|
|
193
194
|
)
|
|
194
195
|
|
|
@@ -247,6 +248,7 @@ def attach_memo_field(
|
|
|
247
248
|
|
|
248
249
|
paragraph.element.insert(0, run_begin)
|
|
249
250
|
paragraph.element.append(run_end)
|
|
251
|
+
_clear_paragraph_layout_cache(paragraph.element) # the field's controls move its text: laid out again
|
|
250
252
|
paragraph.section.mark_dirty()
|
|
251
253
|
|
|
252
254
|
return memo
|
|
@@ -345,8 +345,8 @@ class ShapesNamespace(_Namespace):
|
|
|
345
345
|
section: "int | Section | None" = None,
|
|
346
346
|
section_index: int | None = None,
|
|
347
347
|
) -> "Shape":
|
|
348
|
-
"""도형을 그룹으로 묶는다(`ContainerMember.rect`/`.ellipse`/`.polygon
|
|
349
|
-
각 부재를 그룹 로컬 좌표로 만들어 넘긴다)."""
|
|
348
|
+
"""도형을 그룹으로 묶는다(`ContainerMember.rect`/`.ellipse`/`.polygon`/`.line`/
|
|
349
|
+
`.text_box`/`.picture`/`.group`으로 각 부재를 그룹 로컬 좌표로 만들어 넘긴다)."""
|
|
350
350
|
|
|
351
351
|
from .. import shapes as _shapes
|
|
352
352
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
"""`doc.tables` — 표
|
|
2
|
+
"""`doc.tables` — 표 탐색·매핑·병합·구조 편집·경로 채움.
|
|
3
3
|
|
|
4
4
|
표를 **만드는** 것은 루트에 남았다(`doc.add_table` — python-docx 대응이자
|
|
5
5
|
automation 최다 사용 저작 동사 중 하나). 만든 다음에 하는 일들이 여기 모인다.
|
|
@@ -11,7 +11,7 @@ automation 최다 사용 저작 동사 중 하나). 만든 다음에 하는 일
|
|
|
11
11
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
-
from typing import TYPE_CHECKING, Mapping
|
|
14
|
+
from typing import TYPE_CHECKING, Iterable, Mapping, overload
|
|
15
15
|
|
|
16
16
|
from ._base import _Namespace
|
|
17
17
|
|
|
@@ -28,7 +28,7 @@ __all__ = ["TablesNamespace"]
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class TablesNamespace(_Namespace):
|
|
31
|
-
"""표
|
|
31
|
+
"""표 탐색·매핑·병합·구조 편집·경로 채움."""
|
|
32
32
|
|
|
33
33
|
__slots__ = ()
|
|
34
34
|
_path = "doc.tables"
|
|
@@ -48,6 +48,20 @@ class TablesNamespace(_Namespace):
|
|
|
48
48
|
def __iter__(self):
|
|
49
49
|
return iter(self.all)
|
|
50
50
|
|
|
51
|
+
@overload
|
|
52
|
+
def __getitem__(self, index: int) -> "Table": ...
|
|
53
|
+
|
|
54
|
+
@overload
|
|
55
|
+
def __getitem__(self, index: slice) -> list["Table"]: ...
|
|
56
|
+
|
|
57
|
+
def __getitem__(self, index: int | slice) -> "Table | list[Table]":
|
|
58
|
+
"""문서 순서의 ``index`` 번째 표(``doc.tables[0]``, ``doc.tables[-1]``, ``doc.tables[1:3]``).
|
|
59
|
+
|
|
60
|
+
``doc.tables.all[index]``와 같다. 범위 밖이면 ``IndexError``.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
return self.all[index]
|
|
64
|
+
|
|
51
65
|
def map(self) -> "TableMapResult":
|
|
52
66
|
"""모든 표의 위치·모양·헤더 미리보기를 담은 간결 지도."""
|
|
53
67
|
|
|
@@ -78,3 +92,35 @@ class TablesNamespace(_Namespace):
|
|
|
78
92
|
"""
|
|
79
93
|
|
|
80
94
|
return table.merge_cells(cell_range)
|
|
95
|
+
|
|
96
|
+
def insert_rows(
|
|
97
|
+
self, table: "Table", ref_row: int, count: int = 1, *, side: str = "below", blank: bool = False
|
|
98
|
+
) -> None:
|
|
99
|
+
"""``ref_row`` 행을 복제해 그 아래(``side="above"``면 위)에 ``count`` 행을 넣는다.
|
|
100
|
+
|
|
101
|
+
새 칸은 같은 열 기준 칸의 서식과 글을 받고, ``blank=True``면 한/글처럼 빈 문단 하나만 둔다.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
table.insert_rows(ref_row, count, side=side, blank=blank)
|
|
105
|
+
|
|
106
|
+
def insert_columns(
|
|
107
|
+
self, table: "Table", ref_col: int, count: int = 1, *, side: str = "right", blank: bool = False
|
|
108
|
+
) -> None:
|
|
109
|
+
"""``ref_col`` 열을 복제해 그 오른쪽(``side="left"``면 왼쪽)에 ``count`` 열을 넣는다(표가 넓어진다)."""
|
|
110
|
+
|
|
111
|
+
table.insert_columns(ref_col, count, side=side, blank=blank)
|
|
112
|
+
|
|
113
|
+
def delete_rows(self, table: "Table", rows: int | Iterable[int]) -> None:
|
|
114
|
+
"""행을 지운다. 모든 행은 지울 수 없다(표 삭제를 쓴다)."""
|
|
115
|
+
|
|
116
|
+
table.delete_rows(rows)
|
|
117
|
+
|
|
118
|
+
def delete_columns(self, table: "Table", cols: int | Iterable[int]) -> None:
|
|
119
|
+
"""열을 지우고 그 폭을 남은 열에 나눈다. 모든 열은 지울 수 없다."""
|
|
120
|
+
|
|
121
|
+
table.delete_columns(cols)
|
|
122
|
+
|
|
123
|
+
def split_cell(self, table: "Table", row: int, col: int, *, rows: int = 1, cols: int = 1) -> None:
|
|
124
|
+
"""(``row``, ``col``) 칸을 ``rows`` 줄 × ``cols`` 칸으로 나눈다(한/글의 셀 나누기)."""
|
|
125
|
+
|
|
126
|
+
table.split_cell(row, col, rows=rows, cols=cols)
|
|
@@ -408,7 +408,8 @@ def save_report(
|
|
|
408
408
|
oracle-verified ``visual_complete`` tier (plan §0.0).
|
|
409
409
|
|
|
410
410
|
Like the legacy savers it raises only if the serialize step's open-safety
|
|
411
|
-
check fails; all other gate outcomes are returned in the report.
|
|
411
|
+
check fails; all other gate outcomes are returned in the report. An ``.hwp``
|
|
412
|
+
path is written as HWP 5.0, as :func:`save_to_path` writes it.
|
|
412
413
|
"""
|
|
413
414
|
|
|
414
415
|
_run_pre_save_validation(doc)
|
|
@@ -420,10 +421,15 @@ def save_report(
|
|
|
420
421
|
output_path = path_or_stream
|
|
421
422
|
elif path_or_stream is not None:
|
|
422
423
|
output_stream = path_or_stream
|
|
424
|
+
# An .hwp target gets HWP 5.0 made from the HWPX parts the gate checks; it raises before anything is
|
|
425
|
+
# written when the HWP 5.0 writer cannot express the document.
|
|
426
|
+
hwp5 = None
|
|
427
|
+
if output_path is not None and str(output_path).lower().endswith(".hwp"):
|
|
428
|
+
hwp5 = _hwp5_bytes(archive_bytes)
|
|
423
429
|
|
|
424
430
|
report = doc._save_pipeline.run(
|
|
425
431
|
archive_bytes,
|
|
426
|
-
output_path=output_path,
|
|
432
|
+
output_path=None if hwp5 is not None else output_path,
|
|
427
433
|
output_stream=output_stream,
|
|
428
434
|
quality=quality or QualityPolicy.transparent(),
|
|
429
435
|
before=before,
|
|
@@ -432,6 +438,12 @@ def save_report(
|
|
|
432
438
|
reference_document=doc,
|
|
433
439
|
source_label="document.save_report",
|
|
434
440
|
)
|
|
441
|
+
if hwp5 is not None and report.ok: # the gate passed: publish the HWP 5.0 file in its place
|
|
442
|
+
from ..quality.save_pipeline import write_bytes_atomically
|
|
443
|
+
|
|
444
|
+
assert output_path is not None
|
|
445
|
+
write_bytes_atomically(output_path, hwp5)
|
|
446
|
+
report.output_path = str(output_path)
|
|
435
447
|
if report.ok:
|
|
436
448
|
_mark_save_clean(doc)
|
|
437
449
|
return report
|