Skip to content

roboco-io/hwp2md

Repository files navigation

hwp2md

Go Version License Build Go Report Card

HWP(한글 워드프로세서) 문서를 Markdown으로 변환하는 CLI 도구

개요

이 프로젝트는 HWP/HWPX 문서를 Markdown으로 변환합니다. HWP는 복잡한 테이블 레이아웃, 중첩 표, 다단 구성 등 Markdown에서 직접 표현하기 어려운 구조를 포함할 수 있습니다. 이러한 구조적 차이를 극복하기 위해 2단계 파이프라인 아키텍처를 사용하며, 필요시 LLM을 활용하여 더 읽기 쉬운 Markdown을 생성합니다.

아키텍처

flowchart LR
    subgraph Input
        HWP[HWP/HWPX 문서]
    end

    subgraph Stage1[Stage 1: Parser]
        direction TB
        Parser{Parser}
        Parser --> |HWPX| HWPX[HWPX Parser]
        Parser --> |HWP| HWP5[HWP5 Parser]
        Parser -.-> |선택적| Upstage[Upstage Document Parse]
        HWPX --> IR[IR - 중간 표현]
        HWP5 --> IR
    end

    subgraph Stage2[Stage 2: LLM - 선택적]
        LLM{LLM Provider}
        LLM --> |Anthropic| Claude
        LLM --> |OpenAI| GPT
        LLM --> |Google| Gemini
        LLM --> |Upstage| Solar
        LLM --> |Local| Ollama
    end

    subgraph Output
        MD1[기본 Markdown]
        MD2[향상된 Markdown]
    end

    HWP --> Parser
    IR --> MD1
    Upstage -.-> MD1
    IR -.-> LLM
    MD1 -.-> LLM
    LLM -.-> MD2
Loading
Stage 설명 출력
Stage 1 (Parser) 문서를 파싱하여 중간 표현(IR)으로 변환 구조화된 기본 Markdown
Stage 2 (LLM) LLM을 사용하여 IR을 깔끔한 Markdown으로 포맷팅 가독성이 향상된 Markdown

Stage 1만으로도 기본적인 변환이 가능하지만, 복잡한 레이아웃의 문서는 Stage 2(LLM)를 통해 가독성을 크게 향상시킬 수 있습니다.

설치

Go 설치 (권장)

go install github.com/roboco-io/hwp2md/cmd/hwp2md@latest

바이너리 다운로드

GitHub Releases에서 플랫폼별 바이너리를 다운로드할 수 있습니다.

플랫폼 아키텍처 파일
Windows x64 hwp2md_*_windows_amd64.zip
macOS Intel hwp2md_*_darwin_amd64.tar.gz
macOS Apple Silicon hwp2md_*_darwin_arm64.tar.gz
Linux x64 hwp2md_*_linux_amd64.tar.gz

사용법

기본 변환 (Stage 1만)

# HWPX 파일을 Markdown으로 변환
hwp2md document.hwpx -o output.md

# HWP 5.x 파일을 Markdown으로 변환
hwp2md document.hwp -o output.md

# 표준 출력으로 변환
hwp2md document.hwpx

Note: convert 명령어는 기본 명령이므로 생략할 수 있습니다. hwp2md document.hwpxhwp2md convert document.hwpx는 동일합니다.

Upstage Document Parse 사용 (Stage 1 - 선택적)

기본 내장 파서로 충분하지 않은 경우, Upstage Document Parse API를 선택적으로 사용할 수 있습니다. OCR 기반으로 복잡한 레이아웃이나 스캔된 문서를 더 정확하게 인식합니다.

# Upstage Document Parse 사용
export UPSTAGE_API_KEY="your-api-key"
hwp2md document.hwpx --parser upstage

# 환경변수로 설정
export HWP2MD_PARSER="upstage"
hwp2md document.hwpx

Note: Upstage Document Parse는 API 키가 필요하며 사용량에 따라 비용이 발생합니다. 대부분의 HWPX 문서는 내장 파서로 충분히 변환됩니다.

LLM 포맷팅 (Stage 2)

LLM을 사용하면 더 자연스럽고 읽기 쉬운 Markdown을 생성할 수 있습니다.

# Anthropic Claude 사용 (기본)
export ANTHROPIC_API_KEY="your-api-key"
hwp2md convert document.hwpx --llm

# OpenAI GPT 사용
export OPENAI_API_KEY="your-api-key"
hwp2md convert document.hwpx --llm --provider openai

