Files
test/domain/hwpx/hwpx_domain_guide.md

25 KiB
Raw Permalink Blame History

HWP/HWPX ↔ HTML/CSS 도메인 가이드

목적: HWPX에서 문서 유형·스타일·템플릿을 추출하거나, HTML → HWPX → HWP 변환 시
하드코딩 없이 이 가이드를 참조하여 정확한 매핑을 수행한다.
출처: 한글과컴퓨터 공식 "글 문서 파일 구조 5.0" (revision 1.3, 2018-11-08)
범위: HWP 5.0 바이너리 스펙의 개념 체계 + HWPX XML 태그 + HTML/CSS 매핑


0. 문서 형식 관계

HWP (바이너리)          HWPX (XML)              HTML/CSS
─────────────────   ─────────────────────   ─────────────────
Compound File       ZIP Archive             단일 HTML 파일
├─ FileHeader       ├─ META-INF/            ├─ <head>
├─ DocInfo          │   └─ manifest.xml     │   ├─ <meta>
│  (글꼴, 스타일,   ├─ Contents/            │   └─ <style>
│   테두리/배경,     │   ├─ header.xml       └─ <body>
│   글자모양 등)     │   │  (DocInfo 대응)       ├─ 헤더 영역
├─ BodyText/        │   ├─ section0.xml     │   ├─ 본문
│  └─ Section0      │   │  (본문 대응)       │   └─ 푸터 영역
├─ BinData/         │   └─ section1.xml     └─ @page CSS
│  └─ 이미지 등     ├─ BinData/
└─ PrvImage         │   └─ 이미지 파일
                    └─ version.xml

핵심: HWP 바이너리의 레코드 구조와 HWPX XML의 엘리먼트는 1:1 대응한다.
이 가이드는 두 형식의 공통 개념 체계를 기준으로, CSS 변환까지 연결한다.


1. 단위 체계

1.1 HWPUNIT (글 내부 단위)

HWP는 1/7200 인치를 기본 단위로 사용한다.

변환 대상 공식 예시
HWPUNIT → mm hwpunit / 7200 * 25.4 7200 → 25.4mm (= 1인치)
HWPUNIT → pt hwpunit / 7200 * 72 7200 → 72pt
HWPUNIT → px (96dpi) hwpunit / 7200 * 96 7200 → 96px
mm → HWPUNIT mm / 25.4 * 7200 25.4mm → 7200
pt → HWPUNIT pt / 72 * 7200 10pt → 1000
def hwpunit_to_mm(hwpunit):  return hwpunit / 7200 * 25.4
def hwpunit_to_pt(hwpunit):  return hwpunit / 7200 * 72
def hwpunit_to_px(hwpunit):  return hwpunit / 7200 * 96
def mm_to_hwpunit(mm):       return mm / 25.4 * 7200

1.2 글자 크기 (CharShape)

HWP의 글자 크기는 HWPUNIT 단위이지만 100배 스케일이 적용되어 있다.

HWP 값 실제 크기 CSS
1000 10pt font-size: 10pt
1200 12pt font-size: 12pt
2400 24pt font-size: 24pt
def charsize_to_pt(hwp_size):  return hwp_size / 100  # 1000 → 10pt

1.3 COLORREF (색상)

HWP는 0x00BBGGRR 형식(리틀 엔디안 BGR). CSS는 #RRGGBB.

HWP COLORREF 분해 CSS
0x00000000 R=0, G=0, B=0 #000000 (검정)
0x00FF0000 R=0, G=0, B=255 #0000ff (파랑)
0x0000FF00 R=0, G=255, B=0 #00ff00 (초록)
0x000000FF R=255, G=0, B=0 #ff0000 (빨강)
0x00FFFFFF R=255, G=255, B=255 #ffffff (흰색)
def colorref_to_css(colorref):
    r = colorref & 0xFF
    g = (colorref >> 8) & 0xFF
    b = (colorref >> 16) & 0xFF
    return f'#{r:02x}{g:02x}{b:02x}'

HWPX XML에서의 색상: #RRGGBB 형식으로 직접 기록됨 (변환 불필요).


2. 테두리/배경 (BorderFill)

HWP: HWPTAG_BORDER_FILL (DocInfo 레코드)
HWPX: <hh:borderFill> (header.xml 내)
용도: 표 셀, 문단, 쪽 테두리/배경에 공통 적용

