@kimdayoun/hwpx-mcp 0.3.0 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,175 +13,143 @@
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.HangingIndentCalculator = void 0;
15
15
  /**
16
- * 문자 너비 테이블 (em 단위, 기준 폰트 기준)
17
- * 실제 한글 문서에서 자주 사용되는 마커 문자들의 상대적 너비
16
+ * 문자 너비 테이블 (em 단위).
18
17
  *
19
- * 한글 폰트(함초롬바탕, 맑은 고딕 등)에서 측정된 값 기준
18
+ * 값은 Windows 한/글이 함초롬바탕 10pt 로 그린 PDF 에서 **글자 전진폭**
19
+ * (다음 글자 x − 이 글자 x) 을 잰 것이다. 추정치가 아니다.
20
+ * 측정 원본: src/fixtures/hancom-marker-widths.json
21
+ *
22
+ * 이전 표는 전각 1.0em·공백 0.5em 에 폰트 보정 1.25 를 곱해, 한/글보다
23
+ * 평균 4.14pt(최대 6.30pt) 넓게 계산했다. 한/글은 전각 기호를 0.996em,
24
+ * 공백을 0.498em 로 그리므로 보정 계수는 1.0 이 맞다.
25
+ *
26
+ * 표에 없는 글자는 getCharWidth 의 범주별 기본값을 쓴다.
20
27
  */
