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
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
CONT_PARTS,
|
|
6
6
|
EMPTY_PARTS,
|
|
7
7
|
FILLER_CELLS,
|
|
8
|
+
FRAME_READING_UNITS,
|
|
9
|
+
FRAME_TITLE_BLOCKS,
|
|
8
10
|
IMAGE_CELLS,
|
|
9
11
|
NO_EDGES,
|
|
10
12
|
PART_COLXS,
|
|
@@ -15,6 +17,7 @@ import {
|
|
|
15
17
|
TOC_BLOCKS,
|
|
16
18
|
WrapLexicon,
|
|
17
19
|
collapseEvenSpacing,
|
|
20
|
+
computeBBox,
|
|
18
21
|
computeMedianFontSizeFromFreq,
|
|
19
22
|
detectDocumentStyleHeadings,
|
|
20
23
|
detectHeadings,
|
|
@@ -22,33 +25,39 @@ import {
|
|
|
22
25
|
detectMarkerHeadings,
|
|
23
26
|
detectPageLeadHeadings,
|
|
24
27
|
detectRepeatedPageLabels,
|
|
28
|
+
detectRightArrowRegions,
|
|
25
29
|
detectSiblingStyleHeadings,
|
|
26
30
|
detectTableCaptions,
|
|
27
31
|
detectTypographyHeadings,
|
|
32
|
+
dominantStyle,
|
|
28
33
|
extractImageRegions,
|
|
29
34
|
extractLines,
|
|
30
35
|
extractPageBlocksWithLines,
|
|
31
36
|
filterHiddenText,
|
|
37
|
+
groupByY,
|
|
32
38
|
joinCellEdges,
|
|
33
39
|
joinPageBreakWraps,
|
|
34
40
|
latinSoftWrap,
|
|
41
|
+
mergeLineSimple,
|
|
35
42
|
mergeStackedHeadingLines,
|
|
36
43
|
normalizeItems,
|
|
44
|
+
recordFrameReadingUnit,
|
|
37
45
|
refineDocumentStyleHeadings,
|
|
38
46
|
removeHeaderFooterBlocks,
|
|
39
47
|
removeSideTabs,
|
|
48
|
+
restoreImageBullets,
|
|
40
49
|
startsNewItem,
|
|
41
50
|
trimTrailingEmptyTableCols,
|
|
42
51
|
wrapJoiner
|
|
43
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-KUUSP6OS.js";
|
|
44
53
|
import {
|
|
45
54
|
ocrModelsCached
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import "./chunk-
|
|
48
|
-
import "./chunk-
|
|
55
|
+
} from "./chunk-Z2PPDQK2.js";
|
|
56
|
+
import "./chunk-HRJJDNRD.js";
|
|
57
|
+
import "./chunk-QVCHFCT2.js";
|
|
49
58
|
import {
|
|
50
59
|
blocksToPages
|
|
51
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-4IBY5LTJ.js";
|
|
52
61
|
import {
|
|
53
62
|
encodePng
|
|
54
63
|
} from "./chunk-7FCNOKOR.js";
|
|
@@ -58,7 +67,7 @@ import {
|
|
|
58
67
|
escapeLiteralTags,
|
|
59
68
|
stripScriptTags,
|
|
60
69
|
unframeLayoutTables
|
|
61
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-TMJVD6FW.js";
|
|
62
71
|
import {
|
|
63
72
|
hasRequestedPagesAfter,
|
|
64
73
|
parsePageRange
|
|
@@ -67,11 +76,11 @@ import {
|
|
|
67
76
|
WINGDINGS,
|
|
68
77
|
blocksToMarkdown,
|
|
69
78
|
escapeLiteralDollar
|
|
70
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-VTVK2JMI.js";
|
|
71
80
|
import {
|
|
72
81
|
KordocError,
|
|
73
82
|
sanitizeHref
|
|
74
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-F5YVCJVF.js";
|
|
75
84
|
|
|
76
85
|
// src/pdf/ocr-region-merge.ts
|
|
77
86
|
function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
|
|
@@ -84,8 +93,10 @@ function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
|
|
|
84
93
|
const overlapH = Math.max(0, Math.min(b.y + b.height, region.y2) - Math.max(b.y, region.y1));
|
|
85
94
|
return overlapW * overlapH >= b.width * b.height * 0.8;
|
|
86
95
|
});
|
|
96
|
+
const labels = candidates.filter((b) => b.type === "paragraph" && b.bbox.height <= 24 && (b.text?.match(/[\p{L}\p{N}]/gu)?.length ?? 0) >= 2);
|
|
97
|
+
const axisFragments = rotatedAxisFragments(candidates);
|
|
87
98
|
const accepted = candidates.filter((b) => {
|
|
88
|
-
if (b.type === "paragraph") return (b.text?.match(/[\p{L}\p{N}]/gu)?.length ?? 0) >= 2;
|
|
99
|
+
if (b.type === "paragraph") return (b.text?.match(/[\p{L}\p{N}]/gu)?.length ?? 0) >= 2 || !axisFragments.has(b) && supportedDiagramLabel(b, labels, region);
|
|
89
100
|
const t = b.table;
|
|
90
101
|
if (b.type !== "table" || !t) return false;
|
|
91
102
|
if (t.rows === 1 && t.cols === 1) {
|
|
@@ -96,29 +107,89 @@ function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
|
|
|
96
107
|
return t.rows >= 2 && t.cols >= 2 && headerLabels >= t.cols * 0.75 && t.cells.slice(1).some((row) => row.filter((c) => c.text.trim()).length >= 2);
|
|
97
108
|
});
|
|
98
109
|
const selected = candidates.flatMap((b) => accepted.includes(b) ? [b] : b.type === "table" && b.table ? rowParagraphs(b).filter((p) => /[\p{L}\p{N}]{2}/u.test(p.text ?? "")) : []);
|
|
99
|
-
|
|
110
|
+
const hasOriginal = (block) => blocks.some((existing) => {
|
|
100
111
|
const b = block.bbox;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
});
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
if (existing.pageNumber !== page || !existing.bbox || existing.type === "image") return false;
|
|
113
|
+
const e = existing.bbox;
|
|
114
|
+
const x = Math.max(0, Math.min(e.x + e.width, b.x + b.width) - Math.max(e.x, b.x));
|
|
115
|
+
const y = Math.max(0, Math.min(e.y + e.height, b.y + b.height) - Math.max(e.y, b.y));
|
|
116
|
+
return x * y > b.width * b.height * 0.2;
|
|
117
|
+
});
|
|
118
|
+
const selectedSet = new Set(selected), seen = /* @__PURE__ */ new Set();
|
|
119
|
+
for (const block of selected) {
|
|
120
|
+
if (seen.has(block)) continue;
|
|
121
|
+
const frame = FRAME_READING_UNITS.get(block);
|
|
122
|
+
const source = frame?.blocks.every((member) => selectedSet.has(member)) ? frame.blocks : [block];
|
|
123
|
+
source.forEach((member) => seen.add(member));
|
|
124
|
+
const available = source.filter((member) => !hasOriginal(member));
|
|
125
|
+
const units = frame && available.length === source.length && source === frame.blocks ? [{ blocks: available, bbox: frame.bbox, atomic: true }] : available.map((member) => ({ blocks: [member], bbox: member.bbox, atomic: false }));
|
|
126
|
+
for (const unit of units) {
|
|
127
|
+
const b = unit.bbox;
|
|
128
|
+
const index = blocks.findIndex((existing) => {
|
|
129
|
+
const e = FRAME_READING_UNITS.get(existing)?.bbox ?? existing.bbox;
|
|
130
|
+
if (existing.pageNumber !== page || !e) return false;
|
|
131
|
+
const beside = e.y < region.y2 && e.y + e.height > region.y1 && e.x >= region.x2 - 1;
|
|
132
|
+
return e.y < b.y || beside;
|
|
133
|
+
});
|
|
134
|
+
const placed = unit.blocks.map((member) => member.type === "paragraph" ? { ...member, style: void 0 } : member);
|
|
135
|
+
if (unit.atomic) recordFrameReadingUnit(placed, unit.bbox);
|
|
136
|
+
blocks.splice(index < 0 ? blocks.length : index, 0, ...placed);
|
|
137
|
+
added += placed.length;
|
|
138
|
+
}
|
|
118
139
|
}
|
|
119
140
|
}
|
|
120
141
|
return added;
|
|
121
142
|
}
|
|
143
|
+
function supportedDiagramLabel(block, labels, region) {
|
|
144
|
+
const b = block.bbox, text = block.text?.trim() ?? "";
|
|
145
|
+
if (!b || !/^[\p{L}\p{N}]$/u.test(text) || b.height < 4 || b.width < 1 || b.width > b.height * 2 || b.x < region.x1 || b.y < region.y1 || b.x + b.width > region.x2 || b.y + b.height > region.y2 || b.width * b.height > (region.x2 - region.x1) * (region.y2 - region.y1) * 5e-3 || labels.length < 3 || !labels.some((l) => /\p{L}{3}/u.test(l.text ?? "")) || labels.filter((l) => !/\p{L}/u.test(l.text ?? "") && (l.text?.match(/\p{N}/gu)?.length ?? 0) >= 2).length < 2) return false;
|
|
146
|
+
let above = false, below = false;
|
|
147
|
+
for (const label of labels) {
|
|
148
|
+
const a = label.bbox, em = Math.max(b.height, a.height);
|
|
149
|
+
if (b.x + b.width < a.x - em * 2 || b.x > a.x + a.width + em * 2) continue;
|
|
150
|
+
const upperGap = a.y - (b.y + b.height), lowerGap = b.y - (a.y + a.height);
|
|
151
|
+
if (upperGap >= 0 && upperGap <= em * 4) above = true;
|
|
152
|
+
if (lowerGap >= 0 && lowerGap <= em * 4) below = true;
|
|
153
|
+
}
|
|
154
|
+
return above && below;
|
|
155
|
+
}
|
|
156
|
+
function rotatedAxisFragments(candidates) {
|
|
157
|
+
const paragraphs = candidates.filter((b) => b.type === "paragraph" && b.bbox.height <= 24);
|
|
158
|
+
const axes = [];
|
|
159
|
+
for (const block of paragraphs) {
|
|
160
|
+
const b = block.bbox, text = block.text?.trim() ?? "";
|
|
161
|
+
if (!/^[\d\s.,%+−-]+$/u.test(text) || !/\d/u.test(text) || b.width > b.height * 6) continue;
|
|
162
|
+
const axis = axes.find((a) => Math.abs(a[0].bbox.x + a[0].bbox.width - b.x - b.width) <= Math.max(a[0].bbox.height, b.height) * 0.5);
|
|
163
|
+
if (axis) axis.push(block);
|
|
164
|
+
else axes.push([block]);
|
|
165
|
+
}
|
|
166
|
+
const fragments = /* @__PURE__ */ new Set();
|
|
167
|
+
const aligned = (a, b) => {
|
|
168
|
+
const x = a.bbox, y = b.bbox, tolerance = Math.max(x.height, y.height) * 0.5;
|
|
169
|
+
return Math.abs(x.x - y.x) <= tolerance || Math.abs(x.x + x.width - y.x - y.width) <= tolerance;
|
|
170
|
+
};
|
|
171
|
+
for (const axis of axes) {
|
|
172
|
+
if (axis.length < 3) continue;
|
|
173
|
+
const bottom = Math.min(...axis.map((a) => a.bbox.y)), top = Math.max(...axis.map((a) => a.bbox.y + a.bbox.height));
|
|
174
|
+
const em = Math.max(...axis.map((a) => a.bbox.height)), right = axis[0].bbox.x + axis[0].bbox.width;
|
|
175
|
+
if (top - bottom < em * 6) continue;
|
|
176
|
+
const left = paragraphs.filter((block) => {
|
|
177
|
+
const b = block.bbox, text = block.text?.trim() ?? "";
|
|
178
|
+
return /\p{Script=Latin}/u.test(text) && (text.match(/[\p{L}\p{N}]/gu)?.length ?? 0) <= 3 && b.width <= b.height * 3 && b.x + b.width >= right - em * 6 && b.x + b.width <= right - Math.max(em, b.height) && b.y >= bottom && b.y + b.height <= top;
|
|
179
|
+
});
|
|
180
|
+
const stack = left.filter((a) => left.some((b) => {
|
|
181
|
+
if (a === b || !aligned(a, b)) return false;
|
|
182
|
+
const x = a.bbox, y = b.bbox, gap = Math.max(x.y, y.y) - Math.min(x.y + x.height, y.y + y.height);
|
|
183
|
+
return gap >= -Math.min(x.height, y.height) * 0.5 && gap <= Math.max(x.height, y.height);
|
|
184
|
+
}));
|
|
185
|
+
if (stack.length < 2) continue;
|
|
186
|
+
for (const block of paragraphs) {
|
|
187
|
+
const b = block.bbox;
|
|
188
|
+
if (b.y >= bottom && b.y + b.height <= top && b.x + b.width >= right - em * 6 && b.x + b.width <= right - Math.max(em, b.height) && /^[\p{L}\p{N}]$/u.test(block.text?.trim() ?? "") && stack.some((s) => aligned(s, block))) fragments.add(block);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return fragments;
|
|
192
|
+
}
|
|
122
193
|
function rowParagraphs(block) {
|
|
123
194
|
const t = block.table, b = block.bbox;
|
|
124
195
|
const h = b.height / t.rows;
|
|
@@ -924,6 +995,17 @@ var CARRIED_MIN_COL_W = 4;
|
|
|
924
995
|
var LABEL_ROOM = 1.5;
|
|
925
996
|
var HANGING_MIN = 0.5;
|
|
926
997
|
var HANGING_TOL = 1;
|
|
998
|
+
var KO_ITEMS = "\uAC00\uB098\uB2E4\uB77C\uB9C8\uBC14\uC0AC\uC544\uC790\uCC28\uCE74\uD0C0\uD30C\uD558\uAC70\uB108\uB354\uB7EC\uBA38\uBC84\uC11C\uC5B4\uC800\uCC98\uCEE4\uD130\uD37C\uD5C8\uACE0\uB178\uB3C4\uB85C\uBAA8\uBCF4\uC18C\uC624\uC870\uCD08\uCF54\uD1A0\uD3EC\uD638\uAD6C\uB204\uB450\uB8E8\uBB34\uBD80\uC218\uC6B0\uC8FC\uCD94\uCFE0\uD22C\uD478\uD6C4";
|
|
999
|
+
var ITEM_MARK = /^\s*(?:([가-힣])\.|(\d{1,3})[.)]|\(([가-힣\d]{1,3})\))(?=\s)/;
|
|
1000
|
+
function nextItemHead(prev, next) {
|
|
1001
|
+
const a = ITEM_MARK.exec(prev), b = ITEM_MARK.exec(next);
|
|
1002
|
+
if (!a || !b) return false;
|
|
1003
|
+
const succ = (x, y) => /^\d+$/.test(x) ? /^\d+$/.test(y) && Number(y) === Number(x) + 1 : KO_ITEMS.indexOf(x) >= 0 && KO_ITEMS.indexOf(y) === KO_ITEMS.indexOf(x) + 1;
|
|
1004
|
+
if (a[1] && b[1]) return succ(a[1], b[1]);
|
|
1005
|
+
if (a[2] && b[2]) return succ(a[2], b[2]) && prev.trimStart()[a[2].length] === next.trimStart()[b[2].length];
|
|
1006
|
+
if (a[3] && b[3]) return succ(a[3], b[3]);
|
|
1007
|
+
return false;
|
|
1008
|
+
}
|
|
927
1009
|
function continuesAcross(u, d, x1, x2) {
|
|
928
1010
|
const U = CELL_LINES.get(u), D = CELL_LINES.get(d);
|
|
929
1011
|
if (!U?.length || !D?.length) return false;
|
|
@@ -1055,6 +1137,8 @@ function mergeSplitRow(table, owner, first, colXs, textOnly = false, cut = NO_CU
|
|
|
1055
1137
|
if (!carriedSplit) {
|
|
1056
1138
|
const norm = (c) => flowText(c.text).replace(/\s+/g, "");
|
|
1057
1139
|
if (pairs.some(([u, d]) => hasContent(d.cell) && norm(cell(d)) !== norm(cell(u)) && lineEnded(cell(u), colXs[u.c], colXs[u.c + u.cs], cell(d)))) return false;
|
|
1140
|
+
const oneLine = (c) => CELL_LINES.get(c)?.length === 1;
|
|
1141
|
+
if (pairs.some(([u, d]) => nextItemHead(cell(u).text, cell(d).text)) && pairs.some(([u, d]) => hasContent(u.cell) && hasContent(d.cell) && oneLine(cell(u)) && oneLine(cell(d)) && norm(cell(u)) !== norm(cell(d)))) return false;
|
|
1058
1142
|
const flows = ([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs]) || clauseContinues(cell(u), cell(d));
|
|
1059
1143
|
if (!(cut.open && !newCell)) {
|
|
1060
1144
|
if (pairs.some((p) => p[1].rs > 1 && !flows(p))) return false;
|
|
@@ -1115,7 +1199,7 @@ function sameHeadShape(a, b) {
|
|
|
1115
1199
|
let tall = false;
|
|
1116
1200
|
for (let c = 0; c < a.length; c++) {
|
|
1117
1201
|
if (a[c].colSpan !== b[c].colSpan || a[c].rowSpan !== b[c].rowSpan) return false;
|
|
1118
|
-
if (a[c].rowSpan >= 2 && a[c].text.trim()) tall = true;
|
|
1202
|
+
if (a[c].rowSpan >= 2 && a[c].text.trim() && b[c].text.trim()) tall = true;
|
|
1119
1203
|
}
|
|
1120
1204
|
return tall;
|
|
1121
1205
|
}
|
|
@@ -1152,9 +1236,10 @@ function mergeCrossPageTables(blocks, pageHeights, lex) {
|
|
|
1152
1236
|
if (px && cx && !shiftedSame(px, cx, !CLIP_TABLES.has(prev.table) && !CLIP_TABLES.has(curr.table))) continue;
|
|
1153
1237
|
if (!rowTextsEqual(prev.table.cells[0], curr.table.cells[0]) && sameHeadShape(prev.table.cells[0], curr.table.cells[0])) continue;
|
|
1154
1238
|
let currCells = curr.table.cells;
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1239
|
+
const headRows = repeatedHeaderRows(prev.table, curr.table);
|
|
1240
|
+
if (headRows < 0) continue;
|
|
1241
|
+
if (headRows) currCells = currCells.slice(headRows);
|
|
1242
|
+
if (currCells.length) continueRowSpans(prev.table.cells, currCells);
|
|
1158
1243
|
if (currCells.length === 0) {
|
|
1159
1244
|
blocks.splice(j, 1);
|
|
1160
1245
|
continue;
|
|
@@ -1356,6 +1441,45 @@ function chainHead(blocks, i, pageHeights) {
|
|
|
1356
1441
|
}
|
|
1357
1442
|
return k;
|
|
1358
1443
|
}
|
|
1444
|
+
var ROW_CONTINUATIONS = /* @__PURE__ */ new WeakMap();
|
|
1445
|
+
function continueRowSpans(prevCells, currCells) {
|
|
1446
|
+
const first = currCells[0];
|
|
1447
|
+
const last = prevCells.length;
|
|
1448
|
+
for (let c = 0; c < first.length; c++) {
|
|
1449
|
+
const cell = first[c];
|
|
1450
|
+
if (hasContent(cell) || (cell.rowSpan || 1) < 2) continue;
|
|
1451
|
+
let anchor;
|
|
1452
|
+
for (let r = last - 1; r >= 0 && !anchor; r--) {
|
|
1453
|
+
const a = prevCells[r]?.[c];
|
|
1454
|
+
if (a && r + (a.rowSpan || 1) === last && (a.colSpan || 1) === (cell.colSpan || 1) && (hasContent(a) || a.rowSpan >= 2)) anchor = a;
|
|
1455
|
+
}
|
|
1456
|
+
if (!anchor) continue;
|
|
1457
|
+
if (!hasContent(anchor)) {
|
|
1458
|
+
ROW_CONTINUATIONS.set(anchor, cell);
|
|
1459
|
+
continue;
|
|
1460
|
+
}
|
|
1461
|
+
for (let part = cell; part; ) {
|
|
1462
|
+
const next = ROW_CONTINUATIONS.get(part);
|
|
1463
|
+
anchor.rowSpan = (anchor.rowSpan || 1) + part.rowSpan;
|
|
1464
|
+
part.rowSpan = 1;
|
|
1465
|
+
part.colSpan = 1;
|
|
1466
|
+
ROW_CONTINUATIONS.delete(part);
|
|
1467
|
+
part = next;
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
function repeatedHeaderRows(prev, curr) {
|
|
1472
|
+
if (!rowTextsEqual(prev.cells[0], curr.cells[0])) return 0;
|
|
1473
|
+
const pa = anchorsOf(prev), ca = anchorsOf(curr);
|
|
1474
|
+
let depth = 1;
|
|
1475
|
+
for (let r = 0; r < depth && r < prev.rows; r++) {
|
|
1476
|
+
for (const a of pa) if (a.r === r) depth = Math.max(depth, r + a.rs);
|
|
1477
|
+
}
|
|
1478
|
+
if (depth >= curr.rows || depth > prev.rows) return -1;
|
|
1479
|
+
const p = pa.filter((a) => a.r < depth), d = ca.filter((a) => a.r < depth);
|
|
1480
|
+
const norm = (text) => flowText(text).replace(/\s+/g, "");
|
|
1481
|
+
return p.length === d.length && p.every((a, i) => a.r === d[i].r && a.c === d[i].c && a.rs === d[i].rs && a.cs === d[i].cs && norm(a.cell.text) === norm(d[i].cell.text)) ? depth : -1;
|
|
1482
|
+
}
|
|
1359
1483
|
function rowTextsEqual(a, b) {
|
|
1360
1484
|
if (a.length !== b.length) return false;
|
|
1361
1485
|
const norm = (t) => flowText(t).replace(/\s+/g, "");
|
|
@@ -1450,6 +1574,34 @@ function fillNestedContinuation(blocks, at) {
|
|
|
1450
1574
|
blocks.splice(at, 1);
|
|
1451
1575
|
}
|
|
1452
1576
|
|
|
1577
|
+
// src/pdf/selection-context.ts
|
|
1578
|
+
function selectionContextPages(selected, pageCount) {
|
|
1579
|
+
const out = /* @__PURE__ */ new Set();
|
|
1580
|
+
for (const page of selected) {
|
|
1581
|
+
for (let distance = 1; distance <= 4; distance++) {
|
|
1582
|
+
for (const neighbor of [page - distance, page + distance]) {
|
|
1583
|
+
if (neighbor < 1 || neighbor > pageCount || selected.has(neighbor)) continue;
|
|
1584
|
+
out.add(neighbor);
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
return [...out].sort((a, b) => a - b);
|
|
1589
|
+
}
|
|
1590
|
+
function marginContextBlocks(raw, page, view) {
|
|
1591
|
+
const [x1, y1, x2, y2] = view;
|
|
1592
|
+
const width = x2 - x1, height = y2 - y1;
|
|
1593
|
+
const items = filterHiddenText(normalizeItems(raw), width, height, x1, y1).visible;
|
|
1594
|
+
for (const item of items) {
|
|
1595
|
+
item.x -= x1;
|
|
1596
|
+
item.y -= y1;
|
|
1597
|
+
}
|
|
1598
|
+
return groupByY(items).flatMap((line) => {
|
|
1599
|
+
const bbox = computeBBox(line, page);
|
|
1600
|
+
if (bbox.y + bbox.height < height * 0.88 && bbox.y > height * 0.12) return [];
|
|
1601
|
+
return [{ type: "paragraph", text: mergeLineSimple(line), pageNumber: page, bbox, style: dominantStyle(line) }];
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1453
1605
|
// src/pdf/symbol-fonts.ts
|
|
1454
1606
|
var WINANSI_REVERSE = {
|
|
1455
1607
|
8364: 128,
|
|
@@ -1757,6 +1909,9 @@ var NAMED = {
|
|
|
1757
1909
|
quotedblright: "\u201D",
|
|
1758
1910
|
quotesingle: "'",
|
|
1759
1911
|
quotedbl: '"',
|
|
1912
|
+
bullet: "\u2022",
|
|
1913
|
+
openbullet: "\u25E6",
|
|
1914
|
+
whitebullet: "\u25E6",
|
|
1760
1915
|
question: "?",
|
|
1761
1916
|
exclam: "!",
|
|
1762
1917
|
percent: "%",
|
|
@@ -1773,7 +1928,9 @@ function glyphNameText(name) {
|
|
|
1773
1928
|
let out = "";
|
|
1774
1929
|
for (const part of base.split("_")) {
|
|
1775
1930
|
const uni = /^uni([0-9A-F]{4})$/.exec(part) ?? /^u([0-9A-F]{4,6})$/.exec(part);
|
|
1776
|
-
const
|
|
1931
|
+
const code = uni ? parseInt(uni[1], 16) : void 0;
|
|
1932
|
+
if (code !== void 0 && (code > 1114111 || code >= 55296 && code <= 57343)) return void 0;
|
|
1933
|
+
const ch = /^[A-Za-z]$/.test(part) ? part : NAMED[part] ?? (code !== void 0 ? String.fromCodePoint(code) : void 0);
|
|
1777
1934
|
if (ch === void 0) return void 0;
|
|
1778
1935
|
out += ch;
|
|
1779
1936
|
}
|
|
@@ -2459,6 +2616,35 @@ function demoteNonHeadingRoles(blocks, pageHeights, faceNames) {
|
|
|
2459
2616
|
}
|
|
2460
2617
|
}
|
|
2461
2618
|
}
|
|
2619
|
+
const citedProse = /* @__PURE__ */ new Set();
|
|
2620
|
+
const numberedProse = /* @__PURE__ */ new Set();
|
|
2621
|
+
for (const page of byPage.values()) {
|
|
2622
|
+
const numbered = page.filter((b) => (b.type === "heading" || b.type === "paragraph") && /^[①-⑮]\s*/.test(b.text?.trim() ?? "") && b.bbox && b.style?.fontName && b.style.fontSize && !/Bold|Black|Heavy|Semibold/i.test(faceNames?.get(b.style.fontName) ?? ""));
|
|
2623
|
+
let chain = [];
|
|
2624
|
+
const finish = () => {
|
|
2625
|
+
if (chain.length < 3 || !chain.some((b) => (b.text?.length ?? 0) >= 40 && b.bbox.height >= b.style.fontSize * 2.4)) return;
|
|
2626
|
+
for (const b of chain) numberedProse.add(b);
|
|
2627
|
+
const first = chain[0], size = first.style.fontSize;
|
|
2628
|
+
for (const b of page) if (/^[○●•◦]\s/.test(b.text?.trim() ?? "") && b.style?.fontName === first.style?.fontName && b.style?.fontSize === size && b.bbox && Math.abs(b.bbox.x - first.bbox.x) <= size * 0.5 && (b.text?.length ?? 0) >= 15) numberedProse.add(b);
|
|
2629
|
+
};
|
|
2630
|
+
for (const b of numbered) {
|
|
2631
|
+
const prev = chain.at(-1), size = b.style.fontSize;
|
|
2632
|
+
if (!prev || b.text.trim().charCodeAt(0) !== prev.text.trim().charCodeAt(0) + 1 || b.style.fontName !== prev.style.fontName || size !== prev.style.fontSize || Math.abs(b.bbox.x - prev.bbox.x) > size * 0.5 || prev.bbox.y - (b.bbox.y + b.bbox.height) > size * 8) {
|
|
2633
|
+
finish();
|
|
2634
|
+
chain = [];
|
|
2635
|
+
}
|
|
2636
|
+
chain.push(b);
|
|
2637
|
+
}
|
|
2638
|
+
finish();
|
|
2639
|
+
}
|
|
2640
|
+
for (let i = 0; i + 1 < blocks.length; i++) {
|
|
2641
|
+
const prose = blocks[i], reference = blocks[i + 1];
|
|
2642
|
+
const a = prose.bbox, b = reference.bbox, size = prose.style?.fontSize ?? 0;
|
|
2643
|
+
const source = reference.text?.replace(/<[^>]+>/g, "").trim() ?? "";
|
|
2644
|
+
if (prose.type !== "heading" && prose.type !== "paragraph" && prose.type !== "list" || reference.type !== "heading" && reference.type !== "paragraph" || (prose.text?.length ?? 0) < 40 || !a || !b || size <= 0 || a.height < size * 2.4 || prose.pageNumber !== reference.pageNumber || prose.style?.fontName !== reference.style?.fontName || prose.style?.fontSize !== reference.style?.fontSize || Math.abs(a.x - b.x) > size && !(/^[○●•◦]\s/.test(prose.text ?? "") && b.x >= a.x && b.x - a.x <= size * 2) || a.y - (b.y + b.height) < 0 || a.y - (b.y + b.height) > size || !/^[((].*(?:제\s*\d+\s*조|(?:Article|Section)\s+\d+).*[))]$/i.test(source)) continue;
|
|
2645
|
+
citedProse.add(prose);
|
|
2646
|
+
citedProse.add(reference);
|
|
2647
|
+
}
|
|
2462
2648
|
for (let i = 0; i < blocks.length; i++) {
|
|
2463
2649
|
const block = blocks[i];
|
|
2464
2650
|
if (block.type !== "heading" || !block.text) continue;
|
|
@@ -2506,7 +2692,7 @@ function demoteNonHeadingRoles(blocks, pageHeights, faceNames) {
|
|
|
2506
2692
|
const byline = /Italic|Oblique/i.test(face) && !/Bold|Black|Heavy|Semibold/i.test(face) && !!bodyFace && size <= Number(bodySize) + 0.5 && blocks[i - 1]?.type === "heading" && blocks[i - 1].pageNumber === block.pageNumber;
|
|
2507
2693
|
const ocrFragment = block.style?.fontName === "ocr" && (/^[.,;:…·•-]/.test(text) || text.includes("\u2026") || (text.match(/\p{L}/gu)?.length ?? 0) < 2 || text.split(/\s+/).length > 7);
|
|
2508
2694
|
const crowdedOcr = block.style?.fontName === "ocr" && !!box && [prev, next].every((o) => o?.type === "paragraph" && o.pageNumber === block.pageNumber && o.style?.fontName === "ocr" && !!o.bbox && (o.text?.length ?? 0) >= 15 && Math.abs(o.bbox.x - box.x) <= size * 0.25 && Math.min(o.bbox.y + o.bbox.height, box.y + box.height) - Math.max(o.bbox.y, box.y) >= o.bbox.height * 0.2) && prev.bbox.y > box.y && next.bbox.y < box.y;
|
|
2509
|
-
if (ocrFragment || crowdedOcr || tocEntry || proseStyle || kicker || byline || tiny || !/\p{L}/u.test(text) && !chapterNumber || /^[a-z]/.test(text) || CAPTION.test(text) || EQUATION_NUMBER.test(block.text) || DISPLAY_MATH.test(text) || // 닫는 괄호가 여는 괄호보다 많으면 앞 줄에서 이어진 문장 조각이다 ("Fact-checking) and is used …") — "1)"·"가)" 앞머리 번호는 빼고 센다
|
|
2695
|
+
if (numberedProse.has(block) || citedProse.has(block) || ocrFragment || crowdedOcr || tocEntry || proseStyle || kicker || byline || tiny || !/\p{L}/u.test(text) && !chapterNumber || /^[a-z]/.test(text) || CAPTION.test(text) || EQUATION_NUMBER.test(block.text) || DISPLAY_MATH.test(text) || // 닫는 괄호가 여는 괄호보다 많으면 앞 줄에서 이어진 문장 조각이다 ("Fact-checking) and is used …") — "1)"·"가)" 앞머리 번호는 빼고 센다
|
|
2510
2696
|
unbalancedClose(text.replace(/^\s*[\dA-Za-z가-힣ⅰ-ⅹ]{1,3}\)\s*/, "")) || isRunningHead(block, page, pageHeights.get(block.pageNumber ?? 0))) {
|
|
2511
2697
|
block.type = "paragraph";
|
|
2512
2698
|
block.level = void 0;
|
|
@@ -2547,6 +2733,11 @@ function splitSingleCellTables(blocks) {
|
|
|
2547
2733
|
const out = [];
|
|
2548
2734
|
for (const b of blocks) {
|
|
2549
2735
|
const t = b.type === "table" ? b.table : void 0;
|
|
2736
|
+
const title = t && FRAME_TITLE_BLOCKS.get(t);
|
|
2737
|
+
if (title) {
|
|
2738
|
+
out.push({ ...title, text: `${t.cells[0][0].text.trim()} ${t.cells[0][2].text.trim()}` });
|
|
2739
|
+
continue;
|
|
2740
|
+
}
|
|
2550
2741
|
const only = t && t.rows === 1 && t.cols === 1 && t.cells[0]?.[0]?.blocks?.length === 1 ? t.cells[0][0].blocks[0] : void 0;
|
|
2551
2742
|
const squash = (s) => s.replace(/\s/g, "");
|
|
2552
2743
|
const inner = only && (!squash(t.cells[0][0].text) || only.type === "table" && squash(t.cells[0][0].text) === squash(only.table.cells.flat().map((c) => c.text).join(""))) ? only : void 0;
|
|
@@ -2556,12 +2747,16 @@ function splitSingleCellTables(blocks) {
|
|
|
2556
2747
|
continue;
|
|
2557
2748
|
}
|
|
2558
2749
|
const cell = t && t.rows === 1 && t.cols === 1 ? t.cells[0]?.[0] : void 0;
|
|
2559
|
-
if (!cell
|
|
2750
|
+
if (!cell) {
|
|
2560
2751
|
out.push(b);
|
|
2561
2752
|
continue;
|
|
2562
2753
|
}
|
|
2563
2754
|
const lines = (cell.text ?? "").split(/\n/).map((l) => l.trim()).filter(Boolean);
|
|
2564
2755
|
if (t?.caption?.trim()) out.push({ type: "paragraph", text: t.caption.trim(), pageNumber: b.pageNumber, bbox: b.bbox });
|
|
2756
|
+
if (cell.blocks?.length) {
|
|
2757
|
+
out.push(...splitSingleCellTables(cell.blocks));
|
|
2758
|
+
continue;
|
|
2759
|
+
}
|
|
2565
2760
|
for (const text of lines) out.push({ type: "paragraph", text, pageNumber: b.pageNumber, bbox: b.bbox });
|
|
2566
2761
|
}
|
|
2567
2762
|
return out;
|
|
@@ -2686,7 +2881,7 @@ function mergeLinkRuns(markdown) {
|
|
|
2686
2881
|
|
|
2687
2882
|
// src/pdf/formula-ocr.ts
|
|
2688
2883
|
async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
|
|
2689
|
-
const formulaMod = await import("./formula-
|
|
2884
|
+
const formulaMod = await import("./formula-7ZOZ5QJ6.js");
|
|
2690
2885
|
const { FormulaPipeline, ensureFormulaModels } = formulaMod;
|
|
2691
2886
|
await ensureFormulaModels((p) => {
|
|
2692
2887
|
if (p.phase === "download" && p.total) {
|
|
@@ -2909,12 +3104,29 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2909
3104
|
const uncoveredImageRegions = /* @__PURE__ */ new Map();
|
|
2910
3105
|
const largeImageRegions = /* @__PURE__ */ new Set();
|
|
2911
3106
|
const imageState = createPdfImageState();
|
|
3107
|
+
const imageBulletShapes = /* @__PURE__ */ new Map();
|
|
3108
|
+
const imageArrowDirections = /* @__PURE__ */ new Map();
|
|
2912
3109
|
const extractedImages = [];
|
|
2913
3110
|
const pageImageBlocks = /* @__PURE__ */ new Map();
|
|
2914
3111
|
const carry = {};
|
|
2915
3112
|
const vectorPageOps = /* @__PURE__ */ new Map();
|
|
2916
3113
|
const wrapLexicon = new WrapLexicon();
|
|
2917
3114
|
const noteMarks = /* @__PURE__ */ new Map();
|
|
3115
|
+
const headerContext = [];
|
|
3116
|
+
if (pageFilter && options?.removeHeaderFooter !== false && pageFilter.size < effectivePageCount) {
|
|
3117
|
+
for (const number of selectionContextPages(pageFilter, effectivePageCount)) {
|
|
3118
|
+
let contextPage;
|
|
3119
|
+
try {
|
|
3120
|
+
contextPage = await doc.getPage(number);
|
|
3121
|
+
const content = await contextPage.getTextContent();
|
|
3122
|
+
pageHeights.set(number, contextPage.view[3] - contextPage.view[1]);
|
|
3123
|
+
headerContext.push(...marginContextBlocks(content.items, number, contextPage.view));
|
|
3124
|
+
} catch {
|
|
3125
|
+
} finally {
|
|
3126
|
+
contextPage?.cleanup();
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
2918
3130
|
let parsedPages = 0;
|
|
2919
3131
|
for (let i = 1; i <= effectivePageCount; i++) {
|
|
2920
3132
|
if (pageFilter && !pageFilter.has(i)) continue;
|
|
@@ -2968,6 +3180,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2968
3180
|
} : rawOps;
|
|
2969
3181
|
remapSymbolFontItems(visible, (loadedName) => fontObj(loadedName)?.name);
|
|
2970
3182
|
remapControlGlyphs(visible, differencesOf);
|
|
3183
|
+
await restoreImageBullets(visible, page, opList.fnArray, opList.argsArray, imageBulletShapes);
|
|
2971
3184
|
const faces = /* @__PURE__ */ new Map();
|
|
2972
3185
|
for (const it of visible) {
|
|
2973
3186
|
if (!it.fontName) continue;
|
|
@@ -3014,7 +3227,8 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3014
3227
|
if (marks.length) noteMarks.set(i, { marks, seps: footnoteSeparators(extractLines(opList.fnArray, opList.argsArray).horizontals, pageW, pageH) });
|
|
3015
3228
|
const stamp = marginStamp(visible);
|
|
3016
3229
|
const flow = stamp.length ? visible.filter((it) => !stamp.includes(it)) : visible;
|
|
3017
|
-
const
|
|
3230
|
+
const rightArrows = options?.tables !== false ? await detectRightArrowRegions(page, opList.fnArray, opList.argsArray, imageArrowDirections) : [];
|
|
3231
|
+
const pageBlocks = orderTwoUpPage(extractPageBlocksWithLines(flow, i, opList, pageW, pageH, void 0, options?.tables !== false, carry, wrapLexicon, rightArrows), pageW, pageH);
|
|
3018
3232
|
if (stamp.length) pageBlocks.unshift({ type: "paragraph", text: [...stamp].sort((a, b) => a.y - b.y).map((it) => it.text).join(" "), pageNumber: i });
|
|
3019
3233
|
for (const b of pageBlocks) blocks.push(b);
|
|
3020
3234
|
try {
|
|
@@ -3070,7 +3284,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3070
3284
|
}
|
|
3071
3285
|
if (targets.size > 0) {
|
|
3072
3286
|
try {
|
|
3073
|
-
const { runPdfOcr } = await import("./pdf-ocr-
|
|
3287
|
+
const { runPdfOcr } = await import("./pdf-ocr-7IOOVR2I.js");
|
|
3074
3288
|
const mode = typeof options?.ocr === "function" ? options.ocr : "builtin";
|
|
3075
3289
|
const regionPages = new Map([...ocrRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
|
|
3076
3290
|
const ocrPageBlocks = await runPdfOcr(ocrBuffer, targets, mode, warnings, options?.onProgress, options?.tables !== false, vectorPageOps, regionPages);
|
|
@@ -3137,8 +3351,8 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3137
3351
|
warnings.push({ page, message: `${count}\uAC1C \uC774\uBBF8\uC9C0 \uC601\uC5ED\uC5D0 \uCD94\uCD9C \uAC00\uB2A5\uD55C \uD14D\uC2A4\uD2B8 \uC5C6\uC74C (\uADF8\uB9BC/\uCC28\uD2B8/\uB3C4\uC7A5 \uB0B4\uC6A9 \uB204\uB77D \uAC00\uB2A5 \u2014 \uADF8\uB9BC \uC18D \uAE00\uC740 ocr: true / CLI --ocr \uB85C \uC77D\uC2B5\uB2C8\uB2E4)`, code: "SKIPPED_IMAGE" });
|
|
3138
3352
|
}
|
|
3139
3353
|
}
|
|
3140
|
-
if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
|
|
3141
|
-
const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks);
|
|
3354
|
+
if (options?.removeHeaderFooter !== false && (parsedPageCount >= 3 || headerContext.length)) {
|
|
3355
|
+
const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks, false, headerContext);
|
|
3142
3356
|
for (let ri = removed.length - 1; ri >= 0; ri--) {
|
|
3143
3357
|
blocks.splice(removed[ri], 1);
|
|
3144
3358
|
}
|
|
@@ -3186,6 +3400,10 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3186
3400
|
const outline = blocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
|
|
3187
3401
|
sanitizeBlockControlChars(blocks);
|
|
3188
3402
|
let outBlocks = splitSingleCellTables(blocks);
|
|
3403
|
+
if (options?.layoutTables !== "keep") {
|
|
3404
|
+
blocks.length = 0;
|
|
3405
|
+
for (const block of outBlocks) blocks.push(block);
|
|
3406
|
+
}
|
|
3189
3407
|
outBlocks = inlineFootnotes(outBlocks, noteMarks);
|
|
3190
3408
|
outBlocks = relocateEndnotes(outBlocks);
|
|
3191
3409
|
if (options?.removeHeaderFooter !== false) outBlocks = outBlocks.filter((b) => {
|
|
@@ -3302,4 +3520,4 @@ export {
|
|
|
3302
3520
|
parsePdfDocument,
|
|
3303
3521
|
removeHeaderFooterBlocks
|
|
3304
3522
|
};
|
|
3305
|
-
//# sourceMappingURL=parser-
|
|
3523
|
+
//# sourceMappingURL=parser-SOWTUOMK.js.map
|