python-hwpx 1.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.
- python-hwpx-1.0/LICENSE +32 -0
- python-hwpx-1.0/PKG-INFO +199 -0
- python-hwpx-1.0/README.md +169 -0
- python-hwpx-1.0/pyproject.toml +64 -0
- python-hwpx-1.0/setup.cfg +4 -0
- python-hwpx-1.0/src/hwpx/__init__.py +23 -0
- python-hwpx-1.0/src/hwpx/document.py +518 -0
- python-hwpx-1.0/src/hwpx/opc/package.py +274 -0
- python-hwpx-1.0/src/hwpx/oxml/__init__.py +138 -0
- python-hwpx-1.0/src/hwpx/oxml/body.py +151 -0
- python-hwpx-1.0/src/hwpx/oxml/common.py +31 -0
- python-hwpx-1.0/src/hwpx/oxml/document.py +1932 -0
- python-hwpx-1.0/src/hwpx/oxml/header.py +543 -0
- python-hwpx-1.0/src/hwpx/oxml/parser.py +62 -0
- python-hwpx-1.0/src/hwpx/oxml/schema.py +41 -0
- python-hwpx-1.0/src/hwpx/oxml/utils.py +82 -0
- python-hwpx-1.0/src/hwpx/package.py +202 -0
- python-hwpx-1.0/src/hwpx/tools/__init__.py +36 -0
- python-hwpx-1.0/src/hwpx/tools/_schemas/header.xsd +14 -0
- python-hwpx-1.0/src/hwpx/tools/_schemas/section.xsd +12 -0
- python-hwpx-1.0/src/hwpx/tools/object_finder.py +347 -0
- python-hwpx-1.0/src/hwpx/tools/text_extractor.py +726 -0
- python-hwpx-1.0/src/hwpx/tools/validator.py +184 -0
- python-hwpx-1.0/src/python_hwpx.egg-info/PKG-INFO +199 -0
- python-hwpx-1.0/src/python_hwpx.egg-info/SOURCES.txt +32 -0
- python-hwpx-1.0/src/python_hwpx.egg-info/dependency_links.txt +1 -0
- python-hwpx-1.0/src/python_hwpx.egg-info/entry_points.txt +2 -0
- python-hwpx-1.0/src/python_hwpx.egg-info/requires.txt +9 -0
- python-hwpx-1.0/src/python_hwpx.egg-info/top_level.txt +1 -0
- python-hwpx-1.0/tests/test_document_formatting.py +405 -0
- python-hwpx-1.0/tests/test_integration_hwpx_compatibility.py +139 -0
- python-hwpx-1.0/tests/test_memo_and_style_editing.py +238 -0
- python-hwpx-1.0/tests/test_oxml_parsing.py +159 -0
- python-hwpx-1.0/tests/test_text_extractor_annotations.py +126 -0
python-hwpx-1.0/LICENSE
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Non-Commercial License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 python-hwpx Maintainers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to use,
|
|
7
|
+
copy, modify, merge, publish, distribute, and sublicense the Software only for
|
|
8
|
+
non-commercial purposes, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
1. Non-Commercial Use Only. The Software may be used, copied, modified,
|
|
11
|
+
merged, published, distributed, and sublicensed only for non-commercial
|
|
12
|
+
purposes. "Non-Commercial" means use that is not primarily intended for or
|
|
13
|
+
directed toward commercial advantage, monetary compensation, or any form of
|
|
14
|
+
direct or indirect commercial exploitation.
|
|
15
|
+
|
|
16
|
+
2. Attribution. The above copyright notice and this permission notice shall be
|
|
17
|
+
included in all copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
3. No Warranty of Commercial Support. The maintainers are not obligated to
|
|
20
|
+
provide commercial support, maintenance, or updates.
|
|
21
|
+
|
|
22
|
+
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
|
|
30
|
+
If you require permissions to use this Software for commercial purposes,
|
|
31
|
+
please contact the copyright holders to negotiate an alternative licensing
|
|
32
|
+
arrangement.
|
python-hwpx-1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: python-hwpx
|
|
3
|
+
Version: 1.0
|
|
4
|
+
Summary: Hancom HWPX 패키지를 로드하고 편집하기 위한 Python 유틸리티 모음
|
|
5
|
+
Author: python-hwpx Maintainers
|
|
6
|
+
License: Non-Commercial License
|
|
7
|
+
Project-URL: Homepage, https://github.com/hancom-io/python-hwpx
|
|
8
|
+
Project-URL: Documentation, https://github.com/hancom-io/python-hwpx/tree/main/docs
|
|
9
|
+
Project-URL: Issues, https://github.com/hancom-io/python-hwpx/issues
|
|
10
|
+
Keywords: hwp,hwpx,hancom,opc,xml
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Classifier: Topic :: Text Processing :: Markup :: XML
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: lxml<6,>=4.9
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
26
|
+
Requires-Dist: twine>=4.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest>=7.4; extra == "dev"
|
|
28
|
+
Provides-Extra: test
|
|
29
|
+
Requires-Dist: pytest>=7.4; extra == "test"
|
|
30
|
+
|
|
31
|
+
# python-hwpx
|
|
32
|
+
|
|
33
|
+
python-hwpx는 Hancom HWPX 패키지를 분석하고 편집하기 위한 Python 유틸리티 모음입니다. Open Packaging Convention(OPC) 컨테이너를 검증하고, 문단/섹션 조작을 위한 고수준 래퍼와 텍스트 추출 도구를 함께 제공합니다.
|
|
34
|
+
|
|
35
|
+
## 주요 기능
|
|
36
|
+
|
|
37
|
+
- **패키지 검사 및 로딩** – `hwpx.opc.package.HwpxPackage`는 `mimetype`, `META-INF/container.xml`, `version.xml`을 확인하면서 루트 파일과 매니페스트를 메모리에 적재합니다.
|
|
38
|
+
- **문서 편집 API** – `hwpx.document.HwpxDocument`는 문단 추가, 표/개체/컨트롤 삽입, 섹션·헤더 속성 업데이트 등 편집 기능을 제공합니다.
|
|
39
|
+
- **메모 CRUD와 필드 앵커** – 섹션의 `<hp:memogroup>`와 헤더의 `memoProperties`를 연결해 메모를 관리하고, 본문에 MEMO 필드 컨트롤을 삽입해 편집기에서 풍선 메모가 표시되도록 할 수 있습니다.
|
|
40
|
+
- **스타일 기반 텍스트 변환** – 런의 문자 서식을 분석해 특정 색상/밑줄을 가진 텍스트만 찾아 치환하거나 삭제할 수 있습니다.
|
|
41
|
+
- **텍스트 추출 파이프라인** – `hwpx.tools.text_extractor.TextExtractor`는 하이라이트/각주/컨트롤 표시 방식을 세밀하게 제어하면서 문단 텍스트를 추출합니다.
|
|
42
|
+
- **객체 검색 유틸리티** – `hwpx.tools.object_finder.ObjectFinder`는 XPath, 속성 매칭, 주석 종류 필터를 활용해 원하는 XML 요소를 찾습니다.
|
|
43
|
+
|
|
44
|
+
## 빠른 시작
|
|
45
|
+
|
|
46
|
+
### 1. 환경 준비
|
|
47
|
+
|
|
48
|
+
가상 환경을 만든 뒤 PyPI에 배포된 패키지를 설치하세요.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
python -m venv .venv
|
|
52
|
+
source .venv/bin/activate
|
|
53
|
+
python -m pip install --upgrade pip
|
|
54
|
+
python -m pip install python-hwpx
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
최신 개발 버전을 사용하거나 소스 코드를 수정하려면 편집 가능한 설치를 권장합니다.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
python -m pip install -e .[dev]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
설치와 환경 구성에 관한 더 자세한 내용은 [설치 가이드](docs/installation.md)를 참고하세요.
|
|
64
|
+
|
|
65
|
+
### 2. 패키지 구조 살펴보기
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from hwpx.opc.package import HwpxPackage
|
|
69
|
+
|
|
70
|
+
package = HwpxPackage.open("sample.hwpx")
|
|
71
|
+
print("MIME type:", package.mimetype)
|
|
72
|
+
|
|
73
|
+
for rootfile in package.iter_rootfiles():
|
|
74
|
+
print(f"{rootfile.full_path} ({rootfile.media_type})")
|
|
75
|
+
|
|
76
|
+
main = package.main_content
|
|
77
|
+
print("Main content located at:", main.full_path)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 3. 문서 편집하기
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from hwpx.document import HwpxDocument
|
|
84
|
+
|
|
85
|
+
document = HwpxDocument.open("sample.hwpx")
|
|
86
|
+
section = document.sections[0]
|
|
87
|
+
|
|
88
|
+
headline = document.add_paragraph(
|
|
89
|
+
"새 소식",
|
|
90
|
+
section=section,
|
|
91
|
+
style_id_ref=1,
|
|
92
|
+
char_pr_id_ref=6,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
table = document.add_table(
|
|
96
|
+
rows=2,
|
|
97
|
+
cols=3,
|
|
98
|
+
section=section,
|
|
99
|
+
border_fill_id_ref="3",
|
|
100
|
+
)
|
|
101
|
+
table.set_cell_text(0, 0, "Quarter")
|
|
102
|
+
table.set_cell_text(0, 1, "Results")
|
|
103
|
+
table.set_cell_text(0, 2, "Forecast")
|
|
104
|
+
table.merge_cells(0, 0, 0, 2)
|
|
105
|
+
table.cell(1, 0).text = "Q1"
|
|
106
|
+
|
|
107
|
+
header = document.headers[0]
|
|
108
|
+
header.set_begin_numbering(page=1)
|
|
109
|
+
|
|
110
|
+
document.save("sample-updated.hwpx")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 4. 메모 필드 연결과 스타일 치환
|
|
114
|
+
|
|
115
|
+
한글 편집기에서 메모가 보이려면 본문 문단에 MEMO 필드 컨트롤이 존재해야 합니다. 아래 예제는 새 메모를 추가한 뒤, 해당 문단 앞뒤에 `fieldBegin`/`fieldEnd`를 삽입합니다. 고유 식별자는 프로젝트 상황에 맞게 생성하세요.
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
section = document.sections[0]
|
|
119
|
+
todo = document.add_paragraph(
|
|
120
|
+
"TODO: 통합 테스트 결과",
|
|
121
|
+
section=section,
|
|
122
|
+
char_pr_id_ref=10,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
document.add_memo_with_anchor(
|
|
126
|
+
"테스트 시나리오를 12월 2일까지 업데이트하세요.",
|
|
127
|
+
paragraph=todo,
|
|
128
|
+
memo_shape_id_ref="0",
|
|
129
|
+
memo_id="release-memo-1",
|
|
130
|
+
char_pr_id_ref="10",
|
|
131
|
+
attributes={"author": "QA"},
|
|
132
|
+
anchor_char_pr_id_ref="10",
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
document.replace_text_in_runs("TODO", "DONE", text_color="#C00000")
|
|
136
|
+
|
|
137
|
+
document.save("sample-memo.hwpx")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`examples/build_release_checklist.py`는 동일한 패턴으로 QA용 점검 문서를 생성하므로, 메모 핸들링을 자동화하고 싶다면 참고하세요.
|
|
141
|
+
|
|
142
|
+
### 5. 텍스트 추출 및 주석 처리
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from hwpx.tools.text_extractor import AnnotationOptions, TextExtractor
|
|
146
|
+
|
|
147
|
+
options = AnnotationOptions(
|
|
148
|
+
highlight="markers",
|
|
149
|
+
hyperlink="target",
|
|
150
|
+
control="placeholder",
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
with TextExtractor("sample.hwpx") as extractor:
|
|
154
|
+
for paragraph in extractor.iter_document_paragraphs():
|
|
155
|
+
text = paragraph.text(annotations=options)
|
|
156
|
+
if text.strip():
|
|
157
|
+
print(text)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
주요 사용 패턴과 추가적인 매개변수는 [사용 가이드](docs/usage.md)에서 더 자세히 확인할 수 있습니다.
|
|
161
|
+
|
|
162
|
+
## 알려진 제약
|
|
163
|
+
- 머리말/꼬리말 편집 시 `<hp:headerApply>`와 마스터 페이지 연결을 아직 구현하지 않아, `set_header_text()`로 작성한 내용이 한글 편집기에는 표시되지 않습니다.
|
|
164
|
+
- `add_shape()`/`add_control()`은 필수 하위 노드를 생성하지 않으므로, 새 도형이나 컨트롤을 추가한 문서는 한글 편집기에서 열리지 않거나 예기치 않게 종료될 수 있습니다.
|
|
165
|
+
- 메모와 스타일 기반 텍스트 치환 기능은 단일 `<hp:t>`로 구성된 단순 런에 최적화되어 있으며, 마크업이 중첩된 복합 텍스트 스팬에서는 동작이 제한될 수 있습니다. 메모를 본문에 노출하려면 반드시 대응되는 MEMO 필드 컨트롤을 삽입해야 합니다.
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
## 문서
|
|
170
|
+
|
|
171
|
+
- [설치 가이드](docs/installation.md)
|
|
172
|
+
- [사용 가이드](docs/usage.md)
|
|
173
|
+
- [실전 예제](docs/examples.md)
|
|
174
|
+
- [자주 묻는 질문](docs/faq.md)
|
|
175
|
+
- [HWPX 스키마 구조와 파이썬 모델 현황](docs/schema-overview.md)
|
|
176
|
+
- [릴리스 가이드](docs/release.md)
|
|
177
|
+
|
|
178
|
+
## 예제 스크립트
|
|
179
|
+
|
|
180
|
+
`examples/` 디렉터리에는 다음과 같은 샘플이 포함되어 있습니다.
|
|
181
|
+
|
|
182
|
+
- `extract_text.py` – `TextExtractor`를 이용한 문단 텍스트 추출.
|
|
183
|
+
- `find_objects.py` – `ObjectFinder`로 특정 요소와 주석 검색.
|
|
184
|
+
- `build_release_checklist.py` – 메모 필드 앵커와 스타일 치환을 포함한 QA용 HWPX 생성 스크립트.
|
|
185
|
+
- `FormattingShowcase.hwpx` – 각종 서식과 개체가 포함된 샘플 문서.
|
|
186
|
+
|
|
187
|
+
## 추가 자료
|
|
188
|
+
|
|
189
|
+
- [DevDoc/OWPML 스키마 구성.md](DevDoc/OWPML%20%EC%8A%A4%ED%82%A4%EB%A7%88%20%EA%B5%AC%EC%84%B1.md) – HWPX 문서에서 사용되는 OWPML 요소를 자세히 다룹니다.
|
|
190
|
+
- [DevDoc/컨테이너 패키징.md](DevDoc/%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%20%ED%8C%A8%ED%82%A4%EC%A7%95.md) – HWPX OPC 아카이브 구성 규칙과 관례를 정리했습니다.
|
|
191
|
+
- [hancom-io/hwpx-owpml-model](https://github.com/hancom-io/hwpx-owpml-model) – 스키마 동작을 참조하기 위한 공식 C++ 기반 OWPML 모델 구현입니다.
|
|
192
|
+
- [neolord0/hwpxlib](https://github.com/neolord0/hwpxlib) – HWPX 문서를 읽고 쓰기 위한 레퍼런스 Java 라이브러리입니다.
|
|
193
|
+
|
|
194
|
+
## 기여하기
|
|
195
|
+
|
|
196
|
+
버그 리포트와 패치 제안은 언제나 환영합니다. 개발 환경 설정과 테스트 방법은 [CONTRIBUTING.md](CONTRIBUTING.md)를 참고하세요.
|
|
197
|
+
|
|
198
|
+
## 연락처
|
|
199
|
+
- kokyuhyun@hotmail.com
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# python-hwpx
|
|
2
|
+
|
|
3
|
+
python-hwpx는 Hancom HWPX 패키지를 분석하고 편집하기 위한 Python 유틸리티 모음입니다. Open Packaging Convention(OPC) 컨테이너를 검증하고, 문단/섹션 조작을 위한 고수준 래퍼와 텍스트 추출 도구를 함께 제공합니다.
|
|
4
|
+
|
|
5
|
+
## 주요 기능
|
|
6
|
+
|
|
7
|
+
- **패키지 검사 및 로딩** – `hwpx.opc.package.HwpxPackage`는 `mimetype`, `META-INF/container.xml`, `version.xml`을 확인하면서 루트 파일과 매니페스트를 메모리에 적재합니다.
|
|
8
|
+
- **문서 편집 API** – `hwpx.document.HwpxDocument`는 문단 추가, 표/개체/컨트롤 삽입, 섹션·헤더 속성 업데이트 등 편집 기능을 제공합니다.
|
|
9
|
+
- **메모 CRUD와 필드 앵커** – 섹션의 `<hp:memogroup>`와 헤더의 `memoProperties`를 연결해 메모를 관리하고, 본문에 MEMO 필드 컨트롤을 삽입해 편집기에서 풍선 메모가 표시되도록 할 수 있습니다.
|
|
10
|
+
- **스타일 기반 텍스트 변환** – 런의 문자 서식을 분석해 특정 색상/밑줄을 가진 텍스트만 찾아 치환하거나 삭제할 수 있습니다.
|
|
11
|
+
- **텍스트 추출 파이프라인** – `hwpx.tools.text_extractor.TextExtractor`는 하이라이트/각주/컨트롤 표시 방식을 세밀하게 제어하면서 문단 텍스트를 추출합니다.
|
|
12
|
+
- **객체 검색 유틸리티** – `hwpx.tools.object_finder.ObjectFinder`는 XPath, 속성 매칭, 주석 종류 필터를 활용해 원하는 XML 요소를 찾습니다.
|
|
13
|
+
|
|
14
|
+
## 빠른 시작
|
|
15
|
+
|
|
16
|
+
### 1. 환경 준비
|
|
17
|
+
|
|
18
|
+
가상 환경을 만든 뒤 PyPI에 배포된 패키지를 설치하세요.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
python -m venv .venv
|
|
22
|
+
source .venv/bin/activate
|
|
23
|
+
python -m pip install --upgrade pip
|
|
24
|
+
python -m pip install python-hwpx
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
최신 개발 버전을 사용하거나 소스 코드를 수정하려면 편집 가능한 설치를 권장합니다.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
python -m pip install -e .[dev]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
설치와 환경 구성에 관한 더 자세한 내용은 [설치 가이드](docs/installation.md)를 참고하세요.
|
|
34
|
+
|
|
35
|
+
### 2. 패키지 구조 살펴보기
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from hwpx.opc.package import HwpxPackage
|
|
39
|
+
|
|
40
|
+
package = HwpxPackage.open("sample.hwpx")
|
|
41
|
+
print("MIME type:", package.mimetype)
|
|
42
|
+
|
|
43
|
+
for rootfile in package.iter_rootfiles():
|
|
44
|
+
print(f"{rootfile.full_path} ({rootfile.media_type})")
|
|
45
|
+
|
|
46
|
+
main = package.main_content
|
|
47
|
+
print("Main content located at:", main.full_path)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 3. 문서 편집하기
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from hwpx.document import HwpxDocument
|
|
54
|
+
|
|
55
|
+
document = HwpxDocument.open("sample.hwpx")
|
|
56
|
+
section = document.sections[0]
|
|
57
|
+
|
|
58
|
+
headline = document.add_paragraph(
|
|
59
|
+
"새 소식",
|
|
60
|
+
section=section,
|
|
61
|
+
style_id_ref=1,
|
|
62
|
+
char_pr_id_ref=6,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
table = document.add_table(
|
|
66
|
+
rows=2,
|
|
67
|
+
cols=3,
|
|
68
|
+
section=section,
|
|
69
|
+
border_fill_id_ref="3",
|
|
70
|
+
)
|
|
71
|
+
table.set_cell_text(0, 0, "Quarter")
|
|
72
|
+
table.set_cell_text(0, 1, "Results")
|
|
73
|
+
table.set_cell_text(0, 2, "Forecast")
|
|
74
|
+
table.merge_cells(0, 0, 0, 2)
|
|
75
|
+
table.cell(1, 0).text = "Q1"
|
|
76
|
+
|
|
77
|
+
header = document.headers[0]
|
|
78
|
+
header.set_begin_numbering(page=1)
|
|
79
|
+
|
|
80
|
+
document.save("sample-updated.hwpx")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 4. 메모 필드 연결과 스타일 치환
|
|
84
|
+
|
|
85
|
+
한글 편집기에서 메모가 보이려면 본문 문단에 MEMO 필드 컨트롤이 존재해야 합니다. 아래 예제는 새 메모를 추가한 뒤, 해당 문단 앞뒤에 `fieldBegin`/`fieldEnd`를 삽입합니다. 고유 식별자는 프로젝트 상황에 맞게 생성하세요.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
section = document.sections[0]
|
|
89
|
+
todo = document.add_paragraph(
|
|
90
|
+
"TODO: 통합 테스트 결과",
|
|
91
|
+
section=section,
|
|
92
|
+
char_pr_id_ref=10,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
document.add_memo_with_anchor(
|
|
96
|
+
"테스트 시나리오를 12월 2일까지 업데이트하세요.",
|
|
97
|
+
paragraph=todo,
|
|
98
|
+
memo_shape_id_ref="0",
|
|
99
|
+
memo_id="release-memo-1",
|
|
100
|
+
char_pr_id_ref="10",
|
|
101
|
+
attributes={"author": "QA"},
|
|
102
|
+
anchor_char_pr_id_ref="10",
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
document.replace_text_in_runs("TODO", "DONE", text_color="#C00000")
|
|
106
|
+
|
|
107
|
+
document.save("sample-memo.hwpx")
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`examples/build_release_checklist.py`는 동일한 패턴으로 QA용 점검 문서를 생성하므로, 메모 핸들링을 자동화하고 싶다면 참고하세요.
|
|
111
|
+
|
|
112
|
+
### 5. 텍스트 추출 및 주석 처리
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from hwpx.tools.text_extractor import AnnotationOptions, TextExtractor
|
|
116
|
+
|
|
117
|
+
options = AnnotationOptions(
|
|
118
|
+
highlight="markers",
|
|
119
|
+
hyperlink="target",
|
|
120
|
+
control="placeholder",
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
with TextExtractor("sample.hwpx") as extractor:
|
|
124
|
+
for paragraph in extractor.iter_document_paragraphs():
|
|
125
|
+
text = paragraph.text(annotations=options)
|
|
126
|
+
if text.strip():
|
|
127
|
+
print(text)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
주요 사용 패턴과 추가적인 매개변수는 [사용 가이드](docs/usage.md)에서 더 자세히 확인할 수 있습니다.
|
|
131
|
+
|
|
132
|
+
## 알려진 제약
|
|
133
|
+
- 머리말/꼬리말 편집 시 `<hp:headerApply>`와 마스터 페이지 연결을 아직 구현하지 않아, `set_header_text()`로 작성한 내용이 한글 편집기에는 표시되지 않습니다.
|
|
134
|
+
- `add_shape()`/`add_control()`은 필수 하위 노드를 생성하지 않으므로, 새 도형이나 컨트롤을 추가한 문서는 한글 편집기에서 열리지 않거나 예기치 않게 종료될 수 있습니다.
|
|
135
|
+
- 메모와 스타일 기반 텍스트 치환 기능은 단일 `<hp:t>`로 구성된 단순 런에 최적화되어 있으며, 마크업이 중첩된 복합 텍스트 스팬에서는 동작이 제한될 수 있습니다. 메모를 본문에 노출하려면 반드시 대응되는 MEMO 필드 컨트롤을 삽입해야 합니다.
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
## 문서
|
|
140
|
+
|
|
141
|
+
- [설치 가이드](docs/installation.md)
|
|
142
|
+
- [사용 가이드](docs/usage.md)
|
|
143
|
+
- [실전 예제](docs/examples.md)
|
|
144
|
+
- [자주 묻는 질문](docs/faq.md)
|
|
145
|
+
- [HWPX 스키마 구조와 파이썬 모델 현황](docs/schema-overview.md)
|
|
146
|
+
- [릴리스 가이드](docs/release.md)
|
|
147
|
+
|
|
148
|
+
## 예제 스크립트
|
|
149
|
+
|
|
150
|
+
`examples/` 디렉터리에는 다음과 같은 샘플이 포함되어 있습니다.
|
|
151
|
+
|
|
152
|
+
- `extract_text.py` – `TextExtractor`를 이용한 문단 텍스트 추출.
|
|
153
|
+
- `find_objects.py` – `ObjectFinder`로 특정 요소와 주석 검색.
|
|
154
|
+
- `build_release_checklist.py` – 메모 필드 앵커와 스타일 치환을 포함한 QA용 HWPX 생성 스크립트.
|
|
155
|
+
- `FormattingShowcase.hwpx` – 각종 서식과 개체가 포함된 샘플 문서.
|
|
156
|
+
|
|
157
|
+
## 추가 자료
|
|
158
|
+
|
|
159
|
+
- [DevDoc/OWPML 스키마 구성.md](DevDoc/OWPML%20%EC%8A%A4%ED%82%A4%EB%A7%88%20%EA%B5%AC%EC%84%B1.md) – HWPX 문서에서 사용되는 OWPML 요소를 자세히 다룹니다.
|
|
160
|
+
- [DevDoc/컨테이너 패키징.md](DevDoc/%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%20%ED%8C%A8%ED%82%A4%EC%A7%95.md) – HWPX OPC 아카이브 구성 규칙과 관례를 정리했습니다.
|
|
161
|
+
- [hancom-io/hwpx-owpml-model](https://github.com/hancom-io/hwpx-owpml-model) – 스키마 동작을 참조하기 위한 공식 C++ 기반 OWPML 모델 구현입니다.
|
|
162
|
+
- [neolord0/hwpxlib](https://github.com/neolord0/hwpxlib) – HWPX 문서를 읽고 쓰기 위한 레퍼런스 Java 라이브러리입니다.
|
|
163
|
+
|
|
164
|
+
## 기여하기
|
|
165
|
+
|
|
166
|
+
버그 리포트와 패치 제안은 언제나 환영합니다. 개발 환경 설정과 테스트 방법은 [CONTRIBUTING.md](CONTRIBUTING.md)를 참고하세요.
|
|
167
|
+
|
|
168
|
+
## 연락처
|
|
169
|
+
- kokyuhyun@hotmail.com
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools<69", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "python-hwpx"
|
|
7
|
+
version = "1.0"
|
|
8
|
+
description = "Hancom HWPX 패키지를 로드하고 편집하기 위한 Python 유틸리티 모음"
|
|
9
|
+
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
|
+
license = { text = "Non-Commercial License" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "python-hwpx Maintainers" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["hwp", "hwpx", "hancom", "opc", "xml"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 3 - Alpha",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Topic :: Software Development :: Libraries",
|
|
25
|
+
"Topic :: Text Processing :: Markup :: XML",
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"lxml>=4.9,<6",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.optional-dependencies]
|
|
32
|
+
dev = [
|
|
33
|
+
"build>=1.0",
|
|
34
|
+
"twine>=4.0",
|
|
35
|
+
"pytest>=7.4",
|
|
36
|
+
]
|
|
37
|
+
test = [
|
|
38
|
+
"pytest>=7.4",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[project.urls]
|
|
42
|
+
Homepage = "https://github.com/hancom-io/python-hwpx"
|
|
43
|
+
Documentation = "https://github.com/hancom-io/python-hwpx/tree/main/docs"
|
|
44
|
+
Issues = "https://github.com/hancom-io/python-hwpx/issues"
|
|
45
|
+
|
|
46
|
+
[project.scripts]
|
|
47
|
+
hwpx-validate = "hwpx.tools.validator:main"
|
|
48
|
+
|
|
49
|
+
[tool.setuptools]
|
|
50
|
+
package-dir = { "" = "src" }
|
|
51
|
+
include-package-data = true
|
|
52
|
+
license-files = ["LICENSE"]
|
|
53
|
+
|
|
54
|
+
[tool.setuptools.packages.find]
|
|
55
|
+
where = ["src"]
|
|
56
|
+
include = ["hwpx*"]
|
|
57
|
+
|
|
58
|
+
[tool.setuptools.package-data]
|
|
59
|
+
"hwpx.tools" = ["_schemas/*.xsd"]
|
|
60
|
+
|
|
61
|
+
[tool.pytest.ini_options]
|
|
62
|
+
pythonpath = ["src"]
|
|
63
|
+
addopts = "-ra"
|
|
64
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
"""High-level utilities for working with HWPX documents."""
|
|
3
|
+
|
|
4
|
+
__version__ = "0.1.0"
|
|
5
|
+
|
|
6
|
+
from .tools.text_extractor import (
|
|
7
|
+
DEFAULT_NAMESPACES,
|
|
8
|
+
ParagraphInfo,
|
|
9
|
+
SectionInfo,
|
|
10
|
+
TextExtractor,
|
|
11
|
+
)
|
|
12
|
+
from .tools.object_finder import FoundElement, ObjectFinder
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"__version__",
|
|
16
|
+
"DEFAULT_NAMESPACES",
|
|
17
|
+
"ParagraphInfo",
|
|
18
|
+
"SectionInfo",
|
|
19
|
+
"TextExtractor",
|
|
20
|
+
"FoundElement",
|
|
21
|
+
"ObjectFinder",
|
|
22
|
+
]
|
|
23
|
+
|