python-hwpx 2.9.1__tar.gz → 2.10.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.
Files changed (97) hide show
  1. python_hwpx-2.10.0/NOTICE +42 -0
  2. {python_hwpx-2.9.1/src/python_hwpx.egg-info → python_hwpx-2.10.0}/PKG-INFO +8 -1
  3. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/README.md +7 -0
  4. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/pyproject.toml +2 -1
  5. python_hwpx-2.10.0/src/hwpx/__init__.py +79 -0
  6. python_hwpx-2.10.0/src/hwpx/authoring.py +1881 -0
  7. python_hwpx-2.10.0/src/hwpx/builder/__init__.py +43 -0
  8. python_hwpx-2.10.0/src/hwpx/builder/core.py +512 -0
  9. python_hwpx-2.10.0/src/hwpx/builder/report.py +59 -0
  10. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/document.py +189 -14
  11. python_hwpx-2.10.0/src/hwpx/form_fill.py +333 -0
  12. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/opc/package.py +62 -11
  13. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/document.py +841 -13
  14. python_hwpx-2.10.0/src/hwpx/oxml/namespaces.py +50 -0
  15. python_hwpx-2.10.0/src/hwpx/presets/__init__.py +22 -0
  16. python_hwpx-2.10.0/src/hwpx/presets/proposal.py +538 -0
  17. python_hwpx-2.10.0/src/hwpx/template_formfit.py +592 -0
  18. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/archive_cli.py +31 -1
  19. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/package_validator.py +62 -1
  20. python_hwpx-2.10.0/src/hwpx/tools/recover.py +151 -0
  21. python_hwpx-2.10.0/src/hwpx/tools/repair.py +263 -0
  22. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/validator.py +26 -7
  23. {python_hwpx-2.9.1 → python_hwpx-2.10.0/src/python_hwpx.egg-info}/PKG-INFO +8 -1
  24. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/python_hwpx.egg-info/SOURCES.txt +21 -0
  25. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/python_hwpx.egg-info/entry_points.txt +1 -0
  26. python_hwpx-2.10.0/tests/test_builder_core.py +937 -0
  27. python_hwpx-2.10.0/tests/test_builder_vertical_slice.py +165 -0
  28. python_hwpx-2.10.0/tests/test_deviations_registry.py +12 -0
  29. python_hwpx-2.10.0/tests/test_document_plan.py +639 -0
  30. python_hwpx-2.10.0/tests/test_form_fill_split_run.py +301 -0
  31. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_gap_closure_tools.py +65 -6
  32. python_hwpx-2.10.0/tests/test_hwpxlib_corpus_read.py +36 -0
  33. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_opc_package.py +29 -0
  34. python_hwpx-2.10.0/tests/test_proposal_preset.py +47 -0
  35. python_hwpx-2.10.0/tests/test_recover_broken_zip.py +243 -0
  36. python_hwpx-2.10.0/tests/test_repair_repack.py +225 -0
  37. python_hwpx-2.10.0/tests/test_template_formfit.py +343 -0
  38. python_hwpx-2.10.0/tests/test_validation_severity.py +52 -0
  39. python_hwpx-2.9.1/NOTICE +0 -14
  40. python_hwpx-2.9.1/src/hwpx/__init__.py +0 -41
  41. python_hwpx-2.9.1/src/hwpx/oxml/namespaces.py +0 -25
  42. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/LICENSE +0 -0
  43. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/setup.cfg +0 -0
  44. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/data/Skeleton.hwpx +0 -0
  45. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/opc/relationships.py +0 -0
  46. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/opc/xml_utils.py +0 -0
  47. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/__init__.py +0 -0
  48. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/body.py +0 -0
  49. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/common.py +0 -0
  50. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/header.py +0 -0
  51. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/header_part.py +0 -0
  52. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/memo.py +0 -0
  53. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/paragraph.py +0 -0
  54. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/parser.py +0 -0
  55. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/schema.py +0 -0
  56. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/section.py +0 -0
  57. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/table.py +0 -0
  58. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/oxml/utils.py +0 -0
  59. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/package.py +0 -0
  60. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/py.typed +0 -0
  61. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/templates.py +0 -0
  62. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/__init__.py +0 -0
  63. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/_schemas/header.xsd +0 -0
  64. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/_schemas/section.xsd +0 -0
  65. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/exporter.py +0 -0
  66. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/object_finder.py +0 -0
  67. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/page_guard.py +0 -0
  68. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/table_navigation.py +0 -0
  69. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/template_analyzer.py +0 -0
  70. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/text_extract_cli.py +0 -0
  71. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/hwpx/tools/text_extractor.py +0 -0
  72. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/python_hwpx.egg-info/dependency_links.txt +0 -0
  73. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/python_hwpx.egg-info/requires.txt +0 -0
  74. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/src/python_hwpx.egg-info/top_level.txt +0 -0
  75. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_coverage_targets.py +0 -0
  76. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_document_context_manager.py +0 -0
  77. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_document_formatting.py +0 -0
  78. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_document_save_api.py +0 -0
  79. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_hp_tab_support.py +0 -0
  80. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_id_generator_range.py +0 -0
  81. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_inline_models.py +0 -0
  82. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_integration_hwpx_compatibility.py +0 -0
  83. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_integration_roundtrip.py +0 -0
  84. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_memo_and_style_editing.py +0 -0
  85. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_new_features.py +0 -0
  86. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_oxml_parsing.py +0 -0
  87. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_packaging_license_metadata.py +0 -0
  88. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_packaging_py_typed.py +0 -0
  89. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_paragraph_section_management.py +0 -0
  90. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_repr_snapshots.py +0 -0
  91. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_section_headers.py +0 -0
  92. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_skeleton_template_ids.py +0 -0
  93. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_split_merged_cell.py +0 -0
  94. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_table_navigation.py +0 -0
  95. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_tables_default_border.py +0 -0
  96. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_text_extractor_annotations.py +0 -0
  97. {python_hwpx-2.9.1 → python_hwpx-2.10.0}/tests/test_version_metadata.py +0 -0