2.1 테두리선 종류

HWP 값 이름 HWPX type 속성 CSS border-style
0 실선 SOLID solid
1 긴 점선 DASH dashed
2 점선 DOT dotted
3 -.-.-. DASH_DOT dashed (근사)
4 -..-.. DASH_DOT_DOT dashed (근사)
5 긴 Dash LONG_DASH dashed
6 큰 동그라미 CIRCLE dotted (근사)
7 2중선 DOUBLE double
8 가는선+굵은선 THIN_THICK double (근사)
9 굵은선+가는선 THICK_THIN double (근사)
10 가는+굵은+가는 THIN_THICK_THIN double (근사)
11 물결 WAVE solid (근사)
12 물결 2중선 DOUBLE_WAVE double (근사)
13 두꺼운 3D THICK_3D ridge
14 두꺼운 3D(역) THICK_3D_REV groove
15 3D 단선 3D outset
16 3D 단선(역) 3D_REV inset
— 없음 NONE none

2.2 테두리선 굵기

HWP 값 실제 굵기 HWPX width 속성 CSS border-width
0 0.1 mm 0.1mm 0.1mm ≈ 0.4px
1 0.12 mm 0.12mm 0.12mm ≈ 0.5px
2 0.15 mm 0.15mm 0.15mm ≈ 0.6px
3 0.2 mm 0.2mm 0.2mm ≈ 0.8px
4 0.25 mm 0.25mm 0.25mm ≈ 1px
5 0.3 mm 0.3mm 0.3mm ≈ 1.1px
6 0.4 mm 0.4mm 0.4mm ≈ 1.5px
7 0.5 mm 0.5mm 0.5mm ≈ 1.9px
8 0.6 mm 0.6mm 0.6mm ≈ 2.3px
9 0.7 mm 0.7mm 0.7mm ≈ 2.6px
10 1.0 mm 1.0mm 1mm ≈ 3.8px
11 1.5 mm 1.5mm 1.5mm ≈ 5.7px
12 2.0 mm 2.0mm 2mm ≈ 7.6px
13 3.0 mm 3.0mm 3mm ≈ 11.3px
14 4.0 mm 4.0mm 4mm ≈ 15.1px
15 5.0 mm 5.0mm 5mm ≈ 18.9px
BORDER_WIDTH_MAP = {
    0: 0.1, 1: 0.12, 2: 0.15, 3: 0.2, 4: 0.25, 5: 0.3,
    6: 0.4, 7: 0.5,  8: 0.6,  9: 0.7, 10: 1.0, 11: 1.5,
    12: 2.0, 13: 3.0, 14: 4.0, 15: 5.0
}
def border_width_to_css(hwp_val):
    mm = BORDER_WIDTH_MAP.get(hwp_val, 0.12)
    return f'{mm}mm'  # 또는 mm * 3.7795px

2.3 테두리 4방향 순서

HWP 배열 인덱스 HWPX 속성 CSS 대응
[0] <left> / <hh:left> border-left
[1] <right> / <hh:right> border-right
[2] <top> / <hh:top> border-top
[3] <bottom> / <hh:bottom> border-bottom

2.4 채우기 (Fill) 정보

채우기 종류 (type 비트) HWPX 엘리먼트 CSS 대응
0x00 — 없음 (없음) background: none
0x01 — 단색 <hh:windowBrush> 또는 <hh:colorFill> background-color: #...
0x02 — 이미지 <hh:imgBrush> background-image: url(...)
0x04 — 그러데이션 <hh:gradation> background: linear-gradient(...)

단색 채우기 구조 (가장 빈번):

<!-- HWPX header.xml -->
<hh:borderFill id="4">
  <hh:slash .../>
  <hh:backSlash .../>
  <hh:left type="SOLID" width="0.12mm" color="#000000"/>
  <hh:right type="SOLID" width="0.12mm" color="#000000"/>
  <hh:top type="SOLID" width="0.12mm" color="#000000"/>
  <hh:bottom type="SOLID" width="0.12mm" color="#000000"/>
  <hh:diagonal .../>
  <hh:fillBrush>
    <hh:windowBrush faceColor="#E8F5E9" hatchColor="none" .../>
  </hh:fillBrush>