# Google Gemini 사용
export GOOGLE_API_KEY="your-api-key"
hwp2md convert document.hwpx --llm --provider gemini

# Upstage Solar 사용
export UPSTAGE_API_KEY="your-api-key"
hwp2md convert document.hwpx --llm --provider upstage

# Ollama 사용 (로컬)
hwp2md convert document.hwpx --llm --provider ollama --model llama3.2

IR 추출

# JSON 형식으로 IR 추출
hwp2md extract document.hwpx -o output.json

# 텍스트 형식으로 추출
hwp2md extract document.hwpx --format text

환경 변수

변수 설명
HWP2MD_PARSER 파서 선택 (native, upstage) - 기본: native (upstage는 선택적)
HWP2MD_LLM true로 설정하면 LLM 포맷팅 활성화
HWP2MD_MODEL 사용할 모델 이름 (프로바이더 자동 감지)
HWP2MD_BASE_URL 프라이빗 API 엔드포인트 (Bedrock, Azure, 로컬 서버)
ANTHROPIC_API_KEY Anthropic API 키
OPENAI_API_KEY OpenAI API 키
GOOGLE_API_KEY Google Gemini API 키
UPSTAGE_API_KEY Upstage API 키 (LLM 및 Document Parse)
OLLAMA_HOST Ollama 서버 주소 (기본: http://localhost:11434)

모델 이름으로 프로바이더가 자동 감지됩니다:

  • claude-* → Anthropic
  • gpt-*, o1-*, o3-* → OpenAI
  • gemini-* → Google Gemini
  • solar-* → Upstage
  • 그 외 → Ollama (로컬)

프라이빗 테넌시

AWS Bedrock, Azure OpenAI, 로컬 서버 등 프라이빗 엔드포인트를 사용할 수 있습니다:

# AWS Bedrock
hwp2md convert document.hwpx --llm --model claude-3-sonnet --base-url https://bedrock-runtime.us-east-1.amazonaws.com

# Azure OpenAI
hwp2md convert document.hwpx --llm --model gpt-4 --base-url https://your-resource.openai.azure.com

# 로컬 서버
hwp2md convert document.hwpx --llm --model llama3.2 --base-url http://localhost:8080

지원 포맷

포맷 상태 설명
HWPX ✅ 지원 XML 기반 개방형 포맷 (한컴오피스 2014+)
HWP 5.x ✅ 지원 OLE2/CFB 바이너리 포맷 (한글 2002~2022)
HWP 3.x 미정 레거시 바이너리 포맷

HWP 5.x 지원 기능

기능 상태
문단/텍스트 ✅ 지원
테이블 (셀 병합 포함) ✅ 지원
이미지 참조 ⚠️ 부분 지원
압축 문서 ✅ 지원
암호화/DRM 문서 ❌ 미지원

LLM 프로바이더

프로바이더 기본 모델 설명
anthropic claude-sonnet-4-20250514 Anthropic Claude
openai gpt-4o-mini OpenAI GPT (Azure, Bedrock 호환)
gemini gemini-1.5-flash Google Gemini
upstage solar-pro Upstage Solar
ollama llama3.2 로컬 Ollama 서버

컨트리뷰션

개발 환경 설정

# 저장소 클론
git clone https://github.com/roboco-io/hwp2md.git
cd hwp2md

# 의존성 다운로드
go mod download

# Git hooks 설치 (필수)
make hooks

# 빌드
make build

요구사항

권장: 이 프로젝트는 Claude Code를 활용한 AI 협업 개발로 진행되었습니다. 복잡한 파서 로직이나 새로운 기능 구현 시 Claude Code 사용을 권장합니다. 자세한 내용은 바이브 코딩 튜토리얼을 참조하세요.

개발 워크플로우

flowchart TB
    subgraph Local[로컬 개발]
        Code[코드 작성]
    end

    subgraph PreCommit[pre-commit hook]
        direction TB
        Gofmt[gofmt 포맷 검사]
        Lint[golangci-lint]
        UT[Unit Tests]
    end

    subgraph PrePush[pre-push hook]
        E2E[E2E Tests]
    end

    subgraph CI[GitHub Actions]
        Test[Test Workflow]
        Release[Release Workflow]
    end

    Code --> |git commit| PreCommit
    Gofmt --> |통과| Lint
    Lint --> |통과| UT
    UT --> |통과| Commit[커밋 완료]

    Commit --> |git push| PrePush
    E2E --> |통과| Push[푸시 완료]

    Push --> CI
    Test --> |v* 태그| Release
    Release --> Binary[바이너리 배포]
Loading

Git Hooks

make hooks로 설치되는 Git hooks가 코드 품질을 자동으로 검증합니다:

Hook 실행 시점 검증 항목 실패 시
pre-commit 커밋 전 gofmt + golangci-lint + Unit Tests 커밋 차단
pre-push 푸시 전 E2E Tests 푸시 차단

pre-commit 검증 순서

  1. gofmt - Go 코드 포맷팅 검사 (Go만 있으면 항상 실행)
  2. golangci-lint - 정적 분석 (설치된 경우에만 실행)
    • errcheck: 에러 반환값 무시 검출
    • ineffassign: 사용되지 않는 할당 검출
    • unused: 사용되지 않는 코드 검출
    • staticcheck: 정적 분석
    • 기타 linter들 (.golangci.yml 참조)
  3. Unit Tests - ./internal/... 패키지 테스트

참고: gofmt는 golangci-lint에 포함되어 있지만, golangci-lint가 Go 버전 불일치 등으로 실행되지 않는 환경에서도 기본 포맷팅 검사를 보장하기 위해 별도로 먼저 실행합니다.

# hooks 설치
make hooks

# 수동 실행
make test      # unit tests + e2e tests
make lint      # golangci-lint
make fmt       # gofmt 자동 수정
make test-e2e  # e2e tests만

테스트 구조

종류 경로 설명
Unit Tests internal/*/ 패키지별 단위 테스트
E2E Tests tests/ CLI 통합 테스트, LLM 연동 테스트
# 전체 테스트
make test

# unit tests만
go test -race ./internal/...

# e2e tests만
go test -race ./tests/...

# 특정 테스트
go test -v -run TestName ./internal/parser/hwpx/

GitHub Actions

Workflow 트리거 동작
Test push, PR lint + unit tests + e2e tests
Release v* 태그 goreleaser로 크로스 플랫폼 바이너리 빌드 및 배포

프로젝트 구조

hwp2md/
├── cmd/hwp2md/      # CLI 엔트리포인트
├── internal/
│   ├── cli/               # CLI 명령 구현
│   ├── config/            # 설정 관리
│   ├── ir/                # 중간 표현 (Intermediate Representation)
│   ├── llm/               # LLM 프로바이더
│   │   ├── anthropic/     # Anthropic Claude
│   │   ├── openai/        # OpenAI GPT
│   │   ├── gemini/        # Google Gemini
│   │   ├── upstage/       # Upstage Solar
│   │   └── ollama/        # Local Ollama
│   └── parser/            # 문서 파서
│       ├── hwpx/          # HWPX 파서 (XML 기반)
│       ├── hwp5/          # HWP 5.x 파서 (바이너리)
│       └── upstage/       # Upstage Document Parse (선택적)
├── docs/                  # 문서
└── tests/                 # 테스트 데이터

변환 품질 예시

실제 변환 결과를 확인하여 품질을 평가할 수 있습니다.

Stage 1 (Parser 비교)

동일한 문서를 내장 파서와 Upstage Document Parse로 변환한 결과를 비교할 수 있습니다.

파서 결과 설명
원본 한글 테스트.hwpx, PDF 테스트용 한글 문서 (공무원 채용 공고)
Native 결과 보기 내장 HWPX 파서 (기본)
Upstage 결과 보기 Upstage Document Parse API (선택적)

Stage 2 (LLM 비교)

동일한 문서를 여러 LLM으로 변환한 결과를 비교할 수 있습니다.

LLM 결과 모델
Claude 결과 보기 claude-sonnet-4-20250514
GPT 결과 보기 gpt-4o-mini
Gemini 결과 보기 gemini-2.0-flash
Solar 결과 보기 solar-pro

Stage 1은 문서 구조를 그대로 추출하며, Stage 2는 LLM을 통해 더 읽기 쉬운 형태로 정리합니다.

테스트 파일 출처: 한국문화원 문서 뷰어 테스트 예시

문서

기술 문서

개발 가이드

라이센스

MIT License - 자세한 내용은 LICENSE 파일을 참조하세요.

About

HWP(한글 워드프로세서) 문서를 Markdown으로 변환하는 도구

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages