Skip to main content

Round-trip safe HWPX reader/editor/writer for Python

Project description

jakal-hwpx

jakal-hwpx는 ZIP 기반 HWPX 문서를 열고, 수정하고, 검증하고, 다시 저장하기 위한 Python 라이브러리입니다.

저장소 구성

  • src/jakal_hwpx: 패키지 소스 코드
  • tests: 테스트 코드
  • examples/samples/hwpx: 고정 테스트 fixture로 쓰는 HWPX 샘플
  • examples/output_smoke: 소규모 smoke corpus
  • examples/output: showcase 생성 결과물

요구 사항

  • Python 3.11 이상
  • Git LFS 불필요

설치

PyPI에서 설치:

python -m pip install --upgrade pip
python -m pip install jakal-hwpx

로컬 체크아웃에서 설치:

python -m pip install --upgrade pip
python -m pip install .

개발 모드 설치:

python -m pip install -e .[dev]

샘플 .hwp/.hwpx 문서는 저장소에 일반 Git blob으로 포함되어 있으므로 클론 후 별도 git lfs install 또는 git lfs pull 단계가 필요하지 않습니다.

  • 패키지 이름: jakal-hwpx
  • import 경로: jakal_hwpx

빠른 시작

from jakal_hwpx import HwpxDocument

doc = HwpxDocument.blank()
doc.set_metadata(title="예제", creator="jakal-hwpx")
doc.set_paragraph_text(0, 0, "Hello HWPX")
doc.save("build/hello.hwpx")

이 패키지는 ZIP 기반 HWPX 패키지를 주 대상으로 동작합니다. .hwp -> .hwpx 변환기는 여전히 번들하지 않습니다.

실험적 저수준 .hwp 지원도 포함합니다. HwpBinaryDocument는 Compound File 기반 legacy HWP 문서에서 FileHeader, DocInfo, BodyText/Section*, PrvText를 읽고, 기존 스트림 크기를 보존하는 범위에서 미리보기 텍스트와 본문 텍스트의 same-length 치환을 저장할 수 있습니다.

객체 기반 실험 API인 HwpDocument도 포함합니다. 이 레이어는 HwpSection, HwpParagraphObject를 통해 .hwp 문서를 HwpxDocument와 비슷한 방식으로 다루도록 맞춘 래퍼입니다. Windows에서 한컴오피스 자동화가 가능한 환경이라면 내부적으로 .hwp -> .hwpx -> HwpxDocument 브리지를 사용해 tables(), pictures(), append_paragraph(), append_table() 같은 고수준 API도 그대로 위임할 수 있습니다.

Windows + Hancom automation 없이도 pure-python 실험 경로를 추가했습니다. build_hwp_pure_profile()hwp_collection/에서 table + picture + hyperlink가 함께 있는 donor를 골라 base.hwp + feature templates를 추출하고, HwpDocument.blank_from_profile()은 그 profile만으로 append_table_pure(), append_picture_pure(), append_hyperlink_pure()를 수행합니다. 기본 bundled profile도 패키지에 포함되므로, donor나 profile 경로를 따로 넘기지 않아도 HwpDocument.blank()append_*_pure()를 바로 사용할 수 있습니다.

from jakal_hwpx import HwpBinaryDocument, HwpDocument

binary_doc = HwpBinaryDocument.open("input.hwp")
print(binary_doc.file_header().version)
print(binary_doc.preview_text())

doc = HwpDocument.open("input.hwp")
paragraph = next(p for p in doc.section(0).paragraphs() if "2027" in p.text)
paragraph.replace_text_same_length("2027", "2028", count=1)
doc.save("build/edited.hwp")

# Hancom automation is available:
doc = HwpDocument.open("input.hwp")
doc.append_paragraph("Bridge paragraph")
doc.append_hyperlink("https://example.com", display_text="Example")
doc.save("build/edited_via_bridge.hwp")

# Pure-python experimental path:
from jakal_hwpx import HwpDocument, build_hwp_pure_profile

profile = build_hwp_pure_profile("hwp_collection", "build/hwp_pure_profile")
doc = HwpDocument.blank_from_profile(profile.root)
doc.append_table_pure()
doc.append_picture_pure()
doc.append_hyperlink_pure()
doc.save("build/pure_profile_output.hwp")