21
28
  const CHAR_WIDTH_TABLE = {
22
- // 불릿 문자 (전각 = 1em)
23
- '○': 1.0,
24
- '●': 1.0,
25
- '•': 0.6, // 중간 불릿
26
- '▪': 0.6,
27
- '◆': 1.0,
28
- '◇': 1.0,
29
- '■': 1.0,
30
- '□': 1.0,
31
- '※': 1.0,
32
- '★': 1.0,
33
- '☆': 1.0,
34
- '◎': 1.0, // 이중 원
35
- '◉': 1.0,
36
- '▶': 1.0, // 화살표
37
- '▷': 1.0,
38
- '►': 1.0,
39
- '▻': 0.6,
40
- '▸': 0.6, // 작은 화살표
41
- '▹': 0.6,
42
- '➢': 1.0,
43
- '➣': 1.0,
44
- '➤': 1.0,
45
- '✓': 0.7, // 체크마크
46
- '✔': 0.7,
47
- '✗': 0.7,
48
- '✘': 0.7,
49
- '✦': 0.7, // 별
50
- '✧': 0.7,
51
- '→': 1.0, // 화살표
52
- '⇒': 1.0,
53
- '▣': 1.0, // 박스
54
- '▤': 1.0,
55
- '▥': 1.0,
56
- // 대시/하이픈
57
- '-': 0.5,
58
- '–': 0.7, // en-dash
59
- '—': 1.0, // em-dash
60
- // 숫자 (반각이지만 한글 폰트에서는 조금 넓음)
61
- '0': 0.6,
62
- '1': 0.6,
63
- '2': 0.6,
64
- '3': 0.6,
65
- '4': 0.6,
66
- '5': 0.6,
67
- '6': 0.6,
68
- '7': 0.6,
69
- '8': 0.6,
70
- '9': 0.6,
71
- // 구두점 (한글 폰트에서 조금 넓음)
72
- '.': 0.35,
73
- ')': 0.4,
74
- '(': 0.4,
75
- // 공백 (한글 폰트에서 더 넓음)
76
- ' ': 0.5,
77
- // 한글 자모/글자 (전각)
78
- '가': 1.0,
79
- '나': 1.0,
80
- '다': 1.0,
81
- '라': 1.0,
82
- '마': 1.0,
83
- '바': 1.0,
84
- '사': 1.0,
85
- '아': 1.0,
86
- '자': 1.0,
87
- '차': 1.0,
88
- '카': 1.0,
89
- '타': 1.0,
90
- '파': 1.0,
91
- '하': 1.0,
92
- // 원문자 (전각)
93
- '①': 1.0,
94
- '②': 1.0,
95
- '③': 1.0,
96
- '④': 1.0,
97
- '⑤': 1.0,
98
- '⑥': 1.0,
99
- '⑦': 1.0,
100
- '⑧': 1.0,
101
- '⑨': 1.0,
102
- '⑩': 1.0,
103
- '⑪': 1.0,
104
- '⑫': 1.0,
105
- '⑬': 1.0,
106
- '⑭': 1.0,
107
- '⑮': 1.0,
108
- '⑯': 1.0,
109
- '⑰': 1.0,
110
- '⑱': 1.0,
111
- '⑲': 1.0,
112
- '⑳': 1.0,
113
- // 로마 숫자/알파벳 대문자 (반각이지만 한글 폰트에서 조금 넓음)
114
- 'I': 0.4,
115
- 'V': 0.7,
116
- 'X': 0.7,
29
+ // 전각 기호 (실측 0.996em: ○ ● □ ■ ▶ ①)
30
+ '○': 0.996,
31
+ '●': 0.996,
32
+ '◆': 0.996,
33
+ '◇': 0.996,
34
+ '■': 0.996,
35
+ '□': 0.996,
36
+ '★': 0.996,
37
+ '☆': 0.996,
38
+ '◎': 0.996,
39
+ '◉': 0.996,
40
+ '▶': 0.996,
41
+ '▷': 0.996,
42
+ '►': 0.996,
43
+ '➢': 0.996,
44
+ '➣': 0.996,
45
+ '➤': 0.996,
46
+ '→': 0.996,
47
+ '⇒': 0.996,
48
+ '▣': 0.996,
49
+ '▤': 0.996,
50
+ '▥': 0.996,
51
+ // 폭이 좁은 기호 (실측: ※ 0.756, • 0.456)
52
+ '※': 0.756,
53
+ '•': 0.456,
54
+ '▪': 0.456,
55
+ '▻': 0.456,
56
+ '▸': 0.456,
57
+ '▹': 0.456,
58
+ // 체크·별 기호 (실측 ✓ 0.996)
59
+ '✓': 0.996,
60
+ '✔': 0.996,
61
+ '✗': 0.996,
62
+ '✘': 0.996,
63
+ '✦': 0.996,
64
+ '✧': 0.996,
65
+ // 대시 (실측 - 0.834, — 0.852)
66
+ '-': 0.834,
67
+ '–': 0.834,
68
+ '—': 0.852,
69
+ // 숫자 (실측 1 0.576, 0 0.588)
70
+ '0': 0.588,
71
+ '1': 0.576,
72
+ '2': 0.588,
73
+ '3': 0.588,
74
+ '4': 0.588,
75
+ '5': 0.588,
76
+ '6': 0.588,
77
+ '7': 0.588,
78
+ '8': 0.588,
79
+ '9': 0.588,
80
+ // 구두점·공백 (실측 . 0.294, ( 0.498, ) 0.504, 공백 0.498)
81
+ '.': 0.294,
82
+ ')': 0.504,
83
+ '(': 0.498,
84
+ ':': 0.294,
85
+ ' ': 0.498,
86
+ // 알파벳 (실측 A 0.744, B 0.66, I 0.372, a 0.492)
87
+ 'I': 0.372,
88
+ 'V': 0.744,
89
+ 'X': 0.744,
117
90
  'L': 0.6,
118
- 'C': 0.7,
119
- 'D': 0.7,
91
+ 'C': 0.744,
92
+ 'D': 0.744,
120
93
  'M': 0.9,
121
- 'A': 0.7,
122
- 'B': 0.7,
123
- 'E': 0.6,
94
+ 'A': 0.744,
95
+ 'B': 0.66,
96
+ 'E': 0.66,
124
97
  'F': 0.6,
125
- 'G': 0.7,
126
- 'H': 0.7,
127
- // 알파벳 소문자 (반각)
128
- 'a': 0.55,
129
- 'b': 0.55,
130
- 'c': 0.55,
131
- 'd': 0.55,
132
- 'e': 0.55,
98
+ 'G': 0.744,
99
+ 'H': 0.744,
100
+ 'a': 0.492,
101
+ 'b': 0.492,
102
+ 'c': 0.492,
103
+ 'd': 0.492,
104
+ 'e': 0.492,
133
105
  'f': 0.35,
134
- 'g': 0.55,
135
- 'h': 0.55,
136
- // 콜론 (마커 뒤에 올 수 있음)
137
- ':': 0.35,
138
- // 법률/공문서 한글 문자
139
- '제': 1.0,
140
- '조': 1.0,
141
- '항': 1.0,
142
- '호': 1.0,
143
- '목': 1.0,
144
- '의': 1.0,
106
+ 'g': 0.492,
107
+ 'h': 0.492,
145
108
  };
109
+ /** 한글 음절 전진폭 (실측 가·본 0.972em). */
110
+ const HANGUL_SYLLABLE_WIDTH = 0.972;
111
+ /** 원문자·전각 기호 기본 전진폭 (실측 ① 0.996em). */
112
+ const FULL_WIDTH_SYMBOL = 0.996;
146
113
  /**
147
- * @deprecated Use getFontFactor(fontName) instead
148
- * 기본 한글 폰트 보정 계수 (하위 호환성 유지)
149
- */
150
- const HANGUL_FONT_FACTOR = 1.3;
151
- /**
152
- * 폰트별 보정 계수 테이블
153
- * 실측 기반 값 (한글에서 실제 렌더링 너비 / em 값)
114
+ * 폰트별 보정 계수 — CHAR_WIDTH_TABLE(함초롬바탕 실측) 대비 배율.
115
+ *
116
+ * 함초롬 계열만 한/글에서 실측했다(1.0). 나머지는 측정하지 않았으므로
117
+ * 종전 표가 함초롬(1.25) 대비 두던 **상대 비율**만 옮겼다
118
+ * (예: 맑은 고딕 1.35/1.25 = 1.08). 새 폰트를 쓰는 양식이 생기면
119
+ * scripts 쪽 측정 문서로 다시 재서 이 값을 교체한다.
154
120
  */
