kordoc 4.18.2 → 4.18.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/{-I3CP33G4.js → -DDAVBMHD.js} +11 -11
- package/dist/{chunk-O2DI4GHD.js → chunk-274ZPMHK.js} +2 -2
- package/dist/{chunk-QGFZU3JE.cjs → chunk-3WLZOJIE.cjs} +10 -8
- package/dist/chunk-3WLZOJIE.cjs.map +1 -0
- package/dist/{chunk-UZGZRGYM.cjs → chunk-3XSP7V5P.cjs} +10 -5
- package/dist/chunk-3XSP7V5P.cjs.map +1 -0
- package/dist/{chunk-GM7XIZF2.js → chunk-4IBY5LTJ.js} +2 -2
- package/dist/chunk-6H25SXDI.js +11 -0
- package/dist/chunk-6H25SXDI.js.map +1 -0
- package/dist/{chunk-N5DQFA7L.js → chunk-7GR2GCJF.js} +10 -5
- package/dist/chunk-7GR2GCJF.js.map +1 -0
- package/dist/{chunk-YNLW6EGU.cjs → chunk-AVIZ55NQ.cjs} +3 -3
- package/dist/chunk-AVIZ55NQ.cjs.map +1 -0
- package/dist/chunk-DC6CTQTK.js +9 -0
- package/dist/chunk-DC6CTQTK.js.map +1 -0
- package/dist/{chunk-L5RLJPI3.js → chunk-DUV7Y6IQ.js} +3 -3
- package/dist/{chunk-KDMAYOWH.cjs → chunk-E2644XCO.cjs} +698 -189
- package/dist/chunk-E2644XCO.cjs.map +1 -0
- package/dist/{chunk-LSOD2A6N.js → chunk-ELOPDQES.js} +2 -2
- package/dist/{chunk-M4P7YS2N.js → chunk-F2GDLA45.js} +81 -61
- package/dist/chunk-F2GDLA45.js.map +1 -0
- package/dist/{chunk-OBILAVWC.js → chunk-F5YVCJVF.js} +10 -5
- package/dist/chunk-F5YVCJVF.js.map +1 -0
- package/dist/chunk-GS7T56RP.cjs.map +1 -1
- package/dist/{chunk-4B2EXELH.js → chunk-HRJJDNRD.js} +2 -2
- package/dist/{chunk-CKUIFTXJ.js → chunk-IAXGGQGD.js} +2 -2
- package/dist/{chunk-BL7KRE6X.js → chunk-IBQCK4F3.js} +7 -3
- package/dist/chunk-IBQCK4F3.js.map +1 -0
- package/dist/chunk-J55UQC5H.cjs.map +1 -1
- package/dist/{chunk-OGAYGUJF.js → chunk-KUUSP6OS.js} +581 -72
- package/dist/chunk-KUUSP6OS.js.map +1 -0
- package/dist/{chunk-LACO375L.js → chunk-LGF2IO66.js} +4 -3
- package/dist/chunk-LGF2IO66.js.map +1 -0
- package/dist/{chunk-L64QRUMK.js → chunk-MXA6YW2W.js} +582 -73
- package/dist/chunk-MXA6YW2W.js.map +1 -0
- package/dist/{chunk-OI5ZSSIC.cjs → chunk-OIUSF2VA.cjs} +16 -12
- package/dist/chunk-OIUSF2VA.cjs.map +1 -0
- package/dist/{chunk-6OKBTY72.js → chunk-QVCHFCT2.js} +2 -2
- package/dist/{chunk-C2CVOC5K.js → chunk-RCI7LY4N.js} +8 -4
- package/dist/chunk-RCI7LY4N.js.map +1 -0
- package/dist/{chunk-W2YYBPW5.cjs → chunk-SVNBZEL6.cjs} +3 -3
- package/dist/chunk-SVNBZEL6.cjs.map +1 -0
- package/dist/{chunk-VSY5PAJ5.js → chunk-T2BJPT6D.js} +3 -3
- package/dist/{chunk-VSY5PAJ5.js.map → chunk-T2BJPT6D.js.map} +1 -1
- package/dist/chunk-TK3FDAEE.cjs +9 -0
- package/dist/chunk-TK3FDAEE.cjs.map +1 -0
- package/dist/{chunk-F5HING4Y.js → chunk-TMJVD6FW.js} +5 -4
- package/dist/chunk-TMJVD6FW.js.map +1 -0
- package/dist/{chunk-T4MXCSBP.js → chunk-V5X4LLVM.js} +71 -47
- package/dist/chunk-V5X4LLVM.js.map +1 -0
- package/dist/{chunk-IA3UKDHA.js → chunk-VTVK2JMI.js} +3 -2
- package/dist/{chunk-IA3UKDHA.js.map → chunk-VTVK2JMI.js.map} +1 -1
- package/dist/{chunk-B2E6C2LH.js → chunk-XG4SYOZL.js} +6 -4
- package/dist/chunk-XG4SYOZL.js.map +1 -0
- package/dist/{chunk-QP7IXF7R.js → chunk-YCY2R4FM.js} +2 -2
- package/dist/{chunk-NZM2SSI4.js → chunk-Z2PPDQK2.js} +2 -2
- package/dist/chunks-5QTTAT5T.js +10 -0
- package/dist/cli.js +179 -119
- package/dist/cli.js.map +1 -1
- package/dist/{formula-E3N7KDDG.js → formula-7ZOZ5QJ6.js} +8 -4
- package/dist/{formula-E3N7KDDG.js.map → formula-7ZOZ5QJ6.js.map} +1 -1
- package/dist/{formula-AQZODKZF.js → formula-HQFZEXFF.js} +7 -3
- package/dist/{formula-AQZODKZF.js.map → formula-HQFZEXFF.js.map} +1 -1
- package/dist/{formula-VY4ITOMN.cjs → formula-YYJQBKEN.cjs} +13 -9
- package/dist/formula-YYJQBKEN.cjs.map +1 -0
- package/dist/{image-ocr-IMYXOHHV.js → image-ocr-4BGX2EJJ.js} +7 -6
- package/dist/{image-ocr-IMYXOHHV.js.map → image-ocr-4BGX2EJJ.js.map} +1 -1
- package/dist/{image-ocr-6LYEBMVR.cjs → image-ocr-CC26Q5KG.cjs} +16 -15
- package/dist/image-ocr-CC26Q5KG.cjs.map +1 -0
- package/dist/{image-ocr-LN3GSQPW.js → image-ocr-RK3HJVCI.js} +10 -9
- package/dist/{image-ocr-LN3GSQPW.js.map → image-ocr-RK3HJVCI.js.map} +1 -1
- package/dist/index.cjs +860 -817
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +141 -98
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +26 -26
- package/dist/mcp.js.map +1 -1
- package/dist/{model-bundle-IHKNDLOT.js → model-bundle-VHRXG63R.js} +5 -5
- package/dist/{models-YXITRAMR.js → models-G3WA24SY.js} +5 -5
- package/dist/page-range-QHHFTL7X.cjs.map +1 -1
- package/dist/{parser-7KECZTTP.cjs → parser-BGORCLIU.cjs} +461 -243
- package/dist/parser-BGORCLIU.cjs.map +1 -0
- package/dist/{parser-M3T2EWUN.js → parser-GFDGAVLV.js} +255 -37
- package/dist/parser-GFDGAVLV.js.map +1 -0
- package/dist/{parser-KB4BYQBZ.js → parser-SOWTUOMK.js} +258 -40
- package/dist/parser-SOWTUOMK.js.map +1 -0
- package/dist/pdf-ocr-7IOOVR2I.js +20 -0
- package/dist/pdf-ocr-EJ2HNZN6.cjs +17 -0
- package/dist/pdf-ocr-EJ2HNZN6.cjs.map +1 -0
- package/dist/pdf-ocr-RACAZU3N.js +16 -0
- package/dist/{profile-io-GQWQR7YQ.js → profile-io-Q2T47RVH.js} +3 -3
- package/dist/{rasterize-Y6TVFQ3M.js → rasterize-OAVMUTE6.js} +3 -3
- package/dist/{redact-doc-TRPZ3HNW.js → redact-doc-ECFOVR4X.js} +11 -11
- package/dist/{render-GHT5HKBO.js → render-NSKWZVTD.js} +7 -7
- package/dist/seal-A4MG7MPQ.js +10 -0
- package/dist/{setup-AGSCEHDB.js → setup-REH2KZP2.js} +3 -3
- package/dist/visual-B56WQAGW.js +20 -0
- package/dist/{watch-ALSEW4GB.js → watch-JXDUZYBY.js} +13 -13
- package/dist/watch-JXDUZYBY.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-B2E6C2LH.js.map +0 -1
- package/dist/chunk-BL7KRE6X.js.map +0 -1
- package/dist/chunk-C2CVOC5K.js.map +0 -1
- package/dist/chunk-F5HING4Y.js.map +0 -1
- package/dist/chunk-KDMAYOWH.cjs.map +0 -1
- package/dist/chunk-L64QRUMK.js.map +0 -1
- package/dist/chunk-LACO375L.js.map +0 -1
- package/dist/chunk-M4P7YS2N.js.map +0 -1
- package/dist/chunk-N5DQFA7L.js.map +0 -1
- package/dist/chunk-OBILAVWC.js.map +0 -1
- package/dist/chunk-OGAYGUJF.js.map +0 -1
- package/dist/chunk-OI5ZSSIC.cjs.map +0 -1
- package/dist/chunk-QGFZU3JE.cjs.map +0 -1
- package/dist/chunk-T4MXCSBP.js.map +0 -1
- package/dist/chunk-UZGZRGYM.cjs.map +0 -1
- package/dist/chunk-W2YYBPW5.cjs.map +0 -1
- package/dist/chunk-YNLW6EGU.cjs.map +0 -1
- package/dist/chunks-IFFRC5IQ.js +0 -10
- package/dist/formula-VY4ITOMN.cjs.map +0 -1
- package/dist/image-ocr-6LYEBMVR.cjs.map +0 -1
- package/dist/parser-7KECZTTP.cjs.map +0 -1
- package/dist/parser-KB4BYQBZ.js.map +0 -1
- package/dist/parser-M3T2EWUN.js.map +0 -1
- package/dist/pdf-ocr-4S2OAHUX.js +0 -15
- package/dist/pdf-ocr-IGYCZ7G2.cjs +0 -16
- package/dist/pdf-ocr-IGYCZ7G2.cjs.map +0 -1
- package/dist/pdf-ocr-YEBFWU2K.js +0 -19
- package/dist/seal-3YTXSABW.js +0 -10
- package/dist/visual-R3E35Q2K.js +0 -20
- package/dist/watch-ALSEW4GB.js.map +0 -1
- /package/dist/{-I3CP33G4.js.map → -DDAVBMHD.js.map} +0 -0
- /package/dist/{chunk-O2DI4GHD.js.map → chunk-274ZPMHK.js.map} +0 -0
- /package/dist/{chunk-GM7XIZF2.js.map → chunk-4IBY5LTJ.js.map} +0 -0
- /package/dist/{chunk-L5RLJPI3.js.map → chunk-DUV7Y6IQ.js.map} +0 -0
- /package/dist/{chunk-LSOD2A6N.js.map → chunk-ELOPDQES.js.map} +0 -0
- /package/dist/{chunk-4B2EXELH.js.map → chunk-HRJJDNRD.js.map} +0 -0
- /package/dist/{chunk-CKUIFTXJ.js.map → chunk-IAXGGQGD.js.map} +0 -0
- /package/dist/{chunk-6OKBTY72.js.map → chunk-QVCHFCT2.js.map} +0 -0
- /package/dist/{chunk-QP7IXF7R.js.map → chunk-YCY2R4FM.js.map} +0 -0
- /package/dist/{chunk-NZM2SSI4.js.map → chunk-Z2PPDQK2.js.map} +0 -0
- /package/dist/{chunks-IFFRC5IQ.js.map → chunks-5QTTAT5T.js.map} +0 -0
- /package/dist/{model-bundle-IHKNDLOT.js.map → model-bundle-VHRXG63R.js.map} +0 -0
- /package/dist/{models-YXITRAMR.js.map → models-G3WA24SY.js.map} +0 -0
- /package/dist/{pdf-ocr-4S2OAHUX.js.map → pdf-ocr-7IOOVR2I.js.map} +0 -0
- /package/dist/{pdf-ocr-YEBFWU2K.js.map → pdf-ocr-RACAZU3N.js.map} +0 -0
- /package/dist/{profile-io-GQWQR7YQ.js.map → profile-io-Q2T47RVH.js.map} +0 -0
- /package/dist/{rasterize-Y6TVFQ3M.js.map → rasterize-OAVMUTE6.js.map} +0 -0
- /package/dist/{redact-doc-TRPZ3HNW.js.map → redact-doc-ECFOVR4X.js.map} +0 -0
- /package/dist/{render-GHT5HKBO.js.map → render-NSKWZVTD.js.map} +0 -0
- /package/dist/{seal-3YTXSABW.js.map → seal-A4MG7MPQ.js.map} +0 -0
- /package/dist/{setup-AGSCEHDB.js.map → setup-REH2KZP2.js.map} +0 -0
- /package/dist/{visual-R3E35Q2K.js.map → visual-B56WQAGW.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
blocksToPages,
|
|
3
3
|
inlineImagesIntoMarkdown
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-274ZPMHK.js";
|
|
5
5
|
import {
|
|
6
6
|
parsePageRange
|
|
7
7
|
} from "./chunk-V4BH5SRQ.js";
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
tidyScriptTags,
|
|
32
32
|
unframeLayoutTables,
|
|
33
33
|
wrapScript
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-XG4SYOZL.js";
|
|
35
35
|
import {
|
|
36
36
|
KordocError,
|
|
37
37
|
OPTIONAL_DEP_INSTALL_HINT,
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
escapeHtml,
|
|
42
42
|
isPathTraversal,
|
|
43
43
|
normalizeSectionHref,
|
|
44
|
+
partExtension,
|
|
44
45
|
precheckZipSize,
|
|
45
46
|
sanitizeError,
|
|
46
47
|
sanitizeHref,
|
|
@@ -48,7 +49,7 @@ import {
|
|
|
48
49
|
toArrayBuffer,
|
|
49
50
|
unescapeHtml,
|
|
50
51
|
unzipLimitBytes
|
|
51
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-7GR2GCJF.js";
|
|
52
53
|
|
|
53
54
|
// src/plain-markdown.ts
|
|
54
55
|
function toPlainMarkdown(md2) {
|
|
@@ -585,7 +586,8 @@ function createSectionShared() {
|
|
|
585
586
|
numState: /* @__PURE__ */ new Map(),
|
|
586
587
|
pageText: { headers: [], footers: [] },
|
|
587
588
|
track: { deleteDepth: 0, warned: false, deletedObjects: /* @__PURE__ */ new WeakSet(), deletedImageRefs: /* @__PURE__ */ new Set() },
|
|
588
|
-
pageState: { base: 0, allUsable: true }
|
|
589
|
+
pageState: { base: 0, allUsable: true },
|
|
590
|
+
tocTexts: /* @__PURE__ */ new Set()
|
|
589
591
|
};
|
|
590
592
|
}
|
|
591
593
|
function createXmlParser(warnings) {
|
|
@@ -937,7 +939,7 @@ function parseParaHeadings(doc, map) {
|
|
|
937
939
|
if (map.size > 0) break;
|
|
938
940
|
}
|
|
939
941
|
}
|
|
940
|
-
function detectHwpxHeadings(blocks, styleMap) {
|
|
942
|
+
function detectHwpxHeadings(blocks, styleMap, tocTexts) {
|
|
941
943
|
if (blocks.some((b) => b.type === "heading")) return;
|
|
942
944
|
let baseFontSize = 0;
|
|
943
945
|
const sizeFreq = /* @__PURE__ */ new Map();
|
|
@@ -954,7 +956,7 @@ function detectHwpxHeadings(blocks, styleMap) {
|
|
|
954
956
|
}
|
|
955
957
|
}
|
|
956
958
|
for (const block of blocks) {
|
|
957
|
-
if (block.type !== "paragraph" || !block.text || TOC_ENTRY_BLOCKS.has(block)) continue;
|
|
959
|
+
if (block.type !== "paragraph" || !block.text || TOC_ENTRY_BLOCKS.has(block) || tocTexts?.has(block.text.trim())) continue;
|
|
958
960
|
const text = block.text.trim();
|
|
959
961
|
if (text.length === 0 || text.length > 200 || /^\d+$/.test(text)) continue;
|
|
960
962
|
let level = 0;
|
|
@@ -2121,13 +2123,13 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
|
|
|
2121
2123
|
}
|
|
2122
2124
|
if (tableCtx) tableStack.push(tableCtx);
|
|
2123
2125
|
const newTable = { rows: [], currentRow: [], cell: null, sourceId: el.getAttribute("id") ?? void 0 };
|
|
2124
|
-
walkSection(el, blocks, newTable, tableStack, ctx, depth + 1);
|
|
2126
|
+
inIndependentDeletionStory(ctx.shared.track, () => walkSection(el, blocks, newTable, tableStack, ctx, depth + 1));
|
|
2125
2127
|
tableCtx = completeTable(newTable, tableStack, blocks, ctx);
|
|
2126
2128
|
break;
|
|
2127
2129
|
}
|
|
2128
2130
|
// 표/도표 캡션 — IRTable.caption으로 보존 (v3.0, 기존 무음 드롭 수정)
|
|
2129
2131
|
case "caption": {
|
|
2130
|
-
const cap = collectSubListContent(el, ctx);
|
|
2132
|
+
const cap = inIndependentDeletionStory(ctx.shared.track, () => collectSubListContent(el, ctx));
|
|
2131
2133
|
if (cap.text) {
|
|
2132
2134
|
if (tableCtx) {
|
|
2133
2135
|
tableCtx.caption = (tableCtx.caption ? tableCtx.caption + "\n" : "") + cap.text;
|
|
@@ -2187,6 +2189,9 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
|
|
|
2187
2189
|
if (text) {
|
|
2188
2190
|
if (ph?.prefix) text = ph.prefix + " " + text;
|
|
2189
2191
|
headingLevel = tocEntry ? void 0 : ph?.headingLevel;
|
|
2192
|
+
if (tocEntry) {
|
|
2193
|
+
for (const line of text.split("\n")) if (line.trim()) ctx.shared.tocTexts.add(line.trim());
|
|
2194
|
+
}
|
|
2190
2195
|
}
|
|
2191
2196
|
if (segments) {
|
|
2192
2197
|
const cell2 = tableCtx?.cell ?? null;
|
|
@@ -2272,6 +2277,15 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
|
|
|
2272
2277
|
if (spanMode !== "foreign" && el.getAttribute("paraPrIDRef") === KORDOC_PARA_QUOTE) block.quote = true;
|
|
2273
2278
|
}
|
|
2274
2279
|
if (!headingLevel && !block.spans && placeholderSpans) block.spans = withPrefixSpan(placeholderSpans, ph?.prefix);
|
|
2280
|
+
if (headingLevel && placeholderSpans) {
|
|
2281
|
+
const shown = withPrefixSpan(placeholderSpans.filter((s) => !s.placeholder), ph?.prefix).map((s) => s.text).join("").trim();
|
|
2282
|
+
if (shown) block.text = shown;
|
|
2283
|
+
else {
|
|
2284
|
+
block.type = "paragraph";
|
|
2285
|
+
delete block.level;
|
|
2286
|
+
block.spans = withPrefixSpan(placeholderSpans, ph?.prefix);
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2275
2289
|
blocks.push(block);
|
|
2276
2290
|
} else {
|
|
2277
2291
|
blocks.push({ type: "paragraph", text, pageNumber: ctx.page });
|
|
@@ -2513,10 +2527,10 @@ function walkParagraphChildren(node, blocks, tableCtx, tableStack, ctx, depth =
|
|
|
2513
2527
|
}
|
|
2514
2528
|
if (tableCtx) tableStack.push(tableCtx);
|
|
2515
2529
|
const newTable = { rows: [], currentRow: [], cell: null, inline: isInlineTbl(el), sourceId: el.getAttribute("id") ?? void 0 };
|
|
2516
|
-
walkSection(el, blocks, newTable, tableStack, ctx, d + 1);
|
|
2530
|
+
inIndependentDeletionStory(ctx.shared.track, () => walkSection(el, blocks, newTable, tableStack, ctx, d + 1));
|
|
2517
2531
|
tableCtx = completeTable(newTable, tableStack, blocks, ctx);
|
|
2518
2532
|
} else if (localTag === "caption" && !inShape) {
|
|
2519
|
-
const cap = collectSubListContent(el, ctx);
|
|
2533
|
+
const cap = inIndependentDeletionStory(ctx.shared.track, () => collectSubListContent(el, ctx));
|
|
2520
2534
|
if (cap.text) {
|
|
2521
2535
|
if (tableCtx?.cell) mergeBlocksIntoCell(tableCtx.cell, [{ type: "paragraph", text: cap.text, pageNumber: ctx.page }]);
|
|
2522
2536
|
else if (tableCtx) {
|
|
@@ -2712,7 +2726,7 @@ function extractParagraphInfo(para2, styleMap, ctx) {
|
|
|
2712
2726
|
// 아니므로 방출하지 않는다
|
|
2713
2727
|
case "header":
|
|
2714
2728
|
case "footer": {
|
|
2715
|
-
if (!ctx) break;
|
|
2729
|
+
if (!ctx || isInDeletedRange(ctx)) break;
|
|
2716
2730
|
const t = collectSubListText(k, ctx);
|
|
2717
2731
|
if (t && hasPageAutoNum(k) && !/\p{L}/u.test(t)) break;
|
|
2718
2732
|
if (t) {
|
|
@@ -2834,9 +2848,10 @@ function extractParagraphInfo(para2, styleMap, ctx) {
|
|
|
2834
2848
|
if (isInlineTbl(child)) text += "";
|
|
2835
2849
|
break;
|
|
2836
2850
|
// 양식 선택 상자·라디오 단추 — 한컴이 그리는 상자 기호와 캡션 글 (종전엔 통째로 빠졌다: form-002 "원천기술형"·서울 결재 "부분공개")
|
|
2851
|
+
// 지운 구간의 양식 단추·수식은 글처럼 내지 않는다 (최종본)
|
|
2837
2852
|
case "checkBtn":
|
|
2838
2853
|
case "radioBtn":
|
|
2839
|
-
text += formButtonText(child, tag === "radioBtn");
|
|
2854
|
+
if (!isInDeletedRange(ctx)) text += formButtonText(child, tag === "radioBtn");
|
|
2840
2855
|
break;
|
|
2841
2856
|
// 하이퍼링크
|
|
2842
2857
|
case "hyperlink": {
|
|
@@ -2906,6 +2921,7 @@ function extractParagraphInfo(para2, styleMap, ctx) {
|
|
|
2906
2921
|
// 스크립트가 담겨 있음. hml-equation-parser 로 LaTeX 변환 후 `$...$`
|
|
2907
2922
|
// 로 래핑. 실패/빈 스크립트면 무시 (대체 텍스트 누출 방지).
|
|
2908
2923
|
case "equation": {
|
|
2924
|
+
if (isInDeletedRange(ctx)) break;
|
|
2909
2925
|
const script = findChildByLocalName(child, "script");
|
|
2910
2926
|
const raw = script ? extractTextFromNode(script) : "";
|
|
2911
2927
|
if (raw.trim()) {
|
|
@@ -3453,7 +3469,7 @@ function resolveImageBlocks(binDataMap, blocks, warnings, sweepUnreferenced) {
|
|
|
3453
3469
|
resolveImageSentinels(blocks, renamed);
|
|
3454
3470
|
return images;
|
|
3455
3471
|
}
|
|
3456
|
-
function collectHwp5BinData(fileIndex) {
|
|
3472
|
+
function collectHwp5BinData(fileIndex, readStream) {
|
|
3457
3473
|
const binDataMap = /* @__PURE__ */ new Map();
|
|
3458
3474
|
if (fileIndex) {
|
|
3459
3475
|
for (const entry of fileIndex) {
|
|
@@ -3461,35 +3477,37 @@ function collectHwp5BinData(fileIndex) {
|
|
|
3461
3477
|
const match = entry.name.match(BIN_ENTRY_RE);
|
|
3462
3478
|
if (!match) continue;
|
|
3463
3479
|
const idx = parseInt(match[1], 16);
|
|
3464
|
-
const
|
|
3480
|
+
const raw = readStream ? readStream(`/BinData/${entry.name}`) : Buffer.from(entry.content);
|
|
3481
|
+
if (!raw) continue;
|
|
3482
|
+
const data = normalizeBinPayload(raw);
|
|
3465
3483
|
binDataMap.set(idx, { data, name: entry.name });
|
|
3466
3484
|
}
|
|
3467
3485
|
}
|
|
3468
3486
|
return binDataMap;
|
|
3469
3487
|
}
|
|
3470
|
-
function collectHwp5BinDataLenient(lcfb) {
|
|
3488
|
+
function collectHwp5BinDataLenient(lcfb, readStream = lcfb.findStream) {
|
|
3471
3489
|
const binDataMap = /* @__PURE__ */ new Map();
|
|
3472
3490
|
const binRe = /^BIN([0-9A-Fa-f]{4,8})(?:\.|$)/;
|
|
3473
3491
|
for (const e of lcfb.entries()) {
|
|
3474
3492
|
const match = e.name.match(binRe);
|
|
3475
3493
|
if (!match) continue;
|
|
3476
3494
|
const idx = parseInt(match[1], 16);
|
|
3477
|
-
const raw =
|
|
3495
|
+
const raw = readStream(e.name);
|
|
3478
3496
|
if (!raw) continue;
|
|
3479
3497
|
binDataMap.set(idx, { data: normalizeBinPayload(raw), name: e.name });
|
|
3480
3498
|
}
|
|
3481
3499
|
return binDataMap;
|
|
3482
3500
|
}
|
|
3483
|
-
function extractHwp5Images(fileIndex, blocks, warnings, sweepUnreferenced) {
|
|
3484
|
-
const binDataMap = collectHwp5BinData(fileIndex);
|
|
3501
|
+
function extractHwp5Images(fileIndex, blocks, warnings, sweepUnreferenced, readStream) {
|
|
3502
|
+
const binDataMap = collectHwp5BinData(fileIndex, readStream);
|
|
3485
3503
|
if (binDataMap.size === 0) {
|
|
3486
3504
|
resolveImageSentinels(blocks, /* @__PURE__ */ new Map());
|
|
3487
3505
|
return [];
|
|
3488
3506
|
}
|
|
3489
3507
|
return resolveImageBlocks(binDataMap, blocks, warnings, sweepUnreferenced);
|
|
3490
3508
|
}
|
|
3491
|
-
function extractHwp5ImagesLenient(lcfb, blocks, warnings, sweepUnreferenced) {
|
|
3492
|
-
const binDataMap = collectHwp5BinDataLenient(lcfb);
|
|
3509
|
+
function extractHwp5ImagesLenient(lcfb, blocks, warnings, sweepUnreferenced, readStream) {
|
|
3510
|
+
const binDataMap = collectHwp5BinDataLenient(lcfb, readStream);
|
|
3493
3511
|
if (binDataMap.size === 0) {
|
|
3494
3512
|
resolveImageSentinels(blocks, /* @__PURE__ */ new Map());
|
|
3495
3513
|
return [];
|
|
@@ -3746,8 +3764,11 @@ async function resolveSectionPaths(zip) {
|
|
|
3746
3764
|
function parseSectionPathsFromManifest(xml) {
|
|
3747
3765
|
const parser = createXmlParser();
|
|
3748
3766
|
const doc = parser.parseFromString(stripDtd(xml), "text/xml");
|
|
3749
|
-
const
|
|
3750
|
-
const
|
|
3767
|
+
const opf = "http://www.idpf.org/2007/opf/";
|
|
3768
|
+
const namespacedItems = doc.getElementsByTagNameNS(opf, "item");
|
|
3769
|
+
const namespacedSpine = doc.getElementsByTagNameNS(opf, "itemref");
|
|
3770
|
+
const items = namespacedItems.length ? namespacedItems : doc.getElementsByTagName("opf:item");
|
|
3771
|
+
const spine = namespacedSpine.length ? namespacedSpine : doc.getElementsByTagName("opf:itemref");
|
|
3751
3772
|
const idToHref = /* @__PURE__ */ new Map();
|
|
3752
3773
|
for (let i = 0; i < items.length; i++) {
|
|
3753
3774
|
const item = items[i];
|
|
@@ -3954,7 +3975,7 @@ async function parseHwpxDocument(buffer, options) {
|
|
|
3954
3975
|
applyPageText(blocks, shared);
|
|
3955
3976
|
const images = await extractImagesFromZip(zip, blocks, decompressed, warnings, !options?.pages, shared.track.deletedImageRefs);
|
|
3956
3977
|
const shown = options?.layoutTables === "keep" ? blocks : unframeLayoutTables(blocks, !!options?.keepTrailingEmptyCols);
|
|
3957
|
-
detectHwpxHeadings(shown, styleMap);
|
|
3978
|
+
detectHwpxHeadings(shown, styleMap, shared.tocTexts);
|
|
3958
3979
|
const outline = shown.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
|
|
3959
3980
|
const markdown = blocksToMarkdown(shown);
|
|
3960
3981
|
return { markdown, blocks: shown, metadata, outline: outline.length > 0 ? outline : void 0, warnings: warnings.length > 0 ? warnings : void 0, images: images.length > 0 ? images : void 0 };
|
|
@@ -5361,6 +5382,7 @@ function createHwp5DocState() {
|
|
|
5361
5382
|
outlineNumberingId: 0,
|
|
5362
5383
|
autoCounters: /* @__PURE__ */ new Map(),
|
|
5363
5384
|
headerTexts: /* @__PURE__ */ new Set(),
|
|
5385
|
+
tocTexts: /* @__PURE__ */ new Set(),
|
|
5364
5386
|
headerBlocks: [],
|
|
5365
5387
|
footerBlocks: []
|
|
5366
5388
|
};
|
|
@@ -5506,6 +5528,12 @@ function parseParagraph(records, start, end, ctx) {
|
|
|
5506
5528
|
if (bullet && bullet.char !== "\uFFFF") headMarker = bullet.char;
|
|
5507
5529
|
}
|
|
5508
5530
|
}
|
|
5531
|
+
if (toc.tocEntry) {
|
|
5532
|
+
for (const line of text.split("\n")) if (line.trim()) {
|
|
5533
|
+
ctx.doc.tocTexts.add(line.trim());
|
|
5534
|
+
if (headMarker) ctx.doc.tocTexts.add(`${headMarker} ${line.trim()}`);
|
|
5535
|
+
}
|
|
5536
|
+
}
|
|
5509
5537
|
return emitParagraphBlocks({
|
|
5510
5538
|
text,
|
|
5511
5539
|
headMarker,
|
|
@@ -5970,7 +5998,7 @@ function readHwp5DocInfoRecords(c) {
|
|
|
5970
5998
|
}
|
|
5971
5999
|
}
|
|
5972
6000
|
function readHwp5SectionStreams(c) {
|
|
5973
|
-
return c.distribution ? c.cfb ? findViewTextSections(c.cfb, c.compressed) : findViewTextSectionsLenient(c.lenientCfb, c.compressed) : c.encrypted ? findSectionsVia(c.findStream) : c.cfb ? findSections(c.cfb) : findSectionsLenient(c.lenientCfb
|
|
6001
|
+
return c.distribution ? c.cfb ? findViewTextSections(c.cfb, c.compressed) : findViewTextSectionsLenient(c.lenientCfb, c.compressed) : c.encrypted ? findSectionsVia(c.findStream) : c.cfb ? findSections(c.cfb) : findSectionsLenient(c.lenientCfb);
|
|
5974
6002
|
}
|
|
5975
6003
|
function readHwp5SectionRecords(c, sections, warnings) {
|
|
5976
6004
|
const out = [];
|
|
@@ -5990,7 +6018,8 @@ function readHwp5SectionRecords(c, sections, warnings) {
|
|
|
5990
6018
|
return out;
|
|
5991
6019
|
}
|
|
5992
6020
|
function readHwp5BinData(c) {
|
|
5993
|
-
|
|
6021
|
+
const readStream = c.encrypted ? c.findStream : void 0;
|
|
6022
|
+
return c.cfb ? collectHwp5BinData(c.cfb.FileIndex, readStream) : collectHwp5BinDataLenient(c.lenientCfb, readStream);
|
|
5994
6023
|
}
|
|
5995
6024
|
function parseHwp5Document(buffer, options) {
|
|
5996
6025
|
const c = openHwp5Container(buffer, options);
|
|
@@ -6055,7 +6084,7 @@ function parseHwp5Document(buffer, options) {
|
|
|
6055
6084
|
bodyBlocks = bodyBlocks.filter((b) => b.pageNumber != null && pageFilter.has(b.pageNumber));
|
|
6056
6085
|
}
|
|
6057
6086
|
const blocks = [...doc.headerBlocks, ...bodyBlocks, ...doc.footerBlocks];
|
|
6058
|
-
const images = cfb ? extractHwp5Images(cfb.FileIndex, blocks, warnings, !pageFilter) : extractHwp5ImagesLenient(lenientCfb, blocks, warnings, !pageFilter);
|
|
6087
|
+
const images = cfb ? extractHwp5Images(cfb.FileIndex, blocks, warnings, !pageFilter, encrypted ? findStream : void 0) : extractHwp5ImagesLenient(lenientCfb, blocks, warnings, !pageFilter, encrypted ? findStream : void 0);
|
|
6059
6088
|
let flatBlocks = flattenLayoutTables(blocks);
|
|
6060
6089
|
if (options?.layoutTables !== "keep") flatBlocks = unframeLayoutTables(flatBlocks, !!options?.keepTrailingEmptyCols);
|
|
6061
6090
|
if (options?.dedupeRunningHeaders) {
|
|
@@ -6065,7 +6094,7 @@ function parseHwp5Document(buffer, options) {
|
|
|
6065
6094
|
flatBlocks = deduped;
|
|
6066
6095
|
}
|
|
6067
6096
|
if (docInfo) {
|
|
6068
|
-
detectHwp5Headings(flatBlocks, docInfo);
|
|
6097
|
+
detectHwp5Headings(flatBlocks, docInfo, doc.tocTexts);
|
|
6069
6098
|
}
|
|
6070
6099
|
const outline = flatBlocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
|
|
6071
6100
|
let markdown = blocksToMarkdown(flatBlocks);
|
|
@@ -6098,7 +6127,7 @@ function parseDocInfoFromStream(raw, compressed) {
|
|
|
6098
6127
|
return null;
|
|
6099
6128
|
}
|
|
6100
6129
|
}
|
|
6101
|
-
function detectHwp5Headings(blocks, docInfo) {
|
|
6130
|
+
function detectHwp5Headings(blocks, docInfo, tocTexts) {
|
|
6102
6131
|
let baseFontSize = 0;
|
|
6103
6132
|
const sizeFreq = /* @__PURE__ */ new Map();
|
|
6104
6133
|
for (const b of blocks) {
|
|
@@ -6128,7 +6157,7 @@ function detectHwp5Headings(blocks, docInfo) {
|
|
|
6128
6157
|
if (baseFontSize <= 0) return;
|
|
6129
6158
|
for (const block of blocks) {
|
|
6130
6159
|
if (block.type === "heading") continue;
|
|
6131
|
-
if (block.type !== "paragraph" || !block.text || TOC_ENTRY_BLOCKS.has(block)) continue;
|
|
6160
|
+
if (block.type !== "paragraph" || !block.text || TOC_ENTRY_BLOCKS.has(block) || tocTexts?.has(block.text.trim())) continue;
|
|
6132
6161
|
const text = block.text.trim();
|
|
6133
6162
|
if (text.length === 0 || text.length > 200) continue;
|
|
6134
6163
|
if (/^\d+$/.test(text)) continue;
|
|
@@ -6262,16 +6291,15 @@ function findSections(cfb) {
|
|
|
6262
6291
|
}
|
|
6263
6292
|
return sections.sort((a, b) => a.idx - b.idx).map((s) => s.content);
|
|
6264
6293
|
}
|
|
6265
|
-
function findSectionsLenient(lcfb
|
|
6294
|
+
function findSectionsLenient(lcfb) {
|
|
6266
6295
|
const sections = [];
|
|
6267
|
-
let
|
|
6296
|
+
let totalBytes = 0;
|
|
6268
6297
|
for (let i = 0; i < MAX_SECTIONS; i++) {
|
|
6269
6298
|
const raw = lcfb.findStream(`/BodyText/Section${i}`) ?? lcfb.findStream(`Section${i}`);
|
|
6270
6299
|
if (!raw) break;
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
sections.push({ idx: i, content });
|
|
6300
|
+
totalBytes += raw.length;
|
|
6301
|
+
if (totalBytes > MAX_TOTAL_DECOMPRESS) throw new KordocError("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
|
|
6302
|
+
sections.push({ idx: i, content: raw });
|
|
6275
6303
|
}
|
|
6276
6304
|
if (sections.length === 0) {
|
|
6277
6305
|
for (const e of lcfb.entries()) {
|
|
@@ -6280,10 +6308,9 @@ function findSectionsLenient(lcfb, compressed) {
|
|
|
6280
6308
|
const idx = parseInt(e.name.replace("Section", ""), 10) || 0;
|
|
6281
6309
|
const raw = lcfb.findStream(e.name);
|
|
6282
6310
|
if (raw) {
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
sections.push({ idx, content });
|
|
6311
|
+
totalBytes += raw.length;
|
|
6312
|
+
if (totalBytes > MAX_TOTAL_DECOMPRESS) throw new KordocError("\uCD1D \uC555\uCD95 \uD574\uC81C \uD06C\uAE30 \uCD08\uACFC (decompression bomb \uC758\uC2EC)");
|
|
6313
|
+
sections.push({ idx, content: raw });
|
|
6287
6314
|
}
|
|
6288
6315
|
}
|
|
6289
6316
|
}
|
|
@@ -19387,7 +19414,7 @@ function collectRichText(root) {
|
|
|
19387
19414
|
const el = children[i];
|
|
19388
19415
|
const local = el.localName || el.tagName?.replace(/^[^:]+:/, "") || "";
|
|
19389
19416
|
if (local === "rPh") continue;
|
|
19390
|
-
if (local === "t") out += escapeLiteralTags(el.textContent ?? "");
|
|
19417
|
+
if (local === "t") out += escapeLiteralTags(escapeLiteralDollar(el.textContent ?? ""));
|
|
19391
19418
|
else walk(el);
|
|
19392
19419
|
}
|
|
19393
19420
|
};
|
|
@@ -20011,14 +20038,14 @@ function extractSheetCells(records, bofIndex, sst, convertNum) {
|
|
|
20011
20038
|
const h = readCellHeader(rec.data);
|
|
20012
20039
|
if (h && rec.data.length >= 10) {
|
|
20013
20040
|
const isst = rec.data.readUInt32LE(6);
|
|
20014
|
-
cells.push({ row: h.row, col: h.col, value: escapeLiteralTags(sst[isst] ?? "") });
|
|
20041
|
+
cells.push({ row: h.row, col: h.col, value: escapeLiteralTags(escapeLiteralDollar(sst[isst] ?? "")) });
|
|
20015
20042
|
}
|
|
20016
20043
|
break;
|
|
20017
20044
|
}
|
|
20018
20045
|
case OP_LABEL: {
|
|
20019
20046
|
const h = readCellHeader(rec.data);
|
|
20020
20047
|
if (h) {
|
|
20021
|
-
cells.push({ row: h.row, col: h.col, value: escapeLiteralTags(decodeLabelString(rec.data)) });
|
|
20048
|
+
cells.push({ row: h.row, col: h.col, value: escapeLiteralTags(escapeLiteralDollar(decodeLabelString(rec.data))) });
|
|
20022
20049
|
}
|
|
20023
20050
|
break;
|
|
20024
20051
|
}
|
|
@@ -20034,7 +20061,7 @@ function extractSheetCells(records, bofIndex, sst, convertNum) {
|
|
|
20034
20061
|
cells.push({
|
|
20035
20062
|
row: h.row,
|
|
20036
20063
|
col: h.col,
|
|
20037
|
-
value: escapeLiteralTags(decodeFormulaStringRecord(next.data))
|
|
20064
|
+
value: escapeLiteralTags(escapeLiteralDollar(decodeFormulaStringRecord(next.data)))
|
|
20038
20065
|
});
|
|
20039
20066
|
i = j;
|
|
20040
20067
|
} else {
|
|
@@ -20746,6 +20773,7 @@ function isDisplayMath(el) {
|
|
|
20746
20773
|
// src/docx/parser.ts
|
|
20747
20774
|
var MAX_DECOMPRESS_SIZE5 = unzipLimitBytes(100 * 1024 * 1024);
|
|
20748
20775
|
var MEDIA_PART_RE = /^word\/(?:media|embeddings)\//;
|
|
20776
|
+
var NEVER_READ_RE = /^word\/(?:embeddings\/.*|media\/.+\.(?:mp4|m4v|mov|avi|wmv|mpe?g|mkv|webm|mp3|wav|m4a|wma|aac|ogg|flac|mid|bin))$/i;
|
|
20749
20777
|
function matchesLocal(el, localName3) {
|
|
20750
20778
|
return el.localName === localName3 || (el.tagName?.endsWith(`:${localName3}`) ?? false);
|
|
20751
20779
|
}
|
|
@@ -20937,7 +20965,7 @@ function parseFootnotes(xml) {
|
|
|
20937
20965
|
const runs = findElements(p, "r");
|
|
20938
20966
|
for (const r of runs) {
|
|
20939
20967
|
const tElements = getChildElements(r, "t");
|
|
20940
|
-
for (const t of tElements) texts.push(escapeLiteralTags(t.textContent ?? ""));
|
|
20968
|
+
for (const t of tElements) texts.push(escapeLiteralTags(escapeLiteralDollar(t.textContent ?? "")));
|
|
20941
20969
|
}
|
|
20942
20970
|
}
|
|
20943
20971
|
notes.set(id, texts.join("").trim());
|
|
@@ -20968,7 +20996,7 @@ function collectOmmlRoots(p) {
|
|
|
20968
20996
|
function extractRun(r) {
|
|
20969
20997
|
let text = "";
|
|
20970
20998
|
for (const el of effectiveChildElements(r)) {
|
|
20971
|
-
if (matchesLocal(el, "t")) text += escapeLiteralTags(el.textContent ?? "");
|
|
20999
|
+
if (matchesLocal(el, "t")) text += escapeLiteralTags(escapeLiteralDollar(el.textContent ?? ""));
|
|
20972
21000
|
else if (matchesLocal(el, "br") || matchesLocal(el, "cr")) text += "\n";
|
|
20973
21001
|
else if (matchesLocal(el, "tab")) text += " ";
|
|
20974
21002
|
else if (matchesLocal(el, "sym")) text += symbolChar(getAttr(el, "font"), getAttr(el, "char"));
|
|
@@ -21264,7 +21292,7 @@ async function buildImageMap(zip, rels, doc, warnings, readBytes) {
|
|
|
21264
21292
|
let data = null;
|
|
21265
21293
|
if (readBytes) data = await imgFile.async("uint8array");
|
|
21266
21294
|
imgIdx++;
|
|
21267
|
-
const ext = imgPath
|
|
21295
|
+
const ext = partExtension(imgPath);
|
|
21268
21296
|
const mimeMap = {
|
|
21269
21297
|
png: "image/png",
|
|
21270
21298
|
jpg: "image/jpeg",
|
|
@@ -21363,7 +21391,7 @@ async function parseHeaderFooterBlocks(zip, doc, rels, kind, styles, numbering,
|
|
|
21363
21391
|
}
|
|
21364
21392
|
async function parseDocxDocument(buffer, options) {
|
|
21365
21393
|
const readImages = options?.images !== false;
|
|
21366
|
-
precheckZipSize(buffer, MAX_DECOMPRESS_SIZE5, void 0, { re: MEDIA_PART_RE, skip: !readImages });
|
|
21394
|
+
precheckZipSize(buffer, MAX_DECOMPRESS_SIZE5, void 0, { re: MEDIA_PART_RE, skip: !readImages, never: NEVER_READ_RE });
|
|
21367
21395
|
const zip = await JSZip5.loadAsync(buffer);
|
|
21368
21396
|
const warnings = [];
|
|
21369
21397
|
const docFile = zip.file("word/document.xml");
|
|
@@ -21484,6 +21512,7 @@ import JSZip6 from "jszip";
|
|
|
21484
21512
|
import { DOMParser as DOMParser4 } from "@xmldom/xmldom";
|
|
21485
21513
|
var MAX_DECOMPRESS_SIZE6 = unzipLimitBytes(100 * 1024 * 1024);
|
|
21486
21514
|
var MEDIA_PART_RE2 = /^ppt\/(?:media|embeddings)\//;
|
|
21515
|
+
var NEVER_READ_RE2 = /^ppt\/(?:embeddings\/.*|media\/.+\.(?:mp4|m4v|mov|avi|wmv|mpe?g|mkv|webm|mp3|wav|m4a|wma|aac|ogg|flac|mid|bin))$/i;
|
|
21487
21516
|
var MAX_ZIP_ENTRIES2 = 1e4;
|
|
21488
21517
|
var MAX_SLIDES = 2e3;
|
|
21489
21518
|
var SKIP_PLACEHOLDERS = /* @__PURE__ */ new Set(["sldNum", "dt", "ftr", "hdr", "sldImg"]);
|
|
@@ -21580,12 +21609,14 @@ function paragraphText(p) {
|
|
|
21580
21609
|
const name = localName(child);
|
|
21581
21610
|
if (name === "r" || name === "fld") {
|
|
21582
21611
|
const t = findChildByLocalName(child, "t");
|
|
21583
|
-
|
|
21612
|
+
const rPr = findChildByLocalName(child, "rPr");
|
|
21613
|
+
const baseline = Number(rPr ? getAttr2(rPr, "baseline") ?? 0 : 0);
|
|
21614
|
+
if (t) text += wrapScript(escapeLiteralTags(escapeLiteralDollar(rawTextContent(t))), baseline > 0 ? "sup" : baseline < 0 ? "sub" : null);
|
|
21584
21615
|
} else if (name === "br") {
|
|
21585
21616
|
text += " ";
|
|
21586
21617
|
}
|
|
21587
21618
|
}
|
|
21588
|
-
return text.replace(/\s+/g, " ").trim();
|
|
21619
|
+
return tidyScriptTags(text.replace(/\s+/g, " ").trim());
|
|
21589
21620
|
}
|
|
21590
21621
|
function bodyParagraphs(txBody) {
|
|
21591
21622
|
const out = [];
|
|
@@ -21659,7 +21690,7 @@ async function pictureBlock(pic, ctx) {
|
|
|
21659
21690
|
if (!filename) {
|
|
21660
21691
|
const file = ctx.zip.file(rel.target);
|
|
21661
21692
|
if (!file) return null;
|
|
21662
|
-
const ext = rel.target
|
|
21693
|
+
const ext = partExtension(rel.target);
|
|
21663
21694
|
filename = `image_${String(ctx.imageNames.size + 1).padStart(3, "0")}.${ext}`;
|
|
21664
21695
|
try {
|
|
21665
21696
|
if (ctx.options?.images !== false) {
|
|
@@ -21737,7 +21768,7 @@ async function notesText(zip, rels) {
|
|
|
21737
21768
|
return texts.join(" ");
|
|
21738
21769
|
}
|
|
21739
21770
|
async function parsePptxDocument(buffer, options) {
|
|
21740
|
-
precheckZipSize(buffer, MAX_DECOMPRESS_SIZE6, MAX_ZIP_ENTRIES2, { re: MEDIA_PART_RE2, skip: options?.images === false });
|
|
21771
|
+
precheckZipSize(buffer, MAX_DECOMPRESS_SIZE6, MAX_ZIP_ENTRIES2, { re: MEDIA_PART_RE2, skip: options?.images === false, never: NEVER_READ_RE2 });
|
|
21741
21772
|
const zip = await JSZip6.loadAsync(buffer);
|
|
21742
21773
|
if (!zip.file("ppt/presentation.xml")) {
|
|
21743
21774
|
throw new KordocError("\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 PPTX \uD30C\uC77C: ppt/presentation.xml\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
@@ -21747,8 +21778,10 @@ async function parsePptxDocument(buffer, options) {
|
|
|
21747
21778
|
const imageNames = /* @__PURE__ */ new Map();
|
|
21748
21779
|
const images = [];
|
|
21749
21780
|
const slides = await slideParts(zip);
|
|
21781
|
+
const pageFilter = options?.pages ? parsePageRange(options.pages, slides.length) : null;
|
|
21750
21782
|
for (let i = 0; i < slides.length; i++) {
|
|
21751
21783
|
const page = i + 1;
|
|
21784
|
+
if (pageFilter && !pageFilter.has(page)) continue;
|
|
21752
21785
|
const root = parseXml3(await zip.file(slides[i]).async("text")).documentElement;
|
|
21753
21786
|
if (getAttr2(root, "show") === "0") {
|
|
21754
21787
|
warnings.push({ page, code: "HIDDEN_TEXT_FILTERED", message: `PPTX \uC228\uAE34 \uC2AC\uB77C\uC774\uB4DC ${page}\uCABD\uC744 \uAC74\uB108\uB701\uB2C8\uB2E4` });
|
|
@@ -28647,7 +28680,7 @@ function sanitizeText(text) {
|
|
|
28647
28680
|
return result;
|
|
28648
28681
|
}
|
|
28649
28682
|
function normForMatch(text) {
|
|
28650
|
-
return sanitizeText(text.replace(/\\\$/g, "$")).replace(/\s+/g, " ").trim();
|
|
28683
|
+
return sanitizeText(text.replace(/\\\$/g, "$").replace(/\\(?=<\/?(?:u|sup|sub)>)/g, "")).replace(/\s+/g, " ").trim();
|
|
28651
28684
|
}
|
|
28652
28685
|
function unescapeGfm(text) {
|
|
28653
28686
|
return text.replace(/\\([~*_`|#<$\\])/g, "$1");
|
|
@@ -29279,6 +29312,7 @@ var ImageRegistry = class {
|
|
|
29279
29312
|
supplied;
|
|
29280
29313
|
byUrl = /* @__PURE__ */ new Map();
|
|
29281
29314
|
ids = /* @__PURE__ */ new Set();
|
|
29315
|
+
names = /* @__PURE__ */ new Set();
|
|
29282
29316
|
parts = [];
|
|
29283
29317
|
picSeq = 0;
|
|
29284
29318
|
binSeq = 0;
|
|
@@ -29299,8 +29333,12 @@ var ImageRegistry = class {
|
|
|
29299
29333
|
let n = 1;
|
|
29300
29334
|
while (this.ids.has(itemId)) itemId = `${m[1].replace(/[^A-Za-z0-9_]/g, "_")}_${n++}`;
|
|
29301
29335
|
this.ids.add(itemId);
|
|
29336
|
+
let name = `BinData/${url}`;
|
|
29337
|
+
let suffix = 1;
|
|
29338
|
+
while (this.names.has(name)) name = `BinData/${m[1]}_${suffix++}.${m[2]}`;
|
|
29339
|
+
this.names.add(name);
|
|
29302
29340
|
part = {
|
|
29303
|
-
name
|
|
29341
|
+
name,
|
|
29304
29342
|
itemId,
|
|
29305
29343
|
mime,
|
|
29306
29344
|
data: m[2].toLowerCase() === "bmp" ? PLACEHOLDER_BMP : PLACEHOLDER_PNG
|
|
@@ -29329,8 +29367,9 @@ var ImageRegistry = class {
|
|
|
29329
29367
|
const base = safe && !url.includes("..") ? safe[1] : `image${++this.binSeq}`;
|
|
29330
29368
|
let itemId = base.replace(/[^A-Za-z0-9_]/g, "_");
|
|
29331
29369
|
let n = 1;
|
|
29332
|
-
while (this.ids.has(itemId)) itemId = `${base.replace(/[^A-Za-z0-9_]/g, "_")}_${n++}`;
|
|
29370
|
+
while (this.ids.has(itemId) || this.names.has(`BinData/${itemId}.${sniffed.ext}`)) itemId = `${base.replace(/[^A-Za-z0-9_]/g, "_")}_${n++}`;
|
|
29333
29371
|
this.ids.add(itemId);
|
|
29372
|
+
this.names.add(`BinData/${itemId}.${sniffed.ext}`);
|
|
29334
29373
|
const dim = probeImageSize(bytes);
|
|
29335
29374
|
let wHU, hHU;
|
|
29336
29375
|
if (dim && dim.w > 0 && dim.h > 0) {
|
|
@@ -34306,30 +34345,11 @@ async function resolveSectionEntryNames(zip) {
|
|
|
34306
34345
|
const f = zip.file(mp);
|
|
34307
34346
|
if (!f) continue;
|
|
34308
34347
|
const xml = await f.async("text");
|
|
34309
|
-
const paths =
|
|
34348
|
+
const paths = parseSectionPathsFromManifest(xml).filter((p) => zip.file(p) !== null);
|
|
34310
34349
|
if (paths.length > 0) return paths;
|
|
34311
34350
|
}
|
|
34312
34351
|
return Object.keys(zip.files).filter((n) => /[Ss]ection\d+\.xml$/.test(n)).sort(compareSectionPaths);
|
|
34313
34352
|
}
|
|
34314
|
-
function sectionPathsFromManifest(xml) {
|
|
34315
|
-
const attr = (tag, name) => {
|
|
34316
|
-
const m = tag.match(new RegExp(`(?:^|\\s)${name}\\s*=\\s*(?:"([^"]*)"|'([^']*)')`));
|
|
34317
|
-
return m ? m[1] ?? m[2] : "";
|
|
34318
|
-
};
|
|
34319
|
-
const idToHref = /* @__PURE__ */ new Map();
|
|
34320
|
-
for (const m of xml.matchAll(/<opf:item(\s(?:"[^"]*"|'[^']*'|[^>"'])*?)\/?>/g)) {
|
|
34321
|
-
const id = attr(m[1], "id");
|
|
34322
|
-
const href = normalizeSectionHref(attr(m[1], "href"));
|
|
34323
|
-
if (id && href) idToHref.set(id, href);
|
|
34324
|
-
}
|
|
34325
|
-
const ordered = [];
|
|
34326
|
-
for (const m of xml.matchAll(/<opf:itemref(\s(?:"[^"]*"|'[^']*'|[^>"'])*?)\/?>/g)) {
|
|
34327
|
-
const href = idToHref.get(attr(m[1], "idref"));
|
|
34328
|
-
if (href) ordered.push(href);
|
|
34329
|
-
}
|
|
34330
|
-
if (ordered.length > 0) return ordered;
|
|
34331
|
-
return Array.from(idToHref.values()).sort(compareSectionPaths);
|
|
34332
|
-
}
|
|
34333
34353
|
|
|
34334
34354
|
// src/roundtrip/hwp5-patch.ts
|
|
34335
34355
|
import { deflateRawSync as deflateRawSync2 } from "zlib";
|
|
@@ -35555,6 +35575,10 @@ async function patchHwpx(original, editedMarkdown, options) {
|
|
|
35555
35575
|
const parsed = await parseHwpxDocument(u8ToArrayBuffer(original), { layoutTables: "keep" });
|
|
35556
35576
|
origBlocks = parsed.blocks;
|
|
35557
35577
|
const visual = await parseHwpxDocument(u8ToArrayBuffer(original));
|
|
35578
|
+
if (parsed.markdown !== visual.markdown && editedMarkdown === visual.markdown) {
|
|
35579
|
+
const verification2 = options?.verify === false ? void 0 : diffUnitLists(splitMarkdownUnits(visual.markdown), splitMarkdownUnits(editedMarkdown));
|
|
35580
|
+
return { success: true, data: new Uint8Array(original), applied: 0, skipped, verification: verification2 };
|
|
35581
|
+
}
|
|
35558
35582
|
if (editedFromVisual(parsed.markdown, visual.markdown, editedMarkdown)) return { success: false, applied: 0, skipped, error: LAYOUT_MODE_MISMATCH };
|
|
35559
35583
|
} catch (err) {
|
|
35560
35584
|
return { success: false, applied: 0, skipped, error: `\uC6D0\uBCF8 HWPX \uD30C\uC2F1 \uC2E4\uD328: ${err instanceof Error ? err.message : String(err)}` };
|
|
@@ -39192,7 +39216,7 @@ var CHAR_CTRL_1SLOT = /* @__PURE__ */ new Set(["lineBreak", "hyphen", "nbSpace",
|
|
|
39192
39216
|
function pushFillers(chars, n, prId) {
|
|
39193
39217
|
for (let i = 0; i < n; i++) chars.push({ ch: "", prId });
|
|
39194
39218
|
}
|
|
39195
|
-
function pushTextSlots(t, chars, prId, depth) {
|
|
39219
|
+
function pushTextSlots(t, chars, prId, depth, del = { deleted: 0 }) {
|
|
39196
39220
|
if (depth > 32) return;
|
|
39197
39221
|
const kids = t.childNodes;
|
|
39198
39222
|
if (!kids) return;
|
|
@@ -39200,19 +39224,24 @@ function pushTextSlots(t, chars, prId, depth) {
|
|
|
39200
39224
|
const c = kids[i];
|
|
39201
39225
|
if (c.nodeType === 3 || c.nodeType === 4) {
|
|
39202
39226
|
for (const cp of c.textContent ?? "") {
|
|
39203
|
-
chars.push({ ch: cp, prId });
|
|
39227
|
+
chars.push({ ch: del.deleted ? "" : cp, prId });
|
|
39204
39228
|
if (cp.length === 2) chars.push({ ch: "", prId });
|
|
39205
39229
|
}
|
|
39206
39230
|
} else if (c.nodeType === 1) {
|
|
39207
39231
|
const el = c;
|
|
39208
39232
|
const tag = ln(el);
|
|
39209
|
-
if (tag === "
|
|
39210
|
-
|
|
39211
|
-
|
|
39233
|
+
if (tag === "deleteBegin" || tag === "deleteEnd") {
|
|
39234
|
+
del.deleted = deletionDelta(el, del.deleted);
|
|
39235
|
+
} else if (tag === "tab") {
|
|
39236
|
+
if (del.deleted) pushFillers(chars, 8, prId);
|
|
39237
|
+
else {
|
|
39238
|
+
chars.push({ ch: "", prId, tab: true, tabW: num2(el, "width") });
|
|
39239
|
+
pushFillers(chars, 7, prId);
|
|
39240
|
+
}
|
|
39212
39241
|
} else if (CHAR_CTRL_1SLOT.has(tag)) {
|
|
39213
|
-
chars.push(tag === "nbSpace" ? { ch: " ", prId, nb: true } : { ch: tag === "fwSpace" ? " " : "", prId });
|
|
39242
|
+
chars.push(del.deleted ? { ch: "", prId } : tag === "nbSpace" ? { ch: " ", prId, nb: true } : { ch: tag === "fwSpace" ? " " : "", prId });
|
|
39214
39243
|
} else {
|
|
39215
|
-
pushTextSlots(el, chars, prId, depth + 1);
|
|
39244
|
+
pushTextSlots(el, chars, prId, depth + 1, del);
|
|
39216
39245
|
}
|
|
39217
39246
|
}
|
|
39218
39247
|
}
|
|
@@ -39237,7 +39266,7 @@ function prepareDeletedRanges(root, depth = 0) {
|
|
|
39237
39266
|
deletedStarts.set(p, deleted);
|
|
39238
39267
|
const scan = (el, xmlDepth) => {
|
|
39239
39268
|
if (xmlDepth > 64) return;
|
|
39240
|
-
if (ln(el) === "ctrl") for (const ch of elements(el)) scan(ch, xmlDepth + 1);
|
|
39269
|
+
if (ln(el) === "ctrl" || ln(el) === "t") for (const ch of elements(el)) scan(ch, xmlDepth + 1);
|
|
39241
39270
|
else {
|
|
39242
39271
|
if (ln(el) === "deleteBegin" || ln(el) === "deleteEnd") deleted = deletionDelta(el, deleted);
|
|
39243
39272
|
deletedControls.set(el, deleted > 0);
|
|
@@ -39269,9 +39298,9 @@ function buildPara(p) {
|
|
|
39269
39298
|
for (const ch of elements(runEl)) {
|
|
39270
39299
|
const cn = ln(ch);
|
|
39271
39300
|
if (cn === "t") {
|
|
39272
|
-
const
|
|
39273
|
-
pushTextSlots(ch, chars, prId, 0);
|
|
39274
|
-
|
|
39301
|
+
const del = { deleted };
|
|
39302
|
+
pushTextSlots(ch, chars, prId, 0, del);
|
|
39303
|
+
deleted = del.deleted;
|
|
39275
39304
|
} else if (OBJ_TAGS.has(cn)) {
|
|
39276
39305
|
const sz = findChildByLocalName(ch, "sz");
|
|
39277
39306
|
const pos = findChildByLocalName(ch, "pos");
|
|
@@ -39793,14 +39822,15 @@ function shapeGeometry(o, boxX, boxY, defs, images, warn, local = false) {
|
|
|
39793
39822
|
const color = esc(line?.getAttribute("color") || "#000000");
|
|
39794
39823
|
const strokeW = style === "NONE" ? 0 : Math.max(0.2, num2(line, "width", 33) / 100 * 2.834645);
|
|
39795
39824
|
const dash = /DASH|DOT/.test(style) ? ` stroke-dasharray="${style.includes("DOT") ? "1,1.5" : "3,1.5"}"` : "";
|
|
39796
|
-
const
|
|
39825
|
+
const keepWidth = local ? ` vector-effect="non-scaling-stroke"` : "";
|
|
39826
|
+
const stroke = strokeW ? ` stroke="${color}" stroke-width="${strokeW.toFixed(2)}"${dash}${keepWidth}` : "";
|
|
39797
39827
|
const fill = ` fill="${shapeFill(el, defs, images, warn)}"`;
|
|
39798
39828
|
let svg = "";
|
|
39799
39829
|
if (o.tag === "rect") svg = `<rect x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}"${fill}${stroke}/>`;
|
|
39800
39830
|
else if (o.tag === "ellipse") svg = `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}"${fill}${stroke}/>`;
|
|
39801
39831
|
else if (o.tag === "line") {
|
|
39802
39832
|
const s = findChildByLocalName(el, "startPt"), e = findChildByLocalName(el, "endPt");
|
|
39803
|
-
svg = `<line x1="${pt(x + num2(s, "x") * sx)}" y1="${pt(y + num2(s, "y") * sy)}" x2="${pt(x + num2(e, "x") * sx)}" y2="${pt(y + num2(e, "y") * sy)}" stroke="${color}" stroke-width="${(strokeW || 0.3).toFixed(2)}"${dash}/>`;
|
|
39833
|
+
svg = `<line x1="${pt(x + num2(s, "x") * sx)}" y1="${pt(y + num2(s, "y") * sy)}" x2="${pt(x + num2(e, "x") * sx)}" y2="${pt(y + num2(e, "y") * sy)}" stroke="${color}" stroke-width="${(strokeW || 0.3).toFixed(2)}"${dash}${keepWidth}/>`;
|
|
39804
39834
|
} else if (o.tag === "polygon" || o.tag === "curv") {
|
|
39805
39835
|
const pts = elements(el).filter((c) => ln(c) === "pt").map((c) => `${pt(x + num2(c, "x") * sx)},${pt(y + num2(c, "y") * sy)}`);
|
|
39806
39836
|
if (pts.length >= 2) svg = `<polygon points="${pts.join(" ")}"${fill}${stroke}/>`;
|
|
@@ -40156,15 +40186,15 @@ function drawGroupByMatrix(o, x, y, baseV, areaW, ctx, depth) {
|
|
|
40156
40186
|
emit(ctx, `<g transform="matrix(${m.slice(0, 4).map((v) => Math.round(v * 1e6) / 1e6).join(" ")} ${pt2(m[4])} ${pt2(m[5])})">`);
|
|
40157
40187
|
const sub = { el: leaf, tag, index: 0, inline: true, width: w, height: h, omL: 0, omR: 0 };
|
|
40158
40188
|
if (tag === "pic") drawPicFrame(leaf, 0, 0, w, h, "", ctx);
|
|
40159
|
-
else if (SHAPE_TAGS.has(tag)) drawShape(sub, 0, 0, ctx, depth + 1,
|
|
40189
|
+
else if (SHAPE_TAGS.has(tag)) drawShape(sub, 0, 0, ctx, depth + 1, [Math.hypot(m[0], m[1]) || 1, Math.hypot(m[2], m[3]) || 1]);
|
|
40160
40190
|
else drawObject(sub, 0, 0, baseV, areaW, ctx, depth + 1);
|
|
40161
40191
|
emit(ctx, "</g>");
|
|
40162
40192
|
ctx.regionRotations.pop();
|
|
40163
40193
|
}
|
|
40164
40194
|
return true;
|
|
40165
40195
|
}
|
|
40166
|
-
function drawShape(o, x, y, ctx, depth,
|
|
40167
|
-
const geometry = shapeGeometry(o, x, y, ctx.defs, ctx.images, (key, msg2) => warnOnce(ctx, key, msg2),
|
|
40196
|
+
function drawShape(o, x, y, ctx, depth, groupScale) {
|
|
40197
|
+
const geometry = shapeGeometry(o, x, y, ctx.defs, ctx.images, (key, msg2) => warnOnce(ctx, key, msg2), !!groupScale);
|
|
40168
40198
|
const b = geometry;
|
|
40169
40199
|
if (geometry.rotation) ctx.regionRotations.push(geometry.rotation);
|
|
40170
40200
|
ctx.stats.shapes++;
|
|
@@ -40176,7 +40206,17 @@ function drawShape(o, x, y, ctx, depth, local = false) {
|
|
|
40176
40206
|
const dt = findChildByLocalName(o.el, "drawText");
|
|
40177
40207
|
const sub = dt ? findChildByLocalName(dt, "subList") : null;
|
|
40178
40208
|
if (sub) {
|
|
40179
|
-
|
|
40209
|
+
const [sx, sy] = groupScale ?? [1, 1];
|
|
40210
|
+
const unscale = sx !== 1 || sy !== 1;
|
|
40211
|
+
if (unscale) {
|
|
40212
|
+
emit(ctx, `<g transform="scale(${1 / sx} ${1 / sy})">`);
|
|
40213
|
+
ctx.regionRotations.push([1 / sx, 0, 0, 1 / sy, 0, 0]);
|
|
40214
|
+
}
|
|
40215
|
+
for (const p of elements(sub)) if (ln(p) === "p") drawPara(p, geometry.x * sx, geometry.y * sy, geometry.w * sx, ctx, depth + 1);
|
|
40216
|
+
if (unscale) {
|
|
40217
|
+
ctx.regionRotations.pop();
|
|
40218
|
+
emit(ctx, "</g>");
|
|
40219
|
+
}
|
|
40180
40220
|
}
|
|
40181
40221
|
if (geometry.rotation) ctx.regionRotations.pop();
|
|
40182
40222
|
if (geometry.transform) emit(ctx, "</g>");
|
|
@@ -41440,7 +41480,7 @@ async function parse(input, options) {
|
|
|
41440
41480
|
buffer = toArrayBuffer(buf);
|
|
41441
41481
|
} catch (err) {
|
|
41442
41482
|
const msg2 = err instanceof Error && "code" in err && err.code === "ENOENT" ? `\uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${input}` : `\uD30C\uC77C \uC77D\uAE30 \uC2E4\uD328: ${input}`;
|
|
41443
|
-
return { success: false, fileType: "unknown", error: msg2, code:
|
|
41483
|
+
return { success: false, fileType: "unknown", error: msg2, code: classifyError(err) };
|
|
41444
41484
|
}
|
|
41445
41485
|
} else if (Buffer.isBuffer(input)) {
|
|
41446
41486
|
buffer = toArrayBuffer(input);
|
|
@@ -41458,9 +41498,12 @@ async function parse(input, options) {
|
|
|
41458
41498
|
}
|
|
41459
41499
|
if (result.success && opts?.classifyTables) classifyTableTree(result.blocks);
|
|
41460
41500
|
let out = result;
|
|
41461
|
-
if (result.success &&
|
|
41462
|
-
|
|
41463
|
-
|
|
41501
|
+
if (result.success && opts?.pages && result.pageCount && parsePageRange(opts.pages, result.pageCount).size === 0) {
|
|
41502
|
+
out = { ...result, warnings: [...result.warnings ?? [], { code: "PARTIAL_PARSE", message: `\uC694\uCCAD\uD55C \uCABD \uBC94\uC704(${opts.pages})\uAC00 \uBB38\uC11C \uCABD(1~${result.pageCount})\uACFC \uACB9\uCE58\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4` }] };
|
|
41503
|
+
}
|
|
41504
|
+
if (out.success && !out.pages) {
|
|
41505
|
+
const pages = blocksToPages(out.blocks);
|
|
41506
|
+
if (pages) out = { ...out, pages };
|
|
41464
41507
|
}
|
|
41465
41508
|
if (out.success && opts?.plain) {
|
|
41466
41509
|
out = { ...out, markdown: toPlainMarkdown(out.markdown), ...out.pages ? { pages: out.pages.map((p) => ({ ...p, markdown: toPlainMarkdown(p.markdown) })) } : {} };
|
|
@@ -41512,7 +41555,7 @@ function scriptsOff(r, off) {
|
|
|
41512
41555
|
}
|
|
41513
41556
|
async function parseImage(buffer, options) {
|
|
41514
41557
|
try {
|
|
41515
|
-
const { parseImageDocument } = await import("./image-ocr-
|
|
41558
|
+
const { parseImageDocument } = await import("./image-ocr-4BGX2EJJ.js");
|
|
41516
41559
|
const { blocks, warnings } = await parseImageDocument(buffer, options);
|
|
41517
41560
|
stripScriptTags({ blocks });
|
|
41518
41561
|
return {
|
|
@@ -41572,7 +41615,7 @@ async function parseHwp(buffer, options) {
|
|
|
41572
41615
|
async function parsePdf(buffer, options) {
|
|
41573
41616
|
let parsePdfDocument;
|
|
41574
41617
|
try {
|
|
41575
|
-
const mod = await import("./parser-
|
|
41618
|
+
const mod = await import("./parser-GFDGAVLV.js");
|
|
41576
41619
|
parsePdfDocument = mod.parsePdfDocument;
|
|
41577
41620
|
} catch {
|
|
41578
41621
|
return {
|
|
@@ -41617,7 +41660,7 @@ async function parseDocx(buffer, options) {
|
|
|
41617
41660
|
async function parsePptx(buffer, options) {
|
|
41618
41661
|
try {
|
|
41619
41662
|
const { markdown, blocks, metadata, outline, warnings, images } = await parsePptxDocument(buffer, options);
|
|
41620
|
-
return { success: true, fileType: "pptx", markdown, blocks, metadata, outline, warnings, images: images?.length ? images : void 0, pageCount: metadata?.pageCount };
|
|
41663
|
+
return scriptsOff({ success: true, fileType: "pptx", markdown, blocks, metadata, outline, warnings, images: images?.length ? images : void 0, pageCount: metadata?.pageCount }, options?.scriptTags === false);
|
|
41621
41664
|
} catch (err) {
|
|
41622
41665
|
return { success: false, fileType: "pptx", error: sanitizeError(err), code: classifyError(err) };
|
|
41623
41666
|
}
|