</hh:borderFill>
/* CSS 대응 */
.cell-bf4 {
  border-left: 0.12mm solid #000000;
  border-right: 0.12mm solid #000000;
  border-top: 0.12mm solid #000000;
  border-bottom: 0.12mm solid #000000;
  background-color: #E8F5E9;
}

2.5 HWPX borderFill → CSS 변환 함수 (의사 코드)

def borderfill_to_css(bf_element):
    """HWPX <hh:borderFill> 엘리먼트 → CSS 딕셔너리"""
    css = {}
    
    for side in ['left', 'right', 'top', 'bottom']:
        el = bf_element.find(f'hh:{side}')
        if el is None:
            css[f'border-{side}'] = 'none'
            continue
        
        btype = el.get('type', 'NONE')
        width = el.get('width', '0.12mm')
        color = el.get('color', '#000000')
        
        if btype == 'NONE':
            css[f'border-{side}'] = 'none'
        else:
            css_style = BORDER_TYPE_MAP.get(btype, 'solid')
            css[f'border-{side}'] = f'{width} {css_style} {color}'
    
    # 배경
    fill = bf_element.find('.//hh:windowBrush')
    if fill is not None:
        face = fill.get('faceColor', 'none')
        if face and face != 'none':
            css['background-color'] = face
    
    return css

3. 글꼴 (FaceName)

HWP: HWPTAG_FACE_NAME (DocInfo)
HWPX: <hh:fontface> → <hh:font> (header.xml)
CSS: font-family

3.1 언어별 글꼴 시스템

HWP는 한글·영문·한자·일어·기타·기호·사용자 총 7개 언어 슬롯에 각각 다른 글꼴을 지정한다.

언어 인덱스 HWPX lang 속성 주요 글꼴 예시
0 HANGUL 맑은 고딕, 나눔고딕
1 LATIN Arial, Times New Roman
2 HANJA (한글 글꼴 공유)
3 JAPANESE MS Mincho
4 OTHER —
5 SYMBOL Symbol, Wingdings
6 USER —

CSS 매핑: 일반적으로 한글(0)과 영문(1) 글꼴을 font-family 스택으로 결합.

/* HWPX: hangul="맑은 고딕" latin="Arial" */
font-family: "맑은 고딕", Arial, sans-serif;

3.2 글꼴 관련 HWPX 구조

<!-- header.xml -->
<hh:fontfaces>
  <hh:fontface lang="HANGUL">
    <hh:font face="맑은 고딕" type="TTF" id="0"/>
  </hh:fontface>
  <hh:fontface lang="LATIN">
    <hh:font face="Arial" type="TTF" id="0"/>
  </hh:fontface>
  ...
</hh:fontfaces>

4. 글자 모양 (CharShape)

HWP: HWPTAG_CHAR_SHAPE (DocInfo, 72바이트)
HWPX: <hh:charPr> (header.xml charProperties 내)
CSS: font-*, color, text-decoration 등

4.1 주요 속성 매핑

HWP 필드 HWPX 속성 CSS 속성 비고
글꼴 ID [7] fontRef font-family 언어별 참조
장평 [7] ratio font-stretch 50%~200%
자간 [7] spacing letter-spacing -50%~50%, pt 변환 필요
기준 크기 height font-size 값/100 = pt
글자 색 color 속성 color COLORREF → #RRGGBB
밑줄 색 underline color text-decoration-color
진하게(bit 1) bold="true" font-weight: bold
기울임(bit 0) italic="true" font-style: italic
밑줄(bit 2-3) underline type text-decoration: underline
취소선(bit 18-20) strikeout type text-decoration: line-through
위첨자(bit 15) supscript vertical-align: super; font-size: 70%
아래첨자(bit 16) subscript vertical-align: sub; font-size: 70%

4.2 HWPX charPr 구조 예시

<hh:charPr id="1" height="1000" bold="false" italic="false"
           underline="NONE" strikeout="NONE" color="#000000">
  <hh:fontRef hangul="0" latin="0" hanja="0" japanese="0"
              other="0" symbol="0" user="0"/>
  <hh:ratio hangul="100" latin="100" .../>
  <hh:spacing hangul="0" latin="0" .../>
  <hh:relSz hangul="100" latin="100" .../>
  <hh:offset hangul="0" latin="0" .../>
