Skip to content

Repository files navigation

hwp-rs

한글과컴퓨터의 한/글 문서 파일(.hwp, .hwpx)을 파싱하는 Rust 라이브러리입니다.

본 프로젝트는 한글과컴퓨터의 한/글 문서 파일 형식 공개 문서를 참고하여 개발하였습니다. 공개 문서 다운로드

지원 형식

  • HWP 5.0: 바이너리 형식 (Compound File Binary Format)
  • HWPX: XML 기반 형식 (OWPML 표준, KS X 6101)
Format Status Notes
HWP 5.0 Maintained / frozen Existing parser support is kept, but new feature work focuses on HWPX.
HWPX Active Primary target for parser reliability and diagnostics improvements.

프로젝트 구조

hwp-rs/
├── crates/
│   └── hwp-core/                # 핵심 Rust 라이브러리
│       ├── src/
│       │   ├── lib.rs           # 라이브러리 진입점, HwpParser 정의
│       │   ├── cfb.rs           # Compound File Binary 파서 (HWP 5.0)
│       │   ├── decompress.rs    # zlib 압축 해제
│       │   ├── error.rs         # 에러 타입 및 ParseWarnings
│       │   ├── types.rs         # 공통 타입 (HWPUNIT, Color 등)
│       │   │
│       │   ├── parser/          # 파일 형식별 파서
│       │   │   ├── mod.rs       # 파서 통합 (HWP/HWPX 자동 감지)
│       │   │   ├── detect.rs    # 파일 형식 감지
│       │   │   └── hwpx/        # HWPX (XML) 파서
│       │   │       ├── section.rs  # 섹션 파싱 (문단, 테이블, 이미지, 하이퍼링크)
│       │   │       ├── header.rs   # 문서 정보 파싱 (폰트, 스타일, 문단 모양)
│       │   │       └── bindata.rs  # 바이너리 데이터 파싱
│       │   │
│       │   ├── document/        # 문서 구조체 정의
│       │   │   ├── fileheader/  # 파일 헤더 (버전, 플래그)
│       │   │   ├── docinfo/     # 문서 정보 (폰트, 스타일, 번호매기기)
│       │   │   ├── bodytext/    # 본문 (섹션, 문단, 표, 그림)
│       │   │   │   ├── ctrl_header/      # 컨트롤 헤더 (표, 각주, 머리글 등)
│       │   │   │   └── shape_component/  # 도형 (사각형, 선, 이미지 등)
│       │   │   ├── bindata/     # 바이너리 데이터 (이미지, OLE)
│       │   │   └── scripts/     # 문서 스크립트
│       │   │
│       │   └── viewer/          # 출력 변환기
│       │       ├── shared.rs    # 공통 유틸리티 (MIME 감지, 이미지 저장)
│       │       ├── markdown/    # Markdown 변환
│       │       └── html/        # HTML 변환 (페이지 레이아웃, SVG 테이블)
│       │
│       └── tests/
│           ├── fixtures/        # 테스트용 HWP/HWPX 파일
│           └── snapshots/       # 스냅샷 테스트 결과
│
└── packages/
    └── hwpx-python/             # Python 바인딩
        ├── src/lib.rs           # PyO3 바인딩 코드
        ├── pyproject.toml       # Python 패키지 설정
        └── Cargo.toml           # Rust 의존성

기능

  • HWP/HWPX 문서 파싱
  • Markdown 변환
    • 테이블 지원 (HTML 테이블 렌더링)
    • 중첩 테이블(Nested Table) 지원
    • 테이블 셀 내 이미지 렌더링
    • 이미지 추출 (base64 또는 파일 저장)
    • 하이퍼링크 렌더링
    • 밑줄(underline) 렌더링
    • 이미지 alt text 커스터마이징
  • HTML 변환
    • XSS 방지 (텍스트 이스케이프)
    • 올바른 charset 선언
  • JSON 변환
  • 텍스트 추출
  • 이미지 추출 (PNG, JPEG, BMP, GIF, WebP, TIFF 지원)
  • 파싱 경고 시스템 (ParseWarnings)

Diagnostics

The parser exposes both legacy string warnings and structured diagnostics. Diagnostics identify unsupported elements, recovered invalid values, skipped binary assets, and likely data loss so conversion problems are visible instead of silently ignored.

Security and reliability

HWP/HWPX files are treated as untrusted input. The HWPX parser enforces ZIP, XML, and section-level resource limits; rejects unsafe ZIP paths; normalizes binary references; and sanitizes image output extensions. CI runs Rust tests, clippy, formatting, dependency audit, dependency policy checks, CodeQL, Python wheel validation, and packaging smoke tests.

See SECURITY.md and docs/security-model.md for the threat model, resource limits, and vulnerability reporting process.

Parser fuzzing is configured with cargo-fuzz targets for autodetected parsing and HWPX-specific parsing. See docs/fuzzing.md for target details and local fuzzing workflow.

Python releases are built as ABI3 wheels and published through PyPI Trusted Publishing. See docs/release.md for release and publishing checks.

CI generates LCOV coverage artifacts with cargo-llvm-cov; see docs/coverage.md for local reports and review policy.

Performance

The repository includes Criterion benchmarks for HWPX parsing and Markdown conversion. CI compiles the benchmark target in test mode to catch performance harness breakage without depending on noisy shared-runner timings. See docs/performance.md for local benchmark workflow and reporting.

Python 사용법

설치

pip install hwpxkit

사용 예제

import hwpxkit

# 파일에서 문서 열기
doc = hwpxkit.parse_file("document.hwpx")

# 또는 바이트에서 파싱
with open("document.hwp", "rb") as f:
    doc = hwpxkit.parse(f.read())

# 문서 정보
print(doc.version)        # 예: "5.1.0.1"
print(doc.section_count)  # 섹션 수
print(doc.warnings)       # 파싱 경고 목록

# Markdown 변환
markdown = doc.to_markdown()
markdown = doc.to_markdown(
    use_html=True,              # HTML 태그 사용 (테이블 등)
    include_version=True,       # 버전 정보 포함
    image_output_dir="./images" # 이미지를 파일로 저장 (없으면 base64)
)

# HTML 변환
html = doc.to_html()
html = doc.to_html(image_output_dir="./images")

# JSON 변환
json_str = doc.to_json()

# 텍스트 추출
text = doc.get_text()

Rust 사용법

use hwp_core::{HwpParser, HwpDocument};
use hwp_core::viewer::markdown::{to_markdown, MarkdownOptions};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let data = std::fs::read("document.hwp")?;
    let parser = HwpParser::new();
    let doc = parser.parse(&data)?;

    let options = MarkdownOptions::default();
    let markdown = to_markdown(&doc, &options);
    println!("{}", markdown);

    // 파싱 경고 확인
    for warning in doc.warnings.warnings() {
        eprintln!("Warning: {}", warning);
    }

    Ok(())
}

개발

빌드

# Rust 라이브러리 빌드
cargo build --release

# Python 휠 빌드
cd packages/hwpx-python
pip install maturin
maturin build --release

테스트

# CI와 동일한 로컬 검사
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace
cargo llvm-cov --workspace --all-features --lcov --output-path lcov.info
cargo bench -p hwp-core --bench parse_benchmark -- --test
cargo check --manifest-path fuzz/Cargo.toml --locked
cargo deny --locked check
cargo audit
cargo audit --file fuzz/Cargo.lock

# 스냅샷 테스트 업데이트
cargo insta accept --workspace

참고 프로젝트

라이선스

MIT

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages