Files
test/domain/hwpx/hwpx_domain_guide.md

25 KiB
Raw 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.1mm0.4px
1 0.12 mm 0.12mm 0.12mm0.5px
2 0.15 mm 0.15mm 0.15mm0.6px
3 0.2 mm 0.2mm 0.2mm0.8px
4 0.25 mm 0.25mm 0.25mm1px
5 0.3 mm 0.3mm 0.3mm1.1px
6 0.4 mm 0.4mm 0.4mm1.5px
7 0.5 mm 0.5mm 0.5mm1.9px
8 0.6 mm 0.6mm 0.6mm2.3px
9 0.7 mm 0.7mm 0.7mm2.6px
10 1.0 mm 1.0mm 1mm3.8px
11 1.5 mm 1.5mm 1.5mm5.7px
12 2.0 mm 2.0mm 2mm7.6px
13 3.0 mm 3.0mm 3mm11.3px
14 4.0 mm 4.0mm 4mm15.1px
15 5.0 mm 5.0mm 5mm18.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)"을 참고하여 작성되었습니다.