hwpkit-dev 0.0.2 → 0.0.3
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.
- package/ .npmignore +4 -2
- package/README.md +39 -2
- package/dist/index.d.mts +41 -14
- package/dist/index.d.ts +41 -14
- package/dist/index.js +3553 -1159
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3553 -1159
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
- package/playground/index.html +346 -0
- package/playground/main.ts +302 -0
- package/playground/vite.config.ts +16 -0
- package/src/contract/decoder.ts +1 -0
- package/src/contract/encoder.ts +6 -1
- package/src/core/BaseDecoder.ts +118 -0
- package/src/core/BaseEncoder.ts +146 -0
- package/src/decoders/docx/DocxDecoder.ts +743 -151
- package/src/decoders/html/HtmlDecoder.ts +366 -0
- package/src/decoders/hwp/HwpScanner.ts +325 -157
- package/src/decoders/hwpx/HwpxDecoder.ts +785 -297
- package/src/decoders/md/MdDecoder.ts +4 -4
- package/src/encoders/docx/DocxEncoder.ts +504 -240
- package/src/encoders/html/HtmlEncoder.ts +17 -19
- package/src/encoders/hwp/HwpEncoder.ts +1466 -859
- package/src/encoders/hwpx/HwpxEncoder.ts +1477 -469
- package/src/encoders/hwpx/constants.ts +148 -0
- package/src/encoders/hwpx/utils.ts +198 -0
- package/src/encoders/md/MdEncoder.ts +20 -15
- package/src/model/builders.ts +4 -4
- package/src/model/doc-props.ts +19 -5
- package/src/model/doc-tree.ts +12 -4
- package/src/pipeline/Pipeline.ts +7 -3
- package/src/pipeline/registry.ts +13 -2
- package/src/safety/StyleBridge.ts +51 -6
- package/src/toolkit/ArchiveKit.ts +56 -0
- package/src/toolkit/StyleMapper.ts +221 -0
- package/src/toolkit/UnitConverter.ts +138 -0
- package/src/toolkit/XmlKit.ts +0 -5
- package/test-styling.ts +210 -0
- package/hwp-analyze.ts +0 -90
- package/inspect-doc.ts +0 -57
- package/output_test.hwp +0 -0
- package/test-docx-to-hwp.ts +0 -45
package/ .npmignore
CHANGED
package/README.md
CHANGED
|
@@ -26,10 +26,11 @@
|
|
|
26
26
|
| 입력 \ 출력 | HWPX | DOCX | Markdown |
|
|
27
27
|
|------------|:----:|:----:|:--------:|
|
|
28
28
|
| **HWPX** | - | O | O |
|
|
29
|
-
| **HWP** |
|
|
29
|
+
| **HWP** | □ | O | O |
|
|
30
30
|
| **DOCX** | O | - | O |
|
|
31
|
-
| **Markdown** |
|
|
31
|
+
| **Markdown** | □ | □ | - |
|
|
32
32
|
|
|
33
|
+
> 한글 소프트웨어서는 작동이 안됨 (수정중)
|
|
33
34
|
---
|
|
34
35
|
|
|
35
36
|
## 설치
|
|
@@ -113,6 +114,42 @@ const doc = buildRoot({ title: '제목' }, [
|
|
|
113
114
|
]);
|
|
114
115
|
```
|
|
115
116
|
|
|
117
|
+
### 스타일 적용
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// 텍스트 스타일
|
|
121
|
+
buildSpan('스타일 적용 텍스트', {
|
|
122
|
+
font: 'Malgun Gothic', // 글꼴
|
|
123
|
+
pt: 14, // 글자 크기 (pt)
|
|
124
|
+
b: true, // 볼드
|
|
125
|
+
i: true, // 이탤릭
|
|
126
|
+
u: true, // 밑줄
|
|
127
|
+
s: true, // 취소선
|
|
128
|
+
color: 'FF0000', // 글색 (hex, BGR)
|
|
129
|
+
bg: 'FFFF00' // 형광펜 (hex, BGR)
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// 표 정렬 및 선 스타일
|
|
133
|
+
buildGrid(rows, {
|
|
134
|
+
align: 'center', // 표 정렬: 'left' | 'center' | 'right'
|
|
135
|
+
defaultStroke: { // 기본 선 스타일
|
|
136
|
+
kind: 'solid', // 선 종류: 'solid' | 'double' | 'dash' | 'dot'
|
|
137
|
+
pt: 1, // 선 굵기 (pt)
|
|
138
|
+
color: '000000' // 선 색상 (hex, BGR)
|
|
139
|
+
},
|
|
140
|
+
colWidths: [100, 100] // 열 너비 (pt)
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// 개별 셀의 선 스타일
|
|
144
|
+
buildCell(content, {
|
|
145
|
+
top: { kind: 'double', pt: 2, color: '0000FF' }, // 상단 선
|
|
146
|
+
bot: { kind: 'dash', pt: 1.5, color: 'FF0000' }, // 하단 선
|
|
147
|
+
left: { kind: 'dot', pt: 1, color: '00FF00' }, // 좌측 선
|
|
148
|
+
right: { kind: 'solid', pt: 3, color: 'FFFF00' }, // 우측 선
|
|
149
|
+
bg: 'FFFFFF' // 셀 배경색
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
116
153
|
### 트리 순회
|
|
117
154
|
|
|
118
155
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type Align = 'left' | 'center' | 'right' | 'justify';
|
|
2
|
-
type ImgWrap = 'inline' | 'square' | 'tight' | 'through' | 'none' | 'behind' | 'front';
|
|
2
|
+
type ImgWrap = 'inline' | 'square' | 'tight' | 'through' | 'none' | 'behind' | 'front' | 'topAndBottom';
|
|
3
3
|
type ImgHorzAlign = 'left' | 'center' | 'right';
|
|
4
4
|
type ImgVertAlign = 'top' | 'center' | 'bottom';
|
|
5
5
|
type ImgHorzRelTo = 'margin' | 'column' | 'page' | 'para';
|
|
@@ -21,7 +21,7 @@ interface ImgLayout {
|
|
|
21
21
|
}
|
|
22
22
|
type VAlign = 'top' | 'mid' | 'bot';
|
|
23
23
|
type Heading = 1 | 2 | 3 | 4 | 5 | 6;
|
|
24
|
-
type StrokeKind = 'solid' | 'dash' | 'dot' | 'double' | 'none';
|
|
24
|
+
type StrokeKind = 'solid' | 'dash' | 'dot' | 'double' | 'none' | 'dashDot' | 'dashDotDot' | 'wave';
|
|
25
25
|
interface TextProps {
|
|
26
26
|
b?: boolean;
|
|
27
27
|
i?: boolean;
|
|
@@ -37,10 +37,15 @@ interface TextProps {
|
|
|
37
37
|
interface ParaProps {
|
|
38
38
|
align?: Align;
|
|
39
39
|
heading?: Heading;
|
|
40
|
+
styleId?: string;
|
|
40
41
|
indentPt?: number;
|
|
42
|
+
indentRightPt?: number;
|
|
43
|
+
firstLineIndentPt?: number;
|
|
44
|
+
leftMargin?: number;
|
|
41
45
|
spaceBefore?: number;
|
|
42
46
|
spaceAfter?: number;
|
|
43
47
|
lineHeight?: number;
|
|
48
|
+
lineHeightFixed?: number;
|
|
44
49
|
listLv?: number;
|
|
45
50
|
listOrd?: boolean;
|
|
46
51
|
listMark?: string;
|
|
@@ -57,6 +62,10 @@ interface CellProps {
|
|
|
57
62
|
right?: Stroke;
|
|
58
63
|
bg?: string;
|
|
59
64
|
padPt?: number;
|
|
65
|
+
padT?: number;
|
|
66
|
+
padB?: number;
|
|
67
|
+
padL?: number;
|
|
68
|
+
padR?: number;
|
|
60
69
|
align?: Align;
|
|
61
70
|
va?: VAlign;
|
|
62
71
|
isHeader?: boolean;
|
|
@@ -75,6 +84,7 @@ interface GridProps {
|
|
|
75
84
|
defaultStroke?: Stroke;
|
|
76
85
|
look?: TableLook;
|
|
77
86
|
headerRow?: boolean;
|
|
87
|
+
align?: Align;
|
|
78
88
|
}
|
|
79
89
|
interface PageDims {
|
|
80
90
|
wPt: number;
|
|
@@ -84,6 +94,8 @@ interface PageDims {
|
|
|
84
94
|
ml: number;
|
|
85
95
|
mr: number;
|
|
86
96
|
orient?: 'portrait' | 'landscape';
|
|
97
|
+
headerPt?: number;
|
|
98
|
+
footerPt?: number;
|
|
87
99
|
}
|
|
88
100
|
interface DocMeta {
|
|
89
101
|
title?: string;
|
|
@@ -93,6 +105,8 @@ interface DocMeta {
|
|
|
93
105
|
keywords?: string;
|
|
94
106
|
created?: string;
|
|
95
107
|
modified?: string;
|
|
108
|
+
zoom?: number;
|
|
109
|
+
viewMode?: string;
|
|
96
110
|
}
|
|
97
111
|
declare const A4: PageDims;
|
|
98
112
|
declare const A4_LANDSCAPE: PageDims;
|
|
@@ -141,14 +155,14 @@ interface LinkNode {
|
|
|
141
155
|
interface ParaNode {
|
|
142
156
|
tag: 'para';
|
|
143
157
|
props: ParaProps;
|
|
144
|
-
kids: (SpanNode | ImgNode | LinkNode)[];
|
|
158
|
+
kids: (SpanNode | ImgNode | LinkNode | GridNode)[];
|
|
145
159
|
}
|
|
146
160
|
interface CellNode {
|
|
147
161
|
tag: 'cell';
|
|
148
162
|
cs: number;
|
|
149
163
|
rs: number;
|
|
150
164
|
props: CellProps;
|
|
151
|
-
kids: ParaNode[];
|
|
165
|
+
kids: (ParaNode | GridNode)[];
|
|
152
166
|
}
|
|
153
167
|
interface RowNode {
|
|
154
168
|
tag: 'row';
|
|
@@ -165,8 +179,16 @@ interface SheetNode {
|
|
|
165
179
|
tag: 'sheet';
|
|
166
180
|
dims: PageDims;
|
|
167
181
|
kids: ContentNode[];
|
|
168
|
-
|
|
169
|
-
|
|
182
|
+
headers?: {
|
|
183
|
+
default?: ParaNode[];
|
|
184
|
+
first?: ParaNode[];
|
|
185
|
+
even?: ParaNode[];
|
|
186
|
+
};
|
|
187
|
+
footers?: {
|
|
188
|
+
default?: ParaNode[];
|
|
189
|
+
first?: ParaNode[];
|
|
190
|
+
even?: ParaNode[];
|
|
191
|
+
};
|
|
170
192
|
}
|
|
171
193
|
interface DocRoot {
|
|
172
194
|
tag: 'root';
|
|
@@ -189,14 +211,19 @@ interface Fail {
|
|
|
189
211
|
declare function succeed<T>(data: T, warns?: string[]): Ok<T>;
|
|
190
212
|
declare function fail(error: string, warns?: string[]): Fail;
|
|
191
213
|
|
|
192
|
-
interface
|
|
214
|
+
interface EncoderOptions {
|
|
215
|
+
[key: string]: any;
|
|
216
|
+
}
|
|
217
|
+
interface Encoder {
|
|
193
218
|
readonly format: string;
|
|
194
|
-
|
|
219
|
+
readonly aliases?: string[];
|
|
220
|
+
encode(doc: DocRoot, options?: EncoderOptions): Promise<Outcome<Uint8Array>>;
|
|
195
221
|
}
|
|
196
222
|
|
|
197
|
-
interface
|
|
223
|
+
interface Decoder {
|
|
198
224
|
readonly format: string;
|
|
199
|
-
|
|
225
|
+
readonly aliases?: string[];
|
|
226
|
+
decode(data: Uint8Array): Promise<Outcome<DocRoot>>;
|
|
200
227
|
}
|
|
201
228
|
|
|
202
229
|
declare class Pipeline {
|
|
@@ -208,7 +235,7 @@ declare class Pipeline {
|
|
|
208
235
|
/** File/Blob 비동기 입력 */
|
|
209
236
|
static openAsync(input: File | Blob | Uint8Array | string, fmt?: string): Promise<Pipeline>;
|
|
210
237
|
/** 목표 포맷으로 변환 */
|
|
211
|
-
to(targetFmt: string): Promise<Outcome<Uint8Array>>;
|
|
238
|
+
to(targetFmt: string, options?: EncoderOptions): Promise<Outcome<Uint8Array>>;
|
|
212
239
|
/** DocRoot만 추출 (인코딩 없이) */
|
|
213
240
|
inspect(): Promise<Outcome<DocRoot>>;
|
|
214
241
|
}
|
|
@@ -227,8 +254,8 @@ declare const registry: FormatRegistry;
|
|
|
227
254
|
|
|
228
255
|
declare function buildRoot(meta?: DocMeta, kids?: SheetNode[]): DocRoot;
|
|
229
256
|
declare function buildSheet(kids?: ContentNode[], dims?: PageDims, opts?: {
|
|
230
|
-
|
|
231
|
-
|
|
257
|
+
headers?: SheetNode["headers"];
|
|
258
|
+
footers?: SheetNode["footers"];
|
|
232
259
|
}): SheetNode;
|
|
233
260
|
declare function buildPageNum(format?: PageNumNode['format']): PageNumNode;
|
|
234
261
|
declare function buildBr(): BrNode;
|
|
@@ -238,7 +265,7 @@ declare function buildSpan(content: string, props?: TextProps): SpanNode;
|
|
|
238
265
|
declare function buildImg(b64: string, mime: ImgNode['mime'], w: number, h: number, alt?: string, layout?: ImgLayout): ImgNode;
|
|
239
266
|
declare function buildGrid(kids: RowNode[], props?: GridProps): GridNode;
|
|
240
267
|
declare function buildRow(kids: CellNode[], heightPt?: number): RowNode;
|
|
241
|
-
declare function buildCell(kids: ParaNode[], opts?: {
|
|
268
|
+
declare function buildCell(kids: (ParaNode | GridNode)[], opts?: {
|
|
242
269
|
cs?: number;
|
|
243
270
|
rs?: number;
|
|
244
271
|
props?: CellProps;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
type Align = 'left' | 'center' | 'right' | 'justify';
|
|
2
|
-
type ImgWrap = 'inline' | 'square' | 'tight' | 'through' | 'none' | 'behind' | 'front';
|
|
2
|
+
type ImgWrap = 'inline' | 'square' | 'tight' | 'through' | 'none' | 'behind' | 'front' | 'topAndBottom';
|
|
3
3
|
type ImgHorzAlign = 'left' | 'center' | 'right';
|
|
4
4
|
type ImgVertAlign = 'top' | 'center' | 'bottom';
|
|
5
5
|
type ImgHorzRelTo = 'margin' | 'column' | 'page' | 'para';
|
|
@@ -21,7 +21,7 @@ interface ImgLayout {
|
|
|
21
21
|
}
|
|
22
22
|
type VAlign = 'top' | 'mid' | 'bot';
|
|
23
23
|
type Heading = 1 | 2 | 3 | 4 | 5 | 6;
|
|
24
|
-
type StrokeKind = 'solid' | 'dash' | 'dot' | 'double' | 'none';
|
|
24
|
+
type StrokeKind = 'solid' | 'dash' | 'dot' | 'double' | 'none' | 'dashDot' | 'dashDotDot' | 'wave';
|
|
25
25
|
interface TextProps {
|
|
26
26
|
b?: boolean;
|
|
27
27
|
i?: boolean;
|
|
@@ -37,10 +37,15 @@ interface TextProps {
|
|
|
37
37
|
interface ParaProps {
|
|
38
38
|
align?: Align;
|
|
39
39
|
heading?: Heading;
|
|
40
|
+
styleId?: string;
|
|
40
41
|
indentPt?: number;
|
|
42
|
+
indentRightPt?: number;
|
|
43
|
+
firstLineIndentPt?: number;
|
|
44
|
+
leftMargin?: number;
|
|
41
45
|
spaceBefore?: number;
|
|
42
46
|
spaceAfter?: number;
|
|
43
47
|
lineHeight?: number;
|
|
48
|
+
lineHeightFixed?: number;
|
|
44
49
|
listLv?: number;
|
|
45
50
|
listOrd?: boolean;
|
|
46
51
|
listMark?: string;
|
|
@@ -57,6 +62,10 @@ interface CellProps {
|
|
|
57
62
|
right?: Stroke;
|
|
58
63
|
bg?: string;
|
|
59
64
|
padPt?: number;
|
|
65
|
+
padT?: number;
|
|
66
|
+
padB?: number;
|
|
67
|
+
padL?: number;
|
|
68
|
+
padR?: number;
|
|
60
69
|
align?: Align;
|
|
61
70
|
va?: VAlign;
|
|
62
71
|
isHeader?: boolean;
|
|
@@ -75,6 +84,7 @@ interface GridProps {
|
|
|
75
84
|
defaultStroke?: Stroke;
|
|
76
85
|
look?: TableLook;
|
|
77
86
|
headerRow?: boolean;
|
|
87
|
+
align?: Align;
|
|
78
88
|
}
|
|
79
89
|
interface PageDims {
|
|
80
90
|
wPt: number;
|
|
@@ -84,6 +94,8 @@ interface PageDims {
|
|
|
84
94
|
ml: number;
|
|
85
95
|
mr: number;
|
|
86
96
|
orient?: 'portrait' | 'landscape';
|
|
97
|
+
headerPt?: number;
|
|
98
|
+
footerPt?: number;
|
|
87
99
|
}
|
|
88
100
|
interface DocMeta {
|
|
89
101
|
title?: string;
|
|
@@ -93,6 +105,8 @@ interface DocMeta {
|
|
|
93
105
|
keywords?: string;
|
|
94
106
|
created?: string;
|
|
95
107
|
modified?: string;
|
|
108
|
+
zoom?: number;
|
|
109
|
+
viewMode?: string;
|
|
96
110
|
}
|
|
97
111
|
declare const A4: PageDims;
|
|
98
112
|
declare const A4_LANDSCAPE: PageDims;
|
|
@@ -141,14 +155,14 @@ interface LinkNode {
|
|
|
141
155
|
interface ParaNode {
|
|
142
156
|
tag: 'para';
|
|
143
157
|
props: ParaProps;
|
|
144
|
-
kids: (SpanNode | ImgNode | LinkNode)[];
|
|
158
|
+
kids: (SpanNode | ImgNode | LinkNode | GridNode)[];
|
|
145
159
|
}
|
|
146
160
|
interface CellNode {
|
|
147
161
|
tag: 'cell';
|
|
148
162
|
cs: number;
|
|
149
163
|
rs: number;
|
|
150
164
|
props: CellProps;
|
|
151
|
-
kids: ParaNode[];
|
|
165
|
+
kids: (ParaNode | GridNode)[];
|
|
152
166
|
}
|
|
153
167
|
interface RowNode {
|
|
154
168
|
tag: 'row';
|
|
@@ -165,8 +179,16 @@ interface SheetNode {
|
|
|
165
179
|
tag: 'sheet';
|
|
166
180
|
dims: PageDims;
|
|
167
181
|
kids: ContentNode[];
|
|
168
|
-
|
|
169
|
-
|
|
182
|
+
headers?: {
|
|
183
|
+
default?: ParaNode[];
|
|
184
|
+
first?: ParaNode[];
|
|
185
|
+
even?: ParaNode[];
|
|
186
|
+
};
|
|
187
|
+
footers?: {
|
|
188
|
+
default?: ParaNode[];
|
|
189
|
+
first?: ParaNode[];
|
|
190
|
+
even?: ParaNode[];
|
|
191
|
+
};
|
|
170
192
|
}
|
|
171
193
|
interface DocRoot {
|
|
172
194
|
tag: 'root';
|
|
@@ -189,14 +211,19 @@ interface Fail {
|
|
|
189
211
|
declare function succeed<T>(data: T, warns?: string[]): Ok<T>;
|
|
190
212
|
declare function fail(error: string, warns?: string[]): Fail;
|
|
191
213
|
|
|
192
|
-
interface
|
|
214
|
+
interface EncoderOptions {
|
|
215
|
+
[key: string]: any;
|
|
216
|
+
}
|
|
217
|
+
interface Encoder {
|
|
193
218
|
readonly format: string;
|
|
194
|
-
|
|
219
|
+
readonly aliases?: string[];
|
|
220
|
+
encode(doc: DocRoot, options?: EncoderOptions): Promise<Outcome<Uint8Array>>;
|
|
195
221
|
}
|
|
196
222
|
|
|
197
|
-
interface
|
|
223
|
+
interface Decoder {
|
|
198
224
|
readonly format: string;
|
|
199
|
-
|
|
225
|
+
readonly aliases?: string[];
|
|
226
|
+
decode(data: Uint8Array): Promise<Outcome<DocRoot>>;
|
|
200
227
|
}
|
|
201
228
|
|
|
202
229
|
declare class Pipeline {
|
|
@@ -208,7 +235,7 @@ declare class Pipeline {
|
|
|
208
235
|
/** File/Blob 비동기 입력 */
|
|
209
236
|
static openAsync(input: File | Blob | Uint8Array | string, fmt?: string): Promise<Pipeline>;
|
|
210
237
|
/** 목표 포맷으로 변환 */
|
|
211
|
-
to(targetFmt: string): Promise<Outcome<Uint8Array>>;
|
|
238
|
+
to(targetFmt: string, options?: EncoderOptions): Promise<Outcome<Uint8Array>>;
|
|
212
239
|
/** DocRoot만 추출 (인코딩 없이) */
|
|
213
240
|
inspect(): Promise<Outcome<DocRoot>>;
|
|
214
241
|
}
|
|
@@ -227,8 +254,8 @@ declare const registry: FormatRegistry;
|
|
|
227
254
|
|
|
228
255
|
declare function buildRoot(meta?: DocMeta, kids?: SheetNode[]): DocRoot;
|
|
229
256
|
declare function buildSheet(kids?: ContentNode[], dims?: PageDims, opts?: {
|
|
230
|
-
|
|
231
|
-
|
|
257
|
+
headers?: SheetNode["headers"];
|
|
258
|
+
footers?: SheetNode["footers"];
|
|
232
259
|
}): SheetNode;
|
|
233
260
|
declare function buildPageNum(format?: PageNumNode['format']): PageNumNode;
|
|
234
261
|
declare function buildBr(): BrNode;
|
|
@@ -238,7 +265,7 @@ declare function buildSpan(content: string, props?: TextProps): SpanNode;
|
|
|
238
265
|
declare function buildImg(b64: string, mime: ImgNode['mime'], w: number, h: number, alt?: string, layout?: ImgLayout): ImgNode;
|
|
239
266
|
declare function buildGrid(kids: RowNode[], props?: GridProps): GridNode;
|
|
240
267
|
declare function buildRow(kids: CellNode[], heightPt?: number): RowNode;
|
|
241
|
-
declare function buildCell(kids: ParaNode[], opts?: {
|
|
268
|
+
declare function buildCell(kids: (ParaNode | GridNode)[], opts?: {
|
|
242
269
|
cs?: number;
|
|
243
270
|
rs?: number;
|
|
244
271
|
props?: CellProps;
|