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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
blocksToPages,
|
|
3
3
|
encodePng
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-274ZPMHK.js";
|
|
5
5
|
import {
|
|
6
6
|
hasRequestedPagesAfter,
|
|
7
7
|
parsePageRange
|
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
CONT_PARTS,
|
|
13
13
|
EMPTY_PARTS,
|
|
14
14
|
FILLER_CELLS,
|
|
15
|
+
FRAME_READING_UNITS,
|
|
16
|
+
FRAME_TITLE_BLOCKS,
|
|
15
17
|
IMAGE_CELLS,
|
|
16
18
|
NO_EDGES,
|
|
17
19
|
PART_COLXS,
|
|
@@ -22,6 +24,7 @@ import {
|
|
|
22
24
|
TOC_BLOCKS,
|
|
23
25
|
WrapLexicon,
|
|
24
26
|
collapseEvenSpacing,
|
|
27
|
+
computeBBox,
|
|
25
28
|
computeMedianFontSizeFromFreq,
|
|
26
29
|
detectDocumentStyleHeadings,
|
|
27
30
|
detectHeadings,
|
|
@@ -29,26 +32,32 @@ import {
|
|
|
29
32
|
detectMarkerHeadings,
|
|
30
33
|
detectPageLeadHeadings,
|
|
31
34
|
detectRepeatedPageLabels,
|
|
35
|
+
detectRightArrowRegions,
|
|
32
36
|
detectSiblingStyleHeadings,
|
|
33
37
|
detectTableCaptions,
|
|
34
38
|
detectTypographyHeadings,
|
|
39
|
+
dominantStyle,
|
|
35
40
|
extractImageRegions,
|
|
36
41
|
extractLines,
|
|
37
42
|
extractPageBlocksWithLines,
|
|
38
43
|
filterHiddenText,
|
|
44
|
+
groupByY,
|
|
39
45
|
joinCellEdges,
|
|
40
46
|
joinPageBreakWraps,
|
|
41
47
|
latinSoftWrap,
|
|
48
|
+
mergeLineSimple,
|
|
42
49
|
mergeStackedHeadingLines,
|
|
43
50
|
normalizeItems,
|
|
44
51
|
ocrModelsCached,
|
|
52
|
+
recordFrameReadingUnit,
|
|
45
53
|
refineDocumentStyleHeadings,
|
|
46
54
|
removeHeaderFooterBlocks,
|
|
47
55
|
removeSideTabs,
|
|
56
|
+
restoreImageBullets,
|
|
48
57
|
startsNewItem,
|
|
49
58
|
trimTrailingEmptyTableCols,
|
|
50
59
|
wrapJoiner
|
|
51
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-MXA6YW2W.js";
|
|
52
61
|
import {
|
|
53
62
|
CELL_EDGES,
|
|
54
63
|
CONTENT_CELLS,
|
|
@@ -58,12 +67,12 @@ import {
|
|
|
58
67
|
escapeLiteralTags,
|
|
59
68
|
stripScriptTags,
|
|
60
69
|
unframeLayoutTables
|
|
61
|
-
} from "./chunk-
|
|
62
|
-
import "./chunk-
|
|
70
|
+
} from "./chunk-XG4SYOZL.js";
|
|
71
|
+
import "./chunk-ELOPDQES.js";
|
|
63
72
|
import {
|
|
64
73
|
KordocError,
|
|
65
74
|
sanitizeHref
|
|
66
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-7GR2GCJF.js";
|
|
67
76
|
|
|
68
77
|
// src/pdf/ocr-region-merge.ts
|
|
69
78
|
function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
|
|
@@ -76,8 +85,10 @@ function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
|
|
|
76
85
|
const overlapH = Math.max(0, Math.min(b.y + b.height, region.y2) - Math.max(b.y, region.y1));
|
|
77
86
|
return overlapW * overlapH >= b.width * b.height * 0.8;
|
|
78
87
|
});
|
|
88
|
+
const labels = candidates.filter((b) => b.type === "paragraph" && b.bbox.height <= 24 && (b.text?.match(/[\p{L}\p{N}]/gu)?.length ?? 0) >= 2);
|
|
89
|
+
const axisFragments = rotatedAxisFragments(candidates);
|
|
79
90
|
const accepted = candidates.filter((b) => {
|
|
80
|
-
if (b.type === "paragraph") return (b.text?.match(/[\p{L}\p{N}]/gu)?.length ?? 0) >= 2;
|
|
91
|
+
if (b.type === "paragraph") return (b.text?.match(/[\p{L}\p{N}]/gu)?.length ?? 0) >= 2 || !axisFragments.has(b) && supportedDiagramLabel(b, labels, region);
|
|
81
92
|
const t = b.table;
|
|
82
93
|
if (b.type !== "table" || !t) return false;
|
|
83
94
|
if (t.rows === 1 && t.cols === 1) {
|
|
@@ -88,29 +99,89 @@ function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
|
|
|
88
99
|
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);
|
|
89
100
|
});
|
|
90
101
|
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 ?? "")) : []);
|
|
91
|
-
|
|
102
|
+
const hasOriginal = (block) => blocks.some((existing) => {
|
|
92
103
|
const b = block.bbox;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
});
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
if (existing.pageNumber !== page || !existing.bbox || existing.type === "image") return false;
|
|
105
|
+
const e = existing.bbox;
|
|
106
|
+
const x = Math.max(0, Math.min(e.x + e.width, b.x + b.width) - Math.max(e.x, b.x));
|
|
107
|
+
const y = Math.max(0, Math.min(e.y + e.height, b.y + b.height) - Math.max(e.y, b.y));
|
|
108
|
+
return x * y > b.width * b.height * 0.2;
|
|
109
|
+
});
|
|
110
|
+
const selectedSet = new Set(selected), seen = /* @__PURE__ */ new Set();
|
|
111
|
+
for (const block of selected) {
|
|
112
|
+
if (seen.has(block)) continue;
|
|
113
|
+
const frame = FRAME_READING_UNITS.get(block);
|
|
114
|
+
const source = frame?.blocks.every((member) => selectedSet.has(member)) ? frame.blocks : [block];
|
|
115
|
+
source.forEach((member) => seen.add(member));
|
|
116
|
+
const available = source.filter((member) => !hasOriginal(member));
|
|
117
|
+
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 }));
|
|
118
|
+
for (const unit of units) {
|
|
119
|
+
const b = unit.bbox;
|
|
120
|
+
const index = blocks.findIndex((existing) => {
|
|
121
|
+
const e = FRAME_READING_UNITS.get(existing)?.bbox ?? existing.bbox;
|
|
122
|
+
if (existing.pageNumber !== page || !e) return false;
|
|
123
|
+
const beside = e.y < region.y2 && e.y + e.height > region.y1 && e.x >= region.x2 - 1;
|
|
124
|
+
return e.y < b.y || beside;
|
|
125
|
+
});
|
|
126
|
+
const placed = unit.blocks.map((member) => member.type === "paragraph" ? { ...member, style: void 0 } : member);
|
|
127
|
+
if (unit.atomic) recordFrameReadingUnit(placed, unit.bbox);
|
|
128
|
+
blocks.splice(index < 0 ? blocks.length : index, 0, ...placed);
|
|
129
|
+
added += placed.length;
|
|
130
|
+
}
|
|
110
131
|
}
|
|
111
132
|
}
|
|
112
133
|
return added;
|
|
113
134
|
}
|
|
135
|
+
function supportedDiagramLabel(block, labels, region) {
|
|
136
|
+
const b = block.bbox, text = block.text?.trim() ?? "";
|
|
137
|
+
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;
|
|
138
|
+
let above = false, below = false;
|
|
139
|
+
for (const label of labels) {
|
|
140
|
+
const a = label.bbox, em = Math.max(b.height, a.height);
|
|
141
|
+
if (b.x + b.width < a.x - em * 2 || b.x > a.x + a.width + em * 2) continue;
|
|
142
|
+
const upperGap = a.y - (b.y + b.height), lowerGap = b.y - (a.y + a.height);
|
|
143
|
+
if (upperGap >= 0 && upperGap <= em * 4) above = true;
|
|
144
|
+
if (lowerGap >= 0 && lowerGap <= em * 4) below = true;
|
|
145
|
+
}
|
|
146
|
+
return above && below;
|
|
147
|
+
}
|
|
148
|
+
function rotatedAxisFragments(candidates) {
|
|
149
|
+
const paragraphs = candidates.filter((b) => b.type === "paragraph" && b.bbox.height <= 24);
|
|
150
|
+
const axes = [];
|
|
151
|
+
for (const block of paragraphs) {
|
|
152
|
+
const b = block.bbox, text = block.text?.trim() ?? "";
|
|
153
|
+
if (!/^[\d\s.,%+−-]+$/u.test(text) || !/\d/u.test(text) || b.width > b.height * 6) continue;
|
|
154
|
+
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);
|
|
155
|
+
if (axis) axis.push(block);
|
|
156
|
+
else axes.push([block]);
|
|
157
|
+
}
|
|
158
|
+
const fragments = /* @__PURE__ */ new Set();
|
|
159
|
+
const aligned = (a, b) => {
|
|
160
|
+
const x = a.bbox, y = b.bbox, tolerance = Math.max(x.height, y.height) * 0.5;
|
|
161
|
+
return Math.abs(x.x - y.x) <= tolerance || Math.abs(x.x + x.width - y.x - y.width) <= tolerance;
|
|
162
|
+
};
|
|
163
|
+
for (const axis of axes) {
|
|
164
|
+
if (axis.length < 3) continue;
|
|
165
|
+
const bottom = Math.min(...axis.map((a) => a.bbox.y)), top = Math.max(...axis.map((a) => a.bbox.y + a.bbox.height));
|
|
166
|
+
const em = Math.max(...axis.map((a) => a.bbox.height)), right = axis[0].bbox.x + axis[0].bbox.width;
|
|
167
|
+
if (top - bottom < em * 6) continue;
|
|
168
|
+
const left = paragraphs.filter((block) => {
|
|
169
|
+
const b = block.bbox, text = block.text?.trim() ?? "";
|
|
170
|
+
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;
|
|
171
|
+
});
|
|
172
|
+
const stack = left.filter((a) => left.some((b) => {
|
|
173
|
+
if (a === b || !aligned(a, b)) return false;
|
|
174
|
+
const x = a.bbox, y = b.bbox, gap = Math.max(x.y, y.y) - Math.min(x.y + x.height, y.y + y.height);
|
|
175
|
+
return gap >= -Math.min(x.height, y.height) * 0.5 && gap <= Math.max(x.height, y.height);
|
|
176
|
+
}));
|
|
177
|
+
if (stack.length < 2) continue;
|
|
178
|
+
for (const block of paragraphs) {
|
|
179
|
+
const b = block.bbox;
|
|
180
|
+
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);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return fragments;
|
|
184
|
+
}
|
|
114
185
|
function rowParagraphs(block) {
|
|
115
186
|
const t = block.table, b = block.bbox;
|
|
116
187
|
const h = b.height / t.rows;
|
|
@@ -916,6 +987,17 @@ var CARRIED_MIN_COL_W = 4;
|
|
|
916
987
|
var LABEL_ROOM = 1.5;
|
|
917
988
|
var HANGING_MIN = 0.5;
|
|
918
989
|
var HANGING_TOL = 1;
|
|
990
|
+
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";
|
|
991
|
+
var ITEM_MARK = /^\s*(?:([가-힣])\.|(\d{1,3})[.)]|\(([가-힣\d]{1,3})\))(?=\s)/;
|
|
992
|
+
function nextItemHead(prev, next) {
|
|
993
|
+
const a = ITEM_MARK.exec(prev), b = ITEM_MARK.exec(next);
|
|
994
|
+
if (!a || !b) return false;
|
|
995
|
+
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;
|
|
996
|
+
if (a[1] && b[1]) return succ(a[1], b[1]);
|
|
997
|
+
if (a[2] && b[2]) return succ(a[2], b[2]) && prev.trimStart()[a[2].length] === next.trimStart()[b[2].length];
|
|
998
|
+
if (a[3] && b[3]) return succ(a[3], b[3]);
|
|
999
|
+
return false;
|
|
1000
|
+
}
|
|
919
1001
|
function continuesAcross(u, d, x1, x2) {
|
|
920
1002
|
const U = CELL_LINES.get(u), D = CELL_LINES.get(d);
|
|
921
1003
|
if (!U?.length || !D?.length) return false;
|
|
@@ -1047,6 +1129,8 @@ function mergeSplitRow(table, owner, first, colXs, textOnly = false, cut = NO_CU
|
|
|
1047
1129
|
if (!carriedSplit) {
|
|
1048
1130
|
const norm = (c) => flowText(c.text).replace(/\s+/g, "");
|
|
1049
1131
|
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;
|
|
1132
|
+
const oneLine = (c) => CELL_LINES.get(c)?.length === 1;
|
|
1133
|
+
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;
|
|
1050
1134
|
const flows = ([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs]) || clauseContinues(cell(u), cell(d));
|
|
1051
1135
|
if (!(cut.open && !newCell)) {
|
|
1052
1136
|
if (pairs.some((p) => p[1].rs > 1 && !flows(p))) return false;
|
|
@@ -1107,7 +1191,7 @@ function sameHeadShape(a, b) {
|
|
|
1107
1191
|
let tall = false;
|
|
1108
1192
|
for (let c = 0; c < a.length; c++) {
|
|
1109
1193
|
if (a[c].colSpan !== b[c].colSpan || a[c].rowSpan !== b[c].rowSpan) return false;
|
|
1110
|
-
if (a[c].rowSpan >= 2 && a[c].text.trim()) tall = true;
|
|
1194
|
+
if (a[c].rowSpan >= 2 && a[c].text.trim() && b[c].text.trim()) tall = true;
|
|
1111
1195
|
}
|
|
1112
1196
|
return tall;
|
|
1113
1197
|
}
|
|
@@ -1144,9 +1228,10 @@ function mergeCrossPageTables(blocks, pageHeights, lex) {
|
|
|
1144
1228
|
if (px && cx && !shiftedSame(px, cx, !CLIP_TABLES.has(prev.table) && !CLIP_TABLES.has(curr.table))) continue;
|
|
1145
1229
|
if (!rowTextsEqual(prev.table.cells[0], curr.table.cells[0]) && sameHeadShape(prev.table.cells[0], curr.table.cells[0])) continue;
|
|
1146
1230
|
let currCells = curr.table.cells;
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1231
|
+
const headRows = repeatedHeaderRows(prev.table, curr.table);
|
|
1232
|
+
if (headRows < 0) continue;
|
|
1233
|
+
if (headRows) currCells = currCells.slice(headRows);
|
|
1234
|
+
if (currCells.length) continueRowSpans(prev.table.cells, currCells);
|
|
1150
1235
|
if (currCells.length === 0) {
|
|
1151
1236
|
blocks.splice(j, 1);
|
|
1152
1237
|
continue;
|
|
@@ -1348,6 +1433,45 @@ function chainHead(blocks, i, pageHeights) {
|
|
|
1348
1433
|
}
|
|
1349
1434
|
return k;
|
|
1350
1435
|
}
|
|
1436
|
+
var ROW_CONTINUATIONS = /* @__PURE__ */ new WeakMap();
|
|
1437
|
+
function continueRowSpans(prevCells, currCells) {
|
|
1438
|
+
const first = currCells[0];
|
|
1439
|
+
const last = prevCells.length;
|
|
1440
|
+
for (let c = 0; c < first.length; c++) {
|
|
1441
|
+
const cell = first[c];
|
|
1442
|
+
if (hasContent(cell) || (cell.rowSpan || 1) < 2) continue;
|
|
1443
|
+
let anchor;
|
|
1444
|
+
for (let r = last - 1; r >= 0 && !anchor; r--) {
|
|
1445
|
+
const a = prevCells[r]?.[c];
|
|
1446
|
+
if (a && r + (a.rowSpan || 1) === last && (a.colSpan || 1) === (cell.colSpan || 1) && (hasContent(a) || a.rowSpan >= 2)) anchor = a;
|
|
1447
|
+
}
|
|
1448
|
+
if (!anchor) continue;
|
|
1449
|
+
if (!hasContent(anchor)) {
|
|
1450
|
+
ROW_CONTINUATIONS.set(anchor, cell);
|
|
1451
|
+
continue;
|
|
1452
|
+
}
|
|
1453
|
+
for (let part = cell; part; ) {
|
|
1454
|
+
const next = ROW_CONTINUATIONS.get(part);
|
|
1455
|
+
anchor.rowSpan = (anchor.rowSpan || 1) + part.rowSpan;
|
|
1456
|
+
part.rowSpan = 1;
|
|
1457
|
+
part.colSpan = 1;
|
|
1458
|
+
ROW_CONTINUATIONS.delete(part);
|
|
1459
|
+
part = next;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
function repeatedHeaderRows(prev, curr) {
|
|
1464
|
+
if (!rowTextsEqual(prev.cells[0], curr.cells[0])) return 0;
|
|
1465
|
+
const pa = anchorsOf(prev), ca = anchorsOf(curr);
|
|
1466
|
+
let depth = 1;
|
|
1467
|
+
for (let r = 0; r < depth && r < prev.rows; r++) {
|
|
1468
|
+
for (const a of pa) if (a.r === r) depth = Math.max(depth, r + a.rs);
|
|
1469
|
+
}
|
|
1470
|
+
if (depth >= curr.rows || depth > prev.rows) return -1;
|
|
1471
|
+
const p = pa.filter((a) => a.r < depth), d = ca.filter((a) => a.r < depth);
|
|
1472
|
+
const norm = (text) => flowText(text).replace(/\s+/g, "");
|
|
1473
|
+
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;
|
|
1474
|
+
}
|
|
1351
1475
|
function rowTextsEqual(a, b) {
|
|
1352
1476
|
if (a.length !== b.length) return false;
|
|
1353
1477
|
const norm = (t) => flowText(t).replace(/\s+/g, "");
|
|
@@ -1442,6 +1566,34 @@ function fillNestedContinuation(blocks, at) {
|
|
|
1442
1566
|
blocks.splice(at, 1);
|
|
1443
1567
|
}
|
|
1444
1568
|
|
|
1569
|
+
// src/pdf/selection-context.ts
|
|
1570
|
+
function selectionContextPages(selected, pageCount) {
|
|
1571
|
+
const out = /* @__PURE__ */ new Set();
|
|
1572
|
+
for (const page of selected) {
|
|
1573
|
+
for (let distance = 1; distance <= 4; distance++) {
|
|
1574
|
+
for (const neighbor of [page - distance, page + distance]) {
|
|
1575
|
+
if (neighbor < 1 || neighbor > pageCount || selected.has(neighbor)) continue;
|
|
1576
|
+
out.add(neighbor);
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
return [...out].sort((a, b) => a - b);
|
|
1581
|
+
}
|
|
1582
|
+
function marginContextBlocks(raw, page, view) {
|
|
1583
|
+
const [x1, y1, x2, y2] = view;
|
|
1584
|
+
const width = x2 - x1, height = y2 - y1;
|
|
1585
|
+
const items = filterHiddenText(normalizeItems(raw), width, height, x1, y1).visible;
|
|
1586
|
+
for (const item of items) {
|
|
1587
|
+
item.x -= x1;
|
|
1588
|
+
item.y -= y1;
|
|
1589
|
+
}
|
|
1590
|
+
return groupByY(items).flatMap((line) => {
|
|
1591
|
+
const bbox = computeBBox(line, page);
|
|
1592
|
+
if (bbox.y + bbox.height < height * 0.88 && bbox.y > height * 0.12) return [];
|
|
1593
|
+
return [{ type: "paragraph", text: mergeLineSimple(line), pageNumber: page, bbox, style: dominantStyle(line) }];
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1445
1597
|
// src/pdf/symbol-fonts.ts
|
|
1446
1598
|
var WINANSI_REVERSE = {
|
|
1447
1599
|
8364: 128,
|
|
@@ -1749,6 +1901,9 @@ var NAMED = {
|
|
|
1749
1901
|
quotedblright: "\u201D",
|
|
1750
1902
|
quotesingle: "'",
|
|
1751
1903
|
quotedbl: '"',
|
|
1904
|
+
bullet: "\u2022",
|
|
1905
|
+
openbullet: "\u25E6",
|
|
1906
|
+
whitebullet: "\u25E6",
|
|
1752
1907
|
question: "?",
|
|
1753
1908
|
exclam: "!",
|
|
1754
1909
|
percent: "%",
|
|
@@ -1765,7 +1920,9 @@ function glyphNameText(name) {
|
|
|
1765
1920
|
let out = "";
|
|
1766
1921
|
for (const part of base.split("_")) {
|
|
1767
1922
|
const uni = /^uni([0-9A-F]{4})$/.exec(part) ?? /^u([0-9A-F]{4,6})$/.exec(part);
|
|
1768
|
-
const
|
|
1923
|
+
const code = uni ? parseInt(uni[1], 16) : void 0;
|
|
1924
|
+
if (code !== void 0 && (code > 1114111 || code >= 55296 && code <= 57343)) return void 0;
|
|
1925
|
+
const ch = /^[A-Za-z]$/.test(part) ? part : NAMED[part] ?? (code !== void 0 ? String.fromCodePoint(code) : void 0);
|
|
1769
1926
|
if (ch === void 0) return void 0;
|
|
1770
1927
|
out += ch;
|
|
1771
1928
|
}
|
|
@@ -2451,6 +2608,35 @@ function demoteNonHeadingRoles(blocks, pageHeights, faceNames) {
|
|
|
2451
2608
|
}
|
|
2452
2609
|
}
|
|
2453
2610
|
}
|
|
2611
|
+
const citedProse = /* @__PURE__ */ new Set();
|
|
2612
|
+
const numberedProse = /* @__PURE__ */ new Set();
|
|
2613
|
+
for (const page of byPage.values()) {
|
|
2614
|
+
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) ?? ""));
|
|
2615
|
+
let chain = [];
|
|
2616
|
+
const finish = () => {
|
|
2617
|
+
if (chain.length < 3 || !chain.some((b) => (b.text?.length ?? 0) >= 40 && b.bbox.height >= b.style.fontSize * 2.4)) return;
|
|
2618
|
+
for (const b of chain) numberedProse.add(b);
|
|
2619
|
+
const first = chain[0], size = first.style.fontSize;
|
|
2620
|
+
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);
|
|
2621
|
+
};
|
|
2622
|
+
for (const b of numbered) {
|
|
2623
|
+
const prev = chain.at(-1), size = b.style.fontSize;
|
|
2624
|
+
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) {
|
|
2625
|
+
finish();
|
|
2626
|
+
chain = [];
|
|
2627
|
+
}
|
|
2628
|
+
chain.push(b);
|
|
2629
|
+
}
|
|
2630
|
+
finish();
|
|
2631
|
+
}
|
|
2632
|
+
for (let i = 0; i + 1 < blocks.length; i++) {
|
|
2633
|
+
const prose = blocks[i], reference = blocks[i + 1];
|
|
2634
|
+
const a = prose.bbox, b = reference.bbox, size = prose.style?.fontSize ?? 0;
|
|
2635
|
+
const source = reference.text?.replace(/<[^>]+>/g, "").trim() ?? "";
|
|
2636
|
+
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;
|
|
2637
|
+
citedProse.add(prose);
|
|
2638
|
+
citedProse.add(reference);
|
|
2639
|
+
}
|
|
2454
2640
|
for (let i = 0; i < blocks.length; i++) {
|
|
2455
2641
|
const block = blocks[i];
|
|
2456
2642
|
if (block.type !== "heading" || !block.text) continue;
|
|
@@ -2498,7 +2684,7 @@ function demoteNonHeadingRoles(blocks, pageHeights, faceNames) {
|
|
|
2498
2684
|
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;
|
|
2499
2685
|
const ocrFragment = block.style?.fontName === "ocr" && (/^[.,;:…·•-]/.test(text) || text.includes("\u2026") || (text.match(/\p{L}/gu)?.length ?? 0) < 2 || text.split(/\s+/).length > 7);
|
|
2500
2686
|
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;
|
|
2501
|
-
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)"·"가)" 앞머리 번호는 빼고 센다
|
|
2687
|
+
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)"·"가)" 앞머리 번호는 빼고 센다
|
|
2502
2688
|
unbalancedClose(text.replace(/^\s*[\dA-Za-z가-힣ⅰ-ⅹ]{1,3}\)\s*/, "")) || isRunningHead(block, page, pageHeights.get(block.pageNumber ?? 0))) {
|
|
2503
2689
|
block.type = "paragraph";
|
|
2504
2690
|
block.level = void 0;
|
|
@@ -2539,6 +2725,11 @@ function splitSingleCellTables(blocks) {
|
|
|
2539
2725
|
const out = [];
|
|
2540
2726
|
for (const b of blocks) {
|
|
2541
2727
|
const t = b.type === "table" ? b.table : void 0;
|
|
2728
|
+
const title = t && FRAME_TITLE_BLOCKS.get(t);
|
|
2729
|
+
if (title) {
|
|
2730
|
+
out.push({ ...title, text: `${t.cells[0][0].text.trim()} ${t.cells[0][2].text.trim()}` });
|
|
2731
|
+
continue;
|
|
2732
|
+
}
|
|
2542
2733
|
const only = t && t.rows === 1 && t.cols === 1 && t.cells[0]?.[0]?.blocks?.length === 1 ? t.cells[0][0].blocks[0] : void 0;
|
|
2543
2734
|
const squash = (s) => s.replace(/\s/g, "");
|
|
2544
2735
|
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;
|
|
@@ -2548,12 +2739,16 @@ function splitSingleCellTables(blocks) {
|
|
|
2548
2739
|
continue;
|
|
2549
2740
|
}
|
|
2550
2741
|
const cell = t && t.rows === 1 && t.cols === 1 ? t.cells[0]?.[0] : void 0;
|
|
2551
|
-
if (!cell
|
|
2742
|
+
if (!cell) {
|
|
2552
2743
|
out.push(b);
|
|
2553
2744
|
continue;
|
|
2554
2745
|
}
|
|
2555
2746
|
const lines = (cell.text ?? "").split(/\n/).map((l) => l.trim()).filter(Boolean);
|
|
2556
2747
|
if (t?.caption?.trim()) out.push({ type: "paragraph", text: t.caption.trim(), pageNumber: b.pageNumber, bbox: b.bbox });
|
|
2748
|
+
if (cell.blocks?.length) {
|
|
2749
|
+
out.push(...splitSingleCellTables(cell.blocks));
|
|
2750
|
+
continue;
|
|
2751
|
+
}
|
|
2557
2752
|
for (const text of lines) out.push({ type: "paragraph", text, pageNumber: b.pageNumber, bbox: b.bbox });
|
|
2558
2753
|
}
|
|
2559
2754
|
return out;
|
|
@@ -2678,7 +2873,7 @@ function mergeLinkRuns(markdown) {
|
|
|
2678
2873
|
|
|
2679
2874
|
// src/pdf/formula-ocr.ts
|
|
2680
2875
|
async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
|
|
2681
|
-
const formulaMod = await import("./formula-
|
|
2876
|
+
const formulaMod = await import("./formula-HQFZEXFF.js");
|
|
2682
2877
|
const { FormulaPipeline, ensureFormulaModels } = formulaMod;
|
|
2683
2878
|
await ensureFormulaModels((p) => {
|
|
2684
2879
|
if (p.phase === "download" && p.total) {
|
|
@@ -2901,12 +3096,29 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2901
3096
|
const uncoveredImageRegions = /* @__PURE__ */ new Map();
|
|
2902
3097
|
const largeImageRegions = /* @__PURE__ */ new Set();
|
|
2903
3098
|
const imageState = createPdfImageState();
|
|
3099
|
+
const imageBulletShapes = /* @__PURE__ */ new Map();
|
|
3100
|
+
const imageArrowDirections = /* @__PURE__ */ new Map();
|
|
2904
3101
|
const extractedImages = [];
|
|
2905
3102
|
const pageImageBlocks = /* @__PURE__ */ new Map();
|
|
2906
3103
|
const carry = {};
|
|
2907
3104
|
const vectorPageOps = /* @__PURE__ */ new Map();
|
|
2908
3105
|
const wrapLexicon = new WrapLexicon();
|
|
2909
3106
|
const noteMarks = /* @__PURE__ */ new Map();
|
|
3107
|
+
const headerContext = [];
|
|
3108
|
+
if (pageFilter && options?.removeHeaderFooter !== false && pageFilter.size < effectivePageCount) {
|
|
3109
|
+
for (const number of selectionContextPages(pageFilter, effectivePageCount)) {
|
|
3110
|
+
let contextPage;
|
|
3111
|
+
try {
|
|
3112
|
+
contextPage = await doc.getPage(number);
|
|
3113
|
+
const content = await contextPage.getTextContent();
|
|
3114
|
+
pageHeights.set(number, contextPage.view[3] - contextPage.view[1]);
|
|
3115
|
+
headerContext.push(...marginContextBlocks(content.items, number, contextPage.view));
|
|
3116
|
+
} catch {
|
|
3117
|
+
} finally {
|
|
3118
|
+
contextPage?.cleanup();
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
3121
|
+
}
|
|
2910
3122
|
let parsedPages = 0;
|
|
2911
3123
|
for (let i = 1; i <= effectivePageCount; i++) {
|
|
2912
3124
|
if (pageFilter && !pageFilter.has(i)) continue;
|
|
@@ -2960,6 +3172,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2960
3172
|
} : rawOps;
|
|
2961
3173
|
remapSymbolFontItems(visible, (loadedName) => fontObj(loadedName)?.name);
|
|
2962
3174
|
remapControlGlyphs(visible, differencesOf);
|
|
3175
|
+
await restoreImageBullets(visible, page, opList.fnArray, opList.argsArray, imageBulletShapes);
|
|
2963
3176
|
const faces = /* @__PURE__ */ new Map();
|
|
2964
3177
|
for (const it of visible) {
|
|
2965
3178
|
if (!it.fontName) continue;
|
|
@@ -3006,7 +3219,8 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3006
3219
|
if (marks.length) noteMarks.set(i, { marks, seps: footnoteSeparators(extractLines(opList.fnArray, opList.argsArray).horizontals, pageW, pageH) });
|
|
3007
3220
|
const stamp = marginStamp(visible);
|
|
3008
3221
|
const flow = stamp.length ? visible.filter((it) => !stamp.includes(it)) : visible;
|
|
3009
|
-
const
|
|
3222
|
+
const rightArrows = options?.tables !== false ? await detectRightArrowRegions(page, opList.fnArray, opList.argsArray, imageArrowDirections) : [];
|
|
3223
|
+
const pageBlocks = orderTwoUpPage(extractPageBlocksWithLines(flow, i, opList, pageW, pageH, void 0, options?.tables !== false, carry, wrapLexicon, rightArrows), pageW, pageH);
|
|
3010
3224
|
if (stamp.length) pageBlocks.unshift({ type: "paragraph", text: [...stamp].sort((a, b) => a.y - b.y).map((it) => it.text).join(" "), pageNumber: i });
|
|
3011
3225
|
for (const b of pageBlocks) blocks.push(b);
|
|
3012
3226
|
try {
|
|
@@ -3062,7 +3276,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3062
3276
|
}
|
|
3063
3277
|
if (targets.size > 0) {
|
|
3064
3278
|
try {
|
|
3065
|
-
const { runPdfOcr } = await import("./pdf-ocr-
|
|
3279
|
+
const { runPdfOcr } = await import("./pdf-ocr-RACAZU3N.js");
|
|
3066
3280
|
const mode = typeof options?.ocr === "function" ? options.ocr : "builtin";
|
|
3067
3281
|
const regionPages = new Map([...ocrRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
|
|
3068
3282
|
const ocrPageBlocks = await runPdfOcr(ocrBuffer, targets, mode, warnings, options?.onProgress, options?.tables !== false, vectorPageOps, regionPages);
|
|
@@ -3129,8 +3343,8 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3129
3343
|
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" });
|
|
3130
3344
|
}
|
|
3131
3345
|
}
|
|
3132
|
-
if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
|
|
3133
|
-
const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks);
|
|
3346
|
+
if (options?.removeHeaderFooter !== false && (parsedPageCount >= 3 || headerContext.length)) {
|
|
3347
|
+
const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks, false, headerContext);
|
|
3134
3348
|
for (let ri = removed.length - 1; ri >= 0; ri--) {
|
|
3135
3349
|
blocks.splice(removed[ri], 1);
|
|
3136
3350
|
}
|
|
@@ -3178,6 +3392,10 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3178
3392
|
const outline = blocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
|
|
3179
3393
|
sanitizeBlockControlChars(blocks);
|
|
3180
3394
|
let outBlocks = splitSingleCellTables(blocks);
|
|
3395
|
+
if (options?.layoutTables !== "keep") {
|
|
3396
|
+
blocks.length = 0;
|
|
3397
|
+
for (const block of outBlocks) blocks.push(block);
|
|
3398
|
+
}
|
|
3181
3399
|
outBlocks = inlineFootnotes(outBlocks, noteMarks);
|
|
3182
3400
|
outBlocks = relocateEndnotes(outBlocks);
|
|
3183
3401
|
if (options?.removeHeaderFooter !== false) outBlocks = outBlocks.filter((b) => {
|
|
@@ -3294,4 +3512,4 @@ export {
|
|
|
3294
3512
|
parsePdfDocument,
|
|
3295
3513
|
removeHeaderFooterBlocks
|
|
3296
3514
|
};
|
|
3297
|
-
//# sourceMappingURL=parser-
|
|
3515
|
+
//# sourceMappingURL=parser-GFDGAVLV.js.map
|