</hh:charPr>

5. 문단 모양 (ParaShape)

HWP: HWPTAG_PARA_SHAPE (DocInfo, 54바이트)
HWPX: <hh:paraPr> (header.xml paraProperties 내)
CSS: text-align, margin, line-height, text-indent 등

5.1 정렬 방식

HWP 값 (bit 2-4) HWPX 속성값 CSS text-align
0 JUSTIFY justify
1 LEFT left
2 RIGHT right
3 CENTER center
4 DISTRIBUTE justify (근사)
5 DISTRIBUTE_SPACE justify (근사)

5.2 줄 간격 종류

HWP 값 HWPX 속성값 CSS line-height 비고
0 PERCENT 160% (예) 글자 크기 기준 %
1 FIXED 24pt (예) 고정 pt
2 BETWEEN_LINES — 여백만 지정
3 AT_LEAST — 최소값

5.3 주요 속성 매핑

HWP 필드 HWPX 속성 CSS 속성 단위
왼쪽 여백 margin left margin-left / padding-left HWPUNIT → mm
오른쪽 여백 margin right margin-right / padding-right HWPUNIT → mm
들여쓰기 indent text-indent HWPUNIT → mm
문단 간격 위 spacing before margin-top HWPUNIT → mm
문단 간격 아래 spacing after margin-bottom HWPUNIT → mm
줄 간격 lineSpacing line-height 종류에 따라 다름
BorderFill ID borderFillIDRef border + background ID로 참조

5.4 HWPX paraPr 구조 예시

<hh:paraPr id="0" align="JUSTIFY">
  <hh:margin left="0" right="0" indent="0"/>
  <hh:spacing before="0" after="0" 
              lineSpacingType="PERCENT" lineSpacing="160"/>
  <hh:border borderFillIDRef="1" 
             left="0" right="0" top="0" bottom="0"/>
  <hh:autoSpacing eAsianEng="false" eAsianNum="false"/>
</hh:paraPr>

6. 표 (Table) 구조

HWP: HWPTAG_TABLE (본문 레코드)
HWPX: <hp:tbl> (section*.xml 내)
HTML: <table>, <tr>, <td>/<th>

6.1 표 속성 매핑

HWP 필드 HWPX 속성 HTML/CSS 대응 비고
RowCount rowCnt (행 수)
nCols colCnt (열 수) <colgroup> 참조
CellSpacing cellSpacing border-spacing HWPUNIT16
안쪽 여백 cellMargin left/right/top/bottom padding
BorderFill ID borderFillIDRef 표 전체 테두리
쪽나눔(bit 0-1) pageBreak page-break-inside 0=avoid, 1=auto
제목줄 반복(bit 2) repeatHeader <thead> 출력

6.2 열 너비

<!-- HWPX -->
<hp:tbl colCnt="3" rowCnt="5" ...>
  <hp:colSz>
    <hp:widthList>8504 8504 8504</hp:widthList>  <!-- HWPUNIT -->
  </hp:colSz>
  ...
</hp:tbl>
<!-- HTML 변환 -->
<colgroup>
  <col style="width: 33.33%">  <!-- 8504 / 총합 * 100 -->
  <col style="width: 33.33%">
  <col style="width: 33.33%">
</colgroup>

6.3 셀 (Cell) 속성

HWP 필드 HWPX 속성 HTML 속성 비고
Column 주소 colAddr — 0부터 시작
Row 주소 rowAddr — 0부터 시작
열 병합 개수 colSpan colspan 1 = 병합 없음
행 병합 개수 rowSpan rowspan 1 = 병합 없음
셀 폭 width width HWPUNIT
셀 높이 height height HWPUNIT
셀 여백 [4] cellMargin padding HWPUNIT16 → mm
BorderFill ID borderFillIDRef border + background 셀별 스타일

6.4 HWPX 셀 구조 예시

<hp:tc colAddr="0" rowAddr="0" colSpan="2" rowSpan="1"
       width="17008" height="2400" borderFillIDRef="4">
  <hp:cellMargin left="510" right="510" top="142" bottom="142"/>
  <hp:cellAddr colAddr="0" rowAddr="0"/>
  <hp:subList ...>
    <hp:p ...>
      <!-- 셀 내용 -->
    </hp:p>
  </hp:subList>