# Bundled profile path:
doc = HwpDocument.blank()
doc.append_table_pure()
doc.append_picture_pure()
doc.append_hyperlink_pure()
doc.save("build/bundled_pure_output.hwp")

주요 API

대부분의 사용은 HwpxDocument에서 시작합니다.

  • HwpxDocument.open(path): 기존 HWPX 파일 열기
  • HwpxDocument.blank(): 최소 구성의 새 문서 만들기
  • metadata() / set_metadata(): 문서 메타데이터 조회 및 수정
  • get_document_text(): 본문 텍스트 추출
    • 주의: 이 출력은 검색/미리보기용 평탄화 텍스트이며, 편집 대상 문단 인덱스와 1:1로 대응하지 않습니다.
  • set_paragraph_text(): 특정 문단 텍스트 교체
  • append_paragraph(): 문단 추가
  • replace_text(): 문서 전체 텍스트 치환
  • section_settings(): 페이지 설정 조회 및 수정
  • tables(), pictures(), notes(), fields(): 구조화된 요소 접근
  • validation_errors(): 문서 구조 검증
  • save(path): 파일 저장
    • append_row() now fails fast when the template row contains preserved controls such as bookmarks or fields.
    • append_paragraph(..., template_index=...) now fails fast when the selected template paragraph contains preserved controls.
    • validate=True 기본값은 제어문 보존 검사까지 포함합니다. 실패 시 예외 메시지에 섹션 경로와 누락된 제어문 종류가 함께 표시됩니다.

자주 쓰는 helper 타입:

  • SectionSettings
  • Table, TableCell
  • HeaderFooterBlock
  • Bookmark, Field, Note, Equation, ShapeObject

패키지 구조와 타입 설명은 HWPX_MODULE.md를 참고하세요.

공개 API 계약

공식 지원하는 공개 API는 src/jakal_hwpx/__init__.py에서 다시 export하는 top-level jakal_hwpx import 표면입니다.

안정적으로 지원하는 진입점:

  • HwpxDocument, DocumentMetadata
  • Table, TableCell, Picture, Note, Equation, Bookmark, Field, AutoNumber
  • HeaderFooterBlock, SectionSettings, StyleDefinition, ParagraphStyle, CharacterStyle, ShapeObject
  • HwpBinaryDocument, HwpBinaryFileHeader, HwpRecord, HwpParagraph
  • HwpDocument, HwpSection, HwpParagraphObject, HwpDocumentProperties
  • HwpxPart, XmlPart, SectionPart, HeaderPart, ContentHpfPart, SettingsPart, VersionPart, MimetypePart, ContainerPart, ContainerRdfPart, ManifestPart, BinaryDataPart, GenericBinaryPart, GenericTextPart, GenericXmlPart, PreviewImagePart, PreviewTextPart, ScriptPart
  • HwpxError, HwpxValidationError, InvalidHwpxFileError, InvalidHwpFileError, HwpBinaryEditError

반대로 jakal_hwpx.document, jakal_hwpx.parts 같은 내부 모듈 경로 import는 구현 세부사항이며, 호환성 계약 대상으로 보지 않습니다.

지원 범위

지원:

  • Python 3.11, 3.12, 3.13
  • ZIP 기반 HWPX 패키지의 열기, 수정, 검증, 컴파일, 저장
  • legacy binary .hwp 파일의 저수준 열기, 스트림 파싱, 미리보기/본문 same-length 수정, 저장
  • Windows + Hancom automation 환경에서 .hwp의 high-level HWPX bridge editing
  • hwp_collection 기반 pure-python profile build 및 template-backed append_table_pure()/append_picture_pure()/append_hyperlink_pure()
  • jakal_hwpx top-level export를 통한 문서 편집 흐름

비지원:

  • .hwp -> .hwpx 변환기 번들 제공
  • 새로운 .hwp 문서 blank 생성이나 전체 OLE Compound File 재작성
  • Hancom automation이 없는 환경에서 .hwp에 대한 HWPX 수준의 고수준 편집
  • top-level jakal_hwpx export 밖의 내부 import 경로에 대한 호환성 보장

예제

문서 열기와 검증:

from jakal_hwpx import HwpxDocument

doc = HwpxDocument.open("input.hwpx")

