kordoc 4.14.2 → 4.14.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/README.md +38 -5
- package/dist/{-AQKXLFIM.js → -7XBPXCXN.js} +13 -11
- package/dist/{chunk-FOJZNMMK.js → chunk-2LQGSDZ6.js} +1 -1
- package/dist/chunk-2LQGSDZ6.js.map +1 -0
- package/dist/chunk-4R67INKT.js +1002 -0
- package/dist/chunk-4R67INKT.js.map +1 -0
- package/dist/{chunk-ILU76UF3.js → chunk-4RJ5D7MT.js} +2 -2
- package/dist/chunk-4RJ5D7MT.js.map +1 -0
- package/dist/{chunk-EQZI77PP.cjs → chunk-5VVS2QIJ.cjs} +3 -3
- package/dist/{chunk-EQZI77PP.cjs.map → chunk-5VVS2QIJ.cjs.map} +1 -1
- package/dist/{chunk-3DUADAY2.js → chunk-A275ZQLX.js} +209 -87
- package/dist/chunk-A275ZQLX.js.map +1 -0
- package/dist/{chunk-EISO3POT.js → chunk-CVEERPMP.js} +788 -194
- package/dist/chunk-CVEERPMP.js.map +1 -0
- package/dist/{chunk-ZWD734EY.js → chunk-D6KQKMU3.js} +2 -2
- package/dist/{chunk-QOMNEWCQ.cjs → chunk-EBZUZC6F.cjs} +305 -31
- package/dist/chunk-EBZUZC6F.cjs.map +1 -0
- package/dist/{chunk-HR2XNERB.cjs → chunk-EMGF6EEV.cjs} +2 -2
- package/dist/{chunk-HR2XNERB.cjs.map → chunk-EMGF6EEV.cjs.map} +1 -1
- package/dist/{chunk-GDW4YP7K.js → chunk-FAZR34CA.js} +2 -2
- package/dist/{chunk-TNCKOL2O.js → chunk-GTINVM5K.js} +2 -2
- package/dist/{chunk-L7DMSMAG.cjs → chunk-HX4UUF7Y.cjs} +1 -1
- package/dist/chunk-HX4UUF7Y.cjs.map +1 -0
- package/dist/{chunk-UET462HB.js → chunk-I4NNYWIR.js} +2 -2
- package/dist/chunk-IH56ZISC.js +620 -0
- package/dist/chunk-IH56ZISC.js.map +1 -0
- package/dist/{chunk-EDNJLUSE.js → chunk-IHZEFW4L.js} +2 -2
- package/dist/chunk-IW2CB755.cjs +1002 -0
- package/dist/chunk-IW2CB755.cjs.map +1 -0
- package/dist/{chunk-ZWOFQRIB.js → chunk-JCVIOLBF.js} +3 -3
- package/dist/{chunk-JQEFP45L.js → chunk-L5EH2NVO.js} +2 -2
- package/dist/{chunk-247ANM72.cjs → chunk-NOAQRCV6.cjs} +219 -97
- package/dist/chunk-NOAQRCV6.cjs.map +1 -0
- package/dist/{chunk-7IAQ4HOK.js → chunk-NQCUAGLR.js} +1 -1
- package/dist/chunk-NQCUAGLR.js.map +1 -0
- package/dist/{chunk-NS55SM7A.js → chunk-O2PGQNYE.js} +2 -2
- package/dist/{chunk-QC5T6D4J.js → chunk-QGW7NMTX.js} +299 -25
- package/dist/chunk-QGW7NMTX.js.map +1 -0
- package/dist/{chunk-A7QC2ZVP.js → chunk-UVVEBI22.js} +209 -87
- package/dist/chunk-UVVEBI22.js.map +1 -0
- package/dist/chunk-VJHAUMCF.js +949 -0
- package/dist/chunk-VJHAUMCF.js.map +1 -0
- package/dist/{chunk-C7FQBSON.js → chunk-VNFJPTU4.js} +2 -2
- package/dist/{chunk-VQ5W4MYO.js → chunk-VYOGXNQ3.js} +298 -24
- package/dist/chunk-VYOGXNQ3.js.map +1 -0
- package/dist/{chunk-DOGPOY4B.js → chunk-WB5LW52Z.js} +2 -2
- package/dist/{chunk-TSFS5VKD.js → chunk-YGBZABI4.js} +332 -141
- package/dist/chunk-YGBZABI4.js.map +1 -0
- package/dist/chunks-I7TEMJXH.js +10 -0
- package/dist/cli.js +228 -97
- package/dist/cli.js.map +1 -1
- package/dist/{formula-PJJ6S3Z2.cjs → formula-CPO2TZGB.cjs} +9 -9
- package/dist/{formula-PJJ6S3Z2.cjs.map → formula-CPO2TZGB.cjs.map} +1 -1
- package/dist/{formula-5S7WWXGH.js → formula-NOIDZEBA.js} +4 -4
- package/dist/{formula-JGFTXWYT.js → formula-X44GV7TN.js} +3 -3
- package/dist/{image-ocr-WCAYXLOA.js → image-ocr-72RAR4WR.js} +34 -16
- package/dist/image-ocr-72RAR4WR.js.map +1 -0
- package/dist/{image-ocr-FLIL7MGN.js → image-ocr-R6W6A75P.js} +32 -14
- package/dist/image-ocr-R6W6A75P.js.map +1 -0
- package/dist/{image-ocr-ZTYAGV3W.cjs → image-ocr-SUGT64ZM.cjs} +36 -18
- package/dist/image-ocr-SUGT64ZM.cjs.map +1 -0
- package/dist/index.cjs +2416 -1184
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -25
- package/dist/index.d.ts +62 -25
- package/dist/index.js +1853 -621
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +74 -53
- package/dist/mcp.js.map +1 -1
- package/dist/{model-bundle-FSPZZ2EM.js → model-bundle-57CLEBCO.js} +5 -5
- package/dist/{models-CJPAQK5R.js → models-7ELIFTD7.js} +5 -5
- package/dist/{parser-SCUTZAIJ.js → parser-4NKAYWAX.js} +261 -241
- package/dist/parser-4NKAYWAX.js.map +1 -0
- package/dist/{parser-A4TMPJAM.js → parser-HWFQRSUQ.js} +261 -241
- package/dist/parser-HWFQRSUQ.js.map +1 -0
- package/dist/{parser-VCXE4I5A.cjs → parser-RANGXGBD.cjs} +289 -269
- package/dist/parser-RANGXGBD.cjs.map +1 -0
- package/dist/pdf-ocr-BNC34MNU.js +13 -0
- package/dist/pdf-ocr-QX2GB33Q.js +16 -0
- package/dist/pdf-ocr-VHSFACH7.cjs +14 -0
- package/dist/{pdf-ocr-MBZZ57LD.cjs.map → pdf-ocr-VHSFACH7.cjs.map} +1 -1
- package/dist/{profile-io-LBM263K7.js → profile-io-V52PL5ZO.js} +3 -3
- package/dist/{rasterize-46RG4ZF6.js → rasterize-ZIGLJDOG.js} +3 -3
- package/dist/redact-TIQEQI3M.js +18 -0
- package/dist/redact-doc-KXZ3TZAG.js +1216 -0
- package/dist/redact-doc-KXZ3TZAG.js.map +1 -0
- package/dist/{render-NGP5T24S.js → render-U5PE6V2E.js} +7 -7
- package/dist/seal-DNXJBILR.js +10 -0
- package/dist/{setup-AU4OCHNH.js → setup-YRDM4ODP.js} +3 -3
- package/dist/visual-5XWMA4EV.js +19 -0
- package/dist/{watch-MKPUCPXM.js → watch-5IOLBATT.js} +12 -12
- package/package.json +2 -2
- package/dist/chunk-247ANM72.cjs.map +0 -1
- package/dist/chunk-3DUADAY2.js.map +0 -1
- package/dist/chunk-422427XJ.cjs +0 -571
- package/dist/chunk-422427XJ.cjs.map +0 -1
- package/dist/chunk-7IAQ4HOK.js.map +0 -1
- package/dist/chunk-A7QC2ZVP.js.map +0 -1
- package/dist/chunk-DZIXKL7E.js +0 -145
- package/dist/chunk-DZIXKL7E.js.map +0 -1
- package/dist/chunk-EISO3POT.js.map +0 -1
- package/dist/chunk-EP7KOI2V.js +0 -571
- package/dist/chunk-EP7KOI2V.js.map +0 -1
- package/dist/chunk-FOJZNMMK.js.map +0 -1
- package/dist/chunk-ILU76UF3.js.map +0 -1
- package/dist/chunk-KVWV4ULP.js +0 -516
- package/dist/chunk-KVWV4ULP.js.map +0 -1
- package/dist/chunk-L7DMSMAG.cjs.map +0 -1
- package/dist/chunk-QC5T6D4J.js.map +0 -1
- package/dist/chunk-QOMNEWCQ.cjs.map +0 -1
- package/dist/chunk-TSFS5VKD.js.map +0 -1
- package/dist/chunk-VQ5W4MYO.js.map +0 -1
- package/dist/chunks-SX77P5CV.js +0 -10
- package/dist/image-ocr-FLIL7MGN.js.map +0 -1
- package/dist/image-ocr-WCAYXLOA.js.map +0 -1
- package/dist/image-ocr-ZTYAGV3W.cjs.map +0 -1
- package/dist/parser-A4TMPJAM.js.map +0 -1
- package/dist/parser-SCUTZAIJ.js.map +0 -1
- package/dist/parser-VCXE4I5A.cjs.map +0 -1
- package/dist/pdf-ocr-76SAUXMZ.js +0 -13
- package/dist/pdf-ocr-CPU55CVF.js +0 -16
- package/dist/pdf-ocr-MBZZ57LD.cjs +0 -14
- package/dist/redact-7ILEAUTS.js +0 -12
- package/dist/seal-RGUPOLXD.js +0 -10
- package/dist/visual-NZLYIYEM.js +0 -19
- /package/dist/{-AQKXLFIM.js.map → -7XBPXCXN.js.map} +0 -0
- /package/dist/{chunk-ZWD734EY.js.map → chunk-D6KQKMU3.js.map} +0 -0
- /package/dist/{chunk-GDW4YP7K.js.map → chunk-FAZR34CA.js.map} +0 -0
- /package/dist/{chunk-TNCKOL2O.js.map → chunk-GTINVM5K.js.map} +0 -0
- /package/dist/{chunk-UET462HB.js.map → chunk-I4NNYWIR.js.map} +0 -0
- /package/dist/{chunk-EDNJLUSE.js.map → chunk-IHZEFW4L.js.map} +0 -0
- /package/dist/{chunk-ZWOFQRIB.js.map → chunk-JCVIOLBF.js.map} +0 -0
- /package/dist/{chunk-JQEFP45L.js.map → chunk-L5EH2NVO.js.map} +0 -0
- /package/dist/{chunk-NS55SM7A.js.map → chunk-O2PGQNYE.js.map} +0 -0
- /package/dist/{chunk-C7FQBSON.js.map → chunk-VNFJPTU4.js.map} +0 -0
- /package/dist/{chunk-DOGPOY4B.js.map → chunk-WB5LW52Z.js.map} +0 -0
- /package/dist/{chunks-SX77P5CV.js.map → chunks-I7TEMJXH.js.map} +0 -0
- /package/dist/{formula-5S7WWXGH.js.map → formula-NOIDZEBA.js.map} +0 -0
- /package/dist/{formula-JGFTXWYT.js.map → formula-X44GV7TN.js.map} +0 -0
- /package/dist/{model-bundle-FSPZZ2EM.js.map → model-bundle-57CLEBCO.js.map} +0 -0
- /package/dist/{models-CJPAQK5R.js.map → models-7ELIFTD7.js.map} +0 -0
- /package/dist/{pdf-ocr-76SAUXMZ.js.map → pdf-ocr-BNC34MNU.js.map} +0 -0
- /package/dist/{pdf-ocr-CPU55CVF.js.map → pdf-ocr-QX2GB33Q.js.map} +0 -0
- /package/dist/{profile-io-LBM263K7.js.map → profile-io-V52PL5ZO.js.map} +0 -0
- /package/dist/{rasterize-46RG4ZF6.js.map → rasterize-ZIGLJDOG.js.map} +0 -0
- /package/dist/{redact-7ILEAUTS.js.map → redact-TIQEQI3M.js.map} +0 -0
- /package/dist/{render-NGP5T24S.js.map → render-U5PE6V2E.js.map} +0 -0
- /package/dist/{seal-RGUPOLXD.js.map → seal-DNXJBILR.js.map} +0 -0
- /package/dist/{setup-AU4OCHNH.js.map → setup-YRDM4ODP.js.map} +0 -0
- /package/dist/{visual-NZLYIYEM.js.map → visual-5XWMA4EV.js.map} +0 -0
- /package/dist/{watch-MKPUCPXM.js.map → watch-5IOLBATT.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
parseFormatProfileJson
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-GTINVM5K.js";
|
|
5
5
|
import {
|
|
6
6
|
BODY_FONTS,
|
|
7
7
|
BULLET2_CHARS,
|
|
@@ -30,34 +30,34 @@ import {
|
|
|
30
30
|
resolveBuiltinTemplate,
|
|
31
31
|
unknownFontWarnings,
|
|
32
32
|
usesGaejosikMunche
|
|
33
|
-
} from "./chunk-
|
|
34
|
-
import "./chunk-
|
|
35
|
-
import "./chunk-
|
|
36
|
-
import "./chunk-
|
|
33
|
+
} from "./chunk-CVEERPMP.js";
|
|
34
|
+
import "./chunk-JCVIOLBF.js";
|
|
35
|
+
import "./chunk-IH56ZISC.js";
|
|
36
|
+
import "./chunk-IHZEFW4L.js";
|
|
37
37
|
import {
|
|
38
38
|
detectFormat,
|
|
39
39
|
detectImageMime,
|
|
40
40
|
detectZipFormat
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-YGBZABI4.js";
|
|
42
42
|
import "./chunk-7FCNOKOR.js";
|
|
43
|
-
import "./chunk-
|
|
43
|
+
import "./chunk-NQCUAGLR.js";
|
|
44
44
|
import "./chunk-MOL7MDBG.js";
|
|
45
|
-
import "./chunk-
|
|
45
|
+
import "./chunk-4RJ5D7MT.js";
|
|
46
46
|
import {
|
|
47
47
|
blocksToMarkdown
|
|
48
|
-
} from "./chunk-
|
|
49
|
-
import "./chunk-
|
|
48
|
+
} from "./chunk-QGW7NMTX.js";
|
|
49
|
+
import "./chunk-VNFJPTU4.js";
|
|
50
50
|
import {
|
|
51
51
|
KordocError,
|
|
52
52
|
VERSION,
|
|
53
53
|
classifyError,
|
|
54
54
|
sanitizeError,
|
|
55
55
|
toArrayBuffer
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-I4NNYWIR.js";
|
|
57
57
|
|
|
58
58
|
// src/cli.ts
|
|
59
|
-
import { readFileSync as
|
|
60
|
-
import { basename as basename3, resolve as
|
|
59
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, statSync as statSync4 } from "fs";
|
|
60
|
+
import { basename as basename3, resolve as resolve5 } from "path";
|
|
61
61
|
import { Command } from "commander";
|
|
62
62
|
|
|
63
63
|
// src/cli/commands-docs.ts
|
|
@@ -72,7 +72,7 @@ function registerDocCommands(program2) {
|
|
|
72
72
|
if (command.getOptionValueSource("format") === "default" && program2.getOptionValueSource("format") === "cli") {
|
|
73
73
|
opts.format = rootOpts.format;
|
|
74
74
|
}
|
|
75
|
-
const { watchDirectory } = await import("./watch-
|
|
75
|
+
const { watchDirectory } = await import("./watch-5IOLBATT.js");
|
|
76
76
|
await watchDirectory({
|
|
77
77
|
dir,
|
|
78
78
|
outDir: opts.outDir,
|
|
@@ -186,8 +186,8 @@ function registerDocCommands(program2) {
|
|
|
186
186
|
process.exit(1);
|
|
187
187
|
}
|
|
188
188
|
inputs = Object.fromEntries(Object.entries(values).map(([k, v]) => {
|
|
189
|
-
const
|
|
190
|
-
return [k,
|
|
189
|
+
const format2 = formatMap[k];
|
|
190
|
+
return [k, format2 ? { value: v, format: format2 } : v];
|
|
191
191
|
}));
|
|
192
192
|
}
|
|
193
193
|
let outputFormat = opts.format;
|
|
@@ -203,8 +203,8 @@ function registerDocCommands(program2) {
|
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
if (outputFormat === "hwpx-preserve") {
|
|
206
|
-
const
|
|
207
|
-
let isHwpx =
|
|
206
|
+
const format2 = detectFormat(arrayBuffer);
|
|
207
|
+
let isHwpx = format2 === "hwpx";
|
|
208
208
|
if (isHwpx) {
|
|
209
209
|
const zipFormat = await detectZipFormat(arrayBuffer);
|
|
210
210
|
isHwpx = zipFormat === "hwpx";
|
|
@@ -294,7 +294,7 @@ function registerDocCommands(program2) {
|
|
|
294
294
|
});
|
|
295
295
|
program2.command("seal <file>").description('\uB3C4\uC7A5/\uC11C\uBA85 \uC774\uBBF8\uC9C0\uB97C \uC575\uCEE4 \uBB38\uAD6C \uC704\uC5D0 \uBD80\uC720 \uBC30\uCE58 (\uD45C/\uD398\uC774\uC9C0 \uBD88\uD655\uC7A5) \u2014 kordoc seal \uC2E0\uCCAD\uC11C.hwpx --image \uB3C4\uC7A5.png --anchor "(\uC778)" -o \uACB0\uACFC.hwpx').requiredOption("--image <path>", "\uB3C4\uC7A5/\uC11C\uBA85 \uC774\uBBF8\uC9C0 (\uD22C\uBA85 \uBC30\uACBD PNG \uAD8C\uC7A5)").option("--anchor <text>", "\uC575\uCEE4 \uBB38\uAD6C", "(\uC778)").option("-n, --occurrence <num>", "\uAC19\uC740 \uC575\uCEE4\uAC00 \uC5EC\uB7FF\uC77C \uB54C 0-based \uC120\uD0DD", "0").option("--size-mm <num>", "\uB3C4\uC7A5 \uD55C \uBCC0 \uD06C\uAE30 mm (\uAE30\uBCF8: \uC904\uB192\uC774\xD71.6, 7~18 \uD074\uB7A8\uD504)").option("--mode <mode>", "overlap(\uBB38\uAD6C \uC704 \uACB9\uCE68) | right(\uC624\uB978\uCABD \uC606) | auto", "auto").option("--dx <mm>", "x \uBBF8\uC138\uC870\uC815 mm", "0").option("--dy <mm>", "y \uBBF8\uC138\uC870\uC815 mm", "0").option("-o, --output <path>", "\uCD9C\uB825 \uACBD\uB85C (\uAE30\uBCF8: <\uC785\uB825>.sealed.hwpx)").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (file, opts) => {
|
|
296
296
|
try {
|
|
297
|
-
const { placeSealHwpx, detectFormat: detectFormat2 } = await import("./-
|
|
297
|
+
const { placeSealHwpx, detectFormat: detectFormat2 } = await import("./-7XBPXCXN.js");
|
|
298
298
|
const rootOpts = program2.opts();
|
|
299
299
|
const output = opts.output ?? rootOpts.output;
|
|
300
300
|
const silent = opts.silent ?? rootOpts.silent;
|
|
@@ -372,20 +372,20 @@ function registerDocCommands(program2) {
|
|
|
372
372
|
});
|
|
373
373
|
program2.command("patch <original> <edited>").description("\uC11C\uC2DD \uBCF4\uC874 \uB77C\uC6B4\uB4DC\uD2B8\uB9BD \uD328\uCE58 \u2014 \uD3B8\uC9D1\uB41C \uB9C8\uD06C\uB2E4\uC6B4\uC744 \uC6D0\uBCF8 HWPX/HWP\uC5D0 in-place \uBC18\uC601 (kordoc patch \uC6D0\uBCF8.hwpx \uD3B8\uC9D1.md -o \uCD9C\uB825.hwpx). \uBBF8\uC801\uC6A9(skip) \uD3B8\uC9D1\uC774 \uC788\uC73C\uBA74 exit 2").option("-o, --output <path>", "\uCD9C\uB825 \uACBD\uB85C (\uAE30\uBCF8: <\uC6D0\uBCF8>.patched.hwpx|.hwp)").option("--no-verify", "\uD328\uCE58 \uD6C4 \uC7AC\uD30C\uC2F1 \uC790\uB3D9 \uAC80\uC99D \uC0DD\uB7B5").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (original, edited, opts) => {
|
|
374
374
|
try {
|
|
375
|
-
const { patchHwpx, patchHwp, detectFormat: detectFormat2 } = await import("./-
|
|
375
|
+
const { patchHwpx, patchHwp, detectFormat: detectFormat2 } = await import("./-7XBPXCXN.js");
|
|
376
376
|
const rootOpts = program2.opts();
|
|
377
377
|
const output = opts.output ?? rootOpts.output;
|
|
378
378
|
const silent = opts.silent ?? rootOpts.silent;
|
|
379
379
|
const originalBuf = new Uint8Array(readFileSync(resolve(original)));
|
|
380
380
|
const editedMarkdown = readFileSync(resolve(edited), "utf-8");
|
|
381
|
-
const
|
|
382
|
-
const result =
|
|
381
|
+
const format2 = detectFormat2(originalBuf.buffer);
|
|
382
|
+
const result = format2 === "hwp" ? await patchHwp(originalBuf, editedMarkdown, { verify: opts.verify !== false }) : await patchHwpx(originalBuf, editedMarkdown, { verify: opts.verify !== false });
|
|
383
383
|
if (!result.success || !result.data) {
|
|
384
384
|
process.stderr.write(`[kordoc] \uD328\uCE58 \uC2E4\uD328: ${result.error ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}
|
|
385
385
|
`);
|
|
386
386
|
process.exit(1);
|
|
387
387
|
}
|
|
388
|
-
const ext =
|
|
388
|
+
const ext = format2 === "hwp" ? ".hwp" : ".hwpx";
|
|
389
389
|
const outPath = resolve(output ?? original.replace(/\.hwpx?$/i, "") + ".patched" + ext);
|
|
390
390
|
mkdirSync(dirname(outPath), { recursive: true });
|
|
391
391
|
writeFileSync(outPath, result.data);
|
|
@@ -413,7 +413,7 @@ function registerDocCommands(program2) {
|
|
|
413
413
|
});
|
|
414
414
|
program2.command("validate <file>").description("HWPX \uAD6C\uC870 \uAC80\uC99D \u2014 ZIP\xB7mimetype\xB7\uD544\uC218 \uD30C\uC77C\xB7XML \uC6F0\uD3FC\uB4DC\xB7secCnt\xB7manifest \uCC38\uC870 (\uD55C\uCEF4\uB3C5\uC2A4 \uAC70\uBD80 \uC694\uC778 \uC0AC\uC804 \uCC28\uB2E8)").option("--json", "\uACB0\uACFC\uB97C JSON\uC73C\uB85C stdout\uC5D0 \uCD9C\uB825").action(async (file, opts) => {
|
|
415
415
|
try {
|
|
416
|
-
const { validateHwpx } = await import("./-
|
|
416
|
+
const { validateHwpx } = await import("./-7XBPXCXN.js");
|
|
417
417
|
const buf = new Uint8Array(readFileSync(resolve(file)));
|
|
418
418
|
const result = await validateHwpx(buf);
|
|
419
419
|
if (opts.json) {
|
|
@@ -439,7 +439,7 @@ function registerDocCommands(program2) {
|
|
|
439
439
|
}
|
|
440
440
|
|
|
441
441
|
// src/cli/commands-generate.ts
|
|
442
|
-
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
442
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, statSync as statSync2 } from "fs";
|
|
443
443
|
import { basename as basename2, dirname as dirname2, resolve as resolve2 } from "path";
|
|
444
444
|
function registerGenerateCommands(program2) {
|
|
445
445
|
program2.command("generate <markdown>").alias("gen").description("\uB9C8\uD06C\uB2E4\uC6B4 \u2192 \uACF5\uBB38\uC11C HWPX \uC0DD\uC131 \u2014 kordoc generate \uBCF4\uACE0\uC11C.md -o \uBCF4\uACE0\uC11C.hwpx --preset \uBCF4\uACE0\uC11C (markdown\uC5D0 '-' \uC9C0\uC815 \uC2DC stdin)").option("-o, --output <path>", "\uCD9C\uB825 HWPX \uACBD\uB85C (\uAE30\uBCF8: <\uC785\uB825>.hwpx)").option("--preset <name>", "\uACF5\uBB38\uC11C \uD504\uB9AC\uC14B: \uAE30\uC548\uBB38(official)\xB7\uBCF4\uACE0\uC11C(report)\xB7\uACC4\uD68D\uC11C(plan)\xB7\uD1B5\uC9C0(notice)\xB7\uD68C\uC758\uB85D(minutes)\xB7\uAC1C\uC870\uC2DD(gaejosik \u2014 \uD45C\uC9C0\xB7\uBAA9\uCC28\xB7\uC7A5\uD5E4\uB354 \uC790\uB3D9)\xB7\uC5C5\uBB34\uBCF4\uACE0(ministry \u2014 \uC911\uC559\uBD80\uCC98 \uC5C5\uBB34\uBCF4\uACE0: \uC7A5 \uB760\xB7\uC808 \uC22B\uC790\uCE78\xB7\uC18C\uC81C\uBAA9 \uBC15\uC2A4\xB7\u2460 \uD56D\uBAA9 \uB760\xB7\uC131\uACFC \uC694\uC57D\uBC15\uC2A4\xB7\uBCC4\uCCA8 \uB760)\xB7\uBCF4\uB3C4\uC790\uB8CC(press)", "\uAE30\uC548\uBB38").option("--font <type>", "\uBCF8\uBB38 \uAE00\uAF34: myeongjo(\uD568\uCD08\uB86C\uBC14\uD0D5) \uB610\uB294 gothic(\uB9D1\uC740 \uACE0\uB515)").option("--pt <size>", "\uBCF8\uBB38 \uAE00\uC790 \uD06C\uAE30(pt)").option("--line-spacing <percent>", "\uBCF8\uBB38 \uC904\uAC04\uACA9(%)").option("--profile <path>", "\uC11C\uC2DD \uD504\uB85C\uD544 JSON (kordoc profile\uB85C \uCD94\uCD9C) \u2014 \uCC38\uC870 \uBB38\uC11C\uC758 \uD45C \uD14C\uB450\uB9AC\xB7\uC74C\uC601\xB7\uC5F4\uD3ED\xB7\uC140 \uAE00\uAF34 \uC7AC\uD604").option("--org <name>", "\uD45C\uC9C0 \uAE30\uAD00\uBA85 (\uD45C\uC9C0\uB97C \uCF1C\uB294 \uD504\uB9AC\uC14B \uACF5\uD1B5)").option("--date <date>", "\uD45C\uC9C0 \uB0A0\uC9DC (\uAE30\uBCF8 \uC624\uB298 \u2014 'YYYY. M. D.')").option("--toc", "\uBAA9\uCC28 \uD398\uC774\uC9C0 \uAC15\uC81C \uCF1C\uAE30 (\uAC1C\uC870\uC2DD \uC678 \uD504\uB9AC\uC14B\uC5D0\uC11C\uB3C4 h2 \uBAA9\uB85D\uC73C\uB85C \uC0DD\uC131)").option("--no-toc", "\uBAA9\uCC28 \uD398\uC774\uC9C0 \uB044\uAE30 (\uAC1C\uC870\uC2DD \uD504\uB9AC\uC14B \uAE30\uBCF8 \uCF1C\uC9D0)").option("--cover", "\uD45C\uC9C0 \uD398\uC774\uC9C0 \uAC15\uC81C \uCF1C\uAE30 (\uAC1C\uC870\uC2DD \uC678 \uD504\uB9AC\uC14B\uC5D0\uC11C\uB3C4 \uCCAB h1\uC744 \uD45C\uC9C0\uB85C)").option("--no-cover", "\uD45C\uC9C0 \uD398\uC774\uC9C0 \uB044\uAE30 (\uAC1C\uC870\uC2DD \uD504\uB9AC\uC14B \uAE30\uBCF8 \uCF1C\uC9D0)").option("--approval <labels>", "\uACB0\uC7AC\uB780 \uC9C1\uC704 \uB77C\uBCA8 (\uC27C\uD45C \uAD6C\uBD84, \uC608: \uB2F4\uB2F9,\uD300\uC7A5,\uACFC\uC7A5) \u2014 \uBB38\uC11C \uCD5C\uC0C1\uB2E8 \uC6B0\uCE21").option("--page-numbers", "\uCABD\uBC88\uD638 \uAC15\uC81C \uCF1C\uAE30 (\uD558\uB2E8 \uC911\uC559 '- 1 -')").option("--no-page-numbers", "\uCABD\uBC88\uD638 \uB044\uAE30 (\uAC1C\uC870\uC2DD\xB7\uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C \uAE30\uBCF8 \uCF1C\uC9D0)").option("--end-mark", "\uBCF8\uBB38 \uB05D '\uB05D.' \uD45C\uC2DC \uAC15\uC81C \uCF1C\uAE30").option("--no-end-mark", "'\uB05D.' \uD45C\uC2DC \uB044\uAE30 (\uAE30\uC548\uBB38 \uAE30\uBCF8 \uCF1C\uC9D0)").option("--no-body-title-box", "\uBCF8\uBB38 \uCCAB \uD398\uC774\uC9C0 \uC81C\uBAA9 \uBC18\uBCF5 \uBC15\uC2A4 \uB044\uAE30 (\uAC1C\uC870\uC2DD+\uD45C\uC9C0 \uAE30\uBCF8 \uCF1C\uC9D0)").option("--h2-marker <type>", "h2 \uC7A5 \uC81C\uBAA9 \uD45C\uAE30: band(\uB85C\uB9C8\uC790 \uCC44\uC6C0 \uCE78 + \uC81C\uBAA9 \uB760 \uD45C \u2014 \uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C \uAE30\uBCF8)\xB7roman(\u2160. \uD14D\uC2A4\uD2B8)\xB7number(1. \u2014 \uD1B5\uC9C0 \uAE30\uBCF8)\xB7box(\uC7A5 \uC5C6\uC774 \u25A1 \uB300\uD56D\uBAA9)\xB7none").option("--band-color <hex>", "\uB760 \uC81C\uBAA9 \uBC88\uD638\uCE78 \uCC44\uC6C0\uC0C9 #RRGGBB (\uAE30\uBCF8 #003366 \u2014 \uC2E4\uCE21 \uCD5C\uB2E4. \uAD50\uC721\uCCAD\uD615 \uBC1D\uC740 \uB760: #DFE6F7)").option("--band-text-color <hex>", "\uB760 \uC81C\uBAA9 \uBC88\uD638 \uAE00\uC790\uC0C9 #RRGGBB (\uAE30\uBCF8 #FFFFFF \u2014 \uBC1D\uC740 \uB760\uBA74 #000000)").option("--summary <text>", "\uBCF4\uACE0\uC11C \uC694\uC57D \uBC15\uC2A4 (\uC81C\uBAA9\uD45C \uC544\uB798 \uC74C\uC601 \uC0C1\uC790 \u2014 \uB9C8\uD06C\uB2E4\uC6B4 \uC81C\uBAA9 \uC9C1\uD6C4 \uC778\uC6A9\uBB38(>)\uC73C\uB85C\uB3C4 \uC9C0\uC815)").option("--doc-info <spec>", "\uBCF4\uACE0\uC11C \uD45C\uC9C0 \uBB38\uC11C\uC815\uBCF4\uD45C: docNum=\uC2A4\uB9C8\uD2B8\uB3C4\uC2DC\uACFC-123,date=2026. 9. 6.,disclosure=\uACF5\uAC1C,policyNo= (--cover\uC640 \uD568\uAED8)").option("--dept <name>", "\uD45C\uC9C0 \uBD80\uC11C\uBA85 (\uAE30\uAD00\uBA85 \uC544\uB798 \uAD04\uD638)").option("--cover-label <text>", "\uD45C\uC9C0 \uC6B0\uC0C1\uB2E8 \uCDE8\uAE09 \uD45C\uC2DC \u2014 '\uB300\uC678\uC8FC\uC758'\xB7'\uBE44\uACF5\uAC1C' \uBE68\uAC04 \uD14C\uB450\uB9AC \uBC15\uC2A4 (\uC5C5\uBB34\uBCF4\uACE0 \uD504\uB9AC\uC14B \uC2E4\uCE21)").option("--fonts <spec>", "\uC694\uC18C\uBCC4 \uAE00\uAF34 \uC624\uBC84\uB77C\uC774\uB4DC: body=\uB098\uB214\uBA85\uC870,heading=\uB098\uB214\uACE0\uB515,ref=\uD55C\uC591\uC911\uACE0\uB515,table=\uB9D1\uC740 \uACE0\uB515").option("--sizes <spec>", "\uAC1C\uC870\uC2DD \uC694\uC18C\uBCC4 \uD06C\uAE30(pt): dae=16,cham=13,table=12,coverTitle=30 \u2026").option("--levels <spec>", "\uD56D\uBAA9\uBD80\uD638 \uB2E8\uACC4\uBCC4 \uC704\uACC4 \uD0C0\uC774\uD3EC: 0=HY\uACAC\uACE0\uB515/17/bold,1=\uD55C\uCEF4\uB3CB\uC6C0/15/bold,2=\uD734\uBA3C\uBA85\uC870/14 (depth 0~7, \uC22B\uC790=pt\xB7bold\xB7plain\xB7\uAE00\uAF34\uBA85)").option("--bullet2 <char>", "2\uB2E8\uACC4 \uD56D\uBAA9\uBD80\uD638: \u3147(\uC774\uC751 \u2014 \uAE30\uC548\uBB38\xB7\uACF5\uACE0\uBB38 \uC2E4\uCE21 \uC9C0\uBC30) \uB610\uB294 \u25CB(\uC6D0 \u2014 \uBCF4\uACE0\uC11C \uC591\uC2DD)").option("--suppress-single", "\uB2E8\uC77C \uD615\uC81C \uD56D\uBAA9 \uBD80\uD638 \uC0DD\uB7B5 (\uD3B8\uB78C \uADDC\uC815 \u2014 \uAE30\uBCF8\uC740 \uD558\uB098\uC5EC\uB3C4 \uBD80\uD638 \uBD80\uC5EC)").option("--doc-head <spec>", "\uAE30\uC548\uBB38 \uB450\uBB38\uD45C: org=\uAE30\uAD00\uBA85,slogan=\uC6D0\uD6C8,to=\uC218\uC2E0\uCC98,title=\uC81C\uBAA9 (\uBCC4\uC9C0 \uC81C1\uD638\uC11C\uC2DD\xB7\uC11C\uC6B8 \uC2E4\uACB0\uC7AC 6\uD589 \uD45C)").option("--doc-foot <spec>", "\uAE30\uC548\uBB38 \uACB0\uBB38\uD45C: sender=\uBC1C\uC2E0\uBA85\uC758,drafter=\uC8FC\uBB34\uAD00 \uD64D\uAE38\uB3D9,reviewer=\uACFC\uC7A5 \uAE40\uCCA0\uC218,approver=\uAD6D\uC7A5 \uBC15\uC601\uD76C,cooperator=\uD611\uC870\uC790,docNum=\uC2DC\uD589(\uACFC-\uBC88\uD638 (\uB0A0\uC9DC)),receive=\uC811\uC218,zip=\uC6B0\uD3B8\uBC88\uD638,address=\uC8FC\uC18C,site=\uD648\uD398\uC774\uC9C0,phone=\uC804\uD654,fax=\uC804\uC1A1,email=\uBA54\uC77C,disclosure=\uACF5\uAC1C\uAD6C\uBD84").option("--report-info <text>", "\uBCF4\uACE0\uC11C \uB2F4\uB2F9\uC790 \uD589(\uC81C\uBAA9\uD45C \uC544\uB798) / \uAE30\uC548\uBB38 \uC6B0\uC0C1\uB2E8 \uBCF4\uACE0\uC815\uBCF4 \uD589 \u2014 \uC608: '(2026. 7. 11., \uACFC\uC7A5 \uD64D\uAE38\uB3D9, \u260E02-120)'").option("--notice-head <spec>", "\uACF5\uACE0\uBB38 \uB450\uBB38\xB7\uACB0\uBB38: no=\uACF5\uACE0 \uC81C2026-1\uD638,date=2026\uB144 7\uC6D4 11\uC77C,sender=\uD589\uC815\uC548\uC804\uBD80\uC7A5\uAD00").option("--press-head <spec>", "\uBCF4\uB3C4\uC790\uB8CC \uBA38\uB9AC: release=\uBCF4\uB3C4\uC2DC\uC810,distribute=\uBC30\uD3EC\uC77C,dept=\uB2F4\uB2F9\uBD80\uC11C,manager=\uB2F4\uB2F9\uC790,phone=\uC5F0\uB77D\uCC98").option("--press-sub <items>", "\uBCF4\uB3C4\uC790\uB8CC \uBD80\uC81C (\uC138\uBBF8\uCF5C\uB860 \uAD6C\uBD84, \uC81C\uBAA9 \uC544\uB798 '- \u2026 -')").option("--plain", "\uACF5\uBB38\uC11C \uBAA8\uB4DC \uB044\uAE30 (\uBC94\uC6A9 \uB9C8\uD06C\uB2E4\uC6B4 \uBCC0\uD658)").option("--paper <size>", "\uC6A9\uC9C0: A4\xB7A3\xB7B4\xB7B5\xB7Letter \uB610\uB294 '210x297'(mm)").option("--landscape", "\uC6A9\uC9C0 \uAC00\uB85C \uBC29\uD5A5").option("--columns <n>", "\uB2E4\uB2E8 \uAC1C\uC218 (1~8)").option("--header <text>", "\uBA38\uB9AC\uB9D0 \uD14D\uC2A4\uD2B8 (\uBAA8\uB4E0 \uCABD, \uC778\uB77C\uC778 \uB9C8\uD06C\uB2E4\uC6B4 \uD5C8\uC6A9)").option("--footer <text>", "\uAF2C\uB9AC\uB9D0 \uD14D\uC2A4\uD2B8").option("--image-dir <dir>", "\uB9C8\uD06C\uB2E4\uC6B4 \uC774\uBBF8\uC9C0 \uCC38\uC870()\uB97C \uC774 \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uC77D\uC5B4 \uC2E4\uB370\uC774\uD130 \uC784\uBCA0\uB4DC").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (markdown, opts) => {
|
|
@@ -678,16 +678,26 @@ function registerGenerateCommands(program2) {
|
|
|
678
678
|
process.exit(1);
|
|
679
679
|
}
|
|
680
680
|
});
|
|
681
|
-
program2.command("redact <files...>").description("\uAC1C\uC778\uC815\uBCF4 \uC11C\uC2DD \uBCF4\uC874 \uB9C8\uC2A4\uD0B9 \u2014 \uC8FC\uBBFC\uBC88\uD638\xB7\uC804\uD654\xB7\uC774\uBA54\uC77C\xB7\uCE74\uB4DC\xB7\uACC4\uC88C\uB97C \uD0D0\uC9C0\uD574 HWPX/HWP\uB294 \uC6D0\uBCF8 \uC11C\uC2DD \uADF8\uB300\uB85C
|
|
682
|
-
const {
|
|
681
|
+
program2.command("redact <files...>").description("\uAC1C\uC778\uC815\uBCF4 \uC11C\uC2DD \uBCF4\uC874 \uB9C8\uC2A4\uD0B9 \u2014 \uC8FC\uBBFC\xB7\uC678\uAD6D\uC778\uB4F1\uB85D\uBC88\uD638\xB7\uC804\uD654\xB7\uC774\uBA54\uC77C\xB7\uCE74\uB4DC\xB7\uACC4\uC88C\xB7\uC0AC\uC5C5\uC790\uB4F1\uB85D\uBC88\uD638\xB7\uC5EC\uAD8C\xB7\uC6B4\uC804\uBA74\uD5C8\uB97C \uD0D0\uC9C0\uD574 HWPX/HWP\uB294 \uC6D0\uBCF8 \uC11C\uC2DD \uADF8\uB300\uB85C \uAC19\uC740 \uAE38\uC774\uB85C \uAC00\uB9B0 \uD30C\uC77C(\uBCF8\uBB38\xB7\uD45C\xB7\uBA38\uB9AC\uB9D0/\uAF2C\uB9AC\uB9D0\xB7\uAC01\uC8FC\xB7\uAE00\uC0C1\uC790\xB7\uBBF8\uB9AC\uBCF4\uAE30\xB7\uBA54\uD0C0\uB370\uC774\uD130 \uD3EC\uD568), \uADF8 \uC678 \uD3EC\uB9F7(PDF \uB4F1)\uC740 \uC6D0\uBCF8\uC744 \uAC74\uB4DC\uB9AC\uC9C0 \uC54A\uACE0 \uB9C8\uC2A4\uD0B9\uB41C \uB9C8\uD06C\uB2E4\uC6B4\uB9CC \uCD9C\uB825. \uC790\uB3D9 \uAC80\uCD9C \uBCF4\uC870 \uB3C4\uAD6C\uC774\uBBC0\uB85C \uACB0\uACFC\uB294 \uBC18\uB4DC\uC2DC \uC0AC\uB78C\uC774 \uCD5C\uC885 \uD655\uC778\uD558\uC138\uC694 (\uC774\uBBF8\uC9C0 \uC18D \uAE00\uC790\uB294 \uD0D0\uC9C0 \uBD88\uAC00)").option("--rules <csv>", "\uC801\uC6A9 \uB8F0 (\uAE30\uBCF8: rrn,phone,email,card,account,brn,passport,driver \u2014 crn(\uBC95\uC778\uB4F1\uB85D\uBC88\uD638),ip\uB294 opt-in)").option("--mask-char <ch>", "\uB9C8\uC2A4\uD06C \uBB38\uC790 1\uAE00\uC790 (\uAE30\uBCF8: \u25CF)").option("-o, --output <path>", "\uCD9C\uB825 \uACBD\uB85C (\uB2E8\uC77C \uD30C\uC77C \uC2DC)").option("-d, --out-dir <dir>", "\uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC (\uB2E4\uC911 \uD30C\uC77C \uC2DC)").option("--dry-run", "\uD0D0\uC9C0 \uB9AC\uD3EC\uD2B8\uB9CC \uCD9C\uB825, \uD30C\uC77C \uBBF8\uC0DD\uC131").option("--json", "\uB9AC\uD3EC\uD2B8\uB97C JSON\uC73C\uB85C stdout \uCD9C\uB825").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (files, opts) => {
|
|
682
|
+
const { ALL_REDACT_RULES, DEFAULT_REDACT_RULES, redactText } = await import("./redact-TIQEQI3M.js");
|
|
683
|
+
const { redactDocument } = await import("./redact-doc-KXZ3TZAG.js");
|
|
683
684
|
const rootOpts = program2.opts();
|
|
684
685
|
const output = opts.output ?? rootOpts.output;
|
|
686
|
+
const outDir = opts.outDir ?? rootOpts.outDir;
|
|
685
687
|
const silent = opts.silent ?? rootOpts.silent;
|
|
686
|
-
const KNOWN_RULES =
|
|
688
|
+
const KNOWN_RULES = new Set(ALL_REDACT_RULES);
|
|
687
689
|
const rules = opts.rules ? String(opts.rules).split(",").map((r) => r.trim()).filter(Boolean) : [...DEFAULT_REDACT_RULES];
|
|
688
690
|
const badRule = rules.find((r) => !KNOWN_RULES.has(r));
|
|
689
691
|
if (badRule) {
|
|
690
692
|
process.stderr.write(`[kordoc] \uC54C \uC218 \uC5C6\uB294 \uB8F0: ${badRule} (\uD5C8\uC6A9: ${[...KNOWN_RULES].join(", ")})
|
|
693
|
+
`);
|
|
694
|
+
process.exit(1);
|
|
695
|
+
}
|
|
696
|
+
const maskChar = opts.maskChar ?? "\u25CF";
|
|
697
|
+
try {
|
|
698
|
+
redactText("", { maskChar });
|
|
699
|
+
} catch (err) {
|
|
700
|
+
process.stderr.write(`[kordoc] ${sanitizeError(err)}
|
|
691
701
|
`);
|
|
692
702
|
process.exit(1);
|
|
693
703
|
}
|
|
@@ -695,64 +705,114 @@ function registerGenerateCommands(program2) {
|
|
|
695
705
|
process.stderr.write(`[kordoc] \u26A0\uFE0F -o/--output \uC740 \uB2E8\uC77C \uD30C\uC77C \uC804\uC6A9\uC774\uB77C \uBB34\uC2DC\uB429\uB2C8\uB2E4 \u2014 \uB2E4\uC911 \uD30C\uC77C\uC740 -d/--out-dir \uB97C \uC0AC\uC6A9\uD558\uC138\uC694
|
|
696
706
|
`);
|
|
697
707
|
}
|
|
708
|
+
const nameMask = /[*?]/.test(maskChar) ? "\u25CF" : maskChar;
|
|
709
|
+
const maskName = (name) => {
|
|
710
|
+
const probe = name.replace(/_/g, " ");
|
|
711
|
+
const out = [...name];
|
|
712
|
+
for (const h of redactText(probe, { rules, maskChar: nameMask }).hits) {
|
|
713
|
+
for (let k = 0; k < h.length; k++) if (h.masked[k] !== probe[h.index + k]) out[h.index + k] = nameMask;
|
|
714
|
+
}
|
|
715
|
+
return out.join("");
|
|
716
|
+
};
|
|
717
|
+
const shown = (p) => resolve2(dirname2(p), maskName(basename2(p)));
|
|
718
|
+
const inputs = files.map((f) => resolve2(f));
|
|
719
|
+
const sameFile = (a, b) => {
|
|
720
|
+
if (a === b) return true;
|
|
721
|
+
try {
|
|
722
|
+
const sa = statSync2(a), sb = statSync2(b);
|
|
723
|
+
return sa.ino === sb.ino && sa.dev === sb.dev;
|
|
724
|
+
} catch {
|
|
725
|
+
return false;
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
const written = /* @__PURE__ */ new Set();
|
|
729
|
+
const defaultOut = (absPath, ext) => {
|
|
730
|
+
const stem = maskName(basename2(absPath)).replace(/\.[^.]+$/, "");
|
|
731
|
+
const dir = resolve2(outDir ?? dirname2(absPath));
|
|
732
|
+
for (let n = 1; ; n++) {
|
|
733
|
+
const p = resolve2(dir, `${stem}${n > 1 ? `-${n}` : ""}.redacted${ext}`);
|
|
734
|
+
if (!written.has(p) && !inputs.some((i) => sameFile(i, p))) return p;
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
const MAX_LINES = 200;
|
|
698
738
|
const jsonReports = [];
|
|
699
|
-
for (const
|
|
700
|
-
const
|
|
701
|
-
|
|
739
|
+
for (const absPath of inputs) {
|
|
740
|
+
const fileName = maskName(basename2(absPath));
|
|
741
|
+
if (output && files.length === 1 && !opts.dryRun && sameFile(absPath, resolve2(output))) {
|
|
742
|
+
process.stderr.write(`[kordoc] ERROR: ${fileName} \u2014 \uCD9C\uB825 \uACBD\uB85C\uAC00 \uC785\uB825 \uD30C\uC77C\uACFC \uAC19\uC2B5\uB2C8\uB2E4. \uC6D0\uBCF8\uC744 \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 \uB2E4\uB978 -o \uACBD\uB85C\uB97C \uC9C0\uC815\uD558\uC138\uC694
|
|
743
|
+
`);
|
|
744
|
+
process.exitCode = 1;
|
|
745
|
+
continue;
|
|
746
|
+
}
|
|
702
747
|
try {
|
|
703
748
|
const buffer = readFileSync2(absPath);
|
|
704
|
-
const
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
continue;
|
|
712
|
-
}
|
|
713
|
-
const r = redactMarkdown(parsed.markdown, { rules, maskChar: opts.maskChar });
|
|
749
|
+
const r = await redactDocument(toArrayBuffer(buffer), {
|
|
750
|
+
rules,
|
|
751
|
+
maskChar,
|
|
752
|
+
filePath: absPath,
|
|
753
|
+
dryRun: opts.dryRun
|
|
754
|
+
});
|
|
755
|
+
const listed = r.fileHits.length > 0 ? r.fileHits.map((h) => ({ rule: h.rule, masked: h.masked, at: `${h.where} @ ${h.part}` })) : r.markdownHits.map((h) => ({ rule: h.rule, masked: h.masked, at: "" }));
|
|
714
756
|
const byRule = /* @__PURE__ */ new Map();
|
|
715
|
-
for (const h of
|
|
757
|
+
for (const h of listed) byRule.set(h.rule, (byRule.get(h.rule) ?? 0) + 1);
|
|
716
758
|
const ruleSummary = [...byRule.entries()].map(([k, v]) => `${k} ${v}\uAC74`).join(", ") || "0\uAC74";
|
|
759
|
+
const failed = r.residual.length > 0 || r.unscanned.length > 0;
|
|
717
760
|
let outPath = null;
|
|
718
|
-
let
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
continue;
|
|
729
|
-
}
|
|
730
|
-
const ext = format === "hwp" ? ".hwp" : ".hwpx";
|
|
731
|
-
outPath = resolve2(
|
|
732
|
-
output && files.length === 1 ? output : resolve2(opts.outDir ?? dirname2(absPath), fileName.replace(/\.[^.]+$/, "") + ".redacted" + ext)
|
|
733
|
-
);
|
|
734
|
-
mkdirSync2(dirname2(outPath), { recursive: true });
|
|
735
|
-
writeFileSync2(outPath, result.data);
|
|
736
|
-
if (result.skipped.length > 0) {
|
|
737
|
-
patchNote = ` (\u26A0\uFE0F \uBBF8\uC801\uC6A9 ${result.skipped.length}\uAC74 \u2014 \uD574\uB2F9 \uC704\uCE58\uB294 \uC6D0\uBB38 \uC794\uC874, \uC218\uB3D9 \uD655\uC778 \uD544\uC694)`;
|
|
738
|
-
process.exitCode = 2;
|
|
739
|
-
}
|
|
740
|
-
} else {
|
|
741
|
-
outPath = resolve2(
|
|
742
|
-
output && files.length === 1 ? output : resolve2(opts.outDir ?? dirname2(absPath), fileName.replace(/\.[^.]+$/, "") + ".redacted.md")
|
|
743
|
-
);
|
|
744
|
-
mkdirSync2(dirname2(outPath), { recursive: true });
|
|
745
|
-
writeFileSync2(outPath, r.text, "utf-8");
|
|
746
|
-
patchNote = ` (${format}\uB294 \uC11C\uC2DD \uBCF4\uC874 \uBBF8\uC9C0\uC6D0 \u2014 \uB9C8\uC2A4\uD0B9\uB41C \uB9C8\uD06C\uB2E4\uC6B4\uC73C\uB85C \uCD9C\uB825)`;
|
|
761
|
+
let note = "";
|
|
762
|
+
const save = r.data ? r.changed : r.markdownHits.length > 0;
|
|
763
|
+
if (!opts.dryRun && save) {
|
|
764
|
+
const ext = r.data ? r.format === "hwp" ? ".hwp" : ".hwpx" : ".md";
|
|
765
|
+
outPath = output && files.length === 1 ? resolve2(output) : defaultOut(absPath, ext);
|
|
766
|
+
mkdirSync2(dirname2(outPath), { recursive: true });
|
|
767
|
+
if (r.data) writeFileSync2(outPath, r.data);
|
|
768
|
+
else {
|
|
769
|
+
writeFileSync2(outPath, r.markdown, "utf-8");
|
|
770
|
+
note = ` (${r.format} \uC6D0\uBCF8\uC740 \uC218\uC815\uD558\uC9C0 \uC54A\uC74C \u2014 \uB9C8\uC2A4\uD0B9\uB41C \uB9C8\uD06C\uB2E4\uC6B4\uB9CC \uCD9C\uB825)`;
|
|
747
771
|
}
|
|
772
|
+
written.add(outPath);
|
|
773
|
+
} else if (!opts.dryRun && r.data && listed.length > 0) {
|
|
774
|
+
note = " (\u274C \uD30C\uC77C\uC5D0\uC11C \uAC00\uB9B0 \uACF3\uC774 \uC5C6\uC5B4 \uCD9C\uB825\uD558\uC9C0 \uC54A\uC74C)";
|
|
748
775
|
}
|
|
776
|
+
if (failed && process.exitCode !== 1) process.exitCode = 2;
|
|
749
777
|
if (opts.json) {
|
|
750
|
-
jsonReports.push({
|
|
778
|
+
jsonReports.push({
|
|
779
|
+
file: shown(absPath),
|
|
780
|
+
format: r.format,
|
|
781
|
+
rules,
|
|
782
|
+
hits: r.markdownHits,
|
|
783
|
+
fileHits: r.fileHits,
|
|
784
|
+
residual: r.residual,
|
|
785
|
+
unscanned: r.unscanned,
|
|
786
|
+
warnings: r.warnings,
|
|
787
|
+
output: outPath
|
|
788
|
+
});
|
|
751
789
|
}
|
|
752
790
|
if (!silent) {
|
|
753
|
-
process.stderr.write(`[kordoc] ${fileName}: ${ruleSummary}${outPath ? ` \u2192 ${outPath}` : opts.dryRun ? " (dry-run)" : ""}${
|
|
791
|
+
process.stderr.write(`[kordoc] ${fileName}: ${ruleSummary}${outPath ? ` \u2192 ${outPath}` : opts.dryRun ? " (dry-run)" : ""}${note}
|
|
792
|
+
`);
|
|
793
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
794
|
+
for (const h of listed) {
|
|
795
|
+
const key = ` - [${h.rule}] ${h.masked}${h.at ? ` (${h.at})` : ""}`;
|
|
796
|
+
grouped.set(key, (grouped.get(key) ?? 0) + 1);
|
|
797
|
+
}
|
|
798
|
+
const lines = [...grouped].map(([line, n]) => `${line}${n > 1 ? ` \xD7${n}` : ""}`);
|
|
799
|
+
for (const line of lines.slice(0, MAX_LINES)) process.stderr.write(`${line}
|
|
800
|
+
`);
|
|
801
|
+
if (lines.length > MAX_LINES) process.stderr.write(` \u2026 \uC678 ${lines.length - MAX_LINES}\uC904 (\uC804\uCCB4\uB294 --json)
|
|
802
|
+
`);
|
|
803
|
+
if (r.residual.length > 0) {
|
|
804
|
+
process.stderr.write(`[kordoc] \u274C \uB9C8\uC2A4\uD0B9 \uD6C4 \uC7AC\uAC80\uC0AC\uC5D0\uC11C PII ${r.residual.length}\uAC74\uC774 \uB0A8\uC544 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uCD9C\uB825 \uD30C\uC77C\uC744 \uACF5\uAC1C\uD558\uC9C0 \uB9D0\uACE0 \uC218\uB3D9 \uD655\uC778\uD558\uC138\uC694:
|
|
805
|
+
`);
|
|
806
|
+
for (const h of r.residual.slice(0, MAX_LINES)) process.stderr.write(` - [${h.rule}] ${h.masked} (${h.where} @ ${h.part})
|
|
754
807
|
`);
|
|
755
|
-
|
|
808
|
+
if (r.residual.length > MAX_LINES) process.stderr.write(` \u2026 \uC678 ${r.residual.length - MAX_LINES}\uAC74 (\uC804\uCCB4\uB294 --json)
|
|
809
|
+
`);
|
|
810
|
+
}
|
|
811
|
+
if (r.unscanned.length > 0) {
|
|
812
|
+
process.stderr.write(`[kordoc] \u274C \uAE00\uC790\uB97C \uAC80\uC0AC\uD558\uC9C0 \uBABB\uD55C \uACF3\uC774 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uCD9C\uB825 \uD30C\uC77C\uC744 \uACF5\uAC1C\uD558\uC9C0 \uB9D0\uACE0 \uC218\uB3D9 \uD655\uC778\uD558\uC138\uC694: ${r.unscanned.join(", ")}
|
|
813
|
+
`);
|
|
814
|
+
}
|
|
815
|
+
for (const w of r.warnings) process.stderr.write(`[kordoc] \u26A0\uFE0F ${w}
|
|
756
816
|
`);
|
|
757
817
|
}
|
|
758
818
|
} catch (err) {
|
|
@@ -782,7 +842,7 @@ function registerRenderCommands(program2) {
|
|
|
782
842
|
const absPath = resolve3(file);
|
|
783
843
|
const stem = file.replace(/\.hwpx?$/i, "");
|
|
784
844
|
if (fmt === "svg" && !outDir && !pages && !/\.hwp$/i.test(absPath)) {
|
|
785
|
-
const { renderHwpxToSvg } = await import("./render-
|
|
845
|
+
const { renderHwpxToSvg } = await import("./render-U5PE6V2E.js");
|
|
786
846
|
const buffer = readFileSync3(absPath);
|
|
787
847
|
const result = await renderHwpxToSvg(toArrayBuffer(buffer), { highlights, reflow: opts.reflow, reflowMode: opts.reflowMode });
|
|
788
848
|
const outPath = resolve3(output ?? stem + ".svg");
|
|
@@ -796,7 +856,7 @@ function registerRenderCommands(program2) {
|
|
|
796
856
|
}
|
|
797
857
|
return;
|
|
798
858
|
}
|
|
799
|
-
const { renderDocument } = await import("./render-
|
|
859
|
+
const { renderDocument } = await import("./render-U5PE6V2E.js");
|
|
800
860
|
const { scene, assets } = await renderDocument(absPath, {
|
|
801
861
|
format: fmt,
|
|
802
862
|
pages,
|
|
@@ -846,7 +906,7 @@ function registerRenderCommands(program2) {
|
|
|
846
906
|
if (!outDir) throw new KordocError("--out-dir \uC774 \uD544\uC694\uD569\uB2C8\uB2E4 (crop \uC740 \uD30C\uC77C \uC5EC\uB7EC \uAC1C\uB97C \uB0C5\uB2C8\uB2E4)");
|
|
847
907
|
const types = String(opts.target).split(",").map((t) => t.trim()).filter(Boolean);
|
|
848
908
|
for (const t of types) if (!["table", "image", "paragraph", "shape"].includes(t)) throw new KordocError(`--target \uC720\uD615 \uC624\uB958: ${t}`);
|
|
849
|
-
const { extractRenderedRegions } = await import("./render-
|
|
909
|
+
const { extractRenderedRegions } = await import("./render-U5PE6V2E.js");
|
|
850
910
|
const regions = await extractRenderedRegions(resolve3(file), {
|
|
851
911
|
types,
|
|
852
912
|
format: fmt,
|
|
@@ -884,7 +944,7 @@ function registerRenderCommands(program2) {
|
|
|
884
944
|
if (policy !== "none" && !outDir) throw new KordocError("--visual \uC740 crop \uD30C\uC77C\uC744 \uB0B4\uBBC0\uB85C --out-dir \uC774 \uD544\uC694\uD569\uB2C8\uB2E4");
|
|
885
945
|
const cropFmt = String(opts.cropFormat);
|
|
886
946
|
if (!["png", "jpeg"].includes(cropFmt)) throw new KordocError(`--crop-format \uC740 png|jpeg: ${cropFmt}`);
|
|
887
|
-
const { extractTables } = await import("./visual-
|
|
947
|
+
const { extractTables } = await import("./visual-5XWMA4EV.js");
|
|
888
948
|
const tables = await extractTables(resolve3(file), { policy, format: cropFmt, paddingPt: Number(opts.padding) || 0 });
|
|
889
949
|
const dir = outDir ? resolve3(outDir) : void 0;
|
|
890
950
|
if (dir) mkdirSync3(dir, { recursive: true });
|
|
@@ -928,7 +988,7 @@ function registerRenderCommands(program2) {
|
|
|
928
988
|
});
|
|
929
989
|
program2.command("render-worker").description("persistent \uB80C\uB354 \uC6CC\uCEE4 \u2014 stdin NDJSON \uC694\uCCAD \u2192 \uC870\uD310 SVG \uD30C\uC77C \uCD9C\uB825 (\uD504\uB85C\uC138\uC2A4 \uC720\uC9C0, \uCF5C\uB4DC\uC2A4\uD0C0\uD2B8 \uC81C\uAC70)").action(async () => {
|
|
930
990
|
const { createInterface } = await import("readline");
|
|
931
|
-
const { renderHwpxToSvg } = await import("./render-
|
|
991
|
+
const { renderHwpxToSvg } = await import("./render-U5PE6V2E.js");
|
|
932
992
|
const rl = createInterface({ input: process.stdin });
|
|
933
993
|
const write = (o) => void process.stdout.write(JSON.stringify(o) + "\n");
|
|
934
994
|
write({ ready: true, version: VERSION });
|
|
@@ -977,12 +1037,12 @@ function registerSystemCommands(program2) {
|
|
|
977
1037
|
await startMcpServer();
|
|
978
1038
|
});
|
|
979
1039
|
program2.command("setup").description("\uB300\uD654\uD615 \uC124\uCE58 \uB9C8\uBC95\uC0AC \u2014 AI \uD074\uB77C\uC774\uC5B8\uD2B8 \uC790\uB3D9 \uB4F1\uB85D (Mac/Win/Linux)").action(async () => {
|
|
980
|
-
const { runSetup } = await import("./setup-
|
|
1040
|
+
const { runSetup } = await import("./setup-YRDM4ODP.js");
|
|
981
1041
|
await runSetup();
|
|
982
1042
|
});
|
|
983
1043
|
program2.command("check-formula-models").description("PDF \uC218\uC2DD OCR \uBAA8\uB378(MFD + MFR + tokenizer, ~155MB) \uC0C1\uD0DC \uD655\uC778 \u2014 \uC5C6\uAC70\uB098 SHA \uBD88\uC77C\uCE58\uBA74 \uB2E4\uC6B4\uB85C\uB4DC").option("--status-only", "\uC0C1\uD0DC\uB9CC JSON \uC73C\uB85C \uCD9C\uB825 (\uB2E4\uC6B4\uB85C\uB4DC \uC548 \uD568)").action(async (opts) => {
|
|
984
1044
|
try {
|
|
985
|
-
const { getFormulaModelStatus, ensureFormulaModels, getFormulaModelsDir } = await import("./formula-
|
|
1045
|
+
const { getFormulaModelStatus, ensureFormulaModels, getFormulaModelsDir } = await import("./formula-NOIDZEBA.js");
|
|
986
1046
|
const dir = getFormulaModelsDir();
|
|
987
1047
|
if (opts.statusOnly) {
|
|
988
1048
|
const status = await getFormulaModelStatus();
|
|
@@ -1036,7 +1096,7 @@ function registerSystemCommands(program2) {
|
|
|
1036
1096
|
});
|
|
1037
1097
|
program2.command("check-ocr-models").description("\uD14D\uC2A4\uD2B8 OCR \uBAA8\uB378(PP-OCRv5 korean det+rec, ~18MB) \uC0C1\uD0DC \uD655\uC778 \u2014 \uC5C6\uAC70\uB098 SHA \uBD88\uC77C\uCE58\uBA74 \uB2E4\uC6B4\uB85C\uB4DC").option("--status-only", "\uC0C1\uD0DC\uB9CC JSON \uC73C\uB85C \uCD9C\uB825 (\uB2E4\uC6B4\uB85C\uB4DC \uC548 \uD568)").action(async (opts) => {
|
|
1038
1098
|
try {
|
|
1039
|
-
const { getOcrModelStatus, ensureOcrModels, getOcrModelsDir } = await import("./models-
|
|
1099
|
+
const { getOcrModelStatus, ensureOcrModels, getOcrModelsDir } = await import("./models-7ELIFTD7.js");
|
|
1040
1100
|
const dir = getOcrModelsDir();
|
|
1041
1101
|
if (opts.statusOnly) {
|
|
1042
1102
|
const status = await getOcrModelStatus();
|
|
@@ -1090,7 +1150,7 @@ function registerSystemCommands(program2) {
|
|
|
1090
1150
|
});
|
|
1091
1151
|
program2.command("models").description("OCR/\uC218\uC2DD \uBAA8\uB378 \uC624\uD504\uB77C\uC778 \uC0AC\uC774\uB4DC\uB85C\uB4DC \u2014 \uD3D0\uC1C4\uB9DD \uBC18\uC785\uC6A9 \uB0B4\uBCF4\uB0B4\uAE30/\uAC00\uC838\uC624\uAE30 (SHA-256 \uAC80\uC99D)").option("--status", "\uCE90\uC2DC\uC5D0 \uC124\uCE58\uB41C \uBAA8\uB378 \uC0C1\uD0DC\uB97C JSON \uC73C\uB85C \uCD9C\uB825").option("--export <dir>", "\uB85C\uCEEC \uCE90\uC2DC \u2192 \uBC88\uB4E4 \uB514\uB809\uD1A0\uB9AC\uB85C \uB0B4\uBCF4\uB0B4\uAE30 (\uC628\uB77C\uC778 PC\uC5D0\uC11C \uC2E4\uD589)").option("--import <dir>", "\uBC88\uB4E4 \uB514\uB809\uD1A0\uB9AC \u2192 \uB85C\uCEEC \uCE90\uC2DC\uB85C \uC124\uCE58 (\uB0B4\uBD80\uB9DD PC\uC5D0\uC11C \uC2E4\uD589)").action(async (opts) => {
|
|
1092
1152
|
try {
|
|
1093
|
-
const { exportModels, importModels, modelCacheStatus } = await import("./model-bundle-
|
|
1153
|
+
const { exportModels, importModels, modelCacheStatus } = await import("./model-bundle-57CLEBCO.js");
|
|
1094
1154
|
if (opts.status) {
|
|
1095
1155
|
process.stdout.write(JSON.stringify(await modelCacheStatus(), null, 2) + "\n");
|
|
1096
1156
|
return;
|
|
@@ -1126,9 +1186,78 @@ function registerSystemCommands(program2) {
|
|
|
1126
1186
|
});
|
|
1127
1187
|
}
|
|
1128
1188
|
|
|
1189
|
+
// src/cli/commands-worker.ts
|
|
1190
|
+
import { readFileSync as readFileSync4, statSync as statSync3 } from "fs";
|
|
1191
|
+
import { resolve as resolve4 } from "path";
|
|
1192
|
+
import { format } from "util";
|
|
1193
|
+
var PARSE_WORKER_PROTOCOL = 1;
|
|
1194
|
+
var MAX_FILE_BYTES = 500 * 1024 * 1024;
|
|
1195
|
+
var bytesToBase64 = (_key, value) => value instanceof Uint8Array ? Buffer.from(value).toString("base64") : value;
|
|
1196
|
+
async function parseOne(req) {
|
|
1197
|
+
const absPath = resolve4(req.file);
|
|
1198
|
+
try {
|
|
1199
|
+
const size = statSync3(absPath).size;
|
|
1200
|
+
if (size > MAX_FILE_BYTES) {
|
|
1201
|
+
return { success: false, fileType: "unknown", error: `\uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${(size / 1024 / 1024).toFixed(1)}MB)`, code: "PARSE_ERROR" };
|
|
1202
|
+
}
|
|
1203
|
+
const options = { filePath: absPath };
|
|
1204
|
+
if (req.images === false) options.images = false;
|
|
1205
|
+
if (req.ocr === "force") options.ocr = "force";
|
|
1206
|
+
else if (req.ocr === "auto") options.ocr = true;
|
|
1207
|
+
if (req.formulaOcr) options.formulaOcr = true;
|
|
1208
|
+
if (req.password) options.password = req.password;
|
|
1209
|
+
return await parse(toArrayBuffer(readFileSync4(absPath)), options);
|
|
1210
|
+
} catch (err) {
|
|
1211
|
+
return { success: false, fileType: "unknown", error: sanitizeError(err), code: classifyError(err) };
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
function registerWorkerCommands(program2) {
|
|
1215
|
+
program2.command("parse-worker").description("\uC0C1\uC8FC \uD30C\uC2F1 \uC6CC\uCEE4: stdin NDJSON \uC694\uCCAD \u2192 \uD55C \uC904 JSON \uC751\uB2F5 (\uD504\uB85C\uC138\uC2A4 \uC720\uC9C0, \uD30C\uC77C\uB9C8\uB2E4 node \uB97C \uC0C8\uB85C \uB744\uC6B0\uB294 \uBE44\uC6A9 \uC81C\uAC70)").action(async () => {
|
|
1216
|
+
const toStderr = (...args) => void process.stderr.write(format(...args) + "\n");
|
|
1217
|
+
console.log = toStderr;
|
|
1218
|
+
console.info = toStderr;
|
|
1219
|
+
console.warn = toStderr;
|
|
1220
|
+
console.debug = toStderr;
|
|
1221
|
+
const { createInterface } = await import("readline");
|
|
1222
|
+
const rl = createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
1223
|
+
const write = (o) => void process.stdout.write(JSON.stringify(o, bytesToBase64) + "\n");
|
|
1224
|
+
write({ ready: true, version: VERSION, protocol: PARSE_WORKER_PROTOCOL });
|
|
1225
|
+
for await (const line of rl) {
|
|
1226
|
+
const t = line.trim();
|
|
1227
|
+
if (!t) continue;
|
|
1228
|
+
let req;
|
|
1229
|
+
try {
|
|
1230
|
+
req = JSON.parse(t);
|
|
1231
|
+
} catch {
|
|
1232
|
+
write({ error: "\uC798\uBABB\uB41C JSON \uB77C\uC778" });
|
|
1233
|
+
continue;
|
|
1234
|
+
}
|
|
1235
|
+
if (req === null || typeof req !== "object") {
|
|
1236
|
+
write({ error: "JSON \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4" });
|
|
1237
|
+
continue;
|
|
1238
|
+
}
|
|
1239
|
+
if (req.cmd === "quit") break;
|
|
1240
|
+
const id = req.id;
|
|
1241
|
+
if (typeof req.file !== "string" || !req.file) {
|
|
1242
|
+
write({ id, error: "file \uD544\uC218" });
|
|
1243
|
+
continue;
|
|
1244
|
+
}
|
|
1245
|
+
const result = await parseOne({ ...req, file: req.file });
|
|
1246
|
+
try {
|
|
1247
|
+
write({ id, rss: process.memoryUsage.rss(), result });
|
|
1248
|
+
} catch (err) {
|
|
1249
|
+
write({ id, rss: process.memoryUsage.rss(), result: { success: false, fileType: result.fileType, error: sanitizeError(err), code: classifyError(err) } });
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
rl.close();
|
|
1253
|
+
await new Promise((done) => process.stdout.write("", () => done()));
|
|
1254
|
+
process.exit(0);
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1129
1258
|
// src/cli.ts
|
|
1130
1259
|
var program = new Command();
|
|
1131
|
-
program.name("kordoc").description("\uBAA8\uB450 \uD30C\uC2F1\uD574\uBC84\uB9AC\uACA0\uB2E4 \u2014 HWP, HWPX, PDF, XLSX, DOCX, \uC774\uBBF8\uC9C0(PNG/JPG/WebP) \u2192 Markdown").version(VERSION).argument("<files...>", "\uBCC0\uD658\uD560 \uD30C\uC77C \uACBD\uB85C (HWP, HWPX, PDF, XLSX, DOCX, PNG/JPG/WebP \u2014 \uC774\uBBF8\uC9C0\uB294 OCR \uC790\uB3D9 \uC801\uC6A9)").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 \uBC94\uC704 (\uC608: 1-3, 1,3,5) \u2014 \uD55C\uCEF4 \uC800\uC7A5\uBCF8\uC740 \uC2E4\uC81C \uD398\uC774\uC9C0, \uC870\uD310 \uCE90\uC2DC \uC5C6\uC73C\uBA74 \uC139\uC158 \uADFC\uC0AC").option("--format <type>", "\uCD9C\uB825 \uD615\uC2DD: markdown (\uAE30\uBCF8), json, chunks (RAG\uC6A9 \uAD6C\uC870 \uCCAD\uD06C JSON \u2014 \uD5E4\uB529\xB7\uAC1C\uC870\uC2DD \uC704\uACC4 breadcrumb + \uD45C \uB3C5\uB9BD \uCCAD\uD06C)", "markdown").option("--no-header-footer", "PDF \uBA38\uB9AC\uAE00/\uBC14\uB2E5\uAE00 \uC790\uB3D9 \uC81C\uAC70 \uB044\uAE30 (\uAE30\uBCF8: \uC81C\uAC70\uD568)").option("--no-tables", "PDF \uD45C \uAC10\uC9C0 \uB044\uAE30 \u2014 \uD14C\uB450\uB9AC \uBC15\uC2A4\uB97C \uD45C\uB85C \uC624\uC778\uD574 \uC77D\uAE30 \uC21C\uC11C\uAC00 \uB4A4\uC9D1\uD788\uB294 \uBB38\uC11C(2\uB2E8 \uC2DC\uD5D8\uC9C0 \uB4F1)\uC5D0\uC11C \uC790\uC5F0 \uC77D\uAE30\uC21C \uD14D\uC2A4\uD2B8\uB9CC \uBF51\uB294\uB2E4 (#64)").option("--formula-ocr", "PDF \uC218\uC2DD OCR \uD65C\uC131\uD654 (MFD+MFR ONNX, \uCCAB \uC0AC\uC6A9 \uC2DC \uBAA8\uB378 ~155MB \uC790\uB3D9 \uB2E4\uC6B4\uB85C\uB4DC)").option("--ocr", "\uC2A4\uCE94/\uC774\uBBF8\uC9C0 PDF \uD14D\uC2A4\uD2B8 OCR (\uB0B4\uC7A5 PP-OCRv5 korean, \uCCAB \uC0AC\uC6A9 \uC2DC \uBAA8\uB378 ~18MB \uC790\uB3D9 \uB2E4\uC6B4\uB85C\uB4DC \u2014 OCR \uD544\uC694 \uD398\uC774\uC9C0\uB9CC \uC778\uC2DD)").option("--ocr-force", "\uC804 \uD398\uC774\uC9C0 \uAC15\uC81C OCR (\uD14D\uC2A4\uD2B8\uCE35\uC774 \uC788\uC5B4\uB3C4 \uBB34\uC2DC\uD558\uACE0 \uC7AC\uC778\uC2DD)").option("--dedupe-headers", "HWP5 \uB808\uC774\uC544\uC6C3 \uD45C \uD398\uC774\uC9C0 \uBC18\uBCF5 \uB7EC\uB2DD \uD5E4\uB354 \uC911\uBCF5 \uC81C\uAC70 (\uAE30\uBCF8 off \u2014 \uBD99\uC784\uBCC4 \uC7AC\uBC88\uD638 \uC624\uC0AD\uC81C \uC8FC\uC758)").option("--keep-empty-cols", "\uD45C \uC624\uB978\uCABD \uB05D \uBE48 \uC5F4(\uC11C\uC2DD \uC785\uB825\uB780) \uBCF4\uC874 (#47, \uAE30\uBCF8 off: \uD6C4\uD589 \uBE48 \uC5F4 \uD2B8\uB9BC)").option("--keep-empty-paragraphs", "\uBE48 \uBB38\uB2E8 \uBCF4\uC874 \u2014 \uBCF8\uBB38\uC740 \uBE48 paragraph \uBE14\uB85D, \uD45C \uC140\uC740 \uBE48 \uC904\uB85C (#57, \uAE30\uBCF8 off: \uBE48 \uBB38\uB2E8 \uC81C\uAC70)").option("--inline-images", "\uC774\uBBF8\uC9C0\uB97C base64 data URI \uB85C \uB9C8\uD06C\uB2E4\uC6B4\uC5D0 \uC778\uB77C\uC778 (BMP\u2192PNG \uC555\uCD95, HWP5 \uC804\uC6A9 \u2014 \uC778\uB77C\uC778\uB41C \uACBD\uC6B0\uB9CC \uD30C\uC77C \uBBF8\uC800\uC7A5, \uADF8 \uC678 \uD3EC\uB9F7\uC740 \uC800\uC7A5 \uC720\uC9C0)").option("--image-refs", "--format json \uC5D0\uC11C \uC774\uBBF8\uC9C0 \uBC14\uC774\uD2B8\uB97C \uC778\uB77C\uC778\uD558\uC9C0 \uC54A\uACE0 \uD30C\uC77C \uCC38\uC870(images/<\uD30C\uC77C\uBA85>)\uB9CC \uB0A8\uAE40 (#65 \u2014 \uC774\uBBF8\uC9C0\uAC00 \uC218\uBC31 \uC7A5\uC778 \uBB38\uC11C\uC758 \uC9C1\uB82C\uD654 \uD55C\uACC4 \uD68C\uD53C, -o/-d \uC640 \uD568\uAED8 \uC0AC\uC6A9)").option("--password <pw>", "\uC554\uD638\uB85C \uBCF4\uD638\uB41C \uBB38\uC11C\uC758 \uC5F4\uAE30 \uC554\uD638 (#59, HWPX\xB7HWP3\xB7HWP5. \uD55C\uCEF4 DRM \uBB38\uC11C\uB294 \uD574\uB2F9 \uC5C6\uC74C)").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (files, opts) => {
|
|
1260
|
+
program.name("kordoc").description("\uBAA8\uB450 \uD30C\uC2F1\uD574\uBC84\uB9AC\uACA0\uB2E4 \u2014 HWP, HWPX, PDF, XLSX, DOCX, \uC774\uBBF8\uC9C0(PNG/JPG/WebP) \u2192 Markdown").version(VERSION).argument("<files...>", "\uBCC0\uD658\uD560 \uD30C\uC77C \uACBD\uB85C (HWP, HWPX, PDF, XLSX, DOCX, PNG/JPG/WebP \u2014 \uC774\uBBF8\uC9C0\uB294 OCR \uC790\uB3D9 \uC801\uC6A9)").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 \uBC94\uC704 (\uC608: 1-3, 1,3,5) \u2014 \uD55C\uCEF4 \uC800\uC7A5\uBCF8\uC740 \uC2E4\uC81C \uD398\uC774\uC9C0, \uC870\uD310 \uCE90\uC2DC \uC5C6\uC73C\uBA74 \uC139\uC158 \uADFC\uC0AC").option("--format <type>", "\uCD9C\uB825 \uD615\uC2DD: markdown (\uAE30\uBCF8), json, chunks (RAG\uC6A9 \uAD6C\uC870 \uCCAD\uD06C JSON \u2014 \uD5E4\uB529\xB7\uAC1C\uC870\uC2DD \uC704\uACC4 breadcrumb + \uD45C \uB3C5\uB9BD \uCCAD\uD06C)", "markdown").option("--no-header-footer", "PDF \uBA38\uB9AC\uAE00/\uBC14\uB2E5\uAE00 \uC790\uB3D9 \uC81C\uAC70 \uB044\uAE30 (\uAE30\uBCF8: \uC81C\uAC70\uD568)").option("--no-tables", "PDF \uD45C \uAC10\uC9C0 \uB044\uAE30 \u2014 \uD14C\uB450\uB9AC \uBC15\uC2A4\uB97C \uD45C\uB85C \uC624\uC778\uD574 \uC77D\uAE30 \uC21C\uC11C\uAC00 \uB4A4\uC9D1\uD788\uB294 \uBB38\uC11C(2\uB2E8 \uC2DC\uD5D8\uC9C0 \uB4F1)\uC5D0\uC11C \uC790\uC5F0 \uC77D\uAE30\uC21C \uD14D\uC2A4\uD2B8\uB9CC \uBF51\uB294\uB2E4 (#64)").option("--formula-ocr", "PDF \uC218\uC2DD OCR \uD65C\uC131\uD654 (MFD+MFR ONNX, \uCCAB \uC0AC\uC6A9 \uC2DC \uBAA8\uB378 ~155MB \uC790\uB3D9 \uB2E4\uC6B4\uB85C\uB4DC)").option("--ocr", "\uC2A4\uCE94/\uC774\uBBF8\uC9C0 PDF \uD14D\uC2A4\uD2B8 OCR (\uB0B4\uC7A5 PP-OCRv5 korean, \uCCAB \uC0AC\uC6A9 \uC2DC \uBAA8\uB378 ~18MB \uC790\uB3D9 \uB2E4\uC6B4\uB85C\uB4DC \u2014 OCR \uD544\uC694 \uD398\uC774\uC9C0\uB9CC \uC778\uC2DD)").option("--ocr-force", "\uC804 \uD398\uC774\uC9C0 \uAC15\uC81C OCR (\uD14D\uC2A4\uD2B8\uCE35\uC774 \uC788\uC5B4\uB3C4 \uBB34\uC2DC\uD558\uACE0 \uC7AC\uC778\uC2DD)").option("--dedupe-headers", "HWP5 \uB808\uC774\uC544\uC6C3 \uD45C \uD398\uC774\uC9C0 \uBC18\uBCF5 \uB7EC\uB2DD \uD5E4\uB354 \uC911\uBCF5 \uC81C\uAC70 (\uAE30\uBCF8 off \u2014 \uBD99\uC784\uBCC4 \uC7AC\uBC88\uD638 \uC624\uC0AD\uC81C \uC8FC\uC758)").option("--keep-empty-cols", "\uD45C \uC624\uB978\uCABD \uB05D \uBE48 \uC5F4(\uC11C\uC2DD \uC785\uB825\uB780) \uBCF4\uC874 (#47, \uAE30\uBCF8 off: \uD6C4\uD589 \uBE48 \uC5F4 \uD2B8\uB9BC)").option("--keep-empty-paragraphs", "\uBE48 \uBB38\uB2E8 \uBCF4\uC874 \u2014 \uBCF8\uBB38\uC740 \uBE48 paragraph \uBE14\uB85D, \uD45C \uC140\uC740 \uBE48 \uC904\uB85C (#57, \uAE30\uBCF8 off: \uBE48 \uBB38\uB2E8 \uC81C\uAC70)").option("--inline-images", "\uC774\uBBF8\uC9C0\uB97C base64 data URI \uB85C \uB9C8\uD06C\uB2E4\uC6B4\uC5D0 \uC778\uB77C\uC778 (BMP\u2192PNG \uC555\uCD95, HWP5 \uC804\uC6A9 \u2014 \uC778\uB77C\uC778\uB41C \uACBD\uC6B0\uB9CC \uD30C\uC77C \uBBF8\uC800\uC7A5, \uADF8 \uC678 \uD3EC\uB9F7\uC740 \uC800\uC7A5 \uC720\uC9C0)").option("--image-refs", "--format json \uC5D0\uC11C \uC774\uBBF8\uC9C0 \uBC14\uC774\uD2B8\uB97C \uC778\uB77C\uC778\uD558\uC9C0 \uC54A\uACE0 \uD30C\uC77C \uCC38\uC870(images/<\uD30C\uC77C\uBA85>)\uB9CC \uB0A8\uAE40 (#65 \u2014 \uC774\uBBF8\uC9C0\uAC00 \uC218\uBC31 \uC7A5\uC778 \uBB38\uC11C\uC758 \uC9C1\uB82C\uD654 \uD55C\uACC4 \uD68C\uD53C, -o/-d \uC640 \uD568\uAED8 \uC0AC\uC6A9)").option("--password <pw>", "\uC554\uD638\uB85C \uBCF4\uD638\uB41C \uBB38\uC11C\uC758 \uC5F4\uAE30 \uC554\uD638 (#59, HWPX\xB7HWP3\xB7HWP5. \uD55C\uCEF4 DRM \uBB38\uC11C\uB294 \uD574\uB2F9 \uC5C6\uC74C)").option("--no-images", "\uC774\uBBF8\uC9C0 \uBC14\uC774\uD2B8\uB97C \uCD94\uCD9C\xB7\uCD9C\uB825\uD558\uC9C0 \uC54A\uC74C: \uAE00\uC790\uB9CC \uD544\uC694\uD560 \uB54C (\uADF8\uB9BC \uC790\uB9AC \uD45C\uC2DC\uB294 \uB0A8\uAE40, PDF \uB294 PNG \uC778\uCF54\uB529\uC744 \uAC74\uB108\uB700)").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (files, opts) => {
|
|
1132
1261
|
const validFormats = ["markdown", "json", "chunks"];
|
|
1133
1262
|
if (!validFormats.includes(opts.format)) {
|
|
1134
1263
|
process.stderr.write(`[kordoc] \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD615\uC2DD: ${opts.format} (markdown, json, chunks)
|
|
@@ -1141,12 +1270,12 @@ program.name("kordoc").description("\uBAA8\uB450 \uD30C\uC2F1\uD574\uBC84\uB9AC\
|
|
|
1141
1270
|
}
|
|
1142
1271
|
for (let fi = 0; fi < files.length; fi++) {
|
|
1143
1272
|
const filePath = files[fi];
|
|
1144
|
-
const absPath =
|
|
1273
|
+
const absPath = resolve5(filePath);
|
|
1145
1274
|
const fileName = basename3(absPath);
|
|
1146
1275
|
const filePrefix = files.length > 1 ? `[${fi + 1}/${files.length}] ` : "";
|
|
1147
1276
|
let detectedFormat = "unknown";
|
|
1148
1277
|
try {
|
|
1149
|
-
const fileSize =
|
|
1278
|
+
const fileSize = statSync4(absPath).size;
|
|
1150
1279
|
if (fileSize > 500 * 1024 * 1024) {
|
|
1151
1280
|
process.stderr.write(`
|
|
1152
1281
|
[kordoc] SKIP: ${fileName} \u2014 \uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${(fileSize / 1024 / 1024).toFixed(1)}MB)
|
|
@@ -1154,12 +1283,12 @@ program.name("kordoc").description("\uBAA8\uB450 \uD30C\uC2F1\uD574\uBC84\uB9AC\
|
|
|
1154
1283
|
process.exitCode = 1;
|
|
1155
1284
|
continue;
|
|
1156
1285
|
}
|
|
1157
|
-
const buffer =
|
|
1286
|
+
const buffer = readFileSync5(absPath);
|
|
1158
1287
|
const arrayBuffer = toArrayBuffer(buffer);
|
|
1159
|
-
const
|
|
1160
|
-
detectedFormat =
|
|
1288
|
+
const format2 = detectFormat(arrayBuffer);
|
|
1289
|
+
detectedFormat = format2;
|
|
1161
1290
|
if (!opts.silent) {
|
|
1162
|
-
process.stderr.write(`[kordoc] ${filePrefix}${fileName} (${
|
|
1291
|
+
process.stderr.write(`[kordoc] ${filePrefix}${fileName} (${format2}) ...`);
|
|
1163
1292
|
}
|
|
1164
1293
|
const parseOptions = { filePath: absPath };
|
|
1165
1294
|
if (opts.pages) parseOptions.pages = opts.pages;
|
|
@@ -1173,9 +1302,10 @@ program.name("kordoc").description("\uBAA8\uB450 \uD30C\uC2F1\uD574\uBC84\uB9AC\
|
|
|
1173
1302
|
if (opts.keepEmptyParagraphs) parseOptions.keepEmptyParagraphs = true;
|
|
1174
1303
|
if (opts.inlineImages) parseOptions.inlineImages = true;
|
|
1175
1304
|
if (opts.password) parseOptions.password = opts.password;
|
|
1305
|
+
if (opts.images === false) parseOptions.images = false;
|
|
1176
1306
|
if (!opts.silent) {
|
|
1177
1307
|
parseOptions.onProgress = (current, total) => {
|
|
1178
|
-
process.stderr.write(`\r[kordoc] ${filePrefix}${fileName} (${
|
|
1308
|
+
process.stderr.write(`\r[kordoc] ${filePrefix}${fileName} (${format2}) [${current}/${total}]`);
|
|
1179
1309
|
};
|
|
1180
1310
|
}
|
|
1181
1311
|
const result = await parse(arrayBuffer, parseOptions);
|
|
@@ -1216,17 +1346,17 @@ program.name("kordoc").description("\uBAA8\uB450 \uD30C\uC2F1\uD574\uBC84\uB9AC\
|
|
|
1216
1346
|
`);
|
|
1217
1347
|
}
|
|
1218
1348
|
} else if (opts.format === "chunks") {
|
|
1219
|
-
const { blocksToChunks } = await import("./chunks-
|
|
1349
|
+
const { blocksToChunks } = await import("./chunks-I7TEMJXH.js");
|
|
1220
1350
|
output = JSON.stringify(blocksToChunks(result.blocks), null, 2);
|
|
1221
1351
|
} else {
|
|
1222
1352
|
output = markdown;
|
|
1223
1353
|
}
|
|
1224
1354
|
const saveImages = (dir) => {
|
|
1225
1355
|
if (!result.images?.length || imagesInlined) return;
|
|
1226
|
-
const imgDir =
|
|
1356
|
+
const imgDir = resolve5(dir, "images");
|
|
1227
1357
|
mkdirSync4(imgDir, { recursive: true });
|
|
1228
1358
|
for (const img of result.images) {
|
|
1229
|
-
writeFileSync4(
|
|
1359
|
+
writeFileSync4(resolve5(imgDir, img.filename), img.data);
|
|
1230
1360
|
}
|
|
1231
1361
|
const manifest = result.images.map((img) => ({
|
|
1232
1362
|
name: img.filename,
|
|
@@ -1234,7 +1364,7 @@ program.name("kordoc").description("\uBAA8\uB450 \uD30C\uC2F1\uD574\uBC84\uB9AC\
|
|
|
1234
1364
|
bytes: img.data.length,
|
|
1235
1365
|
...img.source ? { source: img.source } : {}
|
|
1236
1366
|
}));
|
|
1237
|
-
writeFileSync4(
|
|
1367
|
+
writeFileSync4(resolve5(imgDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
|
|
1238
1368
|
if (!opts.silent) process.stderr.write(` \u2192 ${result.images.length}\uAC1C \uC774\uBBF8\uC9C0 \u2192 ${imgDir} (manifest.json \uD3EC\uD568)
|
|
1239
1369
|
`);
|
|
1240
1370
|
};
|
|
@@ -1242,11 +1372,11 @@ program.name("kordoc").description("\uBAA8\uB450 \uD30C\uC2F1\uD574\uBC84\uB9AC\
|
|
|
1242
1372
|
writeFileSync4(opts.output, output, "utf-8");
|
|
1243
1373
|
if (!opts.silent) process.stderr.write(` \u2192 ${opts.output}
|
|
1244
1374
|
`);
|
|
1245
|
-
saveImages(
|
|
1375
|
+
saveImages(resolve5(opts.output, ".."));
|
|
1246
1376
|
} else if (opts.outDir) {
|
|
1247
1377
|
mkdirSync4(opts.outDir, { recursive: true });
|
|
1248
1378
|
const outExt = opts.format === "json" ? ".json" : opts.format === "chunks" ? ".chunks.json" : ".md";
|
|
1249
|
-
const outPath =
|
|
1379
|
+
const outPath = resolve5(opts.outDir, fileName.replace(/\.[^.]+$/, outExt));
|
|
1250
1380
|
writeFileSync4(outPath, output, "utf-8");
|
|
1251
1381
|
if (!opts.silent) process.stderr.write(` \u2192 ${outPath}
|
|
1252
1382
|
`);
|
|
@@ -1272,5 +1402,6 @@ registerDocCommands(program);
|
|
|
1272
1402
|
registerGenerateCommands(program);
|
|
1273
1403
|
registerRenderCommands(program);
|
|
1274
1404
|
registerSystemCommands(program);
|
|
1405
|
+
registerWorkerCommands(program);
|
|
1275
1406
|
program.parse();
|
|
1276
1407
|
//# sourceMappingURL=cli.js.map
|