Skip to content

Commit 8a8eff3

Browse files
jk-kim0claude
andcommitted
docs: FC 공백 보존 원칙 지침 문서를 추가합니다
XHTML 원본의 공백을 그대로 MDX로 옮기는 원칙과 구체적 사례(convert_li join)를 정리합니다. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5690925 commit 8a8eff3

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Forward Converter 공백 보존 원칙
2+
3+
## 핵심 원칙
4+
5+
Forward Converter(FC)는 XHTML 원본의 공백, 단락 구조를 **있는 그대로** MDX로 변환해야 한다.
6+
FC 출력의 형태는 XHTML 원문이 결정한다. XHTML 원문과 무관하게 "이렇게 생겨야 한다"는 고정된 출력 형태는 없다.
7+
8+
### 하지 말아야 할 것
9+
10+
- XHTML에 없는 공백을 추가하지 않는다.
11+
- XHTML에 있는 공백을 임의로 제거하지 않는다.
12+
-`<p>` 요소의 콘텐츠를 필터링하지 않는다 (XHTML에 존재하는 구조이다).
13+
- FC 출력 형태를 미리 정해놓고 그에 맞추지 않는다.
14+
15+
### 해야 할 것
16+
17+
- XHTML 텍스트 노드의 공백을 그대로 MDX로 옮긴다.
18+
- `<p>` 요소의 콘텐츠(빈 단락 포함)를 보존한다.
19+
- FC가 삽입하는 구조적 마커(`<br/>` 등)와 XHTML 원본 공백을 구분한다.
20+
21+
## 구체적 사례: `convert_li``join`
22+
23+
### 문제 상황
24+
25+
`convert_li()`에서 `<li>` 내 여러 `<p>` 요소를 MDX 한 줄로 합칠 때,
26+
`<p>` 경계를 `<br/>`로 표현하고 `' '.join(li_itself)`로 연결했다.
27+
28+
`' '.join()`**모든 항목 사이에 공백 하나를 삽입**하는데,
29+
이 공백은 XHTML 원문에 존재하지 않는다.
30+
31+
### XHTML → FC 출력 추적 예시
32+
33+
#### 예시 1: `<br/>` 뒤 빈 `<p>`
34+
35+
```xml
36+
<li>
37+
<p>경우<br/> </p>
38+
<ac:image>...</ac:image>
39+
<p> </p>
40+
</li>
41+
```
42+
43+
`<p>` 경계에서 `<br/>` 구분자가 삽입되므로 `li_itself` 구성은:
44+
45+
| 인덱스 | 출처 || 설명 |
46+
|--------|------|----|------|
47+
| 0 | 첫 번째 `<p>` | `'경우<br/> '` | XHTML 텍스트 노드의 trailing space 보존 |
48+
| 1 | `<br/>` 구분자 | `'<br/>'` | FC가 `<p>` 경계를 표현하기 위해 삽입 |
49+
| 2 | `<p> </p>` | `' '` | 빈 단락의 공백 콘텐츠 보존 |
50+
51+
**`' '.join()` (잘못됨):**
52+
53+
```
54+
'경우<br/> ' + ' ' + '<br/>' + ' ' + ' '
55+
→ '경우<br/> <br/> '
56+
```
57+
58+
join이 삽입한 공백(` `)이 XHTML 원본 공백과 합쳐져 이중 공백이 된다.
59+
60+
**`''.join()` (올바름):**
61+
62+
```
63+
'경우<br/> ' + '<br/>' + ' '
64+
→ '경우<br/> <br/> '
65+
```
66+
67+
XHTML 원본의 공백만 존재한다.
68+
69+
#### 예시 2: `<br/>` 없는 `<p>` + 빈 `<p>`
70+
71+
```xml
72+
<li>
73+
<p>클릭합니다</p>
74+
<ac:image>...</ac:image>
75+
<p></p>
76+
</li>
77+
```
78+
79+
| 인덱스 | 출처 ||
80+
|--------|------|----|
81+
| 0 | 첫 번째 `<p>` | `'클릭합니다'` |
82+
| 1 | `<br/>` 구분자 | `'<br/>'` |
83+
| 2 | `<p></p>` | `''` |
84+
85+
**`' '.join()` (잘못됨):** `'클릭합니다 <br/> '``<br/>` 앞뒤 공백은 XHTML에 없음
86+
87+
**`''.join()` (올바름):** `'클릭합니다<br/>'` — XHTML 그대로
88+
89+
#### 예시 3: 연속 `<p>` 텍스트
90+
91+
```xml
92+
<li>
93+
<p>Text A</p>
94+
<p>Text B</p>
95+
</li>
96+
```
97+
98+
| 인덱스 | 출처 ||
99+
|--------|------|----|
100+
| 0 | 첫 번째 `<p>` | `'Text A'` |
101+
| 1 | `<br/>` 구분자 | `'<br/>'` |
102+
| 2 | 두 번째 `<p>` | `'Text B'` |
103+
104+
**`' '.join()` (잘못됨):** `'Text A <br/> Text B'` — 경계 공백은 XHTML에 없음
105+
106+
**`''.join()` (올바름):** `'Text A<br/>Text B'``<br/>`가 줄바꿈 역할, 추가 공백 불필요
107+
108+
## 수정 방법
109+
110+
```python
111+
# 변경 전 (XHTML에 없는 공백 삽입)
112+
itself = ' '.join(li_itself)
113+
114+
# 변경 후 (XHTML 원본 공백만 보존)
115+
itself = ''.join(li_itself)
116+
```
117+
118+
한 줄 변경이다. 각 `<p>`의 SingleLineParser 출력에 이미 XHTML 원문의 공백이
119+
보존되어 있으므로, join 시 추가 공백을 넣지 않으면 된다.
120+
121+
## 일반 원칙: FC 버그 수정 시 판단 기준
122+
123+
FC 출력이 "올바른지" 판단할 때:
124+
125+
1. **XHTML 원문을 확인**한다 — FC 출력을 보기 전에, 입력인 XHTML이 어떤 구조인지 파악
126+
2. **XHTML의 공백/구조를 그대로 MDX에 반영하는지** 확인한다
127+
3. FC가 삽입하는 구조적 요소(`<br/>` 구분자 등)는 XHTML 원본 공백과 **분리**해서 처리한다
128+
4. "출력이 이렇게 생겨야 한다"는 고정관념 없이, XHTML 원문에서 출력을 **도출**한다

0 commit comments

Comments
 (0)