</hp:tc>
<!-- HTML 변환 -->
<td colspan="2" style="
  width: 60mm;
  height: 8.5mm;
  padding: 0.5mm 1.8mm;
  border: 0.12mm solid #000;
  background-color: #E8F5E9;
">셀 내용</td>

6.5 병합 셀 처리 규칙

HWP/HWPX에서 병합된 셀은 왼쪽 위 셀만 존재하고, 병합에 포함된 다른 셀은 아예 없다. HTML에서는 colspan/rowspan으로 표현하고, 병합된 위치의 <td>를 생략한다.

HWPX: colSpan="2", rowSpan="3" at (col=0, row=0)
 → 이 셀이 col 0~1, row 0~2를 차지
 → col=1/row=0, col=0/row=1, col=1/row=1, col=0/row=2, col=1/row=2 셀은 없음

HTML: <td colspan="2" rowspan="3">...</td>
 → 해당 행/열 위치에서 <td> 생략

7. 용지 설정 (PageDef / SecPr)

HWP: HWPTAG_PAGE_DEF (구역 정의 하위)
HWPX: <hp:secPr> → <hp:pageDef> (section*.xml 내)
CSS: @page, @media print

7.1 용지 크기 사전 정의

용지 이름 가로 (mm) 세로 (mm) HWPUNIT (가로×세로)
A4 210 297 59528 × 84188
A3 297 420 84188 × 119055
B5 176 250 49896 × 70866
Letter 215.9 279.4 61200 × 79200
Legal 215.9 355.6 61200 × 100800

7.2 여백 매핑

<!-- HWPX section0.xml -->
<hp:secPr>
  <hp:pageDef width="59528" height="84188"
              landscape="NARROWLY">  <!-- 좁게 = 세로 -->
    <hp:margin left="8504" right="8504"
               top="5668" bottom="4252"
               header="4252" footer="4252"
               gutter="0"/>
  </hp:pageDef>
</hp:secPr>
/* CSS 변환 */
@page {
  size: A4 portrait;                    /* 210mm × 297mm */
  margin-top: 20mm;                     /* 5668 / 7200 * 25.4 ≈ 20mm */
  margin-bottom: 15mm;                  /* 4252 → 15mm */
  margin-left: 30mm;                    /* 8504 → 30mm */
  margin-right: 30mm;                   /* 8504 → 30mm */
}
/* 머리말/꼬리말 여백은 CSS에서 body padding으로 근사 */

7.3 용지 방향

HWP 값 (bit 0) HWPX 속성값 CSS
0 NARROWLY (좁게) portrait
1 WIDELY (넓게) landscape

8. 머리말/꼬리말 (Header/Footer)

HWP: HWPTAG_CTRL_HEADER → 컨트롤 ID head / foot
HWPX: <hp:headerFooter> (section*.xml 내, 또는 별도 header/footer 영역)
HTML: 페이지 상단/하단 고정 영역

8.1 머리말/꼬리말 적용 범위

HWP/HWPX 설정 의미
양쪽 모든 쪽에 동일
짝수쪽만 짝수 페이지
홀수쪽만 홀수 페이지

8.2 HTML 근사 표현

<!-- 머리말 -->
<div class="page-header" style="
  position: absolute; top: 0; left: 0; right: 0;
  height: 15mm;    /* header margin 값 */
  padding: 0 30mm; /* 좌우 본문 여백 */
">
  <table class="header-table">...</table>
</div>

<!-- 꼬리말 -->
<div class="page-footer" style="
  position: absolute; bottom: 0; left: 0; right: 0;
  height: 15mm;    /* footer margin 값 */
  padding: 0 30mm;
">
  <span class="footer-text">페이지 번호</span>
</div>

9. 구역 정의 (Section)

HWP: 구역 정의 컨트롤 (secd)
HWPX: <hp:secPr> (section*.xml 최상위)

9.1 구역 속성

속성 HWPX CSS/HTML 대응 비고
머리말 감춤 hideHeader header 영역 display:none
꼬리말 감춤 hideFooter footer 영역 display:none
텍스트 방향 textDirection writing-mode 0=가로, 1=세로
단 정의 <hp:colDef> CSS columns / column-count
쪽 번호 pageStartNo 쪽 번호 출력 값 0=이어서