155
121
  const FONT_FACTOR_TABLE = {
156
- // 기본값
157
- 'default': 1.3,
158
- // 한컴 폰트
159
- '함초롬바탕': 1.25,
160
- '함초롬돋움': 1.25,
161
- '한컴바탕': 1.3,
162
- '한컴돋움': 1.3,
163
- // 마이크로소프트 폰트
164
- '맑은 고딕': 1.35,
165
- '맑은고딕': 1.35,
166
- 'Malgun Gothic': 1.35,
167
- '바탕': 1.3,
168
- '돋움': 1.3,
169
- '굴림': 1.3,
170
- '궁서': 1.35,
171
- // 나눔 폰트
172
- '나눔고딕': 1.3,
173
- '나눔명조': 1.3,
174
- 'NanumGothic': 1.3,
175
- 'NanumMyeongjo': 1.3,
176
- '나눔바른고딕': 1.28,
177
- // Adobe 폰트
178
- '본고딕': 1.25,
179
- '본명조': 1.25,
180
- 'Noto Sans KR': 1.25,
181
- 'Noto Serif KR': 1.25,
182
- // 영문 폰트 (한글이 없는 경우)
183
- 'Arial': 1.0,
184
- 'Times New Roman': 1.0,
122
+ // 기본값 — 한/글 새 문서 기본 글꼴이 함초롬바탕이다
123
+ 'default': 1.0,
124
+ // 한컴 폰트 (실측)
125
+ '함초롬바탕': 1.0,
126
+ '함초롬돋움': 1.0,
127
+ 'HCR Batang': 1.0,
128
+ 'HCR Dotum': 1.0,
129
+ '한컴바탕': 1.04,
130
+ '한컴돋움': 1.04,
131
+ // 마이크로소프트 폰트 (미측정, 종전 상대비)
132
+ '맑은 고딕': 1.08,
133
+ '맑은고딕': 1.08,
134
+ 'Malgun Gothic': 1.08,
135
+ '바탕': 1.04,
136
+ '돋움': 1.04,
137
+ '굴림': 1.04,
138
+ '궁서': 1.08,
139
+ // 나눔 폰트 (미측정, 종전 상대비)
140
+ '나눔고딕': 1.04,
141
+ '나눔명조': 1.04,
142
+ 'NanumGothic': 1.04,
143
+ 'NanumMyeongjo': 1.04,
144
+ '나눔바른고딕': 1.024,
145
+ // Adobe 폰트 (미측정, 종전 상대비)
146
+ '본고딕': 1.0,
147
+ '본명조': 1.0,
148
+ 'Noto Sans KR': 1.0,
149
+ 'Noto Serif KR': 1.0,
150
+ // 영문 폰트 (미측정, 종전 상대비)
151
+ 'Arial': 0.8,
152
+ 'Times New Roman': 0.8,
185
153
  };
186
154
  /**
187
155
  * 폰트 보정 계수 가져오기
@@ -247,17 +215,19 @@ class HangingIndentCalculator {
247
215
  if (CHAR_WIDTH_TABLE[char] !== undefined) {
248
216
  return CHAR_WIDTH_TABLE[char];
249
217
  }
250
- // 한글 범위 (가-힣) 체크 - 전각으로 처리
218
+ // 한글 음절 (가-힣)
251
219
  if (/[가-힣]/.test(char)) {
252
- return 1.0;
220
+ return HANGUL_SYLLABLE_WIDTH;
253
221
  }
254
- // 전각 문자 범위 체크
255
- const code = char.charCodeAt(0);
256
- if (code >= 0xFF00 && code <= 0xFFEF) {
257
- return 1.0; // 전각 문자
222
+ const code = char.codePointAt(0) ?? 0;
223
+ // 원문자 ①–⑳ 등 Enclosed Alphanumerics, 도형 기호 블록, 전각 형태
224
+ if ((code >= 0x2460 && code <= 0x24FF) ||
225
+ (code >= 0x25A0 && code <= 0x25FF) ||
226
+ (code >= 0xFF00 && code <= 0xFFEF)) {
227
+ return FULL_WIDTH_SYMBOL;
258
228
  }
259
- // 기본값: 반각 문자로 가정
260
- return 0.55;
229
+ // 표에 없는 반각 문자 — 실측한 소문자 폭을 쓴다
230
+ return 0.492;
261
231
  }
262
232
  /**
263
233
  * 마커 문자열의 너비를 em 단위로 계산