python-hwpx 2.29.1__tar.gz → 2.29.2__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.29.1/src/python_hwpx.egg-info → python_hwpx-2.29.2}/PKG-INFO +3 -2
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/README.md +1 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/pyproject.toml +2 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/blueprint/dump.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/blueprint/native.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/benchmark/blind_eval.py +1 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/conformance/corpus/meeting_summary.hwpx +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/conformance/corpus/notice.hwpx +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/conformance/corpus/report_table.hwpx +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/data/Skeleton.hwpx +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/official_notice/profile.json +2 -2
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/document.py +4 -4
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/evalplan_fill.py +3 -5
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/form_fit/seal.py +2 -3
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/formfill_quality.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/__init__.py +2 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/_document_impl.py +6 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/body.py +1 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/document.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/header.py +2 -2
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/forge.py +1 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/fuzz/runner.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/toc_fidelity.py +1 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/detectors.py +1 -2
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/hancom_worker.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2/src/python_hwpx.egg-info}/PKG-INFO +3 -2
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/python_hwpx.egg-info/requires.txt +1 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_agent_blueprint_contracts.py +1 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_body_patch.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_builder_core.py +4 -4
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_conformance.py +0 -3
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_corpus_read_fidelity.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_coverage_promotion.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_design_builder.py +24 -5
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_document_plan_computed_fields.py +1 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_document_save_api.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_evalplan_fill.py +1 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_exam_measure.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_form_fit.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_formfill_quality.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_integration_roundtrip.py +0 -2
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_markdown_export.py +3 -3
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_new_features.py +3 -8
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_official_lint_gongmun_gate.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_openrate.py +4 -4
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_paragraph_section_management.py +0 -2
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_evaluator.py +1 -7
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_split_cell.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_split_merged_cell.py +0 -1
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_template_formfit.py +2 -2
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_toc_author.py +0 -3
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/LICENSE +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/NOTICE +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/setup.cfg +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/blueprint/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/blueprint/bundle.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/blueprint/catalog.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/blueprint/mapping.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/blueprint/model.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/blueprint/replay.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/catalog.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/cli.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/commands.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/document.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/model.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/path.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/agent/query.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/authoring.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/benchmark/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/body_patch.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/builder/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/builder/core.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/builder/report.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/conformance/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/conformance/badges.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/conformance/corpus/corpus.json +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/conformance/corpus.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/conformance/report.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/conformance/roundtrip_batch.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/conformance/runner.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/_support.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/composer.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/harvest.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/plan.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profile.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/application_form/fragments/body.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/application_form/fragments/heading.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/application_form/fragments/info_table.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/application_form/fragments/title.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/application_form/profile.json +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/application_form/template.hwpx +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/home_notice/fragments/body.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/home_notice/fragments/heading.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/home_notice/fragments/title.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/home_notice/profile.json +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/home_notice/template.hwpx +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/official_notice/fragments/body.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/official_notice/fragments/heading.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/official_notice/fragments/info_table.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/official_notice/fragments/title.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/official_notice/template.hwpx +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/report/fragments/body.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/report/fragments/heading.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/report/fragments/info_table.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/report/fragments/title.xml +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/report/profile.json +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/profiles/report/template.hwpx +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/design/validator.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/exam/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/exam/compose.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/exam/ir.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/exam/measure.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/exam/parser.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/exam/profile.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/fill_residue.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/form_fill.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/form_fit/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/form_fit/apply.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/form_fit/engine.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/form_fit/measure.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/form_fit/policy.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/form_fit/report.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/form_fit/wordbox.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/guidance_scan.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/ingest/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/ingest/base.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/ingest/hwpx_converter.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/layout/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/layout/lint.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/layout/report.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/opc/package.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/opc/relationships.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/opc/security.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/opc/xml_utils.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/canonical_defaults.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/common.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/header_part.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/memo.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/namespaces.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/numbering.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/objects.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/paragraph.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/parser.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/run.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/schema.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/section.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/simple_parts.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/table.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/oxml/utils.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/package.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/patch.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/aggregate.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/campaign.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/domain.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/dossier.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/evaluator.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/intake.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/lineage.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/mutations.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/registry.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/run.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/sanitize.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/scenario.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/practice/split.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/presets/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/presets/proposal.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/py.typed +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/quality/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/quality/ledger.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/quality/policy.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/quality/report.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/quality/save_pipeline.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/table_patch.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/template_formfit.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/templates.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/_schemas/header.xsd +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/_schemas/section.xsd +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/advanced_generators.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/archive_cli.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/doc_diff.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/exporter.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/fuzz/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/fuzz/__main__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/fuzz/catalog.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/fuzz/generator.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/fuzz/minimize.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/generic_inventory.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/id_integrity.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/idempotence.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/ir_equality.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/layout_preview.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/mail_merge.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/markdown_export.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/object_finder.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/official_lint.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/package_reconcile.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/package_validator.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/page_guard.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/pii.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/read_fidelity.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/recover.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/redline.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/repair.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/report_parser.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/report_utils.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/roundtrip_diff.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/style_profile.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/table_cleanup.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/table_compute.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/table_navigation.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/template_analyzer.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/text_extract_cli.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/text_extractor.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/toc_author.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/tools/validator.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/__init__.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/_hancom_open_rate.ps1 +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/_refresh_hwpx_mac.applescript +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/_render_hwpx.ps1 +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/_render_hwpx_mac.applescript +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/diff.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/fixture_corpus.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/masks.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/oracle.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/page_qa.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/qa_contracts.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/qa_metrics.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/hwpx/visual/report.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/python_hwpx.egg-info/SOURCES.txt +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/python_hwpx.egg-info/dependency_links.txt +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/python_hwpx.egg-info/entry_points.txt +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/src/python_hwpx.egg-info/top_level.txt +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_advanced_generators.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_agent_blueprint_dump.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_agent_blueprint_replay.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_agent_catalog.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_agent_cli.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_agent_commands.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_agent_contracts.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_agent_document.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_agent_path_query.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_authoring_profile_routing.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_authoring_profile_routing_oracle.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_authoring_render_check.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_blind_eval_fixture.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_builder_plan_v2.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_builder_vertical_slice.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_cell_line_spacing.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_comment_node_robustness.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_coverage_targets.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_deviations_registry.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_doc_diff.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_document_context_manager.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_document_formatting.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_document_plan.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_exam_compose.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_exam_compose_oracle.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_exam_fixtures.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_exam_ir.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_exam_parser.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_exam_profile.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_existing_document_format_editing.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_fill_residue.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_form_fields.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_form_fill_split_run.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_form_fit_integration.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_form_fit_seal.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_form_fit_seal_placement.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_form_fit_wordbox.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_fuzz_loop.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_fuzz_regressions.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_gap_closure_tools.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_government_report_preset.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_government_table_profile.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_guidance_scan.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_hancom_render_worker.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_hp_tab_support.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_hwpxlib_corpus_read.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_id_generator_range.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_id_integrity.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_image_object_workflow.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_ingest.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_inline_models.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_integration_hwpx_compatibility.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_kordoc_absorption.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_layout_lint.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_layout_preview.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_mail_merge_fit.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_mail_merge_table_compute.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_mail_merge_xlsx.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_memo_and_style_editing.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_namespace_handling.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_official_document_style.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_official_lint_tableaware.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_opc_package.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_open_safety_corpus.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_oxml_parsing.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_packaging_license_metadata.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_packaging_py_typed.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_paragraph_keep_together.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_pii.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_pii_structural.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_pii_wiring.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_campaign_aggregate.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_contracts.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_domain_evaluator.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_intake.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_run_contracts.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_sanitize.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_scenario_forge.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_scenario_pack.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_source_integrity.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_practice_split.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_proposal_preset.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_question_split_detector.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_read_fidelity.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_recover_broken_zip.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_redline_authoring.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_redline_verify.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_repair_repack.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_report_parser.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_report_utils.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_repr_snapshots.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_rhwp_t1_gates.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_rhwp_t2_verification.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_roundtrip_fidelity.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_row_heights.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_save_pipeline.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_save_pipeline_no_bypass.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_section_headers.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_set_paragraph_format_keep.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_skeleton_template_ids.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_style_profile.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_table_cleanup.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_table_navigation.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_table_patch.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_table_patch_dryrun.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_table_patch_m105.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_tables_default_border.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_template_analyzer_enrichment.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_text_extractor_annotations.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_toc_fidelity.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_validation_severity.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_validator_comment_nodes.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_version_metadata.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_visual_fixture_corpus.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_visual_oracle.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_visual_qa_contracts.py +0 -0
- {python_hwpx-2.29.1 → python_hwpx-2.29.2}/tests/test_visual_qa_metrics.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-hwpx
|
|
3
|
-
Version: 2.29.
|
|
3
|
+
Version: 2.29.2
|
|
4
4
|
Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리
|
|
5
5
|
Author: python-hwpx Maintainers
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -37,6 +37,7 @@ Requires-Dist: numpy>=1.26; extra == "test"
|
|
|
37
37
|
Requires-Dist: pillow>=10.0; extra == "test"
|
|
38
38
|
Requires-Dist: pytest>=7.4; extra == "test"
|
|
39
39
|
Requires-Dist: pytest-cov>=5.0; extra == "test"
|
|
40
|
+
Requires-Dist: ruff>=0.12; extra == "test"
|
|
40
41
|
Provides-Extra: typecheck
|
|
41
42
|
Requires-Dist: mypy>=1.10; extra == "typecheck"
|
|
42
43
|
Requires-Dist: pyright>=1.1.390; extra == "typecheck"
|
|
@@ -219,7 +220,7 @@ Apache License 2.0. See LICENSE and NOTICE.
|
|
|
219
220
|
|
|
220
221
|
## Maintainer
|
|
221
222
|
|
|
222
|
-
Primary maintainer/contact:
|
|
223
|
+
Primary maintainer/contact: **Kohkyuhyun** ([@airmang](https://github.com/airmang))
|
|
223
224
|
|
|
224
225
|
- ✉️ [kokyuhyun@hotmail.com](mailto:kokyuhyun@hotmail.com)
|
|
225
226
|
- 🐙 [@airmang](https://github.com/airmang)
|
|
@@ -175,7 +175,7 @@ Apache License 2.0. See LICENSE and NOTICE.
|
|
|
175
175
|
|
|
176
176
|
## Maintainer
|
|
177
177
|
|
|
178
|
-
Primary maintainer/contact:
|
|
178
|
+
Primary maintainer/contact: **Kohkyuhyun** ([@airmang](https://github.com/airmang))
|
|
179
179
|
|
|
180
180
|
- ✉️ [kokyuhyun@hotmail.com](mailto:kokyuhyun@hotmail.com)
|
|
181
181
|
- 🐙 [@airmang](https://github.com/airmang)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-hwpx"
|
|
7
|
-
version = "2.29.
|
|
7
|
+
version = "2.29.2"
|
|
8
8
|
description = "한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리"
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -49,6 +49,7 @@ test = [
|
|
|
49
49
|
"pillow>=10.0",
|
|
50
50
|
"pytest>=7.4",
|
|
51
51
|
"pytest-cov>=5.0",
|
|
52
|
+
"ruff>=0.12",
|
|
52
53
|
]
|
|
53
54
|
typecheck = [
|
|
54
55
|
"mypy>=1.10",
|
|
@@ -16,7 +16,6 @@ from ..document import HwpxAgentDocument, NodeRecord
|
|
|
16
16
|
from ..model import AGENT_CATALOG_SCHEMA, NODE_KINDS, AgentContractError
|
|
17
17
|
from .bundle import (
|
|
18
18
|
ALLOWED_MEDIA_TYPES,
|
|
19
|
-
BlueprintBundle,
|
|
20
19
|
build_blueprint_bundle,
|
|
21
20
|
read_blueprint_bundle,
|
|
22
21
|
write_blueprint_bundle,
|
|
@@ -11,7 +11,6 @@ from dataclasses import dataclass
|
|
|
11
11
|
from typing import Any
|
|
12
12
|
|
|
13
13
|
from hwpx.document import HwpxDocument
|
|
14
|
-
from hwpx.oxml import HwpxOxmlTable
|
|
15
14
|
from hwpx.oxml.namespaces import HH, HP
|
|
16
15
|
|
|
17
16
|
from ..commands import _add, _insert_direct_child, _insert_inline, _remove_inline_element, _table_caption
|
|
@@ -12,7 +12,7 @@ import json
|
|
|
12
12
|
import math
|
|
13
13
|
from collections import Counter, defaultdict
|
|
14
14
|
from pathlib import Path
|
|
15
|
-
from typing import Any, Mapping
|
|
15
|
+
from typing import Any, Mapping
|
|
16
16
|
|
|
17
17
|
BENCHMARK_SCHEMA = "hwpx.blind-real-work-eval/v1"
|
|
18
18
|
RESULT_SCHEMA = "hwpx.blind-real-work-eval-result/v1"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -5,19 +5,16 @@ from __future__ import annotations
|
|
|
5
5
|
|
|
6
6
|
import xml.etree.ElementTree as ET
|
|
7
7
|
import io
|
|
8
|
-
import os
|
|
9
8
|
import re
|
|
10
|
-
import tempfile
|
|
11
9
|
import warnings
|
|
12
10
|
from datetime import datetime
|
|
13
11
|
import logging
|
|
14
12
|
import uuid
|
|
15
13
|
|
|
16
14
|
from os import PathLike
|
|
17
|
-
from pathlib import
|
|
15
|
+
from pathlib import PurePosixPath
|
|
18
16
|
from typing import TYPE_CHECKING, Any, BinaryIO, Iterator, Mapping, Sequence, overload
|
|
19
17
|
|
|
20
|
-
from lxml import etree
|
|
21
18
|
|
|
22
19
|
from .oxml import (
|
|
23
20
|
Bullet,
|
|
@@ -65,6 +62,9 @@ _HWP_UNITS_PER_PT = 100
|
|
|
65
62
|
logger = logging.getLogger(__name__)
|
|
66
63
|
|
|
67
64
|
if TYPE_CHECKING:
|
|
65
|
+
from .form_fit.policy import FitPolicy
|
|
66
|
+
from .form_fit.report import FitResult
|
|
67
|
+
from .tools.validator import ValidationReport
|
|
68
68
|
from .tools.table_navigation import TableFillResult, TableLabelSearchResult, TableMapResult
|
|
69
69
|
|
|
70
70
|
|
|
@@ -18,7 +18,7 @@ from __future__ import annotations
|
|
|
18
18
|
|
|
19
19
|
import re
|
|
20
20
|
from dataclasses import dataclass, field
|
|
21
|
-
from typing import Any
|
|
21
|
+
from typing import Any, Sequence
|
|
22
22
|
|
|
23
23
|
_CIRCLED = "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮"
|
|
24
24
|
|
|
@@ -327,7 +327,7 @@ def _pick_achieve_rate(tabs, want_bands: int | None) -> int | None:
|
|
|
327
327
|
|
|
328
328
|
def _regular_exam_cols(table) -> list[int]:
|
|
329
329
|
"""Logical column indices of the 정기시험 span in a 반영비율 table header."""
|
|
330
|
-
from .table_patch import build_grid,
|
|
330
|
+
from .table_patch import build_grid, _text_of
|
|
331
331
|
tb = table.bytes
|
|
332
332
|
grid, rep = build_grid(tb)
|
|
333
333
|
cols: list[int] = []
|
|
@@ -1084,7 +1084,7 @@ def fill_rubrics(data: bytes, content: EvalPlanContent) -> tuple[bytes, dict[str
|
|
|
1084
1084
|
cells (title / points / 성취기준 / A~E / 수행과제 / 평가요소 leaders / 기본점수 배점),
|
|
1085
1085
|
reshapes+fills the 수행수준 채점기준 ladder, and rewrites each rubric's ordinal
|
|
1086
1086
|
heading paragraph (가./나./다. + sample project title) to the review 영역명."""
|
|
1087
|
-
from .table_patch import apply_table_ops, fill_cells,
|
|
1087
|
+
from .table_patch import apply_table_ops, fill_cells, _all_paragraph_spans
|
|
1088
1088
|
|
|
1089
1089
|
report: dict[str, Any] = {"rubrics": len(content.rubrics), "filled": 0, "skipped": []}
|
|
1090
1090
|
levels = content.levels
|
|
@@ -1122,7 +1122,6 @@ def fill_rubrics(data: bytes, content: EvalPlanContent) -> tuple[bytes, dict[str
|
|
|
1122
1122
|
if hdr is None or base is None:
|
|
1123
1123
|
report["skipped"].append(f"rubric {i}: could not bound item block")
|
|
1124
1124
|
continue
|
|
1125
|
-
item_rows = base - (hdr + 1) # blank example block height (7)
|
|
1126
1125
|
first_item = hdr + 1
|
|
1127
1126
|
todel = list(range(first_item + n, base)) # keep n, drop the surplus
|
|
1128
1127
|
if todel:
|
|
@@ -1471,7 +1470,6 @@ def fill_ratio(data: bytes, content: EvalPlanContent) -> tuple[bytes, dict[str,
|
|
|
1471
1470
|
return data, report
|
|
1472
1471
|
_sp, tb, grid, rep = _grid_of(data, ti)
|
|
1473
1472
|
label_col, area_cols, total_col = _ratio_columns(tb, grid, rep)
|
|
1474
|
-
areas = _area_names(content)
|
|
1475
1473
|
if not area_cols:
|
|
1476
1474
|
report["skipped"].append(f"no area columns detected (label_col={label_col}, total_col={total_col})")
|
|
1477
1475
|
return data, report
|
|
@@ -32,7 +32,7 @@ point is exactly ``100`` HWPUNIT (``7200 / 72``).
|
|
|
32
32
|
from __future__ import annotations
|
|
33
33
|
|
|
34
34
|
import math
|
|
35
|
-
from dataclasses import dataclass
|
|
35
|
+
from dataclasses import dataclass
|
|
36
36
|
from typing import Any, Sequence
|
|
37
37
|
|
|
38
38
|
from .wordbox import Rect, WordBox
|
|
@@ -219,8 +219,7 @@ def check_seal_placement(
|
|
|
219
219
|
offset = math.hypot(scx - acx, scy - acy)
|
|
220
220
|
centered = offset <= tol_pt
|
|
221
221
|
|
|
222
|
-
# Glyphs the seal sits on top of, excluding the anchor's own
|
|
223
|
-
anchor_line = set(_norm(anchor.line_text)) # cheap line-membership proxy by text
|
|
222
|
+
# Glyphs the seal sits on top of, excluding the anchor's own baseline.
|
|
224
223
|
anchor_cy = anchor.center[1]
|
|
225
224
|
occluded = 0
|
|
226
225
|
for g in boxes:
|
|
@@ -135,11 +135,13 @@ __all__ = [
|
|
|
135
135
|
"HwpxOxmlMasterPage",
|
|
136
136
|
"HwpxOxmlMemo",
|
|
137
137
|
"HwpxOxmlMemoGroup",
|
|
138
|
+
"HwpxOxmlNote",
|
|
138
139
|
"HwpxOxmlParagraph",
|
|
139
140
|
"HwpxOxmlRun",
|
|
140
141
|
"HwpxOxmlSection",
|
|
141
142
|
"HwpxOxmlSectionHeaderFooter",
|
|
142
143
|
"HwpxOxmlSectionProperties",
|
|
144
|
+
"HwpxOxmlShape",
|
|
143
145
|
"HwpxOxmlTable",
|
|
144
146
|
"HwpxOxmlTableCell",
|
|
145
147
|
"HwpxTableGridPosition",
|
|
@@ -7,7 +7,7 @@ import logging
|
|
|
7
7
|
import re as _re
|
|
8
8
|
from copy import deepcopy
|
|
9
9
|
from dataclasses import dataclass
|
|
10
|
-
from typing import Any, Callable, Iterable, Iterator, Mapping, Optional, Sequence, TypeVar
|
|
10
|
+
from typing import TYPE_CHECKING, Any, Callable, Iterable, Iterator, Mapping, Optional, Sequence, TypeVar
|
|
11
11
|
from uuid import uuid4
|
|
12
12
|
import xml.etree.ElementTree as ET
|
|
13
13
|
|
|
@@ -52,6 +52,11 @@ from .namespaces import (
|
|
|
52
52
|
)
|
|
53
53
|
from .utils import parse_int
|
|
54
54
|
|
|
55
|
+
if TYPE_CHECKING:
|
|
56
|
+
from hwpx.form_fit.policy import FitPolicy
|
|
57
|
+
from hwpx.form_fit.report import FitResult
|
|
58
|
+
from hwpx.opc.package import HwpxPackage
|
|
59
|
+
|
|
55
60
|
register_owpml_namespaces(ET.register_namespace)
|
|
56
61
|
logger = logging.getLogger(__name__)
|
|
57
62
|
|
|
@@ -13,7 +13,6 @@ from types import ModuleType
|
|
|
13
13
|
|
|
14
14
|
from . import _document_impl as _impl
|
|
15
15
|
from ._document_impl import * # noqa: F401,F403
|
|
16
|
-
from ._document_impl import _memo_id, _object_id, _paragraph_id
|
|
17
16
|
|
|
18
17
|
__all__ = [name for name in dir(_impl) if not name.startswith("_")]
|
|
19
18
|
|
|
@@ -1480,7 +1480,7 @@ def track_change_to_xml(change: TrackChange) -> etree._Element:
|
|
|
1480
1480
|
_set_optional_int_attr(attributes, "id", change.id)
|
|
1481
1481
|
if change.raw_id is not None and change.id is None:
|
|
1482
1482
|
attributes["id"] = change.raw_id
|
|
1483
|
-
return etree.Element(
|
|
1483
|
+
return etree.Element("{http://www.hancom.co.kr/hwpml/2011/head}trackChange", attributes)
|
|
1484
1484
|
|
|
1485
1485
|
|
|
1486
1486
|
def track_change_author_to_xml(author: TrackChangeAuthor) -> etree._Element:
|
|
@@ -1496,7 +1496,7 @@ def track_change_author_to_xml(author: TrackChangeAuthor) -> etree._Element:
|
|
|
1496
1496
|
attributes["id"] = author.raw_id
|
|
1497
1497
|
_set_optional_str_attr(attributes, "color", author.color)
|
|
1498
1498
|
return etree.Element(
|
|
1499
|
-
|
|
1499
|
+
"{http://www.hancom.co.kr/hwpml/2011/head}trackChangeAuthor",
|
|
1500
1500
|
attributes,
|
|
1501
1501
|
)
|
|
1502
1502
|
|
|
@@ -12,7 +12,7 @@ from typing import Any
|
|
|
12
12
|
|
|
13
13
|
from .dossier import synthetic_dossier
|
|
14
14
|
from .mutations import controlled_mutation, mutation_sha256
|
|
15
|
-
from .registry import
|
|
15
|
+
from .registry import SHA256_PATTERN, assert_redacted_payload
|
|
16
16
|
from .scenario import PRACTICE_SCENARIO_SCHEMA, validate_scenario
|
|
17
17
|
from .split import validate_split_manifest
|
|
18
18
|
|
|
@@ -14,7 +14,7 @@ gate on :func:`imaging_available` and degrade otherwise.
|
|
|
14
14
|
"""
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from typing import TYPE_CHECKING
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
if TYPE_CHECKING: # pragma: no cover - typing only
|
|
20
20
|
from PIL import Image
|
|
@@ -88,7 +88,6 @@ def new_ink_ratio_outside_mask(before: "Image.Image", after: "Image.Image", rect
|
|
|
88
88
|
output but not the original, in a region the edit was not allowed to paint.
|
|
89
89
|
"""
|
|
90
90
|
|
|
91
|
-
import numpy as np
|
|
92
91
|
|
|
93
92
|
before, after = _match_size(before, after)
|
|
94
93
|
new_ink = _ink_mask(after) & ~_ink_mask(before)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-hwpx
|
|
3
|
-
Version: 2.29.
|
|
3
|
+
Version: 2.29.2
|
|
4
4
|
Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리
|
|
5
5
|
Author: python-hwpx Maintainers
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -37,6 +37,7 @@ Requires-Dist: numpy>=1.26; extra == "test"
|
|
|
37
37
|
Requires-Dist: pillow>=10.0; extra == "test"
|
|
38
38
|
Requires-Dist: pytest>=7.4; extra == "test"
|
|
39
39
|
Requires-Dist: pytest-cov>=5.0; extra == "test"
|
|
40
|
+
Requires-Dist: ruff>=0.12; extra == "test"
|
|
40
41
|
Provides-Extra: typecheck
|
|
41
42
|
Requires-Dist: mypy>=1.10; extra == "typecheck"
|
|
42
43
|
Requires-Dist: pyright>=1.1.390; extra == "typecheck"
|
|
@@ -219,7 +220,7 @@ Apache License 2.0. See LICENSE and NOTICE.
|
|
|
219
220
|
|
|
220
221
|
## Maintainer
|
|
221
222
|
|
|
222
|
-
Primary maintainer/contact:
|
|
223
|
+
Primary maintainer/contact: **Kohkyuhyun** ([@airmang](https://github.com/airmang))
|
|
223
224
|
|
|
224
225
|
- ✉️ [kokyuhyun@hotmail.com](mailto:kokyuhyun@hotmail.com)
|
|
225
226
|
- 🐙 [@airmang](https://github.com/airmang)
|
|
@@ -132,7 +132,7 @@ def test_manifest_rejects_hash_mismatch_and_absolute_private_label() -> None:
|
|
|
132
132
|
with pytest.raises(AgentContractError):
|
|
133
133
|
validate_blueprint_manifest(manifest)
|
|
134
134
|
manifest = _manifest()
|
|
135
|
-
manifest["source"]["label"] = "/
|
|
135
|
+
manifest["source"]["label"] = "/workspace/private/source.hwpx"
|
|
136
136
|
manifest = with_blueprint_hash(manifest)
|
|
137
137
|
with pytest.raises(AgentContractError):
|
|
138
138
|
validate_blueprint_manifest(manifest)
|
|
@@ -211,7 +211,6 @@ def test_strip_runs_by_color_reaches_cells(work, tmp_path):
|
|
|
211
211
|
|
|
212
212
|
def test_recolor_runs_exact_hex(work, tmp_path):
|
|
213
213
|
"""정확 hex 매칭으로 재색 — 계열 다른 디자인색은 불변."""
|
|
214
|
-
import hwpx.guidance_scan as gs
|
|
215
214
|
from hwpx.body_patch import recolor_runs_by_color
|
|
216
215
|
from hwpx.fill_residue import _scan_paragraphs
|
|
217
216
|
out = tmp_path / "out.hwpx"
|
|
@@ -197,7 +197,7 @@ def test_document_ensure_run_style_supports_rich_char_properties() -> None:
|
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
|
|
200
|
-
def
|
|
200
|
+
def test_builder_lowers_korean_rich_run_and_reopen_preserves_style(tmp_path) -> None:
|
|
201
201
|
from hwpx.builder import Document, Paragraph, Run, Section
|
|
202
202
|
|
|
203
203
|
path = tmp_path / "builder-rich-run.hwpx"
|
|
@@ -280,7 +280,7 @@ def test_ensure_run_style_supports_rich_char_properties() -> None:
|
|
|
280
280
|
assert style.child_attributes["strikeout"]["shape"] == "SOLID"
|
|
281
281
|
|
|
282
282
|
|
|
283
|
-
def
|
|
283
|
+
def test_builder_lowers_mixed_rich_runs_and_reopen_preserves_style(tmp_path) -> None:
|
|
284
284
|
from hwpx.builder import Document, Paragraph, Run, Section
|
|
285
285
|
|
|
286
286
|
path = tmp_path / "builder-rich-runs.hwpx"
|
|
@@ -571,7 +571,7 @@ def test_table_set_column_widths_applies_weighted_cell_sizes() -> None:
|
|
|
571
571
|
assert [table.cell(1, col_index).width for col_index in range(3)] == widths
|
|
572
572
|
|
|
573
573
|
|
|
574
|
-
def
|
|
574
|
+
def test_builder_table_integrates_vertical_merge(tmp_path) -> None:
|
|
575
575
|
from hwpx.builder import Document, Section, Table
|
|
576
576
|
|
|
577
577
|
path = tmp_path / "builder-table-integrated.hwpx"
|
|
@@ -624,7 +624,7 @@ def test_table_set_column_widths_updates_cell_sizes(tmp_path) -> None:
|
|
|
624
624
|
assert [reopened_table.cell(1, col).width for col in range(3)] == [7200, 10800, 3600]
|
|
625
625
|
|
|
626
626
|
|
|
627
|
-
def
|
|
627
|
+
def test_builder_table_integrates_header_merge(tmp_path) -> None:
|
|
628
628
|
from hwpx.builder import Document, Section, Table
|
|
629
629
|
|
|
630
630
|
path = tmp_path / "builder-table-integrated.hwpx"
|
|
@@ -8,7 +8,6 @@ The real-Hancom verification is the opt-in oracle run, not these tests.
|
|
|
8
8
|
"""
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
|
-
import io
|
|
12
11
|
import json
|
|
13
12
|
from pathlib import Path
|
|
14
13
|
|
|
@@ -16,8 +15,6 @@ import pytest
|
|
|
16
15
|
|
|
17
16
|
from hwpx import HwpxDocument
|
|
18
17
|
from hwpx.conformance import (
|
|
19
|
-
Badge,
|
|
20
|
-
BadgeThresholds,
|
|
21
18
|
CaseResult,
|
|
22
19
|
ConformanceCase,
|
|
23
20
|
ConformanceCorpus,
|
|
@@ -194,12 +194,25 @@ def test_compose_returns_not_ok_when_open_safety_raises(tmp_path, monkeypatch):
|
|
|
194
194
|
# --------------------------------------------------------------------------- #
|
|
195
195
|
# Privacy: no residual source PII in committed templates or generated docs.
|
|
196
196
|
# --------------------------------------------------------------------------- #
|
|
197
|
-
|
|
198
|
-
"
|
|
199
|
-
"
|
|
197
|
+
_PUBLIC_PRIVACY_SENTINELS = [
|
|
198
|
+
"source-author@example.invalid",
|
|
199
|
+
"private-origin-user",
|
|
200
|
+
"source-institution.example",
|
|
201
|
+
"source-location.example",
|
|
202
|
+
"source-project-code",
|
|
200
203
|
]
|
|
201
204
|
|
|
202
205
|
|
|
206
|
+
def _privacy_needles() -> list[str]:
|
|
207
|
+
"""Return synthetic public sentinels plus an optional private-CI denylist."""
|
|
208
|
+
private = [
|
|
209
|
+
value.strip().lower()
|
|
210
|
+
for value in os.environ.get("HWPX_PRIVATE_PII_NEEDLES", "").split(",")
|
|
211
|
+
if value.strip()
|
|
212
|
+
]
|
|
213
|
+
return _PUBLIC_PRIVACY_SENTINELS + private
|
|
214
|
+
|
|
215
|
+
|
|
203
216
|
def _text_blob(data: bytes) -> str:
|
|
204
217
|
import zipfile
|
|
205
218
|
|
|
@@ -213,13 +226,19 @@ def _text_blob(data: bytes) -> str:
|
|
|
213
226
|
|
|
214
227
|
@pytest.mark.parametrize("pid", PROFILES)
|
|
215
228
|
def test_profile_and_output_carry_no_source_pii(pid):
|
|
229
|
+
needles = _privacy_needles()
|
|
216
230
|
prof = load_profile(pid)
|
|
217
231
|
blob = _text_blob(prof.template_bytes)
|
|
218
|
-
assert not [n for n in
|
|
232
|
+
assert not [n for n in needles if n in blob], pid
|
|
219
233
|
data, res = compose_bytes(_plan(pid))
|
|
220
234
|
assert res.ok
|
|
221
235
|
out_blob = _text_blob(data)
|
|
222
|
-
assert not [n for n in
|
|
236
|
+
assert not [n for n in needles if n in out_blob], pid
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def test_private_ci_privacy_needles_are_supported(monkeypatch):
|
|
240
|
+
monkeypatch.setenv("HWPX_PRIVATE_PII_NEEDLES", "private-ci-sentinel,second-private-marker")
|
|
241
|
+
assert _privacy_needles()[-2:] == ["private-ci-sentinel", "second-private-marker"]
|
|
223
242
|
|
|
224
243
|
|
|
225
244
|
# --------------------------------------------------------------------------- #
|
|
@@ -7,7 +7,7 @@ from hwpx import (
|
|
|
7
7
|
create_document_from_plan,
|
|
8
8
|
validate_document_plan,
|
|
9
9
|
)
|
|
10
|
-
from hwpx.builder import Bullet, Document, Heading, Paragraph, Run, Section
|
|
10
|
+
from hwpx.builder import Bullet, Document, Heading, Paragraph, Run, Section
|
|
11
11
|
from hwpx.document import HwpxDocument
|
|
12
12
|
|
|
13
13
|
DOCUMENT_PLAN_V2_SCHEMA_VERSION = "hwpx.document_plan.v2"
|
|
@@ -8,7 +8,6 @@ from zipfile import ZipFile
|
|
|
8
8
|
import pytest
|
|
9
9
|
from lxml import etree
|
|
10
10
|
|
|
11
|
-
import hwpx.document as document_module
|
|
12
11
|
from hwpx.document import HwpxDocument
|
|
13
12
|
from hwpx.opc.package import HwpxPackageError
|
|
14
13
|
from hwpx.tools.package_validator import validate_editor_open_safety
|
|
@@ -316,7 +316,7 @@ def test_fill_achievement_reshapes_and_fills():
|
|
|
316
316
|
def test_fill_rubrics_replaces_sample_codes_and_lands_items():
|
|
317
317
|
"""fill_rubrics shrinks each rubric's example item block to the review item
|
|
318
318
|
count, replaces the 한국사 sample 성취기준 codes, and lands the 평가항목 labels."""
|
|
319
|
-
from hwpx.evalplan_fill import fill_rubrics, _rubric_indices, _grid_of
|
|
319
|
+
from hwpx.evalplan_fill import fill_rubrics, _rubric_indices, _grid_of
|
|
320
320
|
from hwpx.formfill_quality import _all_text, _STD_CODE_RE
|
|
321
321
|
c = parse_review_md(SYNTHETIC)
|
|
322
322
|
blank = BLANK_3HAK.read_bytes()
|
|
@@ -17,7 +17,7 @@ HP = "{http://www.hancom.co.kr/hwpml/2011/paragraph}"
|
|
|
17
17
|
|
|
18
18
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
19
19
|
EXAMPLES = REPO_ROOT / "examples"
|
|
20
|
-
FIXTURES =
|
|
20
|
+
FIXTURES = Path(__file__).parent / "fixtures" / "markdown_export"
|
|
21
21
|
|
|
22
22
|
HWPML_2011 = {
|
|
23
23
|
"app": "http://www.hancom.co.kr/hwpml/2011/app",
|
|
@@ -62,12 +62,12 @@ def showcase_doc():
|
|
|
62
62
|
|
|
63
63
|
@pytest.fixture
|
|
64
64
|
def table_merge_doc():
|
|
65
|
-
return HwpxDocument.open(str(FIXTURES / "
|
|
65
|
+
return HwpxDocument.open(str(FIXTURES / "30_table_merge_min.hwpx"))
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
@pytest.fixture
|
|
69
69
|
def stress_doc():
|
|
70
|
-
return HwpxDocument.open(str(FIXTURES / "
|
|
70
|
+
return HwpxDocument.open(str(FIXTURES / "99_all_in_one_stress.hwpx"))
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
# ──────────────────────────────────────────────────────────────────
|