kordoc 2.2.2 → 2.2.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.
- package/dist/{chunk-R34CFFNV.js → chunk-SY2RFVLW.js} +1089 -149
- package/dist/chunk-SY2RFVLW.js.map +1 -0
- package/dist/cli.js +149 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +847 -248
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +97 -7
- package/dist/index.d.ts +97 -7
- package/dist/index.js +843 -248
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +126 -6
- package/dist/mcp.js.map +1 -1
- package/dist/{watch-VNJDVUVQ.js → watch-5P7DJ3HG.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-R34CFFNV.js.map +0 -1
- /package/dist/{watch-VNJDVUVQ.js.map → watch-5P7DJ3HG.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
VERSION,
|
|
4
|
+
blocksToMarkdown,
|
|
5
|
+
extractFormFields,
|
|
6
|
+
fillFormFields,
|
|
7
|
+
fillHwpx,
|
|
8
|
+
markdownToHwpx,
|
|
4
9
|
parse,
|
|
5
10
|
sanitizeError,
|
|
6
11
|
toArrayBuffer
|
|
7
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-SY2RFVLW.js";
|
|
8
13
|
import {
|
|
9
|
-
detectFormat
|
|
14
|
+
detectFormat,
|
|
15
|
+
detectZipFormat
|
|
10
16
|
} from "./chunk-5Y2Q3BRW.js";
|
|
11
17
|
import "./chunk-MOL7MDBG.js";
|
|
12
18
|
|
|
13
19
|
// src/cli.ts
|
|
14
20
|
import { readFileSync, writeFileSync, mkdirSync, statSync } from "fs";
|
|
15
|
-
import { basename, resolve } from "path";
|
|
21
|
+
import { basename, dirname, resolve, extname } from "path";
|
|
16
22
|
import { Command } from "commander";
|
|
17
23
|
var program = new Command();
|
|
18
24
|
program.name("kordoc").description("\uBAA8\uB450 \uD30C\uC2F1\uD574\uBC84\uB9AC\uACA0\uB2E4 \u2014 HWP, HWPX, PDF, XLSX, DOCX \u2192 Markdown").version(VERSION).argument("<files...>", "\uBCC0\uD658\uD560 \uD30C\uC77C \uACBD\uB85C (HWP, HWPX, PDF, XLSX, DOCX)").option("-o, --output <path>", "\uCD9C\uB825 \uD30C\uC77C \uACBD\uB85C (\uB2E8\uC77C \uD30C\uC77C \uC2DC)").option("-d, --out-dir <dir>", "\uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC (\uB2E4\uC911 \uD30C\uC77C \uC2DC)").option("-p, --pages <range>", "\uD398\uC774\uC9C0/\uC139\uC158 \uBC94\uC704 (\uC608: 1-3, 1,3,5)").option("--format <type>", "\uCD9C\uB825 \uD615\uC2DD: markdown (\uAE30\uBCF8) \uB610\uB294 json", "markdown").option("--no-header-footer", "PDF \uBA38\uB9AC\uAE00/\uBC14\uB2E5\uAE00 \uC790\uB3D9 \uC81C\uAC70").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (files, opts) => {
|
|
@@ -105,7 +111,7 @@ program.name("kordoc").description("\uBAA8\uB450 \uD30C\uC2F1\uD574\uBC84\uB9AC\
|
|
|
105
111
|
}
|
|
106
112
|
});
|
|
107
113
|
program.command("watch <dir>").description("\uB514\uB809\uD1A0\uB9AC \uAC10\uC2DC \u2014 \uC0C8 \uBB38\uC11C \uC790\uB3D9 \uBCC0\uD658").option("--webhook <url>", "\uACB0\uACFC \uC804\uC1A1 \uC6F9\uD6C5 URL").option("-d, --out-dir <dir>", "\uBCC0\uD658 \uACB0\uACFC \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC").option("-p, --pages <range>", "\uD398\uC774\uC9C0/\uC139\uC158 \uBC94\uC704").option("--format <type>", "\uCD9C\uB825 \uD615\uC2DD: markdown \uB610\uB294 json", "markdown").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (dir, opts) => {
|
|
108
|
-
const { watchDirectory } = await import("./watch-
|
|
114
|
+
const { watchDirectory } = await import("./watch-5P7DJ3HG.js");
|
|
109
115
|
await watchDirectory({
|
|
110
116
|
dir,
|
|
111
117
|
outDir: opts.outDir,
|
|
@@ -115,5 +121,144 @@ program.command("watch <dir>").description("\uB514\uB809\uD1A0\uB9AC \uAC10\uC2D
|
|
|
115
121
|
silent: opts.silent
|
|
116
122
|
});
|
|
117
123
|
});
|
|
124
|
+
program.command("fill <template>").description("\uC11C\uC2DD \uBB38\uC11C\uC758 \uBE48\uCE78\uC744 \uCC44\uC6CC\uC11C \uCD9C\uB825 \u2014 kordoc fill \uC2E0\uCCAD\uC11C.hwpx -f '\uC131\uBA85=\uD64D\uAE38\uB3D9,\uC804\uD654=010-1234-5678' -o \uACB0\uACFC.hwpx").option("-f, --fields <pairs>", "\uCC44\uC6B8 \uD544\uB4DC (key=value \uC27C\uD45C \uAD6C\uBD84 \uB610\uB294 JSON)").option("-j, --json <path>", "\uCC44\uC6B8 \uD544\uB4DC JSON \uD30C\uC77C \uACBD\uB85C").option("-o, --output <path>", "\uCD9C\uB825 \uD30C\uC77C \uACBD\uB85C (\uD655\uC7A5\uC790\uB85C \uD3EC\uB9F7 \uACB0\uC815: .md, .hwpx)").option("--format <type>", "\uCD9C\uB825 \uD3EC\uB9F7: hwpx-preserve (\uAE30\uBCF8, \uC6D0\uBCF8 \uC2A4\uD0C0\uC77C \uBCF4\uC874), hwpx, markdown", "hwpx-preserve").option("--dry-run", "\uCC44\uC6B0\uC9C0 \uC54A\uACE0 \uC11C\uC2DD \uD544\uB4DC \uBAA9\uB85D\uB9CC \uCD9C\uB825").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (template, opts) => {
|
|
125
|
+
try {
|
|
126
|
+
const absPath = resolve(template);
|
|
127
|
+
const fileSize = statSync(absPath).size;
|
|
128
|
+
if (fileSize > 500 * 1024 * 1024) {
|
|
129
|
+
process.stderr.write(`[kordoc] \uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${(fileSize / 1024 / 1024).toFixed(1)}MB)
|
|
130
|
+
`);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
const buffer = readFileSync(absPath);
|
|
134
|
+
const arrayBuffer = toArrayBuffer(buffer);
|
|
135
|
+
if (!opts.silent) process.stderr.write(`[kordoc] ${basename(absPath)} \uD30C\uC2F1 \uC911...
|
|
136
|
+
`);
|
|
137
|
+
if (opts.dryRun) {
|
|
138
|
+
const result2 = await parse(arrayBuffer);
|
|
139
|
+
if (!result2.success) {
|
|
140
|
+
process.stderr.write(`[kordoc] \uD30C\uC2F1 \uC2E4\uD328: ${result2.error}
|
|
141
|
+
`);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
const formInfo2 = extractFormFields(result2.blocks);
|
|
145
|
+
if (formInfo2.fields.length === 0) {
|
|
146
|
+
process.stderr.write(`[kordoc] \uC11C\uC2DD \uD544\uB4DC\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
147
|
+
`);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
process.stdout.write(JSON.stringify(formInfo2, null, 2) + "\n");
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
let values = {};
|
|
154
|
+
if (opts.json) {
|
|
155
|
+
const jsonPath = resolve(opts.json);
|
|
156
|
+
const jsonContent = readFileSync(jsonPath, "utf-8");
|
|
157
|
+
values = JSON.parse(jsonContent);
|
|
158
|
+
} else if (opts.fields) {
|
|
159
|
+
const fieldsStr = opts.fields;
|
|
160
|
+
if (fieldsStr.startsWith("{")) {
|
|
161
|
+
values = JSON.parse(fieldsStr);
|
|
162
|
+
} else {
|
|
163
|
+
const pairs = fieldsStr.split(/,(?=[가-힣A-Za-z][가-힣A-Za-z\s]*=)/);
|
|
164
|
+
for (const pair of pairs) {
|
|
165
|
+
const eqIdx = pair.indexOf("=");
|
|
166
|
+
if (eqIdx > 0) {
|
|
167
|
+
const key = pair.slice(0, eqIdx).trim();
|
|
168
|
+
const val = pair.slice(eqIdx + 1).trim();
|
|
169
|
+
values[key] = val;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
process.stderr.write(`[kordoc] \uCC44\uC6B8 \uD544\uB4DC\uB97C \uC9C0\uC815\uD574\uC8FC\uC138\uC694 (-f \uB610\uB294 -j \uC635\uC158)
|
|
175
|
+
`);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
let outputFormat = opts.format;
|
|
179
|
+
if (opts.output) {
|
|
180
|
+
const ext = extname(opts.output).toLowerCase();
|
|
181
|
+
if (ext === ".hwpx") outputFormat = outputFormat === "markdown" ? "hwpx-preserve" : outputFormat;
|
|
182
|
+
else if (ext === ".md") outputFormat = "markdown";
|
|
183
|
+
}
|
|
184
|
+
if (outputFormat === "hwpx-preserve") {
|
|
185
|
+
const format = detectFormat(arrayBuffer);
|
|
186
|
+
let isHwpx = format === "hwpx";
|
|
187
|
+
if (isHwpx) {
|
|
188
|
+
const zipFormat = await detectZipFormat(arrayBuffer);
|
|
189
|
+
isHwpx = zipFormat === "hwpx";
|
|
190
|
+
}
|
|
191
|
+
if (!isHwpx) {
|
|
192
|
+
if (!opts.silent) process.stderr.write(`[kordoc] HWPX\uAC00 \uC544\uB2C8\uBBC0\uB85C hwpx \uBAA8\uB4DC\uB85C \uC804\uD658\uD569\uB2C8\uB2E4
|
|
193
|
+
`);
|
|
194
|
+
outputFormat = "hwpx";
|
|
195
|
+
} else {
|
|
196
|
+
const hwpxResult = await fillHwpx(arrayBuffer, values);
|
|
197
|
+
if (!opts.silent) {
|
|
198
|
+
process.stderr.write(`[kordoc] ${hwpxResult.filled.length}\uAC1C \uD544\uB4DC \uCC44\uC6C0 (\uC6D0\uBCF8 \uC2A4\uD0C0\uC77C \uBCF4\uC874)
|
|
199
|
+
`);
|
|
200
|
+
if (hwpxResult.unmatched.length > 0) {
|
|
201
|
+
process.stderr.write(`[kordoc] \u26A0\uFE0F \uB9E4\uCE6D \uC2E4\uD328: ${hwpxResult.unmatched.join(", ")}
|
|
202
|
+
`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (opts.output) {
|
|
206
|
+
mkdirSync(dirname(resolve(opts.output)), { recursive: true });
|
|
207
|
+
writeFileSync(resolve(opts.output), Buffer.from(hwpxResult.buffer));
|
|
208
|
+
if (!opts.silent) process.stderr.write(`[kordoc] \u2192 ${resolve(opts.output)}
|
|
209
|
+
`);
|
|
210
|
+
} else {
|
|
211
|
+
process.stdout.write(Buffer.from(hwpxResult.buffer));
|
|
212
|
+
}
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const result = await parse(arrayBuffer);
|
|
217
|
+
if (!result.success) {
|
|
218
|
+
process.stderr.write(`[kordoc] \uD30C\uC2F1 \uC2E4\uD328: ${result.error}
|
|
219
|
+
`);
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
const formInfo = extractFormFields(result.blocks);
|
|
223
|
+
if (!opts.silent) {
|
|
224
|
+
process.stderr.write(`[kordoc] \uC11C\uC2DD \uD544\uB4DC ${formInfo.fields.length}\uAC1C \uAC10\uC9C0 (\uD655\uC2E0\uB3C4 ${(formInfo.confidence * 100).toFixed(0)}%)
|
|
225
|
+
`);
|
|
226
|
+
}
|
|
227
|
+
const fillResult = fillFormFields(result.blocks, values);
|
|
228
|
+
if (!opts.silent) {
|
|
229
|
+
process.stderr.write(`[kordoc] ${fillResult.filled.length}\uAC1C \uD544\uB4DC \uCC44\uC6C0
|
|
230
|
+
`);
|
|
231
|
+
if (fillResult.unmatched.length > 0) {
|
|
232
|
+
process.stderr.write(`[kordoc] \u26A0\uFE0F \uB9E4\uCE6D \uC2E4\uD328: ${fillResult.unmatched.join(", ")}
|
|
233
|
+
`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const markdown = blocksToMarkdown(fillResult.blocks);
|
|
237
|
+
if (outputFormat === "hwpx") {
|
|
238
|
+
const hwpxBuffer = await markdownToHwpx(markdown);
|
|
239
|
+
if (opts.output) {
|
|
240
|
+
mkdirSync(dirname(resolve(opts.output)), { recursive: true });
|
|
241
|
+
writeFileSync(resolve(opts.output), Buffer.from(hwpxBuffer));
|
|
242
|
+
if (!opts.silent) process.stderr.write(`[kordoc] \u2192 ${resolve(opts.output)}
|
|
243
|
+
`);
|
|
244
|
+
} else {
|
|
245
|
+
process.stdout.write(Buffer.from(hwpxBuffer));
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
if (opts.output) {
|
|
249
|
+
mkdirSync(dirname(resolve(opts.output)), { recursive: true });
|
|
250
|
+
writeFileSync(resolve(opts.output), markdown, "utf-8");
|
|
251
|
+
if (!opts.silent) process.stderr.write(`[kordoc] \u2192 ${resolve(opts.output)}
|
|
252
|
+
`);
|
|
253
|
+
} else {
|
|
254
|
+
process.stdout.write(markdown + "\n");
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
} catch (err) {
|
|
258
|
+
process.stderr.write(`[kordoc] \uC624\uB958: ${sanitizeError(err)}
|
|
259
|
+
`);
|
|
260
|
+
process.exit(1);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
118
263
|
program.parse();
|
|
119
264
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["/** kordoc CLI — 모두 파싱해버리겠다 */\n\nimport { readFileSync, writeFileSync, mkdirSync, statSync } from \"fs\"\nimport { basename, resolve } from \"path\"\nimport { Command } from \"commander\"\nimport { parse, detectFormat } from \"./index.js\"\nimport type { ParseOptions } from \"./types.js\"\nimport { VERSION, toArrayBuffer, sanitizeError } from \"./utils.js\"\n\nconst program = new Command()\n\nprogram\n .name(\"kordoc\")\n .description(\"모두 파싱해버리겠다 — HWP, HWPX, PDF, XLSX, DOCX → Markdown\")\n .version(VERSION)\n .argument(\"<files...>\", \"변환할 파일 경로 (HWP, HWPX, PDF, XLSX, DOCX)\")\n .option(\"-o, --output <path>\", \"출력 파일 경로 (단일 파일 시)\")\n .option(\"-d, --out-dir <dir>\", \"출력 디렉토리 (다중 파일 시)\")\n .option(\"-p, --pages <range>\", \"페이지/섹션 범위 (예: 1-3, 1,3,5)\")\n .option(\"--format <type>\", \"출력 형식: markdown (기본) 또는 json\", \"markdown\")\n .option(\"--no-header-footer\", \"PDF 머리글/바닥글 자동 제거\")\n .option(\"--silent\", \"진행 메시지 숨기기\")\n .action(async (files: string[], opts) => {\n const validFormats = [\"markdown\", \"json\"]\n if (!validFormats.includes(opts.format)) {\n process.stderr.write(`[kordoc] 지원하지 않는 형식: ${opts.format} (markdown 또는 json)\\n`)\n process.exit(1)\n }\n for (let fi = 0; fi < files.length; fi++) {\n const filePath = files[fi]\n const absPath = resolve(filePath)\n const fileName = basename(absPath)\n const filePrefix = files.length > 1 ? `[${fi + 1}/${files.length}] ` : \"\"\n\n try {\n const fileSize = statSync(absPath).size\n if (fileSize > 500 * 1024 * 1024) {\n process.stderr.write(`\\n[kordoc] SKIP: ${fileName} — 파일이 너무 큽니다 (${(fileSize / 1024 / 1024).toFixed(1)}MB)\\n`)\n process.exitCode = 1\n continue\n }\n const buffer = readFileSync(absPath)\n const arrayBuffer = toArrayBuffer(buffer)\n const format = detectFormat(arrayBuffer)\n\n if (!opts.silent) {\n process.stderr.write(`[kordoc] ${filePrefix}${fileName} (${format}) ...`)\n }\n\n const parseOptions: ParseOptions = {}\n if (opts.pages) parseOptions.pages = opts.pages as string\n if (opts.headerFooter === false) parseOptions.removeHeaderFooter = false\n if (!opts.silent) {\n parseOptions.onProgress = (current: number, total: number) => {\n process.stderr.write(`\\r[kordoc] ${filePrefix}${fileName} (${format}) [${current}/${total}]`)\n }\n }\n const result = await parse(arrayBuffer, parseOptions)\n\n if (!result.success) {\n process.stderr.write(` FAIL\\n`)\n process.stderr.write(` → ${result.error}\\n`)\n process.exitCode = 1\n continue\n }\n\n if (!opts.silent) process.stderr.write(` OK\\n`)\n\n let markdown = result.markdown\n // --out-dir 시 이미지 참조 경로에 images/ 접두사 추가\n if (opts.outDir && result.images?.length) {\n markdown = markdown.replace(/!\\[image\\]\\(image_/g, \"\n }\n const output = opts.format === \"json\"\n ? JSON.stringify(result, (_key, value) =>\n value instanceof Uint8Array ? Buffer.from(value).toString(\"base64\") : value\n , 2)\n : markdown\n\n // 이미지 저장 (--out-dir 또는 --output 시)\n const saveImages = (dir: string) => {\n if (!result.images?.length) return\n const imgDir = resolve(dir, \"images\")\n mkdirSync(imgDir, { recursive: true })\n for (const img of result.images) {\n writeFileSync(resolve(imgDir, img.filename), img.data)\n }\n if (!opts.silent) process.stderr.write(` → ${result.images.length}개 이미지 → ${imgDir}\\n`)\n }\n\n if (opts.output && files.length === 1) {\n writeFileSync(opts.output, output, \"utf-8\")\n if (!opts.silent) process.stderr.write(` → ${opts.output}\\n`)\n saveImages(resolve(opts.output, \"..\"))\n } else if (opts.outDir) {\n mkdirSync(opts.outDir, { recursive: true })\n const outExt = opts.format === \"json\" ? \".json\" : \".md\"\n const outPath = resolve(opts.outDir, fileName.replace(/\\.[^.]+$/, outExt))\n writeFileSync(outPath, output, \"utf-8\")\n if (!opts.silent) process.stderr.write(` → ${outPath}\\n`)\n saveImages(opts.outDir)\n } else {\n process.stdout.write(output + \"\\n\")\n }\n } catch (err) {\n process.stderr.write(`\\n[kordoc] ERROR: ${fileName} — ${sanitizeError(err)}\\n`)\n process.exitCode = 1\n }\n }\n })\n\nprogram\n .command(\"watch <dir>\")\n .description(\"디렉토리 감시 — 새 문서 자동 변환\")\n .option(\"--webhook <url>\", \"결과 전송 웹훅 URL\")\n .option(\"-d, --out-dir <dir>\", \"변환 결과 출력 디렉토리\")\n .option(\"-p, --pages <range>\", \"페이지/섹션 범위\")\n .option(\"--format <type>\", \"출력 형식: markdown 또는 json\", \"markdown\")\n .option(\"--silent\", \"진행 메시지 숨기기\")\n .action(async (dir: string, opts) => {\n const { watchDirectory } = await import(\"./watch.js\")\n await watchDirectory({\n dir,\n outDir: opts.outDir,\n webhook: opts.webhook,\n format: opts.format,\n pages: opts.pages,\n silent: opts.silent,\n })\n })\n\nprogram.parse()\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["/** kordoc CLI — 모두 파싱해버리겠다 */\r\n\r\nimport { readFileSync, writeFileSync, mkdirSync, statSync } from \"fs\"\r\nimport { basename, dirname, resolve, extname } from \"path\"\r\nimport { Command } from \"commander\"\r\nimport { parse, detectFormat, detectZipFormat, fillFormFields, extractFormFields, blocksToMarkdown, markdownToHwpx, fillHwpx } from \"./index.js\"\r\nimport type { ParseOptions } from \"./types.js\"\r\nimport { VERSION, toArrayBuffer, sanitizeError } from \"./utils.js\"\r\n\r\nconst program = new Command()\r\n\r\nprogram\r\n .name(\"kordoc\")\r\n .description(\"모두 파싱해버리겠다 — HWP, HWPX, PDF, XLSX, DOCX → Markdown\")\r\n .version(VERSION)\r\n .argument(\"<files...>\", \"변환할 파일 경로 (HWP, HWPX, PDF, XLSX, DOCX)\")\r\n .option(\"-o, --output <path>\", \"출력 파일 경로 (단일 파일 시)\")\r\n .option(\"-d, --out-dir <dir>\", \"출력 디렉토리 (다중 파일 시)\")\r\n .option(\"-p, --pages <range>\", \"페이지/섹션 범위 (예: 1-3, 1,3,5)\")\r\n .option(\"--format <type>\", \"출력 형식: markdown (기본) 또는 json\", \"markdown\")\r\n .option(\"--no-header-footer\", \"PDF 머리글/바닥글 자동 제거\")\r\n .option(\"--silent\", \"진행 메시지 숨기기\")\r\n .action(async (files: string[], opts) => {\r\n const validFormats = [\"markdown\", \"json\"]\r\n if (!validFormats.includes(opts.format)) {\r\n process.stderr.write(`[kordoc] 지원하지 않는 형식: ${opts.format} (markdown 또는 json)\\n`)\r\n process.exit(1)\r\n }\r\n for (let fi = 0; fi < files.length; fi++) {\r\n const filePath = files[fi]\r\n const absPath = resolve(filePath)\r\n const fileName = basename(absPath)\r\n const filePrefix = files.length > 1 ? `[${fi + 1}/${files.length}] ` : \"\"\r\n\r\n try {\r\n const fileSize = statSync(absPath).size\r\n if (fileSize > 500 * 1024 * 1024) {\r\n process.stderr.write(`\\n[kordoc] SKIP: ${fileName} — 파일이 너무 큽니다 (${(fileSize / 1024 / 1024).toFixed(1)}MB)\\n`)\r\n process.exitCode = 1\r\n continue\r\n }\r\n const buffer = readFileSync(absPath)\r\n const arrayBuffer = toArrayBuffer(buffer)\r\n const format = detectFormat(arrayBuffer)\r\n\r\n if (!opts.silent) {\r\n process.stderr.write(`[kordoc] ${filePrefix}${fileName} (${format}) ...`)\r\n }\r\n\r\n const parseOptions: ParseOptions = {}\r\n if (opts.pages) parseOptions.pages = opts.pages as string\r\n if (opts.headerFooter === false) parseOptions.removeHeaderFooter = false\r\n if (!opts.silent) {\r\n parseOptions.onProgress = (current: number, total: number) => {\r\n process.stderr.write(`\\r[kordoc] ${filePrefix}${fileName} (${format}) [${current}/${total}]`)\r\n }\r\n }\r\n const result = await parse(arrayBuffer, parseOptions)\r\n\r\n if (!result.success) {\r\n process.stderr.write(` FAIL\\n`)\r\n process.stderr.write(` → ${result.error}\\n`)\r\n process.exitCode = 1\r\n continue\r\n }\r\n\r\n if (!opts.silent) process.stderr.write(` OK\\n`)\r\n\r\n let markdown = result.markdown\r\n // --out-dir 시 이미지 참조 경로에 images/ 접두사 추가\r\n if (opts.outDir && result.images?.length) {\r\n markdown = markdown.replace(/!\\[image\\]\\(image_/g, \"\r\n }\r\n const output = opts.format === \"json\"\r\n ? JSON.stringify(result, (_key, value) =>\r\n value instanceof Uint8Array ? Buffer.from(value).toString(\"base64\") : value\r\n , 2)\r\n : markdown\r\n\r\n // 이미지 저장 (--out-dir 또는 --output 시)\r\n const saveImages = (dir: string) => {\r\n if (!result.images?.length) return\r\n const imgDir = resolve(dir, \"images\")\r\n mkdirSync(imgDir, { recursive: true })\r\n for (const img of result.images) {\r\n writeFileSync(resolve(imgDir, img.filename), img.data)\r\n }\r\n if (!opts.silent) process.stderr.write(` → ${result.images.length}개 이미지 → ${imgDir}\\n`)\r\n }\r\n\r\n if (opts.output && files.length === 1) {\r\n writeFileSync(opts.output, output, \"utf-8\")\r\n if (!opts.silent) process.stderr.write(` → ${opts.output}\\n`)\r\n saveImages(resolve(opts.output, \"..\"))\r\n } else if (opts.outDir) {\r\n mkdirSync(opts.outDir, { recursive: true })\r\n const outExt = opts.format === \"json\" ? \".json\" : \".md\"\r\n const outPath = resolve(opts.outDir, fileName.replace(/\\.[^.]+$/, outExt))\r\n writeFileSync(outPath, output, \"utf-8\")\r\n if (!opts.silent) process.stderr.write(` → ${outPath}\\n`)\r\n saveImages(opts.outDir)\r\n } else {\r\n process.stdout.write(output + \"\\n\")\r\n }\r\n } catch (err) {\r\n process.stderr.write(`\\n[kordoc] ERROR: ${fileName} — ${sanitizeError(err)}\\n`)\r\n process.exitCode = 1\r\n }\r\n }\r\n })\r\n\r\nprogram\r\n .command(\"watch <dir>\")\r\n .description(\"디렉토리 감시 — 새 문서 자동 변환\")\r\n .option(\"--webhook <url>\", \"결과 전송 웹훅 URL\")\r\n .option(\"-d, --out-dir <dir>\", \"변환 결과 출력 디렉토리\")\r\n .option(\"-p, --pages <range>\", \"페이지/섹션 범위\")\r\n .option(\"--format <type>\", \"출력 형식: markdown 또는 json\", \"markdown\")\r\n .option(\"--silent\", \"진행 메시지 숨기기\")\r\n .action(async (dir: string, opts) => {\r\n const { watchDirectory } = await import(\"./watch.js\")\r\n await watchDirectory({\r\n dir,\r\n outDir: opts.outDir,\r\n webhook: opts.webhook,\r\n format: opts.format,\r\n pages: opts.pages,\r\n silent: opts.silent,\r\n })\r\n })\r\n\r\nprogram\r\n .command(\"fill <template>\")\r\n .description(\"서식 문서의 빈칸을 채워서 출력 — kordoc fill 신청서.hwpx -f '성명=홍길동,전화=010-1234-5678' -o 결과.hwpx\")\r\n .option(\"-f, --fields <pairs>\", \"채울 필드 (key=value 쉼표 구분 또는 JSON)\")\r\n .option(\"-j, --json <path>\", \"채울 필드 JSON 파일 경로\")\r\n .option(\"-o, --output <path>\", \"출력 파일 경로 (확장자로 포맷 결정: .md, .hwpx)\")\r\n .option(\"--format <type>\", \"출력 포맷: hwpx-preserve (기본, 원본 스타일 보존), hwpx, markdown\", \"hwpx-preserve\")\r\n .option(\"--dry-run\", \"채우지 않고 서식 필드 목록만 출력\")\r\n .option(\"--silent\", \"진행 메시지 숨기기\")\r\n .action(async (template: string, opts) => {\r\n try {\r\n const absPath = resolve(template)\r\n const fileSize = statSync(absPath).size\r\n if (fileSize > 500 * 1024 * 1024) {\r\n process.stderr.write(`[kordoc] 파일이 너무 큽니다 (${(fileSize / 1024 / 1024).toFixed(1)}MB)\\n`)\r\n process.exit(1)\r\n }\r\n\r\n const buffer = readFileSync(absPath)\r\n const arrayBuffer = toArrayBuffer(buffer)\r\n\r\n if (!opts.silent) process.stderr.write(`[kordoc] ${basename(absPath)} 파싱 중...\\n`)\r\n\r\n // --dry-run: 필드 목록만 출력\r\n if (opts.dryRun) {\r\n const result = await parse(arrayBuffer)\r\n if (!result.success) {\r\n process.stderr.write(`[kordoc] 파싱 실패: ${result.error}\\n`)\r\n process.exit(1)\r\n }\r\n const formInfo = extractFormFields(result.blocks)\r\n if (formInfo.fields.length === 0) {\r\n process.stderr.write(`[kordoc] 서식 필드를 찾을 수 없습니다.\\n`)\r\n process.exit(1)\r\n }\r\n process.stdout.write(JSON.stringify(formInfo, null, 2) + \"\\n\")\r\n return\r\n }\r\n\r\n // 필드 값 파싱\r\n let values: Record<string, string> = {}\r\n if (opts.json) {\r\n const jsonPath = resolve(opts.json)\r\n const jsonContent = readFileSync(jsonPath, \"utf-8\")\r\n values = JSON.parse(jsonContent)\r\n } else if (opts.fields) {\r\n const fieldsStr: string = opts.fields\r\n if (fieldsStr.startsWith(\"{\")) {\r\n values = JSON.parse(fieldsStr)\r\n } else {\r\n // \"key1=value1,key2=value2\" 파싱 — 값에 쉼표가 있을 수 있으므로\r\n // '=' 앞의 키를 기준으로 분리 (쉼표+한글/영문+= 패턴)\r\n const pairs = fieldsStr.split(/,(?=[가-힣A-Za-z][가-힣A-Za-z\\s]*=)/)\r\n for (const pair of pairs) {\r\n const eqIdx = pair.indexOf(\"=\")\r\n if (eqIdx > 0) {\r\n const key = pair.slice(0, eqIdx).trim()\r\n const val = pair.slice(eqIdx + 1).trim()\r\n values[key] = val\r\n }\r\n }\r\n }\r\n } else {\r\n process.stderr.write(`[kordoc] 채울 필드를 지정해주세요 (-f 또는 -j 옵션)\\n`)\r\n process.exit(1)\r\n }\r\n\r\n // 출력 포맷 결정\r\n let outputFormat = opts.format as string\r\n if (opts.output) {\r\n const ext = extname(opts.output).toLowerCase()\r\n if (ext === \".hwpx\") outputFormat = outputFormat === \"markdown\" ? \"hwpx-preserve\" : outputFormat\r\n else if (ext === \".md\") outputFormat = \"markdown\"\r\n }\r\n\r\n // ─── hwpx-preserve: 원본 ZIP 직접 수정 ───\r\n if (outputFormat === \"hwpx-preserve\") {\r\n const format = detectFormat(arrayBuffer)\r\n let isHwpx = format === \"hwpx\"\r\n if (isHwpx) {\r\n const zipFormat = await detectZipFormat(arrayBuffer)\r\n isHwpx = zipFormat === \"hwpx\"\r\n }\r\n if (!isHwpx) {\r\n if (!opts.silent) process.stderr.write(`[kordoc] HWPX가 아니므로 hwpx 모드로 전환합니다\\n`)\r\n outputFormat = \"hwpx\"\r\n } else {\r\n const hwpxResult = await fillHwpx(arrayBuffer, values)\r\n if (!opts.silent) {\r\n process.stderr.write(`[kordoc] ${hwpxResult.filled.length}개 필드 채움 (원본 스타일 보존)\\n`)\r\n if (hwpxResult.unmatched.length > 0) {\r\n process.stderr.write(`[kordoc] ⚠️ 매칭 실패: ${hwpxResult.unmatched.join(\", \")}\\n`)\r\n }\r\n }\r\n if (opts.output) {\r\n mkdirSync(dirname(resolve(opts.output)), { recursive: true })\r\n writeFileSync(resolve(opts.output), Buffer.from(hwpxResult.buffer))\r\n if (!opts.silent) process.stderr.write(`[kordoc] → ${resolve(opts.output)}\\n`)\r\n } else {\r\n process.stdout.write(Buffer.from(hwpxResult.buffer))\r\n }\r\n return\r\n }\r\n }\r\n\r\n // ─── 일반 경로: parse → fill → output ───\r\n const result = await parse(arrayBuffer)\r\n if (!result.success) {\r\n process.stderr.write(`[kordoc] 파싱 실패: ${result.error}\\n`)\r\n process.exit(1)\r\n }\r\n\r\n const formInfo = extractFormFields(result.blocks)\r\n if (!opts.silent) {\r\n process.stderr.write(`[kordoc] 서식 필드 ${formInfo.fields.length}개 감지 (확신도 ${(formInfo.confidence * 100).toFixed(0)}%)\\n`)\r\n }\r\n\r\n const fillResult = fillFormFields(result.blocks, values)\r\n if (!opts.silent) {\r\n process.stderr.write(`[kordoc] ${fillResult.filled.length}개 필드 채움\\n`)\r\n if (fillResult.unmatched.length > 0) {\r\n process.stderr.write(`[kordoc] ⚠️ 매칭 실패: ${fillResult.unmatched.join(\", \")}\\n`)\r\n }\r\n }\r\n\r\n const markdown = blocksToMarkdown(fillResult.blocks)\r\n\r\n if (outputFormat === \"hwpx\") {\r\n const hwpxBuffer = await markdownToHwpx(markdown)\r\n if (opts.output) {\r\n mkdirSync(dirname(resolve(opts.output)), { recursive: true })\r\n writeFileSync(resolve(opts.output), Buffer.from(hwpxBuffer))\r\n if (!opts.silent) process.stderr.write(`[kordoc] → ${resolve(opts.output)}\\n`)\r\n } else {\r\n process.stdout.write(Buffer.from(hwpxBuffer))\r\n }\r\n } else {\r\n if (opts.output) {\r\n mkdirSync(dirname(resolve(opts.output)), { recursive: true })\r\n writeFileSync(resolve(opts.output), markdown, \"utf-8\")\r\n if (!opts.silent) process.stderr.write(`[kordoc] → ${resolve(opts.output)}\\n`)\r\n } else {\r\n process.stdout.write(markdown + \"\\n\")\r\n }\r\n }\r\n } catch (err) {\r\n process.stderr.write(`[kordoc] 오류: ${sanitizeError(err)}\\n`)\r\n process.exit(1)\r\n }\r\n })\r\n\r\nprogram.parse()\r\n"],"mappings":"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","names":["result","formInfo"]}
|