10. HTML → HWPX → HWP 변환 파이프라인

10.1 전체 흐름

[HTML (우리 출력)]
    ↓ (1) HTML 파싱 → CSS 속성 추출
[중간 표현 (JSON)]
    ↓ (2) 이 가이드의 역방향 매핑
[HWPX (XML ZIP)]
    ↓ (3) 한컴오피스 변환 도구
[HWP (바이너리)]

10.2 단계별 매핑 방향

단계 입력 출력 참조할 가이드 섹션
HTML → HWPX CSS border <hh:borderFill> 생성 §2 역방향
HTML → HWPX CSS font <hh:charPr> + <hh:fontface> §3, §4 역방향
HTML → HWPX CSS text-align 등 <hh:paraPr> §5 역방향
HTML → HWPX <table> <hp:tbl> + <hp:tc> §6 역방향
HTML → HWPX @page CSS <hp:pageDef> §7 역방향
HTML → HWPX header/footer div <hp:headerFooter> §8 역방향

10.3 CSS → HWPX 역변환 예시

def css_border_to_hwpx(css_border):
    """'0.12mm solid #000000' → HWPX 속성"""
    parts = css_border.split()
    width = parts[0]  # '0.12mm'
    style = parts[1]  # 'solid'
    color = parts[2]  # '#000000'
    
    hwpx_type = CSS_TO_BORDER_TYPE.get(style, 'SOLID')
    return {
        'type': hwpx_type,
        'width': width,
        'color': color
    }

CSS_TO_BORDER_TYPE = {
    'solid': 'SOLID', 'dashed': 'DASH', 'dotted': 'DOT',
    'double': 'DOUBLE', 'ridge': 'THICK_3D', 'groove': 'THICK_3D_REV',
    'outset': '3D', 'inset': '3D_REV', 'none': 'NONE'
}

10.4 HWPX ZIP 구조 생성

output.hwpx (ZIP)
├── META-INF/
│   └── manifest.xml          ← 파일 목록
├── Contents/
│   ├── header.xml            ← DocInfo (글꼴, 스타일, borderFill)
│   ├── section0.xml          ← 본문 (문단, 표, 머리말/꼬리말)
│   └── content.hpf           ← 콘텐츠 메타
├── BinData/                  ← 이미지 등
├── Preview/
│   └── PrvImage.png          ← 미리보기
└── version.xml               ← 버전 정보

header.xml 필수 구조:

<?xml version="1.0" encoding="UTF-8"?>
<hh:head xmlns:hh="...">
  <hh:beginNum .../>
  <hh:refList>
    <hh:fontfaces>...</hh:fontfaces>       <!-- §3 -->
    <hh:borderFills>...</hh:borderFills>   <!-- §2 -->
    <hh:charProperties>...</hh:charProperties>  <!-- §4 -->
    <hh:tabProperties>...</hh:tabProperties>
    <hh:numberingProperties>...</hh:numberingProperties>
    <hh:bulletProperties>...</hh:bulletProperties>
    <hh:paraProperties>...</hh:paraProperties>  <!-- §5 -->
    <hh:styles>...</hh:styles>
  </hh:refList>
</hh:head>

section0.xml 필수 구조:

<?xml version="1.0" encoding="UTF-8"?>
<hp:sec xmlns:hp="...">
  <hp:secPr>
    <hp:pageDef .../>          <!-- §7 -->
    <hp:headerFooter .../>     <!-- §8 -->
  </hp:secPr>
  <hp:p paraPrIDRef="0" styleIDRef="0">   <!-- 문단 -->
    <hp:run charPrIDRef="0">
      <hp:t>텍스트</hp:t>
    </hp:run>
  </hp:p>
  <hp:p ...>
    <hp:ctrl>
      <hp:tbl ...>...</hp:tbl>  <!-- §6 -->
    </hp:ctrl>
  </hp:p>
</hp:sec>

11. 시스템 적용 가이드

11.1 적용 대상 모듈

