From 0d74ed5643ec4f2bbf3e670f10b95e2a6b2c652c Mon Sep 17 00:00:00 2001
From: kokyuhyun
Date: Fri, 24 Apr 2026 21:01:39 +0900
Subject: [PATCH] chore: relicense to Apache-2.0
---
CHANGELOG.md | 13 ++
LICENSE | 210 +++++++++++++++++++++----
NOTICE | 14 ++
README.md | 7 +-
examples/build_release_checklist.py | 1 +
examples/extract_text.py | 1 +
examples/find_objects.py | 1 +
pyproject.toml | 5 +-
scripts/analyze_template.py | 1 +
scripts/check_typing_generics_scope.py | 1 +
scripts/office/pack.py | 1 +
scripts/office/unpack.py | 1 +
src/hwpx/__init__.py | 1 +
src/hwpx/document.py | 1 +
src/hwpx/opc/package.py | 1 +
src/hwpx/opc/relationships.py | 1 +
src/hwpx/opc/xml_utils.py | 1 +
src/hwpx/oxml/__init__.py | 1 +
src/hwpx/oxml/body.py | 1 +
src/hwpx/oxml/common.py | 1 +
src/hwpx/oxml/document.py | 1 +
src/hwpx/oxml/header.py | 1 +
src/hwpx/oxml/header_part.py | 1 +
src/hwpx/oxml/memo.py | 1 +
src/hwpx/oxml/namespaces.py | 1 +
src/hwpx/oxml/paragraph.py | 1 +
src/hwpx/oxml/parser.py | 1 +
src/hwpx/oxml/schema.py | 1 +
src/hwpx/oxml/section.py | 1 +
src/hwpx/oxml/table.py | 1 +
src/hwpx/oxml/utils.py | 1 +
src/hwpx/package.py | 1 +
src/hwpx/templates.py | 1 +
src/hwpx/tools/__init__.py | 1 +
src/hwpx/tools/archive_cli.py | 1 +
src/hwpx/tools/exporter.py | 1 +
src/hwpx/tools/object_finder.py | 1 +
src/hwpx/tools/package_validator.py | 1 +
src/hwpx/tools/page_guard.py | 1 +
src/hwpx/tools/table_navigation.py | 1 +
src/hwpx/tools/template_analyzer.py | 1 +
src/hwpx/tools/text_extract_cli.py | 1 +
src/hwpx/tools/text_extractor.py | 1 +
src/hwpx/tools/validator.py | 1 +
44 files changed, 249 insertions(+), 39 deletions(-)
create mode 100644 NOTICE
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 24e35fc..ed02258 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,19 @@
모든 중요한 변경 사항은 이 문서에 기록됩니다. 형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)과 [Semantic Versioning](https://semver.org/lang/ko/)을 따릅니다.
+## [Unreleased]
+### 추가
+- `src/hwpx/tools/_schemas/owpml/`에 2011 Hancom 네임스페이스용 subset XSD 번들을 추가했습니다 (`header.xsd`, `body.xsd`, `paralist.xsd`, `core.xsd`, `xml.xsd`, `NOTICE`).
+- `hwpx.oxml.load_compound_schema()`와 `SchemaImportError`를 추가해 offline compound XSD 로딩을 지원합니다.
+- fixture matrix 기반 Phase 1 validation 리포트(`shared/hwpx/HWPX_STACK_VALIDATION_2026-04-20_pre-phase1.md`, `..._post-phase1.md`)와 회귀 테스트를 추가했습니다.
+
+### 변경
+- License relicensed to Apache-2.0 (sole author, full consent).
+- Previous license terms no longer apply to future releases.
+- `hwpx-validate`는 이제 기본 strict 모드로 Phase 1 subset schema bundle을 사용합니다. `--no-strict`로 warning-only 분류를 지원합니다.
+- `HwpxDocument.validate()`는 기본 `strict=False`로 동작하며, `validate_on_save_strict` 옵션으로 저장 시 strict 검증을 제어할 수 있습니다.
+- 패키지 배포물(sdist/wheel)에 OWPML subset schema bundle이 포함되도록 package-data를 확장했습니다.
+
## [2.9.0] - 2026-04-02
### 추가
- `HwpxDocument.get_table_map()`, `find_cell_by_label()`, `fill_by_path()`를 추가해 HWPX 양식/템플릿 표를 문서 순서 기반으로 탐색하고 채울 수 있게 했습니다.
diff --git a/LICENSE b/LICENSE
index 2b0382d..bd65bbf 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,32 +1,178 @@
-Non-Commercial License
-
-Copyright (c) 2024 python-hwpx Maintainers
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to use,
-copy, modify, merge, publish, distribute, and sublicense the Software only for
-non-commercial purposes, subject to the following conditions:
-
-1. Non-Commercial Use Only. The Software may be used, copied, modified,
- merged, published, distributed, and sublicensed only for non-commercial
- purposes. "Non-Commercial" means use that is not primarily intended for or
- directed toward commercial advantage, monetary compensation, or any form of
- direct or indirect commercial exploitation.
-
-2. Attribution. The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
-3. No Warranty of Commercial Support. The maintainers are not obligated to
- provide commercial support, maintenance, or updates.
-
-THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-If you require permissions to use this Software for commercial purposes,
-please contact the copyright holders to negotiate an alternative licensing
-arrangement.
+Copyright 2025-2026 airmang (Dr. Wily)
+
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf of
+ any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..d4c9a97
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,14 @@
+python-hwpx
+Copyright 2025-2026 airmang
+
+This product includes software developed by airmang.
+Licensed under the Apache License, Version 2.0.
+
+────────────────────────────────────────
+DISCLAIMER — HWPX Format
+
+"HWPX" is the document format specified and trademarked by
+Hancom Inc. (한글과컴퓨터). This project is an independent,
+unofficial implementation and is not affiliated with, endorsed by,
+or sponsored by Hancom Inc.
+────────────────────────────────────────
diff --git a/README.md b/README.md
index 2f29d61..a85a4c6 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
-
+
@@ -318,10 +318,7 @@ pytest
```
## License
-
-[Custom Non-Commercial License](LICENSE) © python-hwpx Maintainers
-
-Commercial use requires separate permission from the copyright holders.
+Apache License 2.0. See LICENSE and NOTICE.
diff --git a/examples/build_release_checklist.py b/examples/build_release_checklist.py
index 7efc880..3a73b64 100644
--- a/examples/build_release_checklist.py
+++ b/examples/build_release_checklist.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+# SPDX-License-Identifier: Apache-2.0
"""Generate an HWPX document exercising memo and style-editing features."""
from __future__ import annotations
diff --git a/examples/extract_text.py b/examples/extract_text.py
index d168762..488299d 100644
--- a/examples/extract_text.py
+++ b/examples/extract_text.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Simple demonstration of :class:`hwpx.tools.text_extractor.TextExtractor`."""
from __future__ import annotations
diff --git a/examples/find_objects.py b/examples/find_objects.py
index e39940b..8f20ef2 100644
--- a/examples/find_objects.py
+++ b/examples/find_objects.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Use :class:`hwpx.tools.object_finder.ObjectFinder` to locate XML nodes."""
from __future__ import annotations
diff --git a/pyproject.toml b/pyproject.toml
index 4cc34e5..33a4711 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -7,8 +7,8 @@ name = "python-hwpx"
version = "2.9.0"
description = "한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리"
readme = { file = "README.md", content-type = "text/markdown" }
-license = "LicenseRef-python-hwpx-NonCommercial"
-license-files = ["LICENSE"]
+license = "Apache-2.0"
+license-files = ["LICENSE", "NOTICE"]
requires-python = ">=3.10"
authors = [
{ name = "python-hwpx Maintainers" },
@@ -16,6 +16,7 @@ authors = [
keywords = ["hwp", "hwpx", "hancom", "opc", "xml", "document-automation", "validation", "template"]
classifiers = [
"Development Status :: 3 - Alpha",
+ "License :: OSI Approved :: Apache Software License",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
diff --git a/scripts/analyze_template.py b/scripts/analyze_template.py
index c1ccbba..6e5a169 100644
--- a/scripts/analyze_template.py
+++ b/scripts/analyze_template.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
from hwpx.tools.template_analyzer import main
diff --git a/scripts/check_typing_generics_scope.py b/scripts/check_typing_generics_scope.py
index aae1ed8..9fc8541 100644
--- a/scripts/check_typing_generics_scope.py
+++ b/scripts/check_typing_generics_scope.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+# SPDX-License-Identifier: Apache-2.0
"""점진 변환 대상 파일에서 typing 제네릭 별칭 사용을 검사한다."""
from __future__ import annotations
diff --git a/scripts/office/pack.py b/scripts/office/pack.py
index 020986f..ac830cf 100644
--- a/scripts/office/pack.py
+++ b/scripts/office/pack.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
from hwpx.tools.archive_cli import pack_main
diff --git a/scripts/office/unpack.py b/scripts/office/unpack.py
index 2e9f64b..104f38f 100644
--- a/scripts/office/unpack.py
+++ b/scripts/office/unpack.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
from hwpx.tools.archive_cli import unpack_main
diff --git a/src/hwpx/__init__.py b/src/hwpx/__init__.py
index 593d43f..ab08ba7 100644
--- a/src/hwpx/__init__.py
+++ b/src/hwpx/__init__.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""High-level utilities for working with HWPX documents."""
from importlib.metadata import PackageNotFoundError, version as _metadata_version
diff --git a/src/hwpx/document.py b/src/hwpx/document.py
index 38701af..61396c1 100644
--- a/src/hwpx/document.py
+++ b/src/hwpx/document.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""High-level representation of an HWPX document."""
from __future__ import annotations
diff --git a/src/hwpx/opc/package.py b/src/hwpx/opc/package.py
index 90abec8..08dc0b9 100644
--- a/src/hwpx/opc/package.py
+++ b/src/hwpx/opc/package.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Utilities for reading and writing HWPX OPC packages."""
from __future__ import annotations
diff --git a/src/hwpx/opc/relationships.py b/src/hwpx/opc/relationships.py
index d05df36..2ab832b 100644
--- a/src/hwpx/opc/relationships.py
+++ b/src/hwpx/opc/relationships.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Helpers for resolving HWPX container and manifest relationships."""
from __future__ import annotations
diff --git a/src/hwpx/opc/xml_utils.py b/src/hwpx/opc/xml_utils.py
index 56feeec..bcd9097 100644
--- a/src/hwpx/opc/xml_utils.py
+++ b/src/hwpx/opc/xml_utils.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""XML 파싱/직렬화를 위한 OPC 공통 유틸리티."""
from __future__ import annotations
diff --git a/src/hwpx/oxml/__init__.py b/src/hwpx/oxml/__init__.py
index 45a583f..c7f61ed 100644
--- a/src/hwpx/oxml/__init__.py
+++ b/src/hwpx/oxml/__init__.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Open XML helpers for the HWPX document format."""
diff --git a/src/hwpx/oxml/body.py b/src/hwpx/oxml/body.py
index bd4fabe..16af353 100644
--- a/src/hwpx/oxml/body.py
+++ b/src/hwpx/oxml/body.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import logging
diff --git a/src/hwpx/oxml/common.py b/src/hwpx/oxml/common.py
index cb65c16..daf074d 100644
--- a/src/hwpx/oxml/common.py
+++ b/src/hwpx/oxml/common.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import logging
diff --git a/src/hwpx/oxml/document.py b/src/hwpx/oxml/document.py
index af2547f..d9544b2 100644
--- a/src/hwpx/oxml/document.py
+++ b/src/hwpx/oxml/document.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Object model mapping for the XML parts of an HWPX document."""
from __future__ import annotations
diff --git a/src/hwpx/oxml/header.py b/src/hwpx/oxml/header.py
index f0adbc8..7d93e1e 100644
--- a/src/hwpx/oxml/header.py
+++ b/src/hwpx/oxml/header.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import logging
diff --git a/src/hwpx/oxml/header_part.py b/src/hwpx/oxml/header_part.py
index bbce725..37ad875 100644
--- a/src/hwpx/oxml/header_part.py
+++ b/src/hwpx/oxml/header_part.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Header-part OpenXML wrappers."""
from __future__ import annotations
diff --git a/src/hwpx/oxml/memo.py b/src/hwpx/oxml/memo.py
index 556e2d3..dc3e58f 100644
--- a/src/hwpx/oxml/memo.py
+++ b/src/hwpx/oxml/memo.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Memo-related OpenXML wrappers."""
from __future__ import annotations
diff --git a/src/hwpx/oxml/namespaces.py b/src/hwpx/oxml/namespaces.py
index d331abc..5f01087 100644
--- a/src/hwpx/oxml/namespaces.py
+++ b/src/hwpx/oxml/namespaces.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Shared namespace constants for the HWPML/OWPML XML schemas.
All modules that need HWPML namespace URIs should import from here
diff --git a/src/hwpx/oxml/paragraph.py b/src/hwpx/oxml/paragraph.py
index c714859..aaee686 100644
--- a/src/hwpx/oxml/paragraph.py
+++ b/src/hwpx/oxml/paragraph.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Paragraph-related OpenXML wrappers."""
from __future__ import annotations
diff --git a/src/hwpx/oxml/parser.py b/src/hwpx/oxml/parser.py
index 4c51e62..b8e72a2 100644
--- a/src/hwpx/oxml/parser.py
+++ b/src/hwpx/oxml/parser.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import logging
diff --git a/src/hwpx/oxml/schema.py b/src/hwpx/oxml/schema.py
index 5d1f162..98f3e3e 100644
--- a/src/hwpx/oxml/schema.py
+++ b/src/hwpx/oxml/schema.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import logging
diff --git a/src/hwpx/oxml/section.py b/src/hwpx/oxml/section.py
index 12dad5f..d6d94ea 100644
--- a/src/hwpx/oxml/section.py
+++ b/src/hwpx/oxml/section.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Section-related OpenXML wrappers."""
from __future__ import annotations
diff --git a/src/hwpx/oxml/table.py b/src/hwpx/oxml/table.py
index 34a862f..075b189 100644
--- a/src/hwpx/oxml/table.py
+++ b/src/hwpx/oxml/table.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Table-related OpenXML wrappers."""
from __future__ import annotations
diff --git a/src/hwpx/oxml/utils.py b/src/hwpx/oxml/utils.py
index 0ec8952..af86581 100644
--- a/src/hwpx/oxml/utils.py
+++ b/src/hwpx/oxml/utils.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import logging
diff --git a/src/hwpx/package.py b/src/hwpx/package.py
index 9e91cd7..a1e444f 100644
--- a/src/hwpx/package.py
+++ b/src/hwpx/package.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""하위 호환을 위한 패키지 모듈.
신규 코드는 :mod:`hwpx.opc.package` 를 직접 사용하세요.
diff --git a/src/hwpx/templates.py b/src/hwpx/templates.py
index d71cdb8..95387b9 100644
--- a/src/hwpx/templates.py
+++ b/src/hwpx/templates.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Embedded templates and sample payloads for HWPX documents."""
from __future__ import annotations
diff --git a/src/hwpx/tools/__init__.py b/src/hwpx/tools/__init__.py
index 80c329c..216d6cc 100644
--- a/src/hwpx/tools/__init__.py
+++ b/src/hwpx/tools/__init__.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Tooling helpers for inspecting HWPX archives."""
from .exporter import (
diff --git a/src/hwpx/tools/archive_cli.py b/src/hwpx/tools/archive_cli.py
index 12261ad..9947348 100644
--- a/src/hwpx/tools/archive_cli.py
+++ b/src/hwpx/tools/archive_cli.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import argparse
diff --git a/src/hwpx/tools/exporter.py b/src/hwpx/tools/exporter.py
index 31d70b2..bab7f75 100644
--- a/src/hwpx/tools/exporter.py
+++ b/src/hwpx/tools/exporter.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Export HWPX document content to plain text, HTML, and Markdown formats.
All exporters accept either an :class:`~hwpx.document.HwpxDocument` instance
diff --git a/src/hwpx/tools/object_finder.py b/src/hwpx/tools/object_finder.py
index 574848d..6c77a0b 100644
--- a/src/hwpx/tools/object_finder.py
+++ b/src/hwpx/tools/object_finder.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Helper utilities that locate XML objects inside HWPX archives."""
from __future__ import annotations
diff --git a/src/hwpx/tools/package_validator.py b/src/hwpx/tools/package_validator.py
index e340db6..b10d71f 100644
--- a/src/hwpx/tools/package_validator.py
+++ b/src/hwpx/tools/package_validator.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import argparse
diff --git a/src/hwpx/tools/page_guard.py b/src/hwpx/tools/page_guard.py
index f76eaac..596a253 100644
--- a/src/hwpx/tools/page_guard.py
+++ b/src/hwpx/tools/page_guard.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Proxy checks for layout drift between a reference and an output HWPX.
This module does not calculate rendered page counts. It compares structural and
diff --git a/src/hwpx/tools/table_navigation.py b/src/hwpx/tools/table_navigation.py
index 681d4d9..7dbd91d 100644
--- a/src/hwpx/tools/table_navigation.py
+++ b/src/hwpx/tools/table_navigation.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""Reusable helpers for HWPX table discovery and form-like navigation."""
from __future__ import annotations
diff --git a/src/hwpx/tools/template_analyzer.py b/src/hwpx/tools/template_analyzer.py
index 8e76701..254f660 100644
--- a/src/hwpx/tools/template_analyzer.py
+++ b/src/hwpx/tools/template_analyzer.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import argparse
diff --git a/src/hwpx/tools/text_extract_cli.py b/src/hwpx/tools/text_extract_cli.py
index 13c5c45..0a48211 100644
--- a/src/hwpx/tools/text_extract_cli.py
+++ b/src/hwpx/tools/text_extract_cli.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import argparse
diff --git a/src/hwpx/tools/text_extractor.py b/src/hwpx/tools/text_extractor.py
index 8034361..3b46fa9 100644
--- a/src/hwpx/tools/text_extractor.py
+++ b/src/hwpx/tools/text_extractor.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
"""High-level routines for traversing text inside HWPX documents."""
from __future__ import annotations
diff --git a/src/hwpx/tools/validator.py b/src/hwpx/tools/validator.py
index 94024e6..19ca09f 100644
--- a/src/hwpx/tools/validator.py
+++ b/src/hwpx/tools/validator.py
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: Apache-2.0
from __future__ import annotations
import argparse