kordoc 3.7.0 → 3.8.0
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 +8 -1
- package/dist/{-7UC4ZWBS.js → -ATVQYFSW.js} +3 -3
- package/dist/{chunk-IJJMVTU5.js → chunk-3R3YK7EM.js} +2 -2
- package/dist/{chunk-QZCP3UWU.cjs → chunk-ITJIALN5.cjs} +2 -2
- package/dist/{chunk-QZCP3UWU.cjs.map → chunk-ITJIALN5.cjs.map} +1 -1
- package/dist/{chunk-MEVKYW55.js → chunk-QV25HMU7.js} +2 -2
- package/dist/{chunk-NXRABCWW.js → chunk-SLKF72QF.js} +170 -89
- package/dist/chunk-SLKF72QF.js.map +1 -0
- package/dist/cli.js +4 -4
- package/dist/index.cjs +311 -230
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +169 -88
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +3 -3
- package/dist/{parser-DR5CTZ74.js → parser-7G5F7PT2.js} +2 -2
- package/dist/{parser-ZHJFQR44.js → parser-DCK42RMA.js} +2 -2
- package/dist/{parser-RFLPUZ7P.cjs → parser-GUSJH44K.cjs} +14 -14
- package/dist/{parser-RFLPUZ7P.cjs.map → parser-GUSJH44K.cjs.map} +1 -1
- package/dist/{watch-UIX447QV.js → watch-GVZESOCE.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-NXRABCWW.js.map +0 -1
- /package/dist/{-7UC4ZWBS.js.map → -ATVQYFSW.js.map} +0 -0
- /package/dist/{chunk-IJJMVTU5.js.map → chunk-3R3YK7EM.js.map} +0 -0
- /package/dist/{chunk-MEVKYW55.js.map → chunk-QV25HMU7.js.map} +0 -0
- /package/dist/{parser-DR5CTZ74.js.map → parser-7G5F7PT2.js.map} +0 -0
- /package/dist/{parser-ZHJFQR44.js.map → parser-DCK42RMA.js.map} +0 -0
- /package/dist/{watch-UIX447QV.js.map → watch-GVZESOCE.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
sanitizeHref,
|
|
20
20
|
stripDtd,
|
|
21
21
|
toArrayBuffer
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-QV25HMU7.js";
|
|
23
23
|
import {
|
|
24
24
|
parsePageRange
|
|
25
25
|
} from "./chunk-GE43BE46.js";
|
|
@@ -1212,57 +1212,62 @@ async function extractImagesFromZip(zip, blocks, decompressed, warnings) {
|
|
|
1212
1212
|
let imageIndex = 0;
|
|
1213
1213
|
const imageBlocks = [];
|
|
1214
1214
|
collectImageBlocks(blocks, imageBlocks);
|
|
1215
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
1215
1216
|
for (const { block, ownerCell } of imageBlocks) {
|
|
1216
1217
|
if (block.type !== "image" || !block.text) continue;
|
|
1217
1218
|
const ref = block.text;
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1219
|
+
let img = resolved.get(ref);
|
|
1220
|
+
if (img === void 0) {
|
|
1221
|
+
img = null;
|
|
1222
|
+
const candidates = [
|
|
1223
|
+
`BinData/${ref}`,
|
|
1224
|
+
`Contents/BinData/${ref}`,
|
|
1225
|
+
ref
|
|
1226
|
+
// 절대 경로일 수도 있음
|
|
1227
|
+
];
|
|
1228
|
+
let resolvedPath = null;
|
|
1229
|
+
if (!ref.includes(".")) {
|
|
1230
|
+
const prefixes = [`BinData/${ref}`, `Contents/BinData/${ref}`];
|
|
1231
|
+
for (const prefix of prefixes) {
|
|
1232
|
+
const match = zip.file(new RegExp(`^${prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.[a-zA-Z0-9]+$`));
|
|
1233
|
+
if (match.length > 0) {
|
|
1234
|
+
resolvedPath = match[0].name;
|
|
1235
|
+
break;
|
|
1236
|
+
}
|
|
1232
1237
|
}
|
|
1233
1238
|
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
if (ownerCell) ownerCell.text = ownerCell.text.replace(``, ``);
|
|
1254
|
-
found = true;
|
|
1255
|
-
break;
|
|
1256
|
-
} catch (err) {
|
|
1257
|
-
if (err instanceof KordocError) throw err;
|
|
1239
|
+
const allCandidates = resolvedPath ? [resolvedPath, ...candidates] : candidates;
|
|
1240
|
+
for (const path of allCandidates) {
|
|
1241
|
+
if (isPathTraversal(path)) continue;
|
|
1242
|
+
const file = zip.file(path);
|
|
1243
|
+
if (!file) continue;
|
|
1244
|
+
try {
|
|
1245
|
+
const data = await file.async("uint8array");
|
|
1246
|
+
decompressed.total += data.length;
|
|
1247
|
+
if (decompressed.total > MAX_DECOMPRESS_SIZE) throw new KordocError("ZIP \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (ZIP bomb \uC758\uC2EC)");
|
|
1248
|
+
const ext = path.includes(".") ? path.split(".").pop() || "png" : "png";
|
|
1249
|
+
const mimeType = imageExtToMime(ext);
|
|
1250
|
+
imageIndex++;
|
|
1251
|
+
const filename = `image_${String(imageIndex).padStart(3, "0")}.${mimeToExt(mimeType)}`;
|
|
1252
|
+
img = { filename, data, mimeType };
|
|
1253
|
+
images.push(img);
|
|
1254
|
+
break;
|
|
1255
|
+
} catch (err) {
|
|
1256
|
+
if (err instanceof KordocError) throw err;
|
|
1257
|
+
}
|
|
1258
1258
|
}
|
|
1259
|
+
if (!img) warnings?.push({ page: block.pageNumber, message: `\uC774\uBBF8\uC9C0 \uD30C\uC77C \uC5C6\uC74C: ${ref}`, code: "SKIPPED_IMAGE" });
|
|
1260
|
+
resolved.set(ref, img);
|
|
1259
1261
|
}
|
|
1260
|
-
if (!
|
|
1261
|
-
warnings?.push({ page: block.pageNumber, message: `\uC774\uBBF8\uC9C0 \uD30C\uC77C \uC5C6\uC74C: ${ref}`, code: "SKIPPED_IMAGE" });
|
|
1262
|
+
if (!img) {
|
|
1262
1263
|
block.type = "paragraph";
|
|
1263
1264
|
block.text = `[\uC774\uBBF8\uC9C0: ${ref}]`;
|
|
1264
1265
|
if (ownerCell) ownerCell.text = ownerCell.text.replace(``, `[\uC774\uBBF8\uC9C0: ${ref}]`);
|
|
1266
|
+
continue;
|
|
1265
1267
|
}
|
|
1268
|
+
block.text = img.filename;
|
|
1269
|
+
block.imageData = { data: img.data, mimeType: img.mimeType, filename: ref };
|
|
1270
|
+
if (ownerCell) ownerCell.text = ownerCell.text.replace(``, ``);
|
|
1266
1271
|
}
|
|
1267
1272
|
return images;
|
|
1268
1273
|
}
|
|
@@ -2628,32 +2633,42 @@ function resolveImageBlocks(binDataMap, blocks, warnings) {
|
|
|
2628
2633
|
if (imageBlocks.length === 0) return [];
|
|
2629
2634
|
const images = [];
|
|
2630
2635
|
const renamed = /* @__PURE__ */ new Map();
|
|
2636
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
2631
2637
|
let imageIndex = 0;
|
|
2632
2638
|
for (const block of imageBlocks) {
|
|
2633
2639
|
if (!block.text) continue;
|
|
2634
2640
|
const storageId = parseInt(block.text, 10);
|
|
2635
2641
|
if (isNaN(storageId)) continue;
|
|
2636
|
-
|
|
2637
|
-
if (
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
+
let img = resolved.get(storageId);
|
|
2643
|
+
if (img === void 0) {
|
|
2644
|
+
const bin = binDataMap.get(storageId);
|
|
2645
|
+
if (!bin) {
|
|
2646
|
+
warnings.push({ page: block.pageNumber, message: `BinData ${storageId} \uC5C6\uC74C`, code: "SKIPPED_IMAGE" });
|
|
2647
|
+
resolved.set(storageId, null);
|
|
2648
|
+
} else {
|
|
2649
|
+
const mime = detectImageMime(bin.data);
|
|
2650
|
+
if (!mime) {
|
|
2651
|
+
warnings.push({ page: block.pageNumber, message: `BinData ${storageId}: \uC54C \uC218 \uC5C6\uB294 \uC774\uBBF8\uC9C0 \uD615\uC2DD`, code: "SKIPPED_IMAGE" });
|
|
2652
|
+
resolved.set(storageId, null);
|
|
2653
|
+
} else {
|
|
2654
|
+
imageIndex++;
|
|
2655
|
+
const ext = mime.includes("jpeg") ? "jpg" : mime.includes("png") ? "png" : mime.includes("gif") ? "gif" : mime.includes("bmp") ? "bmp" : "bin";
|
|
2656
|
+
img = { filename: `image_${String(imageIndex).padStart(3, "0")}.${ext}`, data: new Uint8Array(bin.data), mime };
|
|
2657
|
+
resolved.set(storageId, img);
|
|
2658
|
+
images.push({ filename: img.filename, data: img.data, mimeType: img.mime });
|
|
2659
|
+
renamed.set(storageId, img.filename);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
img = resolved.get(storageId);
|
|
2642
2663
|
}
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
warnings.push({ page: block.pageNumber, message: `BinData ${storageId}: \uC54C \uC218 \uC5C6\uB294 \uC774\uBBF8\uC9C0 \uD615\uC2DD`, code: "SKIPPED_IMAGE" });
|
|
2664
|
+
if (!img) {
|
|
2665
|
+
const bin = binDataMap.get(storageId);
|
|
2646
2666
|
block.type = "paragraph";
|
|
2647
|
-
block.text = `[\uC774\uBBF8\uC9C0: ${bin.name}]`;
|
|
2667
|
+
block.text = bin ? `[\uC774\uBBF8\uC9C0: ${bin.name}]` : `[\uC774\uBBF8\uC9C0: BinData ${storageId}]`;
|
|
2648
2668
|
continue;
|
|
2649
2669
|
}
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
const filename = `image_${String(imageIndex).padStart(3, "0")}.${ext}`;
|
|
2653
|
-
images.push({ filename, data: new Uint8Array(bin.data), mimeType: mime });
|
|
2654
|
-
renamed.set(storageId, filename);
|
|
2655
|
-
block.text = filename;
|
|
2656
|
-
block.imageData = { data: new Uint8Array(bin.data), mimeType: mime, filename: bin.name };
|
|
2670
|
+
block.text = img.filename;
|
|
2671
|
+
block.imageData = { data: img.data, mimeType: img.mime, filename: binDataMap.get(storageId).name };
|
|
2657
2672
|
}
|
|
2658
2673
|
resolveCellImageSentinels(blocks, renamed);
|
|
2659
2674
|
return images;
|
|
@@ -18341,7 +18356,7 @@ function parseTable(tbl, styles, numbering, footnotes, rels) {
|
|
|
18341
18356
|
};
|
|
18342
18357
|
return { type: "table", table };
|
|
18343
18358
|
}
|
|
18344
|
-
async function extractImages(zip, rels, doc) {
|
|
18359
|
+
async function extractImages(zip, rels, doc, warnings) {
|
|
18345
18360
|
const blocks = [];
|
|
18346
18361
|
const images = [];
|
|
18347
18362
|
const drawingElements = findElements(doc.documentElement, "drawing");
|
|
@@ -18372,7 +18387,11 @@ async function extractImages(zip, rels, doc) {
|
|
|
18372
18387
|
const filename = `image_${String(imgIdx).padStart(3, "0")}.${ext}`;
|
|
18373
18388
|
images.push({ filename, data, mimeType: mimeMap[ext] ?? "image/png" });
|
|
18374
18389
|
blocks.push({ type: "image", text: filename });
|
|
18375
|
-
} catch {
|
|
18390
|
+
} catch (err) {
|
|
18391
|
+
warnings.push({
|
|
18392
|
+
code: "SKIPPED_IMAGE",
|
|
18393
|
+
message: `DOCX \uC774\uBBF8\uC9C0 \uCD94\uCD9C \uC2E4\uD328 (${imgPath}): ${err instanceof Error ? err.message : String(err)}`
|
|
18394
|
+
});
|
|
18376
18395
|
}
|
|
18377
18396
|
}
|
|
18378
18397
|
}
|
|
@@ -18396,7 +18415,11 @@ async function parseDocxDocument(buffer, options) {
|
|
|
18396
18415
|
if (stylesFile) {
|
|
18397
18416
|
try {
|
|
18398
18417
|
styles = parseStyles(await stylesFile.async("text"));
|
|
18399
|
-
} catch {
|
|
18418
|
+
} catch (err) {
|
|
18419
|
+
warnings.push({
|
|
18420
|
+
code: "PARTIAL_PARSE",
|
|
18421
|
+
message: `DOCX \uC2A4\uD0C0\uC77C(styles.xml) \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uAE30\uBCF8 \uC2A4\uD0C0\uC77C\uB85C \uACC4\uC18D: ${err instanceof Error ? err.message : String(err)}`
|
|
18422
|
+
});
|
|
18400
18423
|
}
|
|
18401
18424
|
}
|
|
18402
18425
|
let numbering = /* @__PURE__ */ new Map();
|
|
@@ -18404,7 +18427,11 @@ async function parseDocxDocument(buffer, options) {
|
|
|
18404
18427
|
if (numFile) {
|
|
18405
18428
|
try {
|
|
18406
18429
|
numbering = parseNumbering(await numFile.async("text"));
|
|
18407
|
-
} catch {
|
|
18430
|
+
} catch (err) {
|
|
18431
|
+
warnings.push({
|
|
18432
|
+
code: "PARTIAL_PARSE",
|
|
18433
|
+
message: `DOCX \uBC88\uD638\uB9E4\uAE30\uAE30(numbering.xml) \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uBAA9\uB85D \uBC88\uD638 \uC0DD\uB7B5: ${err instanceof Error ? err.message : String(err)}`
|
|
18434
|
+
});
|
|
18408
18435
|
}
|
|
18409
18436
|
}
|
|
18410
18437
|
let footnotes = /* @__PURE__ */ new Map();
|
|
@@ -18412,7 +18439,11 @@ async function parseDocxDocument(buffer, options) {
|
|
|
18412
18439
|
if (fnFile) {
|
|
18413
18440
|
try {
|
|
18414
18441
|
footnotes = parseFootnotes(await fnFile.async("text"));
|
|
18415
|
-
} catch {
|
|
18442
|
+
} catch (err) {
|
|
18443
|
+
warnings.push({
|
|
18444
|
+
code: "PARTIAL_PARSE",
|
|
18445
|
+
message: `DOCX \uAC01\uC8FC(footnotes.xml) \uD30C\uC2F1 \uC2E4\uD328 \u2014 \uAC01\uC8FC \uC0DD\uB7B5: ${err instanceof Error ? err.message : String(err)}`
|
|
18446
|
+
});
|
|
18416
18447
|
}
|
|
18417
18448
|
}
|
|
18418
18449
|
const docXml = await docFile.async("text");
|
|
@@ -18434,7 +18465,7 @@ async function parseDocxDocument(buffer, options) {
|
|
|
18434
18465
|
if (block) blocks.push(block);
|
|
18435
18466
|
}
|
|
18436
18467
|
}
|
|
18437
|
-
const { blocks: imgBlocks, images } = await extractImages(zip, rels, doc);
|
|
18468
|
+
const { blocks: imgBlocks, images } = await extractImages(zip, rels, doc, warnings);
|
|
18438
18469
|
const metadata = {};
|
|
18439
18470
|
const coreFile = zip.file("docProps/core.xml");
|
|
18440
18471
|
if (coreFile) {
|
|
@@ -18452,7 +18483,11 @@ async function parseDocxDocument(buffer, options) {
|
|
|
18452
18483
|
if (created) metadata.createdAt = created;
|
|
18453
18484
|
const modified = getFirst("dcterms:modified");
|
|
18454
18485
|
if (modified) metadata.modifiedAt = modified;
|
|
18455
|
-
} catch {
|
|
18486
|
+
} catch (err) {
|
|
18487
|
+
warnings.push({
|
|
18488
|
+
code: "PARTIAL_PARSE",
|
|
18489
|
+
message: `DOCX \uBA54\uD0C0\uB370\uC774\uD130(core.xml) \uD30C\uC2F1 \uC2E4\uD328: ${err instanceof Error ? err.message : String(err)}`
|
|
18490
|
+
});
|
|
18456
18491
|
}
|
|
18457
18492
|
}
|
|
18458
18493
|
const outline = blocks.filter((b) => b.type === "heading").map((b) => ({ level: b.level ?? 2, text: b.text ?? "" }));
|
|
@@ -21577,9 +21612,22 @@ function precomputeGongmunList(blocks, gongmun) {
|
|
|
21577
21612
|
continue;
|
|
21578
21613
|
}
|
|
21579
21614
|
const run = [];
|
|
21580
|
-
while (i < blocks.length
|
|
21581
|
-
|
|
21582
|
-
|
|
21615
|
+
while (i < blocks.length) {
|
|
21616
|
+
const t = blocks[i].type;
|
|
21617
|
+
if (t === "list_item") {
|
|
21618
|
+
run.push(i);
|
|
21619
|
+
i++;
|
|
21620
|
+
continue;
|
|
21621
|
+
}
|
|
21622
|
+
if (t === "table" || t === "html_table") {
|
|
21623
|
+
let j = i + 1;
|
|
21624
|
+
while (j < blocks.length && (blocks[j].type === "table" || blocks[j].type === "html_table")) j++;
|
|
21625
|
+
if (j < blocks.length && blocks[j].type === "list_item") {
|
|
21626
|
+
i = j;
|
|
21627
|
+
continue;
|
|
21628
|
+
}
|
|
21629
|
+
}
|
|
21630
|
+
break;
|
|
21583
21631
|
}
|
|
21584
21632
|
const depths = run.map((bi) => Math.min(Math.max(blocks[bi].indent || 0, 0), GONGMUN_LIST_LEVELS - 1));
|
|
21585
21633
|
const suppress = gongmun.numbering === "standard" ? computeSuppression(depths) : depths.map(() => false);
|
|
@@ -23148,21 +23196,24 @@ function readRecordsStrict(stream) {
|
|
|
23148
23196
|
}
|
|
23149
23197
|
return recs;
|
|
23150
23198
|
}
|
|
23151
|
-
function serializeRecords(recs, repl) {
|
|
23199
|
+
function serializeRecords(recs, repl, inserts) {
|
|
23152
23200
|
const parts = [];
|
|
23153
|
-
|
|
23154
|
-
const data = repl?.get(i) ?? recs[i].data;
|
|
23201
|
+
const push = (tagId, level, data) => {
|
|
23155
23202
|
const ext = data.length >= 4095;
|
|
23156
23203
|
const header = Buffer.alloc(ext ? 8 : 4);
|
|
23157
|
-
header.writeUInt32LE((
|
|
23204
|
+
header.writeUInt32LE((tagId & 1023 | (level & 1023) << 10 | (ext ? 4095 : data.length) << 20) >>> 0, 0);
|
|
23158
23205
|
if (ext) header.writeUInt32LE(data.length, 4);
|
|
23159
23206
|
parts.push(header, data);
|
|
23207
|
+
};
|
|
23208
|
+
for (let i = 0; i < recs.length; i++) {
|
|
23209
|
+
for (const ins of inserts?.get(i) ?? []) push(ins.tagId, ins.level, ins.data);
|
|
23210
|
+
push(recs[i].tagId, recs[i].level, repl?.get(i) ?? recs[i].data);
|
|
23160
23211
|
}
|
|
23161
23212
|
return Buffer.concat(parts);
|
|
23162
23213
|
}
|
|
23163
23214
|
function scanSection(stream, sectionIndex, compressed) {
|
|
23164
23215
|
const records = readRecordsStrict(stream);
|
|
23165
|
-
if (!records) return { records: [], safe: false, paras: [], tables: [], compressed, repl: /* @__PURE__ */ new Map() };
|
|
23216
|
+
if (!records) return { records: [], safe: false, paras: [], tables: [], compressed, repl: /* @__PURE__ */ new Map(), inserts: /* @__PURE__ */ new Map() };
|
|
23166
23217
|
const safe = serializeRecords(records).equals(stream);
|
|
23167
23218
|
const parent = new Int32Array(records.length).fill(-1);
|
|
23168
23219
|
const stack = [];
|
|
@@ -23261,7 +23312,7 @@ function scanSection(stream, sectionIndex, compressed) {
|
|
|
23261
23312
|
}
|
|
23262
23313
|
tables.push({ sectionIndex, rows, cols, cells });
|
|
23263
23314
|
}
|
|
23264
|
-
return { records, safe, paras, tables, compressed, repl: /* @__PURE__ */ new Map() };
|
|
23315
|
+
return { records, safe, paras, tables, compressed, repl: /* @__PURE__ */ new Map(), inserts: /* @__PURE__ */ new Map() };
|
|
23265
23316
|
}
|
|
23266
23317
|
async function patchHwp(original, editedMarkdown, options) {
|
|
23267
23318
|
const skipped = [];
|
|
@@ -23329,15 +23380,15 @@ async function patchHwp(original, editedMarkdown, options) {
|
|
|
23329
23380
|
}
|
|
23330
23381
|
}
|
|
23331
23382
|
let data;
|
|
23332
|
-
const dirty = scans.some((s) => s.repl.size > 0);
|
|
23383
|
+
const dirty = scans.some((s) => s.repl.size > 0 || s.inserts.size > 0);
|
|
23333
23384
|
if (!dirty) {
|
|
23334
23385
|
data = new Uint8Array(original);
|
|
23335
23386
|
} else {
|
|
23336
23387
|
try {
|
|
23337
23388
|
let out = originalBuf;
|
|
23338
23389
|
for (let i = 0; i < scans.length; i++) {
|
|
23339
|
-
if (scans[i].repl.size === 0) continue;
|
|
23340
|
-
const newStream = serializeRecords(scans[i].records, scans[i].repl);
|
|
23390
|
+
if (scans[i].repl.size === 0 && scans[i].inserts.size === 0) continue;
|
|
23391
|
+
const newStream = serializeRecords(scans[i].records, scans[i].repl, scans[i].inserts);
|
|
23341
23392
|
const content = compressed ? deflateRawSync2(newStream) : newStream;
|
|
23342
23393
|
out = replaceOleStream(out, sectionPaths[i], content);
|
|
23343
23394
|
}
|
|
@@ -23665,24 +23716,25 @@ function applyCellEdit5(table, scanTable, gridR, gridC, newLines, ctx, before, a
|
|
|
23665
23716
|
}
|
|
23666
23717
|
const unstable = newLines.find((l) => sanitizeText(l) !== l);
|
|
23667
23718
|
if (unstable !== void 0) return skip("\uACF5\uBC31 \uC815\uADDC\uD654 \uBD88\uC548\uC815 \uD14D\uC2A4\uD2B8 \u2014 \uD328\uCE58 \uC2DC \uC6D0\uBB38 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0");
|
|
23668
|
-
|
|
23719
|
+
const targets = nonEmpty.length > 0 ? nonEmpty : cell.paras;
|
|
23720
|
+
if (targets.length === 0) return skip("\uC140\uC5D0 \uBB38\uB2E8\uC774 \uC5C6\uC74C \u2014 \uBBF8\uC9C0\uC6D0");
|
|
23669
23721
|
const assigned = [];
|
|
23670
|
-
for (let i = 0; i <
|
|
23722
|
+
for (let i = 0; i < targets.length; i++) {
|
|
23671
23723
|
if (i < newLines.length) {
|
|
23672
|
-
assigned.push(i ===
|
|
23724
|
+
assigned.push(i === targets.length - 1 && newLines.length > targets.length ? newLines.slice(i).join(" ") : newLines[i]);
|
|
23673
23725
|
} else {
|
|
23674
23726
|
assigned.push("");
|
|
23675
23727
|
}
|
|
23676
23728
|
}
|
|
23677
|
-
if (newLines.length >
|
|
23729
|
+
if (newLines.length > targets.length) {
|
|
23678
23730
|
ctx.skipped.push({ reason: "\uC140 \uB0B4 \uC904 \uCD94\uAC00\uB294 \uBB38\uB2E8 \uC0DD\uC131 \uBBF8\uC9C0\uC6D0 \u2014 \uB9C8\uC9C0\uB9C9 \uBB38\uB2E8\uC5D0 \uBCD1\uD569 \uC801\uC6A9", after: summarize(after), partial: true });
|
|
23679
23731
|
} else if (newLines.length < nonEmpty.length && nonEmpty.length > 1) {
|
|
23680
23732
|
ctx.skipped.push({ reason: "\uC140 \uB0B4 \uC904 \uC0AD\uC81C\uB294 \uBB38\uB2E8 \uC81C\uAC70 \uBBF8\uC9C0\uC6D0 \u2014 \uBE48 \uBB38\uB2E8 \uC794\uC874(\uBDF0\uC5B4\uC5D0 \uBE48 \uC904 \uD45C\uC2DC \uAC00\uB2A5)", before: summarize(before), after: summarize(after), partial: true });
|
|
23681
23733
|
}
|
|
23682
23734
|
let staged = 0;
|
|
23683
|
-
for (let i = 0; i <
|
|
23684
|
-
if (assigned[i] ===
|
|
23685
|
-
staged += stageParaPatch(ctx.scans[
|
|
23735
|
+
for (let i = 0; i < targets.length; i++) {
|
|
23736
|
+
if (assigned[i] === targets[i].rawText || normForMatch(assigned[i]) === normForMatch(targets[i].rawText)) continue;
|
|
23737
|
+
staged += stageParaPatch(ctx.scans[targets[i].sectionIndex], targets[i], assigned[i], skip);
|
|
23686
23738
|
}
|
|
23687
23739
|
return staged > 0 ? 1 : 0;
|
|
23688
23740
|
}
|
|
@@ -23752,7 +23804,21 @@ function splitParaText(data) {
|
|
|
23752
23804
|
if (firstP < 0) firstP = k;
|
|
23753
23805
|
lastP = k;
|
|
23754
23806
|
}
|
|
23755
|
-
if (firstP < 0)
|
|
23807
|
+
if (firstP < 0) {
|
|
23808
|
+
if (toks.some((t) => t.visible)) return null;
|
|
23809
|
+
let cut = data.length;
|
|
23810
|
+
for (const t of toks) if (data.readUInt16LE(t.start) === 13) {
|
|
23811
|
+
cut = t.start;
|
|
23812
|
+
break;
|
|
23813
|
+
}
|
|
23814
|
+
return {
|
|
23815
|
+
prefix: data.subarray(0, cut),
|
|
23816
|
+
prefixUnits: cut / 2,
|
|
23817
|
+
core: "",
|
|
23818
|
+
suffix: data.subarray(cut),
|
|
23819
|
+
suffixUnits: (data.length - cut) / 2
|
|
23820
|
+
};
|
|
23821
|
+
}
|
|
23756
23822
|
for (let k = firstP; k <= lastP; k++) if (!toks[k].plain) return null;
|
|
23757
23823
|
for (let k = 0; k < firstP; k++) if (toks[k].visible) return null;
|
|
23758
23824
|
for (let k = lastP + 1; k < toks.length; k++) if (toks[k].visible) return null;
|
|
@@ -23785,7 +23851,6 @@ function rebuildCharShape(csData, coreStartUnit) {
|
|
|
23785
23851
|
}
|
|
23786
23852
|
function stageParaPatch(scan, para, newPlain, skip) {
|
|
23787
23853
|
if (!scan.safe) return skip("\uC139\uC158 \uB808\uCF54\uB4DC \uC7AC\uC9C1\uB82C\uD654 \uBD88\uC77C\uCE58 \u2014 \uC548\uC804\uC744 \uC704\uD574 \uC774 \uC139\uC158\uC740 \uBBF8\uC9C0\uC6D0");
|
|
23788
|
-
if (para.textIdx === -1) return skip("\uBE48 \uBB38\uB2E8 \uD14D\uC2A4\uD2B8 \uCD94\uAC00\uB294 \uBBF8\uC9C0\uC6D0 (v1)");
|
|
23789
23854
|
if (para.textIdx === -2) return skip("\uBCF5\uC218 PARA_TEXT \uB808\uCF54\uB4DC \uBB38\uB2E8 \u2014 \uBBF8\uC9C0\uC6D0 (v1)");
|
|
23790
23855
|
if (para.rangeTagCount > 0) return skip("\uBC94\uC704 \uD0DC\uADF8(\uD615\uAD11\uD39C/\uAD50\uC815\uBD80\uD638) \uBB38\uB2E8 \u2014 \uBBF8\uC9C0\uC6D0 (v1)");
|
|
23791
23856
|
if (para.charShapeIdx < 0 || para.lineSegIdx < 0) return skip("\uBB38\uB2E8 \uB808\uCF54\uB4DC \uAD6C\uC131 \uBE44\uC815\uD615 \u2014 \uBBF8\uC9C0\uC6D0");
|
|
@@ -23793,11 +23858,27 @@ function stageParaPatch(scan, para, newPlain, skip) {
|
|
|
23793
23858
|
if (/[\u0000-\u001f]/.test(newPlain)) return skip("\uC0C8 \uD14D\uC2A4\uD2B8\uC5D0 \uC81C\uC5B4\uBB38\uC790 \uD3EC\uD568 \u2014 \uBBF8\uC9C0\uC6D0");
|
|
23794
23859
|
const records = scan.records;
|
|
23795
23860
|
const headerRec = records[para.headerIdx];
|
|
23796
|
-
const textRec = records[para.textIdx];
|
|
23797
23861
|
const charShapeRec = records[para.charShapeIdx];
|
|
23798
23862
|
if (charShapeRec.data.length < 8) {
|
|
23799
23863
|
return skip("CHAR_SHAPE \uB808\uCF54\uB4DC \uBE44\uC815\uD615 \u2014 \uBBF8\uC9C0\uC6D0");
|
|
23800
23864
|
}
|
|
23865
|
+
if (para.textIdx === -1) {
|
|
23866
|
+
const nCharsLow = para.nCharsRaw & 2147483647;
|
|
23867
|
+
if (nCharsLow > 1) return skip("PARA_TEXT \uC5C6\uB294 \uBB38\uB2E8\uC758 nChars \uBE44\uC815\uD615 \u2014 \uBBF8\uC9C0\uC6D0");
|
|
23868
|
+
const paraEnd = nCharsLow === 1 ? Buffer.from([13, 0]) : Buffer.alloc(0);
|
|
23869
|
+
const at = para.headerIdx + 1;
|
|
23870
|
+
const list = scan.inserts.get(at) ?? [];
|
|
23871
|
+
list.push({ tagId: TAG_PARA_TEXT, level: headerRec.level + 1, data: Buffer.concat([Buffer.from(newPlain, "utf16le"), paraEnd]) });
|
|
23872
|
+
scan.inserts.set(at, list);
|
|
23873
|
+
const newHeader2 = Buffer.from(headerRec.data);
|
|
23874
|
+
newHeader2.writeUInt32LE((para.nCharsRaw & 2147483648 | newPlain.length + nCharsLow) >>> 0, 0);
|
|
23875
|
+
const cs2 = rebuildCharShape(charShapeRec.data, 0);
|
|
23876
|
+
scan.repl.set(para.charShapeIdx, cs2.buf);
|
|
23877
|
+
newHeader2.writeUInt16LE(cs2.count, 12);
|
|
23878
|
+
scan.repl.set(para.headerIdx, newHeader2);
|
|
23879
|
+
return 1;
|
|
23880
|
+
}
|
|
23881
|
+
const textRec = records[para.textIdx];
|
|
23801
23882
|
const seg = splitParaText(textRec.data);
|
|
23802
23883
|
if (!seg) {
|
|
23803
23884
|
return skip(para.ctrlMask !== 0 ? "\uCEE8\uD2B8\uB864 \uBB38\uC790(\uD0ED/\uD544\uB4DC/\uD2B9\uC218\uACF5\uBC31 \uB4F1 \uD14D\uC2A4\uD2B8 \uC911\uAC04) \uD3EC\uD568 \uBB38\uB2E8 \u2014 \uBBF8\uC9C0\uC6D0 (v1)" : "PARA_TEXT \uC7AC\uAD6C\uC131 \uBD88\uC77C\uCE58 \u2014 \uC6D0\uBB38 \uBCF4\uC874 \uBD88\uAC00\uB85C \uBBF8\uC9C0\uC6D0");
|
|
@@ -24403,7 +24484,7 @@ async function parseHwp(buffer, options) {
|
|
|
24403
24484
|
async function parsePdf(buffer, options) {
|
|
24404
24485
|
let parsePdfDocument;
|
|
24405
24486
|
try {
|
|
24406
|
-
const mod = await import("./parser-
|
|
24487
|
+
const mod = await import("./parser-DCK42RMA.js");
|
|
24407
24488
|
parsePdfDocument = mod.parsePdfDocument;
|
|
24408
24489
|
} catch {
|
|
24409
24490
|
return {
|