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 @@

PyPI Python - License: Custom Non-Commercial + License Docs

@@ -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