print(doc.metadata())
print(doc.get_document_text())
print(doc.validation_errors())
print(doc.reference_validation_errors())

메타데이터와 본문 수정:

from jakal_hwpx import HwpxDocument

doc = HwpxDocument.open("input.hwpx")
doc.set_metadata(title="수정된 제목", creator="Docs Team", keyword="example")
doc.replace_text("초안", "최종")
doc.append_paragraph("추가 문단", section_index=0)
doc.save("build/edited.hwpx")

페이지 설정과 표 수정:

from jakal_hwpx import HwpxDocument

doc = HwpxDocument.open("input.hwpx")

settings = doc.section_settings(0)
settings.set_page_size(width=60000, height=85000)
settings.set_margins(left=7000, right=7000, top=5000, bottom=5000)

table = doc.tables()[0]
table.set_cell_text(0, 0, "수정됨")
table.append_row()[0].set_text("새 행")

doc.save("build/layout-updated.hwpx")

북마크, 하이퍼링크, 계산 필드 추가:

from jakal_hwpx import HwpxDocument

doc = HwpxDocument.blank()
bookmark = doc.append_bookmark("summary_anchor")
doc.append_hyperlink("https://example.com", display_text="Example")
doc.append_calculation_field("40+2", display_text="42")
doc.append_cross_reference(bookmark.name or "summary_anchor", display_text="요약으로 이동")
doc.save("build/fields.hwpx")

테스트

python -m pip install -e .[dev]
python -m pytest -q
python scripts/run_stability_lab.py

Windows Hancom smoke validation:

powershell -ExecutionPolicy Bypass -File scripts/setup_hancom_security_module.ps1 -DownloadIfMissing
powershell -ExecutionPolicy Bypass -File scripts/run_hancom_smoke_validation.ps1 -InputPath examples\samples\hwpx\AI와_특이점_보고서.hwpx -OutputPath .codex-temp\hancom-smoke\sample.roundtrip.hwpx
powershell -ExecutionPolicy Bypass -File scripts/run_hancom_corpus_smoke_validation.ps1

The Hancom smoke validator registers the official security module, calls RegisterModule("FilePathCheckDLL", "FilePathCheckerModuleExample"), and emits a structured .run.json log. It also fails fast when existing Hwp.exe processes would make COM validation unreliable.

테스트는 examples/samples/hwpx/ 아래의 고정 fixture corpus를 사용합니다. 로컬과 CI가 같은 경로를 사용하도록 고정해 두었기 때문에 테스트 커버리지가 실행 환경에 따라 흔들리지 않습니다.

추가 문서

라이선스

프로젝트가 직접 작성한 소스 코드는 MIT License를 따릅니다.

샘플 문서와 커밋된 생성 결과물은 별도 권리를 가질 수 있습니다. 재배포 전에는 THIRD_PARTY_NOTICES.md를 확인하세요.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jakal_hwpx-0.3.0b1.tar.gz (2.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jakal_hwpx-0.3.0b1-py3-none-any.whl (2.1 MB view details)

Uploaded Python 3

File details

Details for the file jakal_hwpx-0.3.0b1.tar.gz.

File metadata

  • Download URL: jakal_hwpx-0.3.0b1.tar.gz
  • Upload date:
  • Size: 2.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for jakal_hwpx-0.3.0b1.tar.gz
Algorithm Hash digest
SHA256 90117245886dbcd137890c3f2060eb282453dc6db8135b3808b85f5c4603a1d1
MD5 caf50c8c1f5173dde63c448f6ab31853
BLAKE2b-256 21453377877cb4638fc25a4203d2e58db6192a93a72dd89f1cc55f8643f09f64

See more details on using hashes here.

File details

Details for the file jakal_hwpx-0.3.0b1-py3-none-any.whl.

File metadata

  • Download URL: jakal_hwpx-0.3.0b1-py3-none-any.whl
  • Upload date:
  • Size: 2.1 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for jakal_hwpx-0.3.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 b4eef1ead187975fc856ce5992bdb779f992be5d58a2bb9beb61c3adcced87c1
MD5 75bf77656d2210df4cdde83eea3d79a8
BLAKE2b-256 b6ccc097dc50c41bb4ed842a91d5c5c4856f3d42105773debf6f6dd87f356a02

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page