v5:HWPX 스타일 주입 + 표 열너비 변환_20260127

This commit is contained in:
2026-02-20 11:42:07 +09:00
parent 17e639ed40
commit 71740ce912
6 changed files with 1260 additions and 228 deletions

View File

@@ -1,11 +1,14 @@
# 글벗 (Geulbeot) v4.0
# 글벗 (Geulbeot) v5.0
**AI 기반 문서 자동화 시스템 — GPD 총괄기획실**
**HWPX 스타일 주입 + 표 열 너비 정밀 변환**
다양한 형식의 자료(PDF·HWP·이미지·Excel 등)를 입력하면, AI가 RAG 파이프라인으로 분석한 뒤
선택한 문서 유형(기획서·보고서·발표자료 등)에 맞는 표준 HTML 문서를 자동 생성합니다.
생성된 문서는 웹 편집기에서 수정하고, HTML / PDF / HWP로 출력합니다.
v5에서는 HWP 변환 품질을 고도화했습니다. 기존 pyhwpx 기본 변환에 HWPX 후처리를 추가하여,
커스텀 스타일 주입과 표 열 너비 정밀 조정이 가능해졌습니다.
---
## 🏗 아키텍처 (Architecture)
@@ -47,7 +50,7 @@ RAG 파이프라인 (9단계) ─── 공통 처리
- 자료 입력 → 9단계 RAG 파이프라인 (파일 변환 → 추출 → 도메인 분석 → 청킹 → 임베딩 → 코퍼스 → 인덱싱 → 콘텐츠 생성 → HTML 조립)
- 문서 유형별 생성: 기획서 (Claude 3단계), 보고서 (Gemini 2단계)
- AI 편집: 전체 수정 (`/refine`), 부분 수정 (`/refine-selection`)
- HWP 변환: HTML 스타일 분석 → 역할 매핑 → HWPX 생성
- HWP 변환: 하이브리드 방식 — pyhwpx 기본 생성 → HWPX 스타일 주입 → 표 열 너비 수정
- PDF 변환: WeasyPrint 기반
### 2. Frontend (순수 JavaScript)
@@ -61,14 +64,19 @@ RAG 파이프라인 (9단계) ─── 공통 처리
- **RAG 파이프라인**: 9단계 — 파일 형식 통일 → 텍스트·이미지 추출 → 도메인 분석 → 의미 단위 청킹 → RAG 임베딩 → 코퍼스 구축 → FAISS 인덱싱 → 콘텐츠 생성 → HTML 조립
- **분량 자동 판단**: 5,000자 기준 — 긴 문서는 전체 파이프라인, 짧은 문서는 축약 파이프라인
- **HWP 변환**: pyhwpx 기반 + v4에서 추가된 스타일 분석기·HWPX 생성기·매핑 모듈
- **HWP 변환 (v5 하이브리드 방식)**:
1. HTML 분석 → StyleAnalyzer로 역할 분류
2. pyhwpx 기본 변환 (표·이미지·머리말·꼬리말 정상 처리)
3. HWP → HWPX 변환
4. HWPX 후처리 — header.xml에 커스텀 스타일 정의 주입, section*.xml에 역할별 styleIDRef 매핑
5. HWPX 후처리 — 표 열 너비 정밀 수정 (px/mm/% → HWPML 단위 변환)
### 4. 주요 시나리오 (Core Scenarios)
1. **기획서 생성**: 텍스트 또는 파일을 입력하면, RAG 분석 후 Claude API가 구조 추출 → 페이지 배치 계획 → 글벗 표준 HTML 기획서를 생성. 1~N페이지 옵션 지원
2. **보고서 생성**: 폴더 경로의 자료들을 RAG 파이프라인으로 분석하고, Gemini API가 섹션별 콘텐츠 초안 → 표지·목차·간지·별첨이 포함된 다페이지 HTML 보고서를 생성
3. **AI 편집**: 생성된 문서를 웹 편집기에서 확인 후, "이 부분을 표로 바꿔줘" 같은 피드백으로 전체 또는 선택 부분을 AI가 수정
4. **HWP 내보내기**: 글벗 HTML을 스타일 분석기가 요소별 역할을 분류하고, HWP 스타일로 매핑하여 서식이 유지된 HWP 파일로 변환
4. **HWP 내보내기 (v5 개선)**: 기존 pyhwpx 변환 후 HWPX를 열어 커스텀 스타일(제목 계층·본문·표 등)을 주입하고, 표 열 너비를 원본 HTML과 일치시켜 서식 정확도를 높임
### 프로세스 플로우
@@ -111,6 +119,7 @@ flowchart TD
classDef exportStyle fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1.5px,color:#4a148c
classDef startEnd fill:#1a365d,stroke:#1a365d,color:#fff,stroke-width:2px
classDef planned fill:#f5f5f5,stroke:#999,stroke-width:1px,stroke-dasharray: 5 5,color:#999
classDef newModule fill:#fff3e0,stroke:#ef6c00,stroke-width:2px,color:#e65100
A(["📋 RAG 분석 결과"]):::startEnd
B{"문서 유형 선택"}:::decision
@@ -128,7 +137,7 @@ flowchart TD
K{"출력 형식"}:::decision
L["HTML / PDF"]:::exportStyle
M["HWP 변환\n스타일 분석→매핑→생성"]:::exportStyle
M["HWP 변환 (v5 하이브리드)\npyhwpx→스타일주입→표주입"]:::newModule
N["PPT 변환\n예정"]:::planned
O(["✅ 최종 산출물"]):::startEnd
@@ -146,26 +155,47 @@ flowchart TD
K -->|"PPT"| N -.-> O
```
#### HWP 변환 (v5 하이브리드 방식)
```mermaid
flowchart TD
classDef process fill:#e8f4fd,stroke:#1a365d,stroke-width:1.5px,color:#1a365d
classDef newModule fill:#fff3e0,stroke:#ef6c00,stroke-width:2px,color:#e65100
classDef exportStyle fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1.5px,color:#4a148c
classDef startEnd fill:#1a365d,stroke:#1a365d,color:#fff,stroke-width:2px
A(["📄 글벗 HTML"]):::startEnd
B["① StyleAnalyzer\nHTML 요소 역할 분류"]:::process
C["② pyhwpx 기본 변환\n표·이미지·머리말 처리"]:::process
D["③ HWP → HWPX 변환"]:::process
E["④ 스타일 주입\nhwpx_style_injector\nheader.xml + section.xml"]:::newModule
F["⑤ 표 열 너비 수정\nhwpx_table_injector\npx/mm/% → HWPML"]:::newModule
G([".hwpx 파일"]):::exportStyle
A --> B --> C --> D --> E --> F --> G
```
---
## 🔄 v3 → v4 변경사항
## 🔄 v4 → v5 변경사항
| 영역 | v3 | v4 |
| 영역 | v4 | v5 |
|------|------|------|
| app.py | 모든 로직 포함 (579줄) | 라우팅 전담 (291줄) |
| 비즈니스 로직 | app.py 내부 | handlers/ 패키지로 분리 (briefing + report + common) |
| 프롬프트 | prompts/ 공용 1곳 | handlers/*/prompts/ 모듈별 분리 |
| HWP 변환 | pyhwpx 직접 변환만 | + 스타일 분석기·HWPX 생성기·매핑 모듈 추가 |
| 환경설정 | 없음 | .env + api_config.py (python-dotenv) |
| HWP 변환 방식 | pyhwpx 기본 변환만 | 하이브리드: pyhwpx → HWPX 후처리 |
| 스타일 주입 | style_analyzer로 분석만 | + **hwpx_style_injector** — header.xml 스타일 정의, section.xml 매핑 |
| 표 열 너비 | HTML 원본과 불일치 | + **hwpx_table_injector** — px/mm/% → HWPML 정밀 변환 |
| 표 너비 파싱 | 없음 | html_to_hwp.py에 `_parse_width()` 유틸 추가 |
| HWP 출력 형식 | .hwp만 | .hwpx 출력 지원 (mimetype 추가) |
| 테스트 코드 | dkdl.py 잔존 | 삭제 (정리) |
---
## 🗺 상태 및 로드맵 (Status & Roadmap)
- **Phase 1**: RAG 파이프라인 — 9단계 파이프라인, 도메인 분석, 분량 자동 판단 (🔧 기본 구현 · 현재 버전)
- **Phase 1**: RAG 파이프라인 — 9단계 파이프라인, 도메인 분석, 분량 자동 판단 (🔧 기본 구현)
- **Phase 2**: 문서 생성 — 기획서·보고서 AI 생성 + 글벗 표준 HTML 양식 (🔧 기본 구현)
- **Phase 3**: 출력 — HTML/PDF 다운로드, HWP 변환 (🔧 기본 구현)
- **Phase 4**: HWP/HWPX/HTML 매핑 — 스타일 분석기, HWPX 생성기, 역할→HWP 매핑 (🔧 기본 구현)
- **Phase 4**: HWP/HWPX/HTML 매핑 — 스타일 분석·HWPX 생성·스타일 주입·표 주입 (🔧 기본 구현 · 현재 버전)
- **Phase 5**: 문서 유형 분석·등록 — HWPX 업로드 → AI 구조 분석 → 유형 CRUD + 확장 (예정)
- **Phase 6**: HWPX 템플릿 관리 — 파싱·시맨틱 매핑·스타일 추출·표 매칭·콘텐츠 주입 (예정)
- **Phase 7**: UI 고도화 — 프론트 모듈화, 데모 모드, AI 편집 개선, 도메인 선택기 (예정)
@@ -187,8 +217,8 @@ flowchart TD
```bash
# 저장소 클론 및 설정
git clone http://[Gitea주소]/kei/geulbeot-v4.git
cd geulbeot-v4
git clone http://[Gitea주소]/kei/geulbeot-v5.git
cd geulbeot-v5
# 가상환경
python -m venv venv
@@ -222,27 +252,25 @@ python app.py
## 📂 프로젝트 구조
```
geulbeot_4th/
geulbeot_5th/
├── app.py # Flask 웹 서버 — API 라우팅
├── api_config.py # .env 환경변수 로더
├── handlers/ # 비즈니스 로직
│ ├── common.py # Claude API 호출, JSON/HTML 추출
│ ├── briefing/ # 기획서 처리
│ ├── processor.py # 구조추출 → 배치계획 → HTML 생성
│ │ └── prompts/ # 각 단계별 AI 프롬프트
│ └── report/ # 보고서 처리
│ ├── processor.py # RAG 파이프라인 연동 + AI 편집
│ └── prompts/
│ ├── briefing/ # 기획서 처리 (구조추출 → 배치 → HTML)
└── report/ # 보고서 처리 (RAG 파이프라인 연동)
├── converters/ # 변환 엔진
│ ├── pipeline/ # 9단계 RAG 파이프라인
│ │ ├── router.py # 분량 판단 (5,000자 기준)
│ │ └── step1 ~ step9 # 변환→추출→분석→청킹→임베딩→코퍼스→인덱싱→콘텐츠→HTML
│ ├── style_analyzer.py # HTML 요소 역할 분류 (v4 신규)
│ ├── hwpx_generator.py # HWPX 파일 직접 생성 (v4 신규)
│ ├── hwp_style_mapping.py # 역할 → HWP 스타일 매핑 (v4 신규)
│ ├── html_to_hwp.py # 보고서 → HWP 변환
│ ├── style_analyzer.py # HTML 요소 역할 분류
│ ├── hwpx_generator.py # HWPX 파일 직접 생성
│ ├── hwp_style_mapping.py # 역할 → HWP 스타일 매핑
│ ├── hwpx_style_injector.py # ★ v5 신규 — HWPX 커스텀 스타일 주입
│ ├── hwpx_table_injector.py # ★ v5 신규 — HWPX 표 열 너비 정밀 수정
│ ├── html_to_hwp.py # 보고서 → HWP 변환 (하이브리드 워크플로우)
│ └── html_to_hwp_briefing.py # 기획서 → HWP 변환
├── static/
@@ -279,7 +307,7 @@ geulbeot_4th/
- API 키 분산: 파이프라인 각 step에 개별 정의 (공통화 미완)
- HWP 변환: Windows + pyhwpx + 한글 프로그램 필수
- 문서 유형: 기획서·보고서만 구현, 발표자료·사용자 등록 유형 미구현
- 레거시 잔존: prompts/ 디렉토리, dkdl.py 테스트 코드
- 레거시 잔존: prompts/ 디렉토리
---
@@ -287,9 +315,9 @@ geulbeot_4th/
| 영역 | 줄 수 |
|------|-------|
| Python 전체 | 9,780 |
| Python 전체 | 10,782 (+1,002) |
| 프론트엔드 (JS + CSS + HTML) | 3,859 |
| **합계** | **~13,600** |
| **합계** | **~14,600** |
---
@@ -300,7 +328,8 @@ geulbeot_4th/
| v1 | Flask + Claude API 기획서 생성기 |
| v2 | 웹 편집기 추가 |
| v3 | 9단계 RAG 파이프라인 + HWP 변환 |
| **v4** | **코드 모듈화 (handlers 패키지) + 스타일 분석기·HWPX 생성기** |
| v4 | 코드 모듈화 (handlers 패키지) + 스타일 분석기·HWPX 생성기 |
| **v5** | **HWPX 스타일 주입 + 표 열 너비 정밀 변환** |
---