syhwp
English · 한국어
Pure-Python reader for Korean HWP (.hwp) and HWPX (.hwpx) documents —
the file formats produced by Hancom Office / 한글 (Hangul). Read a document
and get its text, tables, equations and images as plain text, GitHub-flavored
Markdown, or HTML, with a single small dependency and a permissive MIT
license.
Reach for syhwp when you need to read or convert .hwp / .hwpx files in
Python — for search, RAG / LLM pipelines, data migration, or plain text
extraction — and can't use the AGPL-licensed pyhwp.
import syhwp
text = syhwp.extract_text("report.hwp") # plain text
md = syhwp.extract_markdown("report.hwpx") # Markdown (tables as pipe tables)
html = syhwp.extract_html("report.hwp") # standalone HTML
.hwp (legacy binary) and .hwpx (OWPML) are detected automatically and handled
the same way.
Install
pip install syhwp
The only runtime dependency is olefile
(BSD). HWPX parsing uses the Python standard library alone. Works on Python
3.9–3.13, on any OS.
Command line
syhwp report.hwp # Markdown (default)
syhwp report.hwp --text # plain text
syhwp report.hwpx --html # HTML
python -m syhwp report.hwp # equivalent
What the output looks like
A table in the document comes out as a GitHub-flavored Markdown table:
■ Road structure & facilities standard — revision comparison
| Before (2020) | After (2021) | Note |
| --- | --- | --- |
| … design speed 120 110 100 … stopping sight distance 215 185 155 … | … 225 195 170 … | |
Equations are surfaced as their script ([수식: …]) and images as a [그림]
placeholder, so no content is silently dropped.
Library API
Convenience functions — each takes a path and returns a string:
| Function | Returns |
|---|---|
extract_text(path) |
plain text |
extract_markdown(path) |
GFM Markdown; tables become pipe tables |
extract_html(path) |
a standalone HTML document |
detect_format(path) |
"hwp5" or "hwpx" |
Structured access via open():
doc = syhwp.open("report.hwp") # -> Document
doc.version # e.g. "5.1.0.1"
doc.text, doc.markdown, doc.html # rendered forms
for table in doc.tables: # Table(n_rows, n_cols, cells)
print(table.to_markdown())
for cell in table.cells: # Cell(row, col, text, row_span, col_span)
...
for para in doc.paragraphs: # Paragraph(text)
print(para.text)
for eq in doc.equations: # Equation(script)
print(eq.script)
doc.blocks holds every block in reading order as a Paragraph, Table,
Equation, or Image. Errors derive from syhwp.SyhwpError
(UnsupportedFormatError, InvalidHwpError, EncryptedDocumentError).
What is supported
HWP 5.x (.hwp) |
HWPX (.hwpx) |
|
|---|---|---|
| Text | ✅ | ✅ |
| Tables → grid / Markdown / HTML | ✅ | ✅ |
| Equations (as script) | ✅ | ✅ |
| Image placeholders | ✅ | ✅ |
| Document version | ✅ | ✅ |
- Robust by design: unknown records/elements are skipped, and malformed or
corrupt input raises a typed
SyhwpErrorrather than crashing (fuzz-tested). - No servers, no Java, no Rust — pure Python, one dependency.
Limitations
- Password-protected documents cannot be read — they raise
EncryptedDocumentError. Distribution (copy-protected, 배포용) documents are read: their key travels with the file, so the flag asks editors not to edit rather than keeping a secret. Installsyhwp[fast](or havecryptographypresent) to decrypt them ~90× faster than the bundled pure-Python AES. - Merged table cells are captured in the model (
row_span/col_span), but Markdown output leaves the covered cells blank (Markdown cannot merge cells). - HWP 3.x and earlier (a different, pre-5.0 format) are not supported.
Why another HWP library?
If you searched for a pyhwp alternative, an AGPL-free HWP parser, or a way
to read .hwp files without a Java or Rust toolchain — that's the gap syhwp
fills. The existing Python options each have a blocker for commercial or SaaS use:
| Library | License | Note |
|---|---|---|
pyhwp |
AGPL-3.0 | Network copyleft — unsuitable for closed / SaaS use |
libhwp (hwp-rs) |
Apache-2.0 | Unmaintained; no Python 3.12+ wheels |
pyhwpx |
— | Windows-only (COM automation) |
syhwp aims to be the permissively-licensed, maintained, pure-Python option, and
adds HWPX support plus Markdown / HTML output.
How it works
syhwp is a clean-room implementation written from HANCOM's publicly
published HWP 5.0 binary format and OWPML (HWPX) specifications. It does not
derive from or incorporate the AGPL-licensed pyhwp, which is what allows the
permissive MIT license. See DESIGN.md for the record/element layout
and parsing details.
Contributing
Contributions are welcome — see CONTRIBUTING.md. A dev tool,
python scripts/inspect_hwp.py <file>, dumps a document's internal structure to
help add support for new records or elements.
License
MIT © 2026 sysphere
Metadata
Release files for syhwp 0.0.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| syhwp-0.0.8.tar.gz | 44.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| syhwp-0.0.8-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 64.4 kB
Release files / syhwp-0.0.8.tar.gz
| Download URL | syhwp-0.0.8.tar.gz |
|---|---|
| Size | 44.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d5d3d4962e49d4372e436cce21b11a25013cbb2cb3b36d7410759d4ca6387e43
|
|
BLAKE2b-256 checksum How to use checksums |
f87e6806f1df51f4f8456759545e94a8b0961d42f2fabc54695ea64806aaae04
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.
Transparency logRelease files / syhwp-0.0.8-py3-none-any.whl
| Download URL | syhwp-0.0.8-py3-none-any.whl |
|---|---|
| Size | 20.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cc34d3f46abe7cc13b5f718f719a4d028a20f37a4aad811294de256784448c6b
|
|
BLAKE2b-256 checksum How to use checksums |
019d5621be52c9980b78e7616cc6f41ae81917fe9ea248fdbd4f1d64d4bdc5b1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 19, 2026.
Transparency log