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
| Stage | 설명 | 출력 |
|---|---|---|
| Stage 1 (Parser) | 문서를 파싱하여 중간 표현(IR)으로 변환 | 구조화된 기본 Markdown |
| Stage 2 (LLM) | LLM을 사용하여 IR을 깔끔한 Markdown으로 포맷팅 | 가독성이 향상된 Markdown |
Stage 1만으로도 기본적인 변환이 가능하지만, 복잡한 레이아웃의 문서는 Stage 2(LLM)를 통해 가독성을 크게 향상시킬 수 있습니다.
go install github.com/roboco-io/hwp2md/cmd/hwp2md@latestGitHub 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 |
# HWPX 파일을 Markdown으로 변환
hwp2md document.hwpx -o output.md
# HWP 5.x 파일을 Markdown으로 변환
hwp2md document.hwp -o output.md
# 표준 출력으로 변환
hwp2md document.hwpxNote:
convert명령어는 기본 명령이므로 생략할 수 있습니다.hwp2md document.hwpx와hwp2md convert document.hwpx는 동일합니다.
기본 내장 파서로 충분하지 않은 경우, 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.hwpxNote: Upstage Document Parse는 API 키가 필요하며 사용량에 따라 비용이 발생합니다. 대부분의 HWPX 문서는 내장 파서로 충분히 변환됩니다.
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# 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-*→ Anthropicgpt-*,o1-*,o3-*→ OpenAIgemini-*→ Google Geminisolar-*→ 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 | 미정 | 레거시 바이너리 포맷 |
| 기능 | 상태 |
|---|---|
| 문단/텍스트 | ✅ 지원 |
| 테이블 (셀 병합 포함) | ✅ 지원 |
| 이미지 참조 | |
| 압축 문서 | ✅ 지원 |
| 암호화/DRM 문서 | ❌ 미지원 |
| 프로바이더 | 기본 모델 | 설명 |
|---|---|---|
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- Go 1.24 이상
- golangci-lint (lint 검사)
- Claude Code (권장) - AI 페어 프로그래밍 도구
권장: 이 프로젝트는 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[바이너리 배포]
make hooks로 설치되는 Git hooks가 코드 품질을 자동으로 검증합니다:
| Hook | 실행 시점 | 검증 항목 | 실패 시 |
|---|---|---|---|
| pre-commit | 커밋 전 | gofmt + golangci-lint + Unit Tests | 커밋 차단 |
| pre-push | 푸시 전 | E2E Tests | 푸시 차단 |
- gofmt - Go 코드 포맷팅 검사 (Go만 있으면 항상 실행)
- golangci-lint - 정적 분석 (설치된 경우에만 실행)
errcheck: 에러 반환값 무시 검출ineffassign: 사용되지 않는 할당 검출unused: 사용되지 않는 코드 검출staticcheck: 정적 분석- 기타 linter들 (
.golangci.yml참조)
- 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/| 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/ # 테스트 데이터
실제 변환 결과를 확인하여 품질을 평가할 수 있습니다.
동일한 문서를 내장 파서와 Upstage Document Parse로 변환한 결과를 비교할 수 있습니다.
| 파서 | 결과 | 설명 |
|---|---|---|
| 원본 | 한글 테스트.hwpx, PDF | 테스트용 한글 문서 (공무원 채용 공고) |
| Native | 결과 보기 | 내장 HWPX 파서 (기본) |
| Upstage | 결과 보기 | Upstage Document Parse API (선택적) |
동일한 문서를 여러 LLM으로 변환한 결과를 비교할 수 있습니다.
| LLM | 결과 | 모델 |
|---|---|---|
| Claude | 결과 보기 | claude-sonnet-4-20250514 |
| GPT | 결과 보기 | gpt-4o-mini |
| Gemini | 결과 보기 | gemini-2.0-flash |
| Solar | 결과 보기 | solar-pro |
Stage 1은 문서 구조를 그대로 추출하며, Stage 2는 LLM을 통해 더 읽기 쉬운 형태로 정리합니다.
테스트 파일 출처: 한국문화원 문서 뷰어 테스트 예시
- PRD - 제품 요구사항
- 기술 스택 - 기술 스택 결정
- HWPX 스키마 - HWPX 파일 포맷 문서
- HWP5 스키마 - HWP 5.x 바이너리 포맷 문서
- HWPX-Markdown 차이점 - 포맷 간 차이점 및 변환 방식
- 바이브 코딩 튜토리얼 - Claude Code를 활용한 AI 협업 개발 사례
MIT License - 자세한 내용은 LICENSE 파일을 참조하세요.