kordoc 4.14.2 → 4.14.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/README.md +51 -6
- package/dist/{-AQKXLFIM.js → -Z4TJ3QGK.js} +13 -11
- package/dist/{chunk-QOMNEWCQ.cjs → chunk-5LAZQCUJ.cjs} +305 -31
- package/dist/chunk-5LAZQCUJ.cjs.map +1 -0
- package/dist/{chunk-7IAQ4HOK.js → chunk-6BWU6SQX.js} +1 -1
- package/dist/chunk-6BWU6SQX.js.map +1 -0
- package/dist/{chunk-FOJZNMMK.js → chunk-6CUIXJOC.js} +1 -1
- package/dist/chunk-6CUIXJOC.js.map +1 -0
- package/dist/{chunk-ZWD734EY.js → chunk-7SE4EZ45.js} +2 -2
- package/dist/{chunk-TSFS5VKD.js → chunk-D4U2TXDC.js} +332 -141
- package/dist/chunk-D4U2TXDC.js.map +1 -0
- package/dist/chunk-DPWWXUOG.js +2222 -0
- package/dist/chunk-DPWWXUOG.js.map +1 -0
- package/dist/{chunk-GDW4YP7K.js → chunk-GLSBEEZJ.js} +2 -2
- package/dist/{chunk-JQEFP45L.js → chunk-GUJ4Q73I.js} +2 -2
- package/dist/{chunk-ZWOFQRIB.js → chunk-HIJUKZHM.js} +3 -3
- package/dist/chunk-IMAAFSAX.cjs +1352 -0
- package/dist/chunk-IMAAFSAX.cjs.map +1 -0
- package/dist/{chunk-TNCKOL2O.js → chunk-LCW7SEPG.js} +2 -2
- package/dist/chunk-LFSQAMSM.js +1352 -0
- package/dist/chunk-LFSQAMSM.js.map +1 -0
- package/dist/chunk-MG6DJEX4.js +1299 -0
- package/dist/chunk-MG6DJEX4.js.map +1 -0
- package/dist/{chunk-QC5T6D4J.js → chunk-NLU6LBLY.js} +299 -25
- package/dist/chunk-NLU6LBLY.js.map +1 -0
- package/dist/{chunk-EQZI77PP.cjs → chunk-QEJUY6SK.cjs} +3 -3
- package/dist/{chunk-EQZI77PP.cjs.map → chunk-QEJUY6SK.cjs.map} +1 -1
- package/dist/{chunk-VQ5W4MYO.js → chunk-QIF2VXBQ.js} +298 -24
- package/dist/chunk-QIF2VXBQ.js.map +1 -0
- package/dist/{chunk-UET462HB.js → chunk-TITDJWVZ.js} +2 -2
- package/dist/{chunk-247ANM72.cjs → chunk-USHQCF5T.cjs} +870 -147
- package/dist/chunk-USHQCF5T.cjs.map +1 -0
- package/dist/{chunk-C7FQBSON.js → chunk-V3DX4DUF.js} +2 -2
- package/dist/{chunk-DOGPOY4B.js → chunk-VDN7LMPL.js} +2 -2
- package/dist/{chunk-EDNJLUSE.js → chunk-VJIL6PIL.js} +2 -2
- package/dist/{chunk-L7DMSMAG.cjs → chunk-VWUYVEFN.cjs} +1 -1
- package/dist/chunk-VWUYVEFN.cjs.map +1 -0
- package/dist/{chunk-HR2XNERB.cjs → chunk-WJHAU73B.cjs} +2 -2
- package/dist/{chunk-HR2XNERB.cjs.map → chunk-WJHAU73B.cjs.map} +1 -1
- package/dist/{chunk-NS55SM7A.js → chunk-WJJGW5PL.js} +2 -2
- package/dist/{chunk-EISO3POT.js → chunk-XVXHXQIO.js} +788 -194
- package/dist/chunk-XVXHXQIO.js.map +1 -0
- package/dist/{chunk-ILU76UF3.js → chunk-YAKC46HZ.js} +2 -2
- package/dist/chunk-YAKC46HZ.js.map +1 -0
- package/dist/{chunk-3DUADAY2.js → chunk-YAVHVFRY.js} +851 -128
- package/dist/chunk-YAVHVFRY.js.map +1 -0
- package/dist/{chunk-A7QC2ZVP.js → chunk-YT3GC62E.js} +851 -128
- package/dist/chunk-YT3GC62E.js.map +1 -0
- package/dist/chunks-CCMRL4MJ.js +10 -0
- package/dist/cli.js +228 -97
- package/dist/cli.js.map +1 -1
- package/dist/{formula-PJJ6S3Z2.cjs → formula-5LOVHAKE.cjs} +9 -9
- package/dist/{formula-PJJ6S3Z2.cjs.map → formula-5LOVHAKE.cjs.map} +1 -1
- package/dist/{formula-JGFTXWYT.js → formula-7RANCW5L.js} +3 -3
- package/dist/{formula-5S7WWXGH.js → formula-7UYJOVTB.js} +4 -4
- package/dist/{image-ocr-WCAYXLOA.js → image-ocr-I6JOCATS.js} +34 -16
- package/dist/image-ocr-I6JOCATS.js.map +1 -0
- package/dist/{image-ocr-ZTYAGV3W.cjs → image-ocr-NYBJEOH2.cjs} +36 -18
- package/dist/image-ocr-NYBJEOH2.cjs.map +1 -0
- package/dist/{image-ocr-FLIL7MGN.js → image-ocr-ZV6PDBUQ.js} +32 -14
- package/dist/image-ocr-ZV6PDBUQ.js.map +1 -0
- package/dist/index.cjs +4048 -1216
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -28
- package/dist/index.d.ts +66 -28
- package/dist/index.js +3487 -655
- 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-2C5IYDLE.js} +5 -5
- package/dist/{models-CJPAQK5R.js → models-SEQZHZFT.js} +5 -5
- package/dist/{parser-SCUTZAIJ.js → parser-3FNXEP6T.js} +708 -250
- package/dist/parser-3FNXEP6T.js.map +1 -0
- package/dist/{parser-A4TMPJAM.js → parser-FJBJXRJK.js} +708 -250
- package/dist/parser-FJBJXRJK.js.map +1 -0
- package/dist/{parser-VCXE4I5A.cjs → parser-HVEKF73B.cjs} +733 -275
- package/dist/parser-HVEKF73B.cjs.map +1 -0
- package/dist/pdf-ocr-JRDBJ6TA.cjs +14 -0
- package/dist/{pdf-ocr-MBZZ57LD.cjs.map → pdf-ocr-JRDBJ6TA.cjs.map} +1 -1
- package/dist/pdf-ocr-UUBWBEHL.js +16 -0
- package/dist/pdf-ocr-VJSF2SQC.js +13 -0
- package/dist/{profile-io-LBM263K7.js → profile-io-RUFZOZO6.js} +3 -3
- package/dist/{rasterize-46RG4ZF6.js → rasterize-IOYXR5SI.js} +3 -3
- package/dist/redact-NMIKVHMP.js +18 -0
- package/dist/redact-doc-QBHNJ2BU.js +1284 -0
- package/dist/redact-doc-QBHNJ2BU.js.map +1 -0
- package/dist/{render-NGP5T24S.js → render-YZ2TEC3N.js} +7 -7
- package/dist/seal-ECV44TUH.js +10 -0
- package/dist/{setup-AU4OCHNH.js → setup-MPIEP6XT.js} +3 -3
- package/dist/visual-ICMOWUCR.js +19 -0
- package/dist/{watch-MKPUCPXM.js → watch-RYO7MN5B.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 → -Z4TJ3QGK.js.map} +0 -0
- /package/dist/{chunk-ZWD734EY.js.map → chunk-7SE4EZ45.js.map} +0 -0
- /package/dist/{chunk-GDW4YP7K.js.map → chunk-GLSBEEZJ.js.map} +0 -0
- /package/dist/{chunk-JQEFP45L.js.map → chunk-GUJ4Q73I.js.map} +0 -0
- /package/dist/{chunk-ZWOFQRIB.js.map → chunk-HIJUKZHM.js.map} +0 -0
- /package/dist/{chunk-TNCKOL2O.js.map → chunk-LCW7SEPG.js.map} +0 -0
- /package/dist/{chunk-UET462HB.js.map → chunk-TITDJWVZ.js.map} +0 -0
- /package/dist/{chunk-C7FQBSON.js.map → chunk-V3DX4DUF.js.map} +0 -0
- /package/dist/{chunk-DOGPOY4B.js.map → chunk-VDN7LMPL.js.map} +0 -0
- /package/dist/{chunk-EDNJLUSE.js.map → chunk-VJIL6PIL.js.map} +0 -0
- /package/dist/{chunk-NS55SM7A.js.map → chunk-WJJGW5PL.js.map} +0 -0
- /package/dist/{chunks-SX77P5CV.js.map → chunks-CCMRL4MJ.js.map} +0 -0
- /package/dist/{formula-JGFTXWYT.js.map → formula-7RANCW5L.js.map} +0 -0
- /package/dist/{formula-5S7WWXGH.js.map → formula-7UYJOVTB.js.map} +0 -0
- /package/dist/{model-bundle-FSPZZ2EM.js.map → model-bundle-2C5IYDLE.js.map} +0 -0
- /package/dist/{models-CJPAQK5R.js.map → models-SEQZHZFT.js.map} +0 -0
- /package/dist/{pdf-ocr-76SAUXMZ.js.map → pdf-ocr-UUBWBEHL.js.map} +0 -0
- /package/dist/{pdf-ocr-CPU55CVF.js.map → pdf-ocr-VJSF2SQC.js.map} +0 -0
- /package/dist/{profile-io-LBM263K7.js.map → profile-io-RUFZOZO6.js.map} +0 -0
- /package/dist/{rasterize-46RG4ZF6.js.map → rasterize-IOYXR5SI.js.map} +0 -0
- /package/dist/{redact-7ILEAUTS.js.map → redact-NMIKVHMP.js.map} +0 -0
- /package/dist/{render-NGP5T24S.js.map → render-YZ2TEC3N.js.map} +0 -0
- /package/dist/{seal-RGUPOLXD.js.map → seal-ECV44TUH.js.map} +0 -0
- /package/dist/{setup-AU4OCHNH.js.map → setup-MPIEP6XT.js.map} +0 -0
- /package/dist/{visual-NZLYIYEM.js.map → visual-ICMOWUCR.js.map} +0 -0
- /package/dist/{watch-MKPUCPXM.js.map → watch-RYO7MN5B.js.map} +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
HEADING_RATIO_H1,
|
|
7
7
|
HEADING_RATIO_H2,
|
|
8
8
|
HEADING_RATIO_H3
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6BWU6SQX.js";
|
|
10
10
|
import {
|
|
11
11
|
parsePageRange
|
|
12
12
|
} from "./chunk-MOL7MDBG.js";
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
findChildByLocalName,
|
|
20
20
|
hwpFaceToCssStack,
|
|
21
21
|
parseRenderStyles
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-YAKC46HZ.js";
|
|
23
23
|
import {
|
|
24
24
|
MAX_COLS,
|
|
25
25
|
MAX_ROWS,
|
|
@@ -29,17 +29,17 @@ import {
|
|
|
29
29
|
dedupeRunningHeaders,
|
|
30
30
|
flattenLayoutTables,
|
|
31
31
|
mapPuaText
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-NLU6LBLY.js";
|
|
33
33
|
import {
|
|
34
34
|
loadSharp,
|
|
35
35
|
rasterizePageSvg
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-V3DX4DUF.js";
|
|
37
37
|
import {
|
|
38
38
|
KordocError,
|
|
39
39
|
precheckZipSize,
|
|
40
40
|
sanitizeHref,
|
|
41
41
|
toArrayBuffer
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-TITDJWVZ.js";
|
|
43
43
|
|
|
44
44
|
// src/render/svg-render.ts
|
|
45
45
|
import JSZip from "jszip";
|
|
@@ -2813,6 +2813,7 @@ var TAG_TABLE = 77;
|
|
|
2813
2813
|
var TAG_SHAPE_COMPONENT = 76;
|
|
2814
2814
|
var TAG_SHAPE_COMPONENT_PICTURE = 85;
|
|
2815
2815
|
var TAG_SHAPE_COMPONENT_CONTAINER = 86;
|
|
2816
|
+
var TAG_CTRL_DATA = 87;
|
|
2816
2817
|
var TAG_EQEDIT = 88;
|
|
2817
2818
|
var TAG_ID_MAPPINGS = 17;
|
|
2818
2819
|
var TAG_BIN_DATA = 18;
|
|
@@ -2986,6 +2987,8 @@ function parseDocInfo(records) {
|
|
|
2986
2987
|
}
|
|
2987
2988
|
return { charShapes, paraShapes, styles, binData, numberings, bullets };
|
|
2988
2989
|
}
|
|
2990
|
+
var LEADER_TAB_MARK = "";
|
|
2991
|
+
var LITERAL_DOLLAR_MARK = "\uFDD0";
|
|
2989
2992
|
function createParaTextState() {
|
|
2990
2993
|
return { text: "", ctrlIdx: 0, fieldStack: [], fieldRanges: [] };
|
|
2991
2994
|
}
|
|
@@ -3039,8 +3042,9 @@ function appendParaText(state, data, resolveControl) {
|
|
|
3039
3042
|
break;
|
|
3040
3043
|
// 고정폭 공백
|
|
3041
3044
|
// ── inline 타입 (2바이트 + 14바이트 확장) ──
|
|
3045
|
+
// 확장 u16[7] 중 [2] 의 하위 바이트 = 채움 모양(0 없음·3 점선 …), 상위 = 탭 종류+1 (rhwp tab_extended 실측)
|
|
3042
3046
|
case CHAR_TAB:
|
|
3043
|
-
result += " ";
|
|
3047
|
+
result += state.leaderMark && i + 14 <= data.length && data[i + 4] !== 0 ? LEADER_TAB_MARK : " ";
|
|
3044
3048
|
if (i + 14 <= data.length) i += 14;
|
|
3045
3049
|
break;
|
|
3046
3050
|
default:
|
|
@@ -3073,7 +3077,7 @@ function appendParaText(state, data, resolveControl) {
|
|
|
3073
3077
|
break;
|
|
3074
3078
|
}
|
|
3075
3079
|
}
|
|
3076
|
-
result += String.fromCharCode(ch);
|
|
3080
|
+
result += ch === 36 && state.dollarMark ? LITERAL_DOLLAR_MARK : String.fromCharCode(ch);
|
|
3077
3081
|
}
|
|
3078
3082
|
break;
|
|
3079
3083
|
}
|
|
@@ -3098,9 +3102,21 @@ function detectImageMime(data) {
|
|
|
3098
3102
|
if (data[0] === 71 && data[1] === 73 && data[2] === 70) return "image/gif";
|
|
3099
3103
|
if (data[0] === 66 && data[1] === 77) return "image/bmp";
|
|
3100
3104
|
if (data[0] === 215 && data[1] === 205 && data[2] === 198 && data[3] === 154) return "image/wmf";
|
|
3105
|
+
if ((data[0] === 1 || data[0] === 2) && data[1] === 0 && data[2] === 9 && data[3] === 0) return "image/wmf";
|
|
3101
3106
|
if (data[0] === 1 && data[1] === 0 && data[2] === 0 && data[3] === 0) return "image/emf";
|
|
3107
|
+
if (data[0] === 73 && data[1] === 73 && data[2] === 42 && data[3] === 0 || data[0] === 77 && data[1] === 77 && data[2] === 0 && data[3] === 42) return "image/tiff";
|
|
3102
3108
|
return null;
|
|
3103
3109
|
}
|
|
3110
|
+
function mimeExt(mime) {
|
|
3111
|
+
if (mime.includes("jpeg")) return "jpg";
|
|
3112
|
+
if (mime.includes("png")) return "png";
|
|
3113
|
+
if (mime.includes("gif")) return "gif";
|
|
3114
|
+
if (mime.includes("bmp")) return "bmp";
|
|
3115
|
+
if (mime.includes("tiff")) return "tif";
|
|
3116
|
+
if (mime.includes("wmf")) return "wmf";
|
|
3117
|
+
if (mime.includes("emf")) return "emf";
|
|
3118
|
+
return "bin";
|
|
3119
|
+
}
|
|
3104
3120
|
function normalizeBinPayload(data) {
|
|
3105
3121
|
if (detectImageMime(data)) return data;
|
|
3106
3122
|
try {
|
|
@@ -3126,29 +3142,28 @@ function collectImageBlocks(blocks, out, depth = 0) {
|
|
|
3126
3142
|
if (b.children) collectImageBlocks(b.children, out, depth + 1);
|
|
3127
3143
|
}
|
|
3128
3144
|
}
|
|
3129
|
-
|
|
3145
|
+
var IMAGE_SENTINEL_RE = /!\[image\]\(hwp5bin:(\d+)\)/g;
|
|
3146
|
+
function resolveImageSentinels(blocks, renamed, depth = 0) {
|
|
3147
|
+
if (depth > MAX_BLOCK_DEPTH) return;
|
|
3148
|
+
const fix = (s) => s.includes("hwp5bin:") ? s.replace(IMAGE_SENTINEL_RE, (_m, idStr) => {
|
|
3149
|
+
const filename = renamed.get(Number(idStr));
|
|
3150
|
+
return filename ? `` : "[\uC774\uBBF8\uC9C0]";
|
|
3151
|
+
}) : s;
|
|
3130
3152
|
for (const b of blocks) {
|
|
3153
|
+
if (b.text) b.text = fix(b.text);
|
|
3154
|
+
if (b.footnoteText) b.footnoteText = fix(b.footnoteText);
|
|
3131
3155
|
if (b.table) {
|
|
3156
|
+
if (b.table.caption) b.table.caption = fix(b.table.caption);
|
|
3132
3157
|
for (const row of b.table.cells) {
|
|
3133
3158
|
for (const cell of row) {
|
|
3134
|
-
|
|
3135
|
-
if (cell.blocks)
|
|
3159
|
+
cell.text = fix(cell.text);
|
|
3160
|
+
if (cell.blocks) resolveImageSentinels(cell.blocks, renamed, depth + 1);
|
|
3136
3161
|
}
|
|
3137
3162
|
}
|
|
3138
3163
|
}
|
|
3139
|
-
if (b.children)
|
|
3164
|
+
if (b.children) resolveImageSentinels(b.children, renamed, depth + 1);
|
|
3140
3165
|
}
|
|
3141
3166
|
}
|
|
3142
|
-
var CELL_IMAGE_SENTINEL_RE = /!\[image\]\(hwp5bin:(\d+)\)/g;
|
|
3143
|
-
function resolveCellImageSentinels(blocks, renamed) {
|
|
3144
|
-
forEachTableCell(blocks, (cell) => {
|
|
3145
|
-
if (!cell.text.includes("hwp5bin:")) return;
|
|
3146
|
-
cell.text = cell.text.replace(CELL_IMAGE_SENTINEL_RE, (_m, idStr) => {
|
|
3147
|
-
const filename = renamed.get(Number(idStr));
|
|
3148
|
-
return filename ? `` : "[\uC774\uBBF8\uC9C0]";
|
|
3149
|
-
});
|
|
3150
|
-
});
|
|
3151
|
-
}
|
|
3152
3167
|
function resolveImageBlocks(binDataMap, blocks, warnings, sweepUnreferenced) {
|
|
3153
3168
|
const imageBlocks = [];
|
|
3154
3169
|
collectImageBlocks(blocks, imageBlocks);
|
|
@@ -3173,7 +3188,7 @@ function resolveImageBlocks(binDataMap, blocks, warnings, sweepUnreferenced) {
|
|
|
3173
3188
|
resolved.set(storageId, null);
|
|
3174
3189
|
} else {
|
|
3175
3190
|
imageIndex++;
|
|
3176
|
-
const ext =
|
|
3191
|
+
const ext = mimeExt(mime);
|
|
3177
3192
|
img = { filename: `image_${String(imageIndex).padStart(3, "0")}.${ext}`, data: new Uint8Array(bin.data), mime };
|
|
3178
3193
|
resolved.set(storageId, img);
|
|
3179
3194
|
images.push({ filename: img.filename, data: img.data, mimeType: img.mime, source: bin.name });
|
|
@@ -3197,14 +3212,15 @@ function resolveImageBlocks(binDataMap, blocks, warnings, sweepUnreferenced) {
|
|
|
3197
3212
|
const mime = detectImageMime(bin.data);
|
|
3198
3213
|
if (!mime) continue;
|
|
3199
3214
|
imageIndex++;
|
|
3200
|
-
const ext =
|
|
3215
|
+
const ext = mimeExt(mime);
|
|
3201
3216
|
const filename = `image_${String(imageIndex).padStart(3, "0")}.${ext}`;
|
|
3202
3217
|
const data = new Uint8Array(bin.data);
|
|
3203
3218
|
images.push({ filename, data, mimeType: mime, source: bin.name });
|
|
3204
3219
|
blocks.push({ type: "image", text: filename, imageData: { data, mimeType: mime, filename: bin.name } });
|
|
3220
|
+
renamed.set(storageId, filename);
|
|
3205
3221
|
}
|
|
3206
3222
|
}
|
|
3207
|
-
|
|
3223
|
+
resolveImageSentinels(blocks, renamed);
|
|
3208
3224
|
return images;
|
|
3209
3225
|
}
|
|
3210
3226
|
function collectHwp5BinData(fileIndex) {
|
|
@@ -3237,7 +3253,7 @@ function collectHwp5BinDataLenient(lcfb) {
|
|
|
3237
3253
|
function extractHwp5Images(fileIndex, blocks, warnings, sweepUnreferenced) {
|
|
3238
3254
|
const binDataMap = collectHwp5BinData(fileIndex);
|
|
3239
3255
|
if (binDataMap.size === 0) {
|
|
3240
|
-
|
|
3256
|
+
resolveImageSentinels(blocks, /* @__PURE__ */ new Map());
|
|
3241
3257
|
return [];
|
|
3242
3258
|
}
|
|
3243
3259
|
return resolveImageBlocks(binDataMap, blocks, warnings, sweepUnreferenced);
|
|
@@ -3245,7 +3261,7 @@ function extractHwp5Images(fileIndex, blocks, warnings, sweepUnreferenced) {
|
|
|
3245
3261
|
function extractHwp5ImagesLenient(lcfb, blocks, warnings, sweepUnreferenced) {
|
|
3246
3262
|
const binDataMap = collectHwp5BinDataLenient(lcfb);
|
|
3247
3263
|
if (binDataMap.size === 0) {
|
|
3248
|
-
|
|
3264
|
+
resolveImageSentinels(blocks, /* @__PURE__ */ new Map());
|
|
3249
3265
|
return [];
|
|
3250
3266
|
}
|
|
3251
3267
|
return resolveImageBlocks(binDataMap, blocks, warnings, sweepUnreferenced);
|
|
@@ -5003,7 +5019,7 @@ function replaceBracket(strList) {
|
|
|
5003
5019
|
}
|
|
5004
5020
|
function hmlToLatex(hmlEqStr) {
|
|
5005
5021
|
if (!hmlEqStr) return "";
|
|
5006
|
-
let s = hmlEqStr.replace(/`/g, " ");
|
|
5022
|
+
let s = hmlEqStr.replace(/[\r\n\t]+/g, " ").replace(/`/g, " ");
|
|
5007
5023
|
s = s.replace(/\{/g, " { ").replace(/\}/g, " } ").replace(/&/g, " & ");
|
|
5008
5024
|
let tokens = s.split(" ");
|
|
5009
5025
|
for (let i = 0; i < tokens.length; i++) {
|
|
@@ -5098,6 +5114,176 @@ function hwpEquationToLatex(equation) {
|
|
|
5098
5114
|
return hmlToLatex(s).replace(/\s+/g, " ").trim();
|
|
5099
5115
|
}
|
|
5100
5116
|
|
|
5117
|
+
// src/hwp5/ir-assemble.ts
|
|
5118
|
+
var INLINE_TABLE_MARK = "";
|
|
5119
|
+
var INLINE_JOIN = /* @__PURE__ */ new WeakSet();
|
|
5120
|
+
function emitParagraphBlocks(p) {
|
|
5121
|
+
const { headMarker, style, footnotes, objects, pageNumber } = p;
|
|
5122
|
+
const blocks = [];
|
|
5123
|
+
const decorate = (t) => {
|
|
5124
|
+
let deco = style?.strike ? `~~${t}~~` : t;
|
|
5125
|
+
if (style?.underline) deco = `<u>${deco}</u>`;
|
|
5126
|
+
return deco;
|
|
5127
|
+
};
|
|
5128
|
+
if (p.text.includes(INLINE_TABLE_MARK)) {
|
|
5129
|
+
const segments = p.text.split(INLINE_TABLE_MARK);
|
|
5130
|
+
let segIdx = 0;
|
|
5131
|
+
let first = true;
|
|
5132
|
+
let lineOpen = false;
|
|
5133
|
+
let markerPending = !!headMarker;
|
|
5134
|
+
const flush = () => {
|
|
5135
|
+
if (segIdx >= segments.length) return;
|
|
5136
|
+
const s = segments[segIdx++].replace(/\$\$/g, "$ $").trim();
|
|
5137
|
+
if (!s) return;
|
|
5138
|
+
let t = decorate(s);
|
|
5139
|
+
if (markerPending) {
|
|
5140
|
+
t = `${headMarker} ${t}`;
|
|
5141
|
+
markerPending = false;
|
|
5142
|
+
}
|
|
5143
|
+
const block = { type: "paragraph", text: t, pageNumber };
|
|
5144
|
+
if (first) {
|
|
5145
|
+
if (style) block.style = style;
|
|
5146
|
+
if (footnotes.length > 0) block.footnoteText = footnotes.join("; ");
|
|
5147
|
+
first = false;
|
|
5148
|
+
}
|
|
5149
|
+
if (lineOpen) INLINE_JOIN.add(block);
|
|
5150
|
+
lineOpen = true;
|
|
5151
|
+
blocks.push(block);
|
|
5152
|
+
};
|
|
5153
|
+
for (const obj of objects) {
|
|
5154
|
+
if (obj.table) {
|
|
5155
|
+
flush();
|
|
5156
|
+
if (obj.inline && lineOpen) for (const b of obj.blocks) INLINE_JOIN.add(b);
|
|
5157
|
+
lineOpen = obj.inline;
|
|
5158
|
+
}
|
|
5159
|
+
blocks.push(...obj.blocks);
|
|
5160
|
+
}
|
|
5161
|
+
while (segIdx < segments.length) flush();
|
|
5162
|
+
if (first && footnotes.length > 0) blocks.unshift({ type: "paragraph", text: `(\uC8FC: ${footnotes.join("; ")})`, pageNumber });
|
|
5163
|
+
return blocks;
|
|
5164
|
+
}
|
|
5165
|
+
const trimmed = p.text.replace(/\$\$/g, "$ $").trim();
|
|
5166
|
+
if (trimmed) {
|
|
5167
|
+
const block = {
|
|
5168
|
+
type: p.headingLevel > 0 ? "heading" : "paragraph",
|
|
5169
|
+
text: headMarker ? `${headMarker} ${trimmed}` : trimmed,
|
|
5170
|
+
pageNumber
|
|
5171
|
+
};
|
|
5172
|
+
if (p.headingLevel > 0) block.level = p.headingLevel;
|
|
5173
|
+
if (style) {
|
|
5174
|
+
block.style = style;
|
|
5175
|
+
if (style.strike || style.underline) block.text = headMarker ? `${headMarker} ${decorate(trimmed)}` : decorate(trimmed);
|
|
5176
|
+
}
|
|
5177
|
+
if (footnotes.length > 0) block.footnoteText = footnotes.join("; ");
|
|
5178
|
+
blocks.push(block);
|
|
5179
|
+
} else if (footnotes.length > 0) {
|
|
5180
|
+
blocks.push({ type: "paragraph", text: `(\uC8FC: ${footnotes.join("; ")})`, pageNumber });
|
|
5181
|
+
}
|
|
5182
|
+
for (const obj of objects) blocks.push(...obj.blocks);
|
|
5183
|
+
return blocks;
|
|
5184
|
+
}
|
|
5185
|
+
function tableFlatText(table) {
|
|
5186
|
+
const flat = convertTableToText(table.cells);
|
|
5187
|
+
return table.caption ? table.caption + (flat ? "\n" + flat : "") : flat;
|
|
5188
|
+
}
|
|
5189
|
+
function blocksPlainText(blocks, sep) {
|
|
5190
|
+
const parts = [];
|
|
5191
|
+
for (const b of blocks) {
|
|
5192
|
+
if (b.type === "image") continue;
|
|
5193
|
+
if (b.type === "table") {
|
|
5194
|
+
const flat = b.table ? tableFlatText(b.table) : "";
|
|
5195
|
+
if (flat) parts.push(flat);
|
|
5196
|
+
continue;
|
|
5197
|
+
}
|
|
5198
|
+
if (b.text) {
|
|
5199
|
+
let t = b.text;
|
|
5200
|
+
if (b.footnoteText) t += ` (\uC8FC: ${b.footnoteText})`;
|
|
5201
|
+
parts.push(t);
|
|
5202
|
+
}
|
|
5203
|
+
}
|
|
5204
|
+
return parts.join(sep).trim();
|
|
5205
|
+
}
|
|
5206
|
+
function cellTextFromBlocks(blocks) {
|
|
5207
|
+
let text = "";
|
|
5208
|
+
const add = (part, b) => {
|
|
5209
|
+
text += (text ? INLINE_JOIN.has(b) ? " " : "\n" : "") + part;
|
|
5210
|
+
};
|
|
5211
|
+
let hasStructure = false;
|
|
5212
|
+
for (const b of blocks) {
|
|
5213
|
+
if (b.type === "image" && b.text) {
|
|
5214
|
+
add(``, b);
|
|
5215
|
+
hasStructure = true;
|
|
5216
|
+
} else if (b.type === "table" && b.table) {
|
|
5217
|
+
const flat = tableFlatText(b.table);
|
|
5218
|
+
if (flat) add(flat, b);
|
|
5219
|
+
hasStructure = true;
|
|
5220
|
+
} else if (b.text) {
|
|
5221
|
+
if (b.footnoteText) {
|
|
5222
|
+
b.text += ` (\uC8FC: ${b.footnoteText})`;
|
|
5223
|
+
delete b.footnoteText;
|
|
5224
|
+
}
|
|
5225
|
+
add(b.text, b);
|
|
5226
|
+
}
|
|
5227
|
+
}
|
|
5228
|
+
return { text, hasStructure };
|
|
5229
|
+
}
|
|
5230
|
+
function resolveCellOverlaps(cells, rows, cols) {
|
|
5231
|
+
const owner = /* @__PURE__ */ new Map();
|
|
5232
|
+
const out = [];
|
|
5233
|
+
for (const cell of cells) {
|
|
5234
|
+
const r0 = cell.rowAddr ?? 0, c0 = cell.colAddr ?? 0;
|
|
5235
|
+
const hit = owner.get(r0 * cols + c0);
|
|
5236
|
+
if (hit) {
|
|
5237
|
+
if (cell.blocks?.length) {
|
|
5238
|
+
hit.blocks = [...hit.blocks ?? (hit.text ? [{ type: "paragraph", text: hit.text }] : []), ...cell.blocks];
|
|
5239
|
+
}
|
|
5240
|
+
if (cell.text.trim()) hit.text = hit.text.trim() ? `${hit.text}
|
|
5241
|
+
${cell.text}` : cell.text;
|
|
5242
|
+
continue;
|
|
5243
|
+
}
|
|
5244
|
+
const csIn = Math.max(1, Math.min(cell.colSpan, cols - c0));
|
|
5245
|
+
let cs = cell.colSpan;
|
|
5246
|
+
for (let c = c0 + 1; c < c0 + csIn; c++) if (owner.has(r0 * cols + c)) {
|
|
5247
|
+
cs = c - c0;
|
|
5248
|
+
break;
|
|
5249
|
+
}
|
|
5250
|
+
const rsIn = Math.max(1, Math.min(cell.rowSpan, rows - r0));
|
|
5251
|
+
let rs = cell.rowSpan;
|
|
5252
|
+
scan: for (let r = r0 + 1; r < r0 + rsIn; r++) {
|
|
5253
|
+
for (let c = c0; c < c0 + Math.min(cs, csIn); c++) if (owner.has(r * cols + c)) {
|
|
5254
|
+
rs = r - r0;
|
|
5255
|
+
break scan;
|
|
5256
|
+
}
|
|
5257
|
+
}
|
|
5258
|
+
const placed = cs === cell.colSpan && rs === cell.rowSpan ? cell : { ...cell, colSpan: cs, rowSpan: rs };
|
|
5259
|
+
for (let r = r0; r < Math.min(r0 + rs, rows); r++) for (let c = c0; c < Math.min(c0 + cs, cols); c++) owner.set(r * cols + c, placed);
|
|
5260
|
+
out.push(placed);
|
|
5261
|
+
}
|
|
5262
|
+
return out;
|
|
5263
|
+
}
|
|
5264
|
+
function buildAddressedTable(cells, rows, cols, keepAnchoredEmptyCols) {
|
|
5265
|
+
for (const c of cells) {
|
|
5266
|
+
rows = Math.max(rows, Math.min((c.rowAddr ?? 0) + 1, MAX_ROWS));
|
|
5267
|
+
cols = Math.max(cols, Math.min((c.colAddr ?? 0) + 1, MAX_COLS));
|
|
5268
|
+
}
|
|
5269
|
+
const placed = resolveCellOverlaps(cells, rows, cols);
|
|
5270
|
+
const byRow = Array.from({ length: rows }, () => []);
|
|
5271
|
+
for (const c of placed) {
|
|
5272
|
+
const r = c.rowAddr ?? 0;
|
|
5273
|
+
if (r < rows && (c.colAddr ?? 0) < cols) byRow[r].push(c);
|
|
5274
|
+
}
|
|
5275
|
+
const table = buildTable(byRow, { keepAnchoredEmptyCols });
|
|
5276
|
+
if (table.rows === 0) return null;
|
|
5277
|
+
for (const c of placed) {
|
|
5278
|
+
if (!c.blocks?.length && !c.isHeader) continue;
|
|
5279
|
+
const target = table.cells[c.rowAddr ?? 0]?.[c.colAddr ?? 0];
|
|
5280
|
+
if (!target || target.text !== c.text.trim()) continue;
|
|
5281
|
+
if (c.blocks?.length) target.blocks = c.blocks;
|
|
5282
|
+
if (c.isHeader) target.isHeader = true;
|
|
5283
|
+
}
|
|
5284
|
+
return table;
|
|
5285
|
+
}
|
|
5286
|
+
|
|
5101
5287
|
// src/hwp5/body.ts
|
|
5102
5288
|
var MAX_NEST_DEPTH = 8;
|
|
5103
5289
|
function cid(s) {
|
|
@@ -5247,8 +5433,13 @@ function parseParagraph(records, start, end, ctx) {
|
|
|
5247
5433
|
}
|
|
5248
5434
|
for (const ctrl of ctrls) {
|
|
5249
5435
|
applyCtrlEffect(ctrl, records, ctx);
|
|
5436
|
+
if (ctrl.id === CTRL_TBL && ctrl.afterBlocks && ctrl.data.length >= 8 && ctrl.data.readUInt32LE(4) & 1) {
|
|
5437
|
+
ctrl.inlineText = INLINE_TABLE_MARK;
|
|
5438
|
+
}
|
|
5250
5439
|
}
|
|
5251
5440
|
const state = createParaTextState();
|
|
5441
|
+
state.leaderMark = true;
|
|
5442
|
+
state.dollarMark = true;
|
|
5252
5443
|
const resolver = (idx, id) => {
|
|
5253
5444
|
let ctrl = idx >= 0 && idx < ctrls.length ? ctrls[idx] : void 0;
|
|
5254
5445
|
if (!ctrl || ctrl.idRaw !== id && ctrl.id !== id) {
|
|
@@ -5267,17 +5458,28 @@ function parseParagraph(records, start, end, ctx) {
|
|
|
5267
5458
|
const applied = [];
|
|
5268
5459
|
for (const r of ranges) {
|
|
5269
5460
|
const ctrl = ctrls[r.ctrlIdx];
|
|
5270
|
-
if (!ctrl
|
|
5461
|
+
if (!ctrl || r.end <= r.start) continue;
|
|
5271
5462
|
if (applied.some(([s, e]) => r.start < e && r.end > s)) continue;
|
|
5463
|
+
const anchor = text.slice(r.start, r.end);
|
|
5464
|
+
if (ctrl.guide !== void 0) {
|
|
5465
|
+
const plain = anchor.replaceAll(LITERAL_DOLLAR_MARK, "$");
|
|
5466
|
+
if (plain === ctrl.guide || plain.trimEnd() === ctrl.guide) {
|
|
5467
|
+
text = text.slice(0, r.start) + text.slice(r.end);
|
|
5468
|
+
applied.push([r.start, r.end]);
|
|
5469
|
+
}
|
|
5470
|
+
continue;
|
|
5471
|
+
}
|
|
5472
|
+
if (!ctrl.href) continue;
|
|
5272
5473
|
const href = sanitizeHref(ctrl.href);
|
|
5273
5474
|
if (!href) continue;
|
|
5274
|
-
|
|
5275
|
-
if (!anchor.trim()) continue;
|
|
5475
|
+
if (!anchor.trim() || anchor.includes(INLINE_TABLE_MARK) || anchor.includes(LEADER_TAB_MARK)) continue;
|
|
5276
5476
|
text = text.slice(0, r.start) + `[${anchor}](${href})` + text.slice(r.end);
|
|
5277
5477
|
applied.push([r.start, r.end]);
|
|
5278
5478
|
}
|
|
5279
5479
|
}
|
|
5280
|
-
const
|
|
5480
|
+
const leaderAt = text.indexOf(LEADER_TAB_MARK);
|
|
5481
|
+
if (leaderAt >= 0) text = text.slice(0, leaderAt);
|
|
5482
|
+
if (text.includes(LITERAL_DOLLAR_MARK)) text = text.replaceAll(LITERAL_DOLLAR_MARK, "\\$");
|
|
5281
5483
|
let headingLevel = 0;
|
|
5282
5484
|
let headMarker = null;
|
|
5283
5485
|
const ps = ctx.docInfo && paraShapeId >= 0 && paraShapeId < ctx.docInfo.paraShapes.length ? ctx.docInfo.paraShapes[paraShapeId] : null;
|
|
@@ -5301,35 +5503,16 @@ function parseParagraph(records, start, end, ctx) {
|
|
|
5301
5503
|
if (bullet && bullet.char !== "\uFFFF") headMarker = bullet.char;
|
|
5302
5504
|
}
|
|
5303
5505
|
}
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
}
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
const style = resolveCharStyle(charShapeIds, ctx.docInfo);
|
|
5315
|
-
if (style) {
|
|
5316
|
-
block.style = style;
|
|
5317
|
-
if (style.strike || style.underline) {
|
|
5318
|
-
let deco = style.strike ? `~~${trimmed}~~` : trimmed;
|
|
5319
|
-
if (style.underline) deco = `<u>${deco}</u>`;
|
|
5320
|
-
block.text = headMarker ? `${headMarker} ${deco}` : deco;
|
|
5321
|
-
}
|
|
5322
|
-
}
|
|
5323
|
-
}
|
|
5324
|
-
if (footnotes.length > 0) block.footnoteText = footnotes.join("; ");
|
|
5325
|
-
blocks.push(block);
|
|
5326
|
-
} else if (footnotes.length > 0) {
|
|
5327
|
-
blocks.push({ type: "paragraph", text: `(\uC8FC: ${footnotes.join("; ")})`, pageNumber: ctx.page });
|
|
5328
|
-
}
|
|
5329
|
-
for (const ctrl of ctrls) {
|
|
5330
|
-
if (ctrl.afterBlocks) blocks.push(...ctrl.afterBlocks);
|
|
5331
|
-
}
|
|
5332
|
-
return blocks;
|
|
5506
|
+
return emitParagraphBlocks({
|
|
5507
|
+
text,
|
|
5508
|
+
headMarker,
|
|
5509
|
+
headingLevel,
|
|
5510
|
+
style: ctx.docInfo && charShapeIds.length > 0 ? resolveCharStyle(charShapeIds, ctx.docInfo) : void 0,
|
|
5511
|
+
footnotes: ctrls.filter((c) => c.footnote).map((c) => c.footnote),
|
|
5512
|
+
// 컨트롤 파생 블록 (표/이미지/글상자) — 컨트롤 순서대로
|
|
5513
|
+
objects: ctrls.filter((c) => c.afterBlocks).map((c) => ({ blocks: c.afterBlocks, table: c.id === CTRL_TBL, inline: c.inlineText === INLINE_TABLE_MARK })),
|
|
5514
|
+
pageNumber: ctx.page
|
|
5515
|
+
});
|
|
5333
5516
|
}
|
|
5334
5517
|
function applyCtrlEffect(ctrl, records, ctx) {
|
|
5335
5518
|
switch (ctrl.id) {
|
|
@@ -5424,19 +5607,6 @@ function parseListHeaderParagraphs(ctrl, records, ctx) {
|
|
|
5424
5607
|
}
|
|
5425
5608
|
return [];
|
|
5426
5609
|
}
|
|
5427
|
-
function blocksPlainText(blocks, sep) {
|
|
5428
|
-
const parts = [];
|
|
5429
|
-
for (const b of blocks) {
|
|
5430
|
-
if (b.type === "image") continue;
|
|
5431
|
-
if (b.type === "table") continue;
|
|
5432
|
-
if (b.text) {
|
|
5433
|
-
let t = b.text;
|
|
5434
|
-
if (b.footnoteText) t += ` (\uC8FC: ${b.footnoteText})`;
|
|
5435
|
-
parts.push(t);
|
|
5436
|
-
}
|
|
5437
|
-
}
|
|
5438
|
-
return parts.join(sep).trim();
|
|
5439
|
-
}
|
|
5440
5610
|
function applyNoteEffect(ctrl, records, ctx, autoType) {
|
|
5441
5611
|
const num3 = ctx.doc.autoCounters.get(autoType) ?? 1;
|
|
5442
5612
|
let before = "";
|
|
@@ -5475,8 +5645,18 @@ function applyFieldEffect(ctrl) {
|
|
|
5475
5645
|
const url = hyperlinkUrlFromCommand(command);
|
|
5476
5646
|
if (url) ctrl.href = url;
|
|
5477
5647
|
}
|
|
5648
|
+
} else if (ctrl.id === FIELD_CLK && ctrl.data.length >= 8 && !(ctrl.data.readUInt32LE(4) & 1 << 15)) {
|
|
5649
|
+
const command = parseFieldCommand(ctrl.data);
|
|
5650
|
+
const guide = command ? clickHereGuide(command) : void 0;
|
|
5651
|
+
if (guide) ctrl.guide = guide;
|
|
5478
5652
|
}
|
|
5479
5653
|
}
|
|
5654
|
+
function clickHereGuide(command) {
|
|
5655
|
+
const m = /Direction:wstring:(\d+):/.exec(command);
|
|
5656
|
+
if (!m) return void 0;
|
|
5657
|
+
const start = m.index + m[0].length;
|
|
5658
|
+
return command.slice(start, start + Number(m[1])) || void 0;
|
|
5659
|
+
}
|
|
5480
5660
|
function parseFieldCommand(data) {
|
|
5481
5661
|
if (data.length < 11) return null;
|
|
5482
5662
|
const cmdLen = data.readUInt16LE(9);
|
|
@@ -5505,18 +5685,19 @@ function parseTableControl(ctrl, records, ctx) {
|
|
|
5505
5685
|
if (ctx.depth >= MAX_NEST_DEPTH) return null;
|
|
5506
5686
|
const { childStart, childEnd } = ctrl;
|
|
5507
5687
|
const sourceId = ctx.tableIds?.get(childStart - 1);
|
|
5688
|
+
const directLevel = records[childStart - 1].level + 1;
|
|
5508
5689
|
let rows = 0;
|
|
5509
5690
|
let cols = 0;
|
|
5510
5691
|
let tableIdx = -1;
|
|
5511
5692
|
for (let i2 = childStart; i2 < childEnd; i2++) {
|
|
5512
|
-
if (records[i2].tagId === TAG_TABLE && records[i2].data.length >= 8) {
|
|
5693
|
+
if (records[i2].tagId === TAG_TABLE && records[i2].level === directLevel && records[i2].data.length >= 8) {
|
|
5513
5694
|
rows = Math.min(records[i2].data.readUInt16LE(4), MAX_ROWS);
|
|
5514
5695
|
cols = Math.min(records[i2].data.readUInt16LE(6), MAX_COLS);
|
|
5515
5696
|
tableIdx = i2;
|
|
5516
5697
|
break;
|
|
5517
5698
|
}
|
|
5518
5699
|
}
|
|
5519
|
-
if (tableIdx < 0
|
|
5700
|
+
if (tableIdx < 0) return null;
|
|
5520
5701
|
let caption;
|
|
5521
5702
|
for (let i2 = childStart; i2 < tableIdx; i2++) {
|
|
5522
5703
|
if (records[i2].tagId === TAG_LIST_HEADER) {
|
|
@@ -5546,20 +5727,17 @@ function parseTableControl(ctrl, records, ctx) {
|
|
|
5546
5727
|
i++;
|
|
5547
5728
|
}
|
|
5548
5729
|
if (cells.length === 0) return null;
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
const irCells = cellRows2.map((row) => row.map((c) => {
|
|
5553
|
-
const ir = { text: c.text.trim(), colSpan: c.colSpan, rowSpan: c.rowSpan };
|
|
5554
|
-
if (c.blocks?.length) ir.blocks = c.blocks;
|
|
5555
|
-
if (c.isHeader) ir.isHeader = true;
|
|
5556
|
-
return ir;
|
|
5557
|
-
}));
|
|
5558
|
-
const table2 = { rows, cols, cells: irCells, hasHeader: rows > 1 };
|
|
5730
|
+
if (cells.some((c) => c.colAddr !== void 0 && c.rowAddr !== void 0)) {
|
|
5731
|
+
const table2 = buildAddressedTable(cells, rows, cols, ctx.doc.keepTrailingEmptyCols);
|
|
5732
|
+
if (!table2) return null;
|
|
5559
5733
|
if (caption) table2.caption = caption;
|
|
5560
5734
|
if (sourceId) table2.sourceId = sourceId;
|
|
5561
5735
|
return table2;
|
|
5562
5736
|
}
|
|
5737
|
+
if (rows === 0 || cols === 0) {
|
|
5738
|
+
rows = Math.min(cells.length, MAX_ROWS);
|
|
5739
|
+
cols = 1;
|
|
5740
|
+
}
|
|
5563
5741
|
const cellRows = arrangeCells(rows, cols, cells);
|
|
5564
5742
|
const table = buildTable(cellRows, { keepAnchoredEmptyCols: ctx.doc.keepTrailingEmptyCols });
|
|
5565
5743
|
if (caption && table.rows > 0) table.caption = caption;
|
|
@@ -5583,38 +5761,19 @@ function parseCell(records, lhIdx, end, ctx) {
|
|
|
5583
5761
|
if (rs > 0) rowSpan = Math.min(rs, MAX_ROWS);
|
|
5584
5762
|
}
|
|
5585
5763
|
const blocks = ctx.depth < MAX_NEST_DEPTH ? parseParagraphList(records, lhIdx + 1, end, { ...ctx, depth: ctx.depth + 1 }) : [];
|
|
5586
|
-
const
|
|
5587
|
-
|
|
5588
|
-
for (const b of blocks) {
|
|
5589
|
-
if (b.type === "image" && b.text) {
|
|
5590
|
-
parts.push(``);
|
|
5591
|
-
hasStructure = true;
|
|
5592
|
-
} else if (b.type === "table" && b.table) {
|
|
5593
|
-
const flat = convertTableToText(b.table.cells);
|
|
5594
|
-
if (flat) parts.push(flat);
|
|
5595
|
-
hasStructure = true;
|
|
5596
|
-
} else if (b.text) {
|
|
5597
|
-
let t = b.text;
|
|
5598
|
-
if (b.footnoteText) {
|
|
5599
|
-
t += ` (\uC8FC: ${b.footnoteText})`;
|
|
5600
|
-
hasStructure = true;
|
|
5601
|
-
}
|
|
5602
|
-
parts.push(t);
|
|
5603
|
-
}
|
|
5604
|
-
}
|
|
5605
|
-
const cell = { text: parts.join("\n"), colSpan, rowSpan, colAddr, rowAddr };
|
|
5764
|
+
const { text, hasStructure } = cellTextFromBlocks(blocks);
|
|
5765
|
+
const cell = { text, colSpan, rowSpan, colAddr, rowAddr };
|
|
5606
5766
|
if (hasStructure && blocks.length > 0) cell.blocks = blocks;
|
|
5607
5767
|
if (isHeader) cell.isHeader = true;
|
|
5608
5768
|
return cell;
|
|
5609
5769
|
}
|
|
5610
5770
|
function arrangeCells(rows, cols, cells) {
|
|
5611
5771
|
const grid = Array.from({ length: rows }, () => Array(cols).fill(null));
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
for (
|
|
5615
|
-
|
|
5616
|
-
const
|
|
5617
|
-
if (r >= rows || c >= cols) continue;
|
|
5772
|
+
let cellIdx = 0;
|
|
5773
|
+
for (let r = 0; r < rows && cellIdx < cells.length; r++) {
|
|
5774
|
+
for (let c = 0; c < cols && cellIdx < cells.length; c++) {
|
|
5775
|
+
if (grid[r][c] !== null) continue;
|
|
5776
|
+
const cell = cells[cellIdx++];
|
|
5618
5777
|
grid[r][c] = cell;
|
|
5619
5778
|
for (let dr = 0; dr < cell.rowSpan; dr++) {
|
|
5620
5779
|
for (let dc = 0; dc < cell.colSpan; dc++) {
|
|
@@ -5624,22 +5783,6 @@ function arrangeCells(rows, cols, cells) {
|
|
|
5624
5783
|
}
|
|
5625
5784
|
}
|
|
5626
5785
|
}
|
|
5627
|
-
} else {
|
|
5628
|
-
let cellIdx = 0;
|
|
5629
|
-
for (let r = 0; r < rows && cellIdx < cells.length; r++) {
|
|
5630
|
-
for (let c = 0; c < cols && cellIdx < cells.length; c++) {
|
|
5631
|
-
if (grid[r][c] !== null) continue;
|
|
5632
|
-
const cell = cells[cellIdx++];
|
|
5633
|
-
grid[r][c] = cell;
|
|
5634
|
-
for (let dr = 0; dr < cell.rowSpan; dr++) {
|
|
5635
|
-
for (let dc = 0; dc < cell.colSpan; dc++) {
|
|
5636
|
-
if (dr === 0 && dc === 0) continue;
|
|
5637
|
-
if (r + dr < rows && c + dc < cols)
|
|
5638
|
-
grid[r + dr][c + dc] = { text: "", colSpan: 1, rowSpan: 1 };
|
|
5639
|
-
}
|
|
5640
|
-
}
|
|
5641
|
-
}
|
|
5642
|
-
}
|
|
5643
5786
|
}
|
|
5644
5787
|
return grid.map((row) => row.map((c) => c || { text: "", colSpan: 1, rowSpan: 1 }));
|
|
5645
5788
|
}
|
|
@@ -5893,7 +6036,7 @@ function parseHwp5Document(buffer, options) {
|
|
|
5893
6036
|
}
|
|
5894
6037
|
const outline = flatBlocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
|
|
5895
6038
|
let markdown = blocksToMarkdown(flatBlocks);
|
|
5896
|
-
if (options?.inlineImages && images.length > 0) {
|
|
6039
|
+
if (options?.inlineImages && options.images !== false && images.length > 0) {
|
|
5897
6040
|
try {
|
|
5898
6041
|
markdown = inlineImagesIntoMarkdown(markdown, images, { compress: true });
|
|
5899
6042
|
} catch (inlineErr) {
|
|
@@ -5974,6 +6117,11 @@ function detectHwp5Headings(blocks, docInfo) {
|
|
|
5974
6117
|
}
|
|
5975
6118
|
}
|
|
5976
6119
|
}
|
|
6120
|
+
var VT_I2 = 2;
|
|
6121
|
+
var VT_LPSTR = 30;
|
|
6122
|
+
var VT_LPWSTR = 31;
|
|
6123
|
+
var VT_FILETIME = 64;
|
|
6124
|
+
var CODE_PAGE_LABELS = { 949: "euc-kr", 932: "shift_jis", 936: "gbk", 950: "big5", 65001: "utf-8" };
|
|
5977
6125
|
function extractHwp5Metadata(cfb, metadata) {
|
|
5978
6126
|
try {
|
|
5979
6127
|
const summaryEntry = CFB.find(cfb, "/HwpSummaryInformation") || CFB.find(cfb, "/SummaryInformation");
|
|
@@ -5986,26 +6134,60 @@ function extractHwp5Metadata(cfb, metadata) {
|
|
|
5986
6134
|
if (setOffset >= data.length - 8) return;
|
|
5987
6135
|
const numProps = data.readUInt32LE(setOffset + 4);
|
|
5988
6136
|
if (numProps === 0 || numProps > 100) return;
|
|
6137
|
+
const props = /* @__PURE__ */ new Map();
|
|
5989
6138
|
for (let i = 0; i < numProps; i++) {
|
|
5990
6139
|
const entryOffset = setOffset + 8 + i * 8;
|
|
5991
6140
|
if (entryOffset + 8 > data.length) break;
|
|
5992
|
-
const propId = data.readUInt32LE(entryOffset);
|
|
5993
6141
|
const propOffset = setOffset + data.readUInt32LE(entryOffset + 4);
|
|
5994
|
-
if (propOffset + 8
|
|
5995
|
-
if (propId !== 2 && propId !== 4 && propId !== 6) continue;
|
|
5996
|
-
const propType = data.readUInt32LE(propOffset);
|
|
5997
|
-
if (propType !== 30) continue;
|
|
5998
|
-
const strLen = data.readUInt32LE(propOffset + 4);
|
|
5999
|
-
if (strLen === 0 || strLen > 1e4 || propOffset + 8 + strLen > data.length) continue;
|
|
6000
|
-
const str = data.subarray(propOffset + 8, propOffset + 8 + strLen).toString("utf8").replace(/\0+$/, "").trim();
|
|
6001
|
-
if (!str) continue;
|
|
6002
|
-
if (propId === 2) metadata.title = str;
|
|
6003
|
-
else if (propId === 4) metadata.author = str;
|
|
6004
|
-
else if (propId === 6) metadata.description = str;
|
|
6142
|
+
if (propOffset + 8 <= data.length) props.set(data.readUInt32LE(entryOffset), propOffset);
|
|
6005
6143
|
}
|
|
6144
|
+
const cpAt = props.get(1);
|
|
6145
|
+
const codePage = cpAt !== void 0 && data.readUInt32LE(cpAt) === VT_I2 ? data.readUInt16LE(cpAt + 4) : 0;
|
|
6146
|
+
const text = (id) => {
|
|
6147
|
+
const at = props.get(id);
|
|
6148
|
+
return at === void 0 ? void 0 : readPropString(data, at, codePage);
|
|
6149
|
+
};
|
|
6150
|
+
const time = (id) => {
|
|
6151
|
+
const at = props.get(id);
|
|
6152
|
+
return at === void 0 ? void 0 : readPropFileTime(data, at);
|
|
6153
|
+
};
|
|
6154
|
+
const title = text(2), author = text(4), description = text(6) || text(3);
|
|
6155
|
+
if (title) metadata.title = title;
|
|
6156
|
+
if (author) metadata.author = author;
|
|
6157
|
+
if (description) metadata.description = description;
|
|
6158
|
+
const keywords = text(5)?.split(/[,;]/).map((k) => k.trim()).filter(Boolean);
|
|
6159
|
+
if (keywords?.length) metadata.keywords = keywords;
|
|
6160
|
+
const createdAt = time(12), modifiedAt = time(13);
|
|
6161
|
+
if (createdAt) metadata.createdAt = createdAt;
|
|
6162
|
+
if (modifiedAt) metadata.modifiedAt = modifiedAt;
|
|
6006
6163
|
} catch {
|
|
6007
6164
|
}
|
|
6008
6165
|
}
|
|
6166
|
+
function readPropString(data, at, codePage) {
|
|
6167
|
+
const type = data.readUInt32LE(at);
|
|
6168
|
+
const unit = type === VT_LPWSTR ? 2 : type === VT_LPSTR ? 1 : 0;
|
|
6169
|
+
const count = data.readUInt32LE(at + 4);
|
|
6170
|
+
if (!unit || count === 0 || count > 1e4 || at + 8 + count * unit > data.length) return void 0;
|
|
6171
|
+
const bytes = data.subarray(at + 8, at + 8 + count * unit);
|
|
6172
|
+
let s;
|
|
6173
|
+
if (unit === 2 || codePage === 1200) s = bytes.toString("utf16le");
|
|
6174
|
+
else {
|
|
6175
|
+
const label = CODE_PAGE_LABELS[codePage] ?? (codePage >= 1250 && codePage <= 1258 ? `windows-${codePage}` : "utf-8");
|
|
6176
|
+
try {
|
|
6177
|
+
s = new TextDecoder(label).decode(bytes);
|
|
6178
|
+
} catch {
|
|
6179
|
+
s = bytes.toString("utf8");
|
|
6180
|
+
}
|
|
6181
|
+
}
|
|
6182
|
+
const nul = s.indexOf("\0");
|
|
6183
|
+
return (nul >= 0 ? s.slice(0, nul) : s).trim() || void 0;
|
|
6184
|
+
}
|
|
6185
|
+
function readPropFileTime(data, at) {
|
|
6186
|
+
if (data.readUInt32LE(at) !== VT_FILETIME || at + 12 > data.length) return void 0;
|
|
6187
|
+
const ticks = data.readBigUInt64LE(at + 4);
|
|
6188
|
+
if (ticks === 0n) return void 0;
|
|
6189
|
+
return new Date((Number(ticks / 10000000n) - 11644473600) * 1e3).toISOString().replace(".000Z", "Z");
|
|
6190
|
+
}
|
|
6009
6191
|
function extractHwp5MetadataOnly(buffer) {
|
|
6010
6192
|
const cfb = CFB.parse(buffer);
|
|
6011
6193
|
const headerEntry = CFB.find(cfb, "/FileHeader");
|
|
@@ -7080,16 +7262,25 @@ export {
|
|
|
7080
7262
|
TAG_CTRL_HEADER,
|
|
7081
7263
|
TAG_LIST_HEADER,
|
|
7082
7264
|
TAG_TABLE,
|
|
7265
|
+
TAG_CTRL_DATA,
|
|
7083
7266
|
FLAG_COMPRESSED,
|
|
7084
7267
|
FLAG_ENCRYPTED,
|
|
7085
7268
|
FLAG_DISTRIBUTION,
|
|
7086
7269
|
FLAG_DRM,
|
|
7270
|
+
readRecords,
|
|
7087
7271
|
decompressStream,
|
|
7088
7272
|
parseFileHeader,
|
|
7089
7273
|
createParaTextState,
|
|
7090
7274
|
isExtendedOnlyCtrlChar,
|
|
7091
7275
|
appendParaText,
|
|
7092
7276
|
detectImageMime,
|
|
7277
|
+
formatNumber,
|
|
7278
|
+
hwpEquationToLatex,
|
|
7279
|
+
INLINE_TABLE_MARK,
|
|
7280
|
+
emitParagraphBlocks,
|
|
7281
|
+
blocksPlainText,
|
|
7282
|
+
cellTextFromBlocks,
|
|
7283
|
+
buildAddressedTable,
|
|
7093
7284
|
parseHwp5Document,
|
|
7094
7285
|
extractHwp5MetadataOnly,
|
|
7095
7286
|
charWidthEm1000,
|
|
@@ -7119,4 +7310,4 @@ export {
|
|
|
7119
7310
|
cropRect,
|
|
7120
7311
|
extractRenderedRegions
|
|
7121
7312
|
};
|
|
7122
|
-
//# sourceMappingURL=chunk-
|
|
7313
|
+
//# sourceMappingURL=chunk-D4U2TXDC.js.map
|