@@ -0,0 +1,42 @@
1
+ python-hwpx
2
+ Copyright 2025-2026 airmang
3
+
4
+ This product includes software developed by airmang.
5
+ Licensed under the Apache License, Version 2.0.
6
+
7
+ Clean-room implementation references:
8
+
9
+ The HWPX repair and recovery tools include behavior ideas independently
10
+ reimplemented from public references, without copying source code:
11
+
12
+ - sakada3/hwp-ops (Apache-2.0): repair-repack behavior for placing the
13
+ mimetype entry first, storing it uncompressed, and running ZIP integrity
14
+ checks.
15
+ - chrisryugj/kordoc (MIT): broken HWPX ZIP recovery behavior using Local File
16
+ Header scanning when the central directory is damaged.
17
+ - chrisryugj/kordoc (MIT): HWPX form-fill behavior ideas for preserving
18
+ text-node and run structure, including split text-range replacement and empty
19
+ run handling.
20
+ - sakada3/hwp-ops (Apache-2.0): split-run placeholder scan/fill behavior
21
+ ideas, charPrIDRef heterogeneity warning, and touched-paragraph layout-cache
22
+ invalidation.
23
+
24
+ These form-fill references were used as behavior evidence only. The
25
+ implementation is a clean-room Python implementation; no source code was
26
+ copied, translated, vendored, or linked.
27
+
28
+ ## Test fixtures: hwpxlib sample corpus
29
+
30
+ tests/fixtures/hwpxlib_corpus/ contains .hwpx sample files vendored from
31
+ neolord0/hwpxlib (https://github.com/neolord0/hwpxlib), licensed Apache-2.0.
32
+ Only sample DATA files are vendored; no hwpxlib source code or structure is
33
+ copied (clean-room). Pinned ref is recorded in manifest.json.
34
+
35
+ ────────────────────────────────────────
36
+ DISCLAIMER — HWPX Format
37
+
38
+ "HWPX" is the document format specified and trademarked by
39
+ Hancom Inc. (한글과컴퓨터). This project is an independent,
40
+ unofficial implementation and is not affiliated with, endorsed by,
41
+ or sponsored by Hancom Inc.
42
+ ────────────────────────────────────────
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-hwpx
3
- Version: 2.9.1
3
+ Version: 2.10.0
4
4
  Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리
5
5
  Author: python-hwpx Maintainers
6
6
  License-Expression: Apache-2.0
@@ -177,6 +177,13 @@ document.save_to_path("새문서.hwpx")
177
177
  > | **크로스 플랫폼** | ✅ Linux / macOS / Windows / CI | ❌ Windows 전용 | ✅ |
178
178
  > | **방식** | 직접 XML 파싱 | COM 자동화 | OLE 파싱 |
179
179
 
180
+ ## HWPX plugin usage
181
+
182
+ The per-host bundles in the `hwpx-plugins` repository consume `python-hwpx` through
183
+ `hwpx-mcp-server` and the local quickcheck scripts. During local development, set
184
+ `PYTHON_HWPX_REPO=/absolute/path/to/python-hwpx` so the plugin launcher uses this checkout as an
185
+ editable dependency.
186
+
180
187
  ## 🌍 크로스 플랫폼 지원
181
188
 
182
189
  HWPX 파일은 **ZIP + XML** 구조이므로, 한/글 프로그램 없이 Python만으로 읽고 편집하는 워크플로를 구성할 수 있습니다.
@@ -141,6 +141,13 @@ document.save_to_path("새문서.hwpx")
141
141
  > | **크로스 플랫폼** | ✅ Linux / macOS / Windows / CI | ❌ Windows 전용 | ✅ |
142
142
  > | **방식** | 직접 XML 파싱 | COM 자동화 | OLE 파싱 |
143
143
 
144
+ ## HWPX plugin usage
145
+
146
+ The per-host bundles in the `hwpx-plugins` repository consume `python-hwpx` through
147
+ `hwpx-mcp-server` and the local quickcheck scripts. During local development, set
148
+ `PYTHON_HWPX_REPO=/absolute/path/to/python-hwpx` so the plugin launcher uses this checkout as an
149
+ editable dependency.
150
+
144
151
  ## 🌍 크로스 플랫폼 지원
145
152
 
146
153
  HWPX 파일은 **ZIP + XML** 구조이므로, 한/글 프로그램 없이 Python만으로 읽고 편집하는 워크플로를 구성할 수 있습니다.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-hwpx"
7
- version = "2.9.1"
7
+ version = "2.10.0"
8
8
  description = "한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
10
  license = "Apache-2.0"
@@ -57,6 +57,7 @@ hwpx-validate-package = "hwpx.tools.package_validator:main"
57
57
  hwpx-page-guard = "hwpx.tools.page_guard:main"
58
58
  hwpx-analyze-template = "hwpx.tools.template_analyzer:main"
59
59
  hwpx-text-extract = "hwpx.tools.text_extract_cli:main"
60
+ hwpx-repair = "hwpx.tools.repair:main"
60
61
 
61
62
  [tool.setuptools]
62
63
  package-dir = { "" = "src" }
@@ -0,0 +1,79 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """High-level utilities for working with HWPX documents."""
3
+
4
+ from importlib.metadata import PackageNotFoundError, version as _metadata_version
5
+
6
+
7
+ def _resolve_version() -> str:
8
+ """패키지 메타데이터에서 현재 배포 버전을 조회합니다."""
9
+ try:
10
+ return _metadata_version("python-hwpx")
11
+ except PackageNotFoundError:
12
+ return "0+unknown"
13
+
14
+ def __getattr__(name: str) -> object:
15
+ """Resolve dynamic module attributes."""
16
+
17
+ if name == "__version__":
18
+ return _resolve_version()
19
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
20
+
21
+ from .tools.text_extractor import (
22
+ DEFAULT_NAMESPACES,
23
+ ParagraphInfo,
24
+ SectionInfo,
25
+ TextExtractor,
26
+ )
27
+ from .tools.object_finder import FoundElement, ObjectFinder
28
+ from .document import HwpxDocument
29
+ from .package import HwpxPackage
30
+ from .authoring import (
31
+ AUTHORING_REPORT_VERSION,
32
+ DEFAULT_STYLE_PRESET,
33
+ DOCUMENT_PLAN_SCHEMA_VERSION,
34
+ DocumentBlock,
35
+ DocumentPlan,
36
+ DocumentStylePreset,
37
+ PlanValidationIssue,
38
+ PlanValidationReport,
39
+ create_document_from_plan,
40
+ inspect_document_authoring_quality,
41
+ inspect_operating_plan_quality,
42
+ normalize_document_plan,
43
+ validate_document_plan,
44
+ )
45
+ from .template_formfit import (
46
+ TEMPLATE_FORMFIT_BASELINE_SCHEMA_VERSION,
47
+ TEMPLATE_FORMFIT_PLAN_SCHEMA_VERSION,
48
+ analyze_template_formfit,
49
+ apply_template_formfit,
50
+ )
51
+
52
+ __all__ = [
53
+ "__version__",
54
+ "AUTHORING_REPORT_VERSION",
55
+ "DEFAULT_NAMESPACES",
56
+ "DEFAULT_STYLE_PRESET",
57
+ "DOCUMENT_PLAN_SCHEMA_VERSION",
58
+ "DocumentBlock",
59
+ "DocumentPlan",
60
+ "DocumentStylePreset",
61
+ "ParagraphInfo",
62
+ "PlanValidationReport",
63
+ "SectionInfo",
64
+ "TEMPLATE_FORMFIT_BASELINE_SCHEMA_VERSION",
65
+ "TEMPLATE_FORMFIT_PLAN_SCHEMA_VERSION",
66
+ "TextExtractor",
67
+ "FoundElement",
68
+ "ObjectFinder",
69
+ "PlanValidationIssue",
70
+ "HwpxDocument",
71
+ "HwpxPackage",
72
+ "create_document_from_plan",
73
+ "analyze_template_formfit",
74
+ "apply_template_formfit",
75
+ "inspect_document_authoring_quality",
76
+ "inspect_operating_plan_quality",
77
+ "normalize_document_plan",
78
+ "validate_document_plan",
79
+ ]