모듈 파일 이 가이드 활용 방식
doc_template_analyzer.py HWPX → HTML 템플릿 추출 §2,6,7,8 정방향 (HWPX→CSS)
template_manager.py 추출된 스타일 저장/로드 §2 borderFill ID 매핑
custom_doc_type.py HTML 문서 생성 §2,4,5 CSS 값 참조
hwpx_converter.py (예정) HTML → HWPX 변환 §2~8 역방향 (CSS→HWPX)
hwp_converter.py (예정) HWPX → HWP 변환 §1 단위 변환

11.2 하드코딩 제거 전략

현재 문제 (AS-IS):

# doc_template_analyzer.py에 하드코딩됨
border_css = "2px solid var(--primary)"
header_bg = "#E8F5E9"

해결 방향 (TO-BE):

# style.json에서 추출된 borderFill 참조
bf = style['border_fills']['3']  # id=3
border_css = f"{bf['top']['width']} {bf['top']['css_style']} {bf['top']['color']}"
# → "0.12mm solid #000000"

header_bf = style['border_fills']['4']  # id=4 (헤더 배경 포함)
header_bg = header_bf.get('background', 'none')
# → "#E8F5E9"

11.3 이 가이드를 코드에서 참조하는 방식

이 문서(hwpx_domain_guide.md)는 다음과 같이 활용한다:

  1. 변환 테이블을 JSON으로 추출 → hwpx_mappings.json

    • 테두리선 종류, 굵기, 색상 변환 등의 룩업 테이블
  2. 변환 함수 라이브러리 → hwpx_utils.py

    • hwpunit_to_mm(), borderfill_to_css(), css_border_to_hwpx() 등
  3. AI 프롬프트 컨텍스트 → 문서 유형/구조 분석 시 참조

    • "이 HWPX의 borderFill id=3은 실선 0.12mm 검정이므로 표 일반 셀에 해당"
  4. 검증 기준 → 변환 결과물 검증 시 정확성 확인

    • 추출된 CSS가 원본 HWPX의 스펙과 일치하는지

부록 A. 빠른 참조 — HWPX XML 태그 ↔ HWP 레코드 대응

HWP 레코드 (Tag ID) HWPX XML 엘리먼트 위치
HWPTAG_DOCUMENT_PROPERTIES <hh:beginNum> 등 header.xml
HWPTAG_ID_MAPPINGS (암묵적) header.xml
HWPTAG_FACE_NAME <hh:font> header.xml > fontfaces
HWPTAG_BORDER_FILL <hh:borderFill> header.xml > borderFills
HWPTAG_CHAR_SHAPE <hh:charPr> header.xml > charProperties
HWPTAG_TAB_DEF <hh:tabPr> header.xml > tabProperties
HWPTAG_NUMBERING <hh:numbering> header.xml > numberingProperties
HWPTAG_BULLET <hh:bullet> header.xml > bulletProperties
HWPTAG_PARA_SHAPE <hh:paraPr> header.xml > paraProperties
HWPTAG_STYLE <hh:style> header.xml > styles
HWPTAG_PARA_HEADER <hp:p> section*.xml
HWPTAG_TABLE <hp:tbl> section*.xml > p > ctrl
(셀 속성) <hp:tc> section*.xml > tbl > tr > tc
HWPTAG_PAGE_DEF <hp:pageDef> section*.xml > secPr
(머리말/꼬리말) <hp:headerFooter> section*.xml > secPr

부록 B. 빠른 참조 — CSS → HWPX 역변환

CSS 속성 HWPX 대응 변환 공식
font-family <hh:font face="..."> 첫 번째 값 → hangul, 두 번째 → latin
font-size: 10pt <hh:charPr height="1000"> pt × 100
font-weight: bold bold="true"
font-style: italic italic="true"
color: #1a365d color="#1a365d" 동일
text-align: center align="CENTER" 대문자
margin-left: 30mm left="8504" mm → HWPUNIT
line-height: 160% lineSpacing="160" + type="PERCENT"
border: 1px solid #000 <hh:borderFill> 내 각 방향 §2 참조
background-color: #E8F5E9 <hh:windowBrush faceColor="...">
padding: 2mm 5mm <hp:cellMargin top="567" left="1417"> mm → HWPUNIT
width: 210mm width="59528" mm → HWPUNIT
@page { size: A4 } <hp:pageDef width="59528" height="84188">

이 가이드는 한글과컴퓨터의 "글 문서 파일 구조 5.0 (revision 1.3)"을 참고하여 작성되었습니다.