python-hwpx 2.24.0__tar.gz → 2.24.1__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-2.24.0/src/python_hwpx.egg-info → python_hwpx-2.24.1}/PKG-INFO +11 -2
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/README.md +9 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/pyproject.toml +15 -2
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/_document_impl.py +11 -2
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/table_patch.py +30 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1/src/python_hwpx.egg-info}/PKG-INFO +11 -2
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/python_hwpx.egg-info/requires.txt +1 -1
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_document_formatting.py +22 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_table_patch.py +42 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/LICENSE +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/NOTICE +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/setup.cfg +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/authoring.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/body_patch.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/builder/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/builder/core.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/builder/report.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/conformance/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/conformance/badges.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/conformance/corpus/corpus.json +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/conformance/corpus/meeting_summary.hwpx +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/conformance/corpus/notice.hwpx +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/conformance/corpus/report_table.hwpx +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/conformance/corpus.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/conformance/report.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/conformance/roundtrip_batch.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/conformance/runner.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/data/Skeleton.hwpx +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/_support.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/composer.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/harvest.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/plan.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profile.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/application_form/fragments/body.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/application_form/fragments/heading.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/application_form/fragments/info_table.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/application_form/fragments/title.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/application_form/profile.json +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/application_form/template.hwpx +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/home_notice/fragments/body.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/home_notice/fragments/heading.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/home_notice/fragments/title.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/home_notice/profile.json +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/home_notice/template.hwpx +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/official_notice/fragments/body.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/official_notice/fragments/heading.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/official_notice/fragments/info_table.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/official_notice/fragments/title.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/official_notice/profile.json +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/official_notice/template.hwpx +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/report/fragments/body.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/report/fragments/heading.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/report/fragments/info_table.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/report/fragments/title.xml +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/report/profile.json +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/report/template.hwpx +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/validator.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/document.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/evalplan_fill.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/exam/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/exam/compose.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/exam/ir.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/exam/measure.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/exam/parser.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/exam/profile.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/fill_residue.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/form_fill.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/form_fit/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/form_fit/apply.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/form_fit/engine.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/form_fit/measure.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/form_fit/policy.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/form_fit/report.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/form_fit/seal.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/form_fit/wordbox.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/formfill_quality.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/guidance_scan.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/ingest/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/ingest/base.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/ingest/hwpx_converter.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/layout/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/layout/lint.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/layout/report.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/opc/package.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/opc/relationships.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/opc/security.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/opc/xml_utils.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/body.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/canonical_defaults.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/common.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/document.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/header.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/header_part.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/memo.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/namespaces.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/numbering.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/objects.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/paragraph.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/parser.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/run.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/schema.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/section.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/simple_parts.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/table.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/oxml/utils.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/package.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/patch.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/presets/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/presets/proposal.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/py.typed +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/quality/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/quality/ledger.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/quality/policy.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/quality/report.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/quality/save_pipeline.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/template_formfit.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/templates.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/_schemas/header.xsd +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/_schemas/section.xsd +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/advanced_generators.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/archive_cli.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/doc_diff.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/exporter.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/fuzz/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/fuzz/__main__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/fuzz/catalog.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/fuzz/generator.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/fuzz/minimize.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/fuzz/runner.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/generic_inventory.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/id_integrity.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/idempotence.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/ir_equality.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/layout_preview.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/mail_merge.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/markdown_export.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/object_finder.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/official_lint.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/package_reconcile.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/package_validator.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/page_guard.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/pii.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/read_fidelity.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/recover.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/redline.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/repair.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/report_parser.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/report_utils.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/roundtrip_diff.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/style_profile.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/table_cleanup.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/table_compute.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/table_navigation.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/template_analyzer.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/text_extract_cli.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/text_extractor.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/toc_author.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/toc_fidelity.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/tools/validator.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/visual/__init__.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/visual/_hancom_open_rate.ps1 +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/visual/_refresh_hwpx_mac.applescript +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/visual/_render_hwpx.ps1 +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/visual/_render_hwpx_mac.applescript +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/visual/detectors.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/visual/diff.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/visual/masks.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/visual/oracle.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/visual/report.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/python_hwpx.egg-info/SOURCES.txt +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/python_hwpx.egg-info/dependency_links.txt +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/python_hwpx.egg-info/entry_points.txt +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/python_hwpx.egg-info/top_level.txt +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_advanced_generators.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_authoring_profile_routing.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_authoring_profile_routing_oracle.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_authoring_render_check.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_body_patch.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_builder_core.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_builder_plan_v2.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_builder_vertical_slice.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_cell_line_spacing.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_comment_node_robustness.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_conformance.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_corpus_read_fidelity.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_coverage_promotion.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_coverage_targets.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_design_builder.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_deviations_registry.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_doc_diff.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_document_context_manager.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_document_plan.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_document_plan_computed_fields.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_document_save_api.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_evalplan_fill.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_exam_compose.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_exam_compose_oracle.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_exam_fixtures.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_exam_ir.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_exam_measure.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_exam_parser.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_exam_profile.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_existing_document_format_editing.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_fill_residue.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_form_fields.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_form_fill_split_run.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_form_fit.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_form_fit_integration.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_form_fit_seal.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_form_fit_seal_placement.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_form_fit_wordbox.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_formfill_quality.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_fuzz_loop.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_fuzz_regressions.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_gap_closure_tools.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_government_report_preset.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_government_table_profile.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_guidance_scan.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_hp_tab_support.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_hwpxlib_corpus_read.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_id_generator_range.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_id_integrity.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_image_object_workflow.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_ingest.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_inline_models.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_integration_hwpx_compatibility.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_integration_roundtrip.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_kordoc_absorption.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_layout_lint.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_layout_preview.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_mail_merge_fit.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_mail_merge_table_compute.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_mail_merge_xlsx.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_markdown_export.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_memo_and_style_editing.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_namespace_handling.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_new_features.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_official_document_style.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_official_lint_gongmun_gate.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_official_lint_tableaware.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_opc_package.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_open_safety_corpus.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_openrate.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_oxml_parsing.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_packaging_license_metadata.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_packaging_py_typed.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_paragraph_keep_together.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_paragraph_section_management.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_pii.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_pii_structural.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_pii_wiring.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_proposal_preset.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_question_split_detector.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_read_fidelity.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_recover_broken_zip.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_redline_authoring.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_redline_verify.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_repair_repack.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_report_parser.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_report_utils.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_repr_snapshots.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_rhwp_t1_gates.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_rhwp_t2_verification.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_roundtrip_fidelity.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_row_heights.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_save_pipeline.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_save_pipeline_no_bypass.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_section_headers.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_set_paragraph_format_keep.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_skeleton_template_ids.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_split_cell.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_split_merged_cell.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_style_profile.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_table_cleanup.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_table_navigation.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_table_patch_dryrun.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_table_patch_m105.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_tables_default_border.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_template_analyzer_enrichment.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_template_formfit.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_text_extractor_annotations.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_toc_author.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_toc_fidelity.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_validation_severity.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_validator_comment_nodes.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_version_metadata.py +0 -0
- {python_hwpx-2.24.0 → python_hwpx-2.24.1}/tests/test_visual_oracle.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-hwpx
|
|
3
|
-
Version: 2.24.
|
|
3
|
+
Version: 2.24.1
|
|
4
4
|
Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리
|
|
5
5
|
Author: python-hwpx Maintainers
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -20,7 +20,7 @@ Requires-Python: >=3.10
|
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
22
|
License-File: NOTICE
|
|
23
|
-
Requires-Dist: lxml<
|
|
23
|
+
Requires-Dist: lxml<7,>=4.9
|
|
24
24
|
Provides-Extra: visual
|
|
25
25
|
Requires-Dist: pymupdf>=1.24; extra == "visual"
|
|
26
26
|
Requires-Dist: pillow>=10.0; extra == "visual"
|
|
@@ -202,6 +202,15 @@ pip install -e ".[dev]"
|
|
|
202
202
|
pytest
|
|
203
203
|
```
|
|
204
204
|
|
|
205
|
+
## 감사의 말
|
|
206
|
+
|
|
207
|
+
아래 공개 표준·프로젝트에 빚지고 있습니다.
|
|
208
|
+
|
|
209
|
+
- **[OWPML — 개방형 워드프로세서 마크업 언어 (KS X 6101)](https://www.kssn.net/search/stddetail.do?itemNo=K001010119985)** — HWPX가 기반하는 한국 산업 표준
|
|
210
|
+
- **[hancom-io/hwpx-owpml-model](https://github.com/hancom-io/hwpx-owpml-model)** — OWPML 요소 구조 참조 모델 · **[neolord0/hwpxlib](https://github.com/neolord0/hwpxlib)** — 오라클 샘플 코퍼스
|
|
211
|
+
- **[edwardkim/rhwp](https://github.com/edwardkim/rhwp)** — 멱등성·검증 게이트 설계 영감
|
|
212
|
+
- **범정부오피스** — 공무 문서 편집 워크플로 아이디어
|
|
213
|
+
|
|
205
214
|
## License
|
|
206
215
|
|
|
207
216
|
Apache License 2.0. See LICENSE and NOTICE.
|
|
@@ -160,6 +160,15 @@ pip install -e ".[dev]"
|
|
|
160
160
|
pytest
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
+
## 감사의 말
|
|
164
|
+
|
|
165
|
+
아래 공개 표준·프로젝트에 빚지고 있습니다.
|
|
166
|
+
|
|
167
|
+
- **[OWPML — 개방형 워드프로세서 마크업 언어 (KS X 6101)](https://www.kssn.net/search/stddetail.do?itemNo=K001010119985)** — HWPX가 기반하는 한국 산업 표준
|
|
168
|
+
- **[hancom-io/hwpx-owpml-model](https://github.com/hancom-io/hwpx-owpml-model)** — OWPML 요소 구조 참조 모델 · **[neolord0/hwpxlib](https://github.com/neolord0/hwpxlib)** — 오라클 샘플 코퍼스
|
|
169
|
+
- **[edwardkim/rhwp](https://github.com/edwardkim/rhwp)** — 멱등성·검증 게이트 설계 영감
|
|
170
|
+
- **범정부오피스** — 공무 문서 편집 워크플로 아이디어
|
|
171
|
+
|
|
163
172
|
## License
|
|
164
173
|
|
|
165
174
|
Apache License 2.0. See LICENSE and NOTICE.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-hwpx"
|
|
7
|
-
version = "2.24.
|
|
7
|
+
version = "2.24.1"
|
|
8
8
|
description = "한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리"
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -25,7 +25,7 @@ classifiers = [
|
|
|
25
25
|
"Topic :: Text Processing :: Markup :: XML",
|
|
26
26
|
]
|
|
27
27
|
dependencies = [
|
|
28
|
-
"lxml>=4.9,<
|
|
28
|
+
"lxml>=4.9,<7",
|
|
29
29
|
]
|
|
30
30
|
|
|
31
31
|
[project.optional-dependencies]
|
|
@@ -100,11 +100,19 @@ testpaths = ["tests"]
|
|
|
100
100
|
|
|
101
101
|
[tool.mypy]
|
|
102
102
|
python_version = "3.10"
|
|
103
|
+
# Explicit gradual-migration allowlist: transitive imports enter the gate only
|
|
104
|
+
# after they are added here and made clean themselves.
|
|
105
|
+
follow_imports = "skip"
|
|
103
106
|
files = [
|
|
104
107
|
"src/hwpx/document.py",
|
|
105
108
|
"src/hwpx/oxml/document.py",
|
|
106
109
|
"src/hwpx/opc/package.py",
|
|
107
110
|
"src/hwpx/opc/relationships.py",
|
|
111
|
+
"src/hwpx/oxml/paragraph.py",
|
|
112
|
+
"src/hwpx/oxml/run.py",
|
|
113
|
+
"src/hwpx/oxml/table.py",
|
|
114
|
+
"src/hwpx/quality/policy.py",
|
|
115
|
+
"src/hwpx/quality/report.py",
|
|
108
116
|
"src/hwpx/tools/archive_cli.py",
|
|
109
117
|
"src/hwpx/tools/package_validator.py",
|
|
110
118
|
"src/hwpx/tools/page_guard.py",
|
|
@@ -126,6 +134,11 @@ ignore_errors = true
|
|
|
126
134
|
include = [
|
|
127
135
|
"src/hwpx/opc/package.py",
|
|
128
136
|
"src/hwpx/opc/relationships.py",
|
|
137
|
+
"src/hwpx/oxml/paragraph.py",
|
|
138
|
+
"src/hwpx/oxml/run.py",
|
|
139
|
+
"src/hwpx/oxml/table.py",
|
|
140
|
+
"src/hwpx/quality/policy.py",
|
|
141
|
+
"src/hwpx/quality/report.py",
|
|
129
142
|
"src/hwpx/tools/archive_cli.py",
|
|
130
143
|
"src/hwpx/tools/package_validator.py",
|
|
131
144
|
"src/hwpx/tools/page_guard.py",
|
|
@@ -2796,14 +2796,23 @@ class HwpxOxmlTableCell:
|
|
|
2796
2796
|
preserve_format: bool = True,
|
|
2797
2797
|
split_paragraphs: bool = False,
|
|
2798
2798
|
) -> None:
|
|
2799
|
+
previous_text = self.text
|
|
2800
|
+
sanitized_value = _sanitize_text(value)
|
|
2801
|
+
if sanitized_value and sanitized_value != previous_text:
|
|
2802
|
+
sublist = self._ensure_sublist()
|
|
2803
|
+
if (sublist.get("lineWrap") or "").upper() == "SQUEEZE":
|
|
2804
|
+
# SQUEEZE can compress a longer filled value until Hancom
|
|
2805
|
+
# renders adjacent glyphs on top of each other. New content
|
|
2806
|
+
# should wrap/reflow; untouched template cells keep their mode.
|
|
2807
|
+
sublist.set("lineWrap", "BREAK")
|
|
2799
2808
|
if split_paragraphs:
|
|
2800
|
-
self._set_split_paragraph_text(
|
|
2809
|
+
self._set_split_paragraph_text(sanitized_value)
|
|
2801
2810
|
self.element.set("dirty", "1")
|
|
2802
2811
|
self.table.mark_dirty()
|
|
2803
2812
|
return
|
|
2804
2813
|
|
|
2805
2814
|
text_element = self._ensure_text_element()
|
|
2806
|
-
text_element.text =
|
|
2815
|
+
text_element.text = sanitized_value
|
|
2807
2816
|
for node in self.element.findall(f".//{_HP}t"):
|
|
2808
2817
|
if node is text_element:
|
|
2809
2818
|
continue
|
|
@@ -182,6 +182,9 @@ def build_grid(table: bytes) -> tuple[dict[tuple[int, int], _Cell], GridReport]:
|
|
|
182
182
|
|
|
183
183
|
|
|
184
184
|
_P_SPAN_RE = re.compile(rb"<(?:[A-Za-z_][\w.-]*:)?p\b.*?</(?:[A-Za-z_][\w.-]*:)?p>", re.DOTALL)
|
|
185
|
+
_SQUEEZE_WRAP_RE = re.compile(
|
|
186
|
+
rb'<(?:[A-Za-z_][\w.-]*:)?subList\b[^>]*?\blineWrap="(?P<value>SQUEEZE)"'
|
|
187
|
+
)
|
|
185
188
|
|
|
186
189
|
def _first_paragraph_span(cell: bytes) -> tuple[int, int] | None:
|
|
187
190
|
"""Byte span of the cell's first ``<hp:p>...</hp:p>`` (its own subList's
|
|
@@ -196,6 +199,22 @@ def _all_paragraph_spans(cell: bytes) -> list[tuple[int, int]]:
|
|
|
196
199
|
return [(m.start(), m.end()) for m in _P_SPAN_RE.finditer(masked)]
|
|
197
200
|
|
|
198
201
|
|
|
202
|
+
def _squeeze_wrap_edit(cell: bytes) -> tuple[int, int, bytes] | None:
|
|
203
|
+
"""Return a minimal edit that makes a filled cell wrap instead of squeeze.
|
|
204
|
+
|
|
205
|
+
Hancom's ``lineWrap=SQUEEZE`` keeps long replacement text on the existing
|
|
206
|
+
line by compressing glyph advances. Template placeholders often fit, but
|
|
207
|
+
real filled values can become nearly unreadable even though their charPr
|
|
208
|
+
spacing is normal. Only the addressed cell's direct subList is considered;
|
|
209
|
+
nested tables remain untouched.
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
match = _SQUEEZE_WRAP_RE.search(_mask_nested_tables(cell))
|
|
213
|
+
if match is None:
|
|
214
|
+
return None
|
|
215
|
+
return match.start("value"), match.end("value"), b"BREAK"
|
|
216
|
+
|
|
217
|
+
|
|
199
218
|
# --- font shrink-to-fit helpers (byte-preserving charPr materialisation) ------
|
|
200
219
|
|
|
201
220
|
def _header_part_name(parts: Mapping[str, bytes]) -> str | None:
|
|
@@ -602,6 +621,17 @@ def fill_cells(
|
|
|
602
621
|
continue
|
|
603
622
|
if not cell_edits:
|
|
604
623
|
continue
|
|
624
|
+
# A template's short placeholder may legitimately fit under
|
|
625
|
+
# lineWrap=SQUEEZE, while a real filled value is compressed until
|
|
626
|
+
# glyphs appear to overlap. Changed non-empty values must wrap and
|
|
627
|
+
# reflow; preserve SQUEEZE for no-op/clear operations.
|
|
628
|
+
if text.strip():
|
|
629
|
+
wrap_edit = _squeeze_wrap_edit(cell_bytes)
|
|
630
|
+
if wrap_edit is not None:
|
|
631
|
+
ws, we, replacement = wrap_edit
|
|
632
|
+
section_edits.append(
|
|
633
|
+
(ts + cell.start + ws, ts + cell.start + we, replacement)
|
|
634
|
+
)
|
|
605
635
|
section_edits.extend(cell_edits)
|
|
606
636
|
applied.append(CellApplied(section_path, ti, row, col, first_orig or "", text))
|
|
607
637
|
if section_edits:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-hwpx
|
|
3
|
-
Version: 2.24.
|
|
3
|
+
Version: 2.24.1
|
|
4
4
|
Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리
|
|
5
5
|
Author: python-hwpx Maintainers
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -20,7 +20,7 @@ Requires-Python: >=3.10
|
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
22
|
License-File: NOTICE
|
|
23
|
-
Requires-Dist: lxml<
|
|
23
|
+
Requires-Dist: lxml<7,>=4.9
|
|
24
24
|
Provides-Extra: visual
|
|
25
25
|
Requires-Dist: pymupdf>=1.24; extra == "visual"
|
|
26
26
|
Requires-Dist: pillow>=10.0; extra == "visual"
|
|
@@ -202,6 +202,15 @@ pip install -e ".[dev]"
|
|
|
202
202
|
pytest
|
|
203
203
|
```
|
|
204
204
|
|
|
205
|
+
## 감사의 말
|
|
206
|
+
|
|
207
|
+
아래 공개 표준·프로젝트에 빚지고 있습니다.
|
|
208
|
+
|
|
209
|
+
- **[OWPML — 개방형 워드프로세서 마크업 언어 (KS X 6101)](https://www.kssn.net/search/stddetail.do?itemNo=K001010119985)** — HWPX가 기반하는 한국 산업 표준
|
|
210
|
+
- **[hancom-io/hwpx-owpml-model](https://github.com/hancom-io/hwpx-owpml-model)** — OWPML 요소 구조 참조 모델 · **[neolord0/hwpxlib](https://github.com/neolord0/hwpxlib)** — 오라클 샘플 코퍼스
|
|
211
|
+
- **[edwardkim/rhwp](https://github.com/edwardkim/rhwp)** — 멱등성·검증 게이트 설계 영감
|
|
212
|
+
- **범정부오피스** — 공무 문서 편집 워크플로 아이디어
|
|
213
|
+
|
|
205
214
|
## License
|
|
206
215
|
|
|
207
216
|
Apache License 2.0. See LICENSE and NOTICE.
|
|
@@ -405,6 +405,28 @@ def test_table_set_cell_text_removes_layout_cache() -> None:
|
|
|
405
405
|
assert paragraph.find(f"{HP}linesegarray") is None
|
|
406
406
|
|
|
407
407
|
|
|
408
|
+
def test_table_set_cell_text_converts_squeeze_to_break() -> None:
|
|
409
|
+
section_element = ET.Element(f"{HS}sec")
|
|
410
|
+
section = HwpxOxmlSection("section0.xml", section_element)
|
|
411
|
+
manifest = ET.Element("manifest")
|
|
412
|
+
root = HwpxOxmlDocument(manifest, [section], [])
|
|
413
|
+
document = HwpxDocument(cast(HwpxPackage, object()), root)
|
|
414
|
+
|
|
415
|
+
table = document.add_table(1, 1, section=section)
|
|
416
|
+
cell = table.cell(0, 0)
|
|
417
|
+
sublist = cell.element.find(f"{HP}subList")
|
|
418
|
+
assert sublist is not None
|
|
419
|
+
sublist.set("lineWrap", "SQUEEZE")
|
|
420
|
+
|
|
421
|
+
table.set_cell_text(0, 0, "한 줄 폭을 넘는 신규 검토 의견 " * 8)
|
|
422
|
+
|
|
423
|
+
assert sublist.get("lineWrap") == "BREAK"
|
|
424
|
+
|
|
425
|
+
sublist.set("lineWrap", "SQUEEZE")
|
|
426
|
+
table.set_cell_text(0, 0, cell.text)
|
|
427
|
+
assert sublist.get("lineWrap") == "SQUEEZE"
|
|
428
|
+
|
|
429
|
+
|
|
408
430
|
def test_save_removes_stale_layout_cache_after_low_level_text_edit() -> None:
|
|
409
431
|
document = HwpxDocument.new()
|
|
410
432
|
try:
|
|
@@ -107,6 +107,48 @@ def test_fill_changes_only_target_and_preserves_rest(simple):
|
|
|
107
107
|
assert "CELL_FILLED_X" in sec2.decode("utf-8")
|
|
108
108
|
|
|
109
109
|
|
|
110
|
+
def test_fill_cell_converts_squeeze_to_break_only_in_touched_cell(merged):
|
|
111
|
+
_, sec = _section(merged)
|
|
112
|
+
targets = []
|
|
113
|
+
for ti, (start, end) in enumerate(_iter_table_spans(sec)):
|
|
114
|
+
table = sec[start:end]
|
|
115
|
+
for cell in _direct_cells(table):
|
|
116
|
+
cell_bytes = table[cell.start:cell.end]
|
|
117
|
+
if b'lineWrap="SQUEEZE"' in cell_bytes:
|
|
118
|
+
targets.append((ti, cell.row, cell.col))
|
|
119
|
+
assert len(targets) >= 2
|
|
120
|
+
|
|
121
|
+
ti, row, col = targets[0]
|
|
122
|
+
result = fill_cells(
|
|
123
|
+
merged,
|
|
124
|
+
[{"table_index": ti, "row": row, "col": col, "text": "긴 신규 검토 의견 " * 12}],
|
|
125
|
+
)
|
|
126
|
+
assert result.ok
|
|
127
|
+
|
|
128
|
+
_, changed_section = _section(result.data)
|
|
129
|
+
changed_spans = _iter_table_spans(changed_section)
|
|
130
|
+
changed_table = changed_section[changed_spans[ti][0]:changed_spans[ti][1]]
|
|
131
|
+
changed_cell = build_grid(changed_table)[0][(row, col)]
|
|
132
|
+
changed_cell_bytes = changed_table[changed_cell.start:changed_cell.end]
|
|
133
|
+
assert b'lineWrap="BREAK"' in changed_cell_bytes
|
|
134
|
+
assert b'lineWrap="SQUEEZE"' not in changed_cell_bytes
|
|
135
|
+
|
|
136
|
+
other_ti, other_row, other_col = targets[1]
|
|
137
|
+
other_table = changed_section[changed_spans[other_ti][0]:changed_spans[other_ti][1]]
|
|
138
|
+
other_cell = build_grid(other_table)[0][(other_row, other_col)]
|
|
139
|
+
assert b'lineWrap="SQUEEZE"' in other_table[other_cell.start:other_cell.end]
|
|
140
|
+
|
|
141
|
+
original_table = sec[_iter_table_spans(sec)[ti][0]:_iter_table_spans(sec)[ti][1]]
|
|
142
|
+
original_cell = build_grid(original_table)[0][(row, col)]
|
|
143
|
+
original_text = _cell_text(original_table, original_cell)
|
|
144
|
+
noop = fill_cells(
|
|
145
|
+
merged,
|
|
146
|
+
[{"table_index": ti, "row": row, "col": col, "text": original_text}],
|
|
147
|
+
)
|
|
148
|
+
assert noop.byte_identical is True
|
|
149
|
+
assert noop.data == merged
|
|
150
|
+
|
|
151
|
+
|
|
110
152
|
def test_untouched_table_is_byte_identical(merged):
|
|
111
153
|
_, sec = _section(merged)
|
|
112
154
|
spans = _iter_table_spans(sec)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/application_form/profile.json
RENAMED
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/application_form/template.hwpx
RENAMED
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/home_notice/fragments/body.xml
RENAMED
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/home_notice/fragments/heading.xml
RENAMED
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/home_notice/fragments/title.xml
RENAMED
|
File without changes
|
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/home_notice/template.hwpx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/official_notice/profile.json
RENAMED
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/official_notice/template.hwpx
RENAMED
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/report/fragments/body.xml
RENAMED
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/report/fragments/heading.xml
RENAMED
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/report/fragments/info_table.xml
RENAMED
|
File without changes
|
{python_hwpx-2.24.0 → python_hwpx-2.24.1}/src/hwpx/design/profiles/report/fragments/title.xml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|