formatferry 1.0.13 → 1.0.14
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/index.js +651 -46
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19705,9 +19705,12 @@ var InputSanitizer = class {
|
|
|
19705
19705
|
"table",
|
|
19706
19706
|
"thead",
|
|
19707
19707
|
"tbody",
|
|
19708
|
+
"tfoot",
|
|
19708
19709
|
"tr",
|
|
19709
19710
|
"td",
|
|
19710
19711
|
"th",
|
|
19712
|
+
"figure",
|
|
19713
|
+
"figcaption",
|
|
19711
19714
|
"a",
|
|
19712
19715
|
"img",
|
|
19713
19716
|
"sup",
|
|
@@ -21373,7 +21376,9 @@ var _flags = {
|
|
|
21373
21376
|
enableHtml: true,
|
|
21374
21377
|
enablePdfTableDetection: true,
|
|
21375
21378
|
enableData: true,
|
|
21376
|
-
enablePptx: true
|
|
21379
|
+
enablePptx: true,
|
|
21380
|
+
enablePdfEnhanced: true,
|
|
21381
|
+
enablePdfMultiColumn: true
|
|
21377
21382
|
};
|
|
21378
21383
|
function getFeatureFlags() {
|
|
21379
21384
|
return { ..._flags };
|
|
@@ -21640,12 +21645,25 @@ function findTableRegions(items, options = {}) {
|
|
|
21640
21645
|
if (best) break;
|
|
21641
21646
|
else continue;
|
|
21642
21647
|
}
|
|
21643
|
-
const
|
|
21648
|
+
const rawConfidence = scoreCandidate(coalesced, columns);
|
|
21649
|
+
const bbox = computeBbox(coalesced);
|
|
21650
|
+
const ruleBonus = (() => {
|
|
21651
|
+
const hRules = options.ruleSeparators?.filter((r) => r.orientation === "h") ?? [];
|
|
21652
|
+
if (hRules.length === 0) return 0;
|
|
21653
|
+
const tol = 10;
|
|
21654
|
+
const hasTop = hRules.some(
|
|
21655
|
+
(r) => Math.abs(r.position - bbox.y1) <= tol && r.span[0] <= bbox.x0 + tol && r.span[1] >= bbox.x1 - tol
|
|
21656
|
+
);
|
|
21657
|
+
const hasBottom = hRules.some(
|
|
21658
|
+
(r) => Math.abs(r.position - bbox.y0) <= tol && r.span[0] <= bbox.x0 + tol && r.span[1] >= bbox.x1 - tol
|
|
21659
|
+
);
|
|
21660
|
+
return (hasTop ? 0.075 : 0) + (hasBottom ? 0.075 : 0);
|
|
21661
|
+
})();
|
|
21662
|
+
const confidence = Math.min(1, rawConfidence + ruleBonus);
|
|
21644
21663
|
if (confidence < MIN_CONFIDENCE_EMIT) {
|
|
21645
21664
|
if (best) break;
|
|
21646
21665
|
continue;
|
|
21647
21666
|
}
|
|
21648
|
-
const bbox = computeBbox(coalesced);
|
|
21649
21667
|
const medianH = median(coalesced.flatMap((r) => r.items.map((it) => it.height))) || 0;
|
|
21650
21668
|
const mayContinue = options.pageBottomY !== void 0 && medianH > 0 && bbox.y0 - options.pageBottomY < medianH * 2;
|
|
21651
21669
|
best = {
|
|
@@ -21953,6 +21971,142 @@ function looksLikeHeader(row) {
|
|
|
21953
21971
|
return boldish / n >= 0.5 || allCaps / n >= 0.5 || trailingColon / n >= 0.5;
|
|
21954
21972
|
}
|
|
21955
21973
|
|
|
21974
|
+
// ../../src/shared/adapters/pdf-struct-tree-adapter.ts
|
|
21975
|
+
function buildMcidMap(items) {
|
|
21976
|
+
const map = /* @__PURE__ */ new Map();
|
|
21977
|
+
let currentId = null;
|
|
21978
|
+
for (const item of items) {
|
|
21979
|
+
const itemType = "type" in item ? item.type : void 0;
|
|
21980
|
+
if (itemType === "beginMarkedContentProps") {
|
|
21981
|
+
const mc = item;
|
|
21982
|
+
if (mc.id != null) {
|
|
21983
|
+
currentId = mc.id;
|
|
21984
|
+
if (!map.has(currentId)) map.set(currentId, "");
|
|
21985
|
+
}
|
|
21986
|
+
} else if (itemType === "endMarkedContent") {
|
|
21987
|
+
currentId = null;
|
|
21988
|
+
} else if ("str" in item && currentId !== null) {
|
|
21989
|
+
const existing = map.get(currentId) ?? "";
|
|
21990
|
+
map.set(currentId, existing + item.str);
|
|
21991
|
+
}
|
|
21992
|
+
}
|
|
21993
|
+
return map;
|
|
21994
|
+
}
|
|
21995
|
+
function countNodes(node, limit) {
|
|
21996
|
+
let n = 1;
|
|
21997
|
+
if ("children" in node && node.children) {
|
|
21998
|
+
for (const child of node.children) {
|
|
21999
|
+
n += countNodes(child, limit);
|
|
22000
|
+
if (n >= limit) return n;
|
|
22001
|
+
}
|
|
22002
|
+
}
|
|
22003
|
+
return n;
|
|
22004
|
+
}
|
|
22005
|
+
function esc(str) {
|
|
22006
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
22007
|
+
}
|
|
22008
|
+
function isContent(node) {
|
|
22009
|
+
return "id" in node && !("role" in node);
|
|
22010
|
+
}
|
|
22011
|
+
function walkChildren(children, mcidMap, depth) {
|
|
22012
|
+
return children.map((c) => walkNode(c, mcidMap, depth)).join("");
|
|
22013
|
+
}
|
|
22014
|
+
function walkNode(node, mcidMap, depth = 0) {
|
|
22015
|
+
if (depth > 50) return "";
|
|
22016
|
+
if (isContent(node)) {
|
|
22017
|
+
const text = mcidMap.get(node.id) ?? "";
|
|
22018
|
+
return esc(text);
|
|
22019
|
+
}
|
|
22020
|
+
const children = node.children ?? [];
|
|
22021
|
+
const inner = walkChildren(children, mcidMap, depth + 1);
|
|
22022
|
+
switch (node.role) {
|
|
22023
|
+
case "H":
|
|
22024
|
+
return `<h1>${inner}</h1>`;
|
|
22025
|
+
case "H1":
|
|
22026
|
+
return `<h1>${inner}</h1>`;
|
|
22027
|
+
case "H2":
|
|
22028
|
+
return `<h2>${inner}</h2>`;
|
|
22029
|
+
case "H3":
|
|
22030
|
+
return `<h3>${inner}</h3>`;
|
|
22031
|
+
case "H4":
|
|
22032
|
+
return `<h4>${inner}</h4>`;
|
|
22033
|
+
case "H5":
|
|
22034
|
+
return `<h5>${inner}</h5>`;
|
|
22035
|
+
case "H6":
|
|
22036
|
+
return `<h6>${inner}</h6>`;
|
|
22037
|
+
case "P":
|
|
22038
|
+
return inner ? `<p>${inner}</p>` : "";
|
|
22039
|
+
case "L":
|
|
22040
|
+
return inner ? `<ul>${inner}</ul>` : "";
|
|
22041
|
+
case "LI":
|
|
22042
|
+
return inner ? `<li>${inner}</li>` : "";
|
|
22043
|
+
case "Lbl":
|
|
22044
|
+
return inner ? `<span>${inner}</span> ` : "";
|
|
22045
|
+
case "LBody":
|
|
22046
|
+
return inner;
|
|
22047
|
+
case "Table":
|
|
22048
|
+
return inner ? `<table>${inner}</table>` : "";
|
|
22049
|
+
case "THead":
|
|
22050
|
+
return inner ? `<thead>${inner}</thead>` : "";
|
|
22051
|
+
case "TBody":
|
|
22052
|
+
return inner ? `<tbody>${inner}</tbody>` : "";
|
|
22053
|
+
case "TFoot":
|
|
22054
|
+
return inner ? `<tfoot>${inner}</tfoot>` : "";
|
|
22055
|
+
case "TR":
|
|
22056
|
+
return inner ? `<tr>${inner}</tr>` : "";
|
|
22057
|
+
case "TH":
|
|
22058
|
+
return `<th>${inner}</th>`;
|
|
22059
|
+
case "TD":
|
|
22060
|
+
return `<td>${inner}</td>`;
|
|
22061
|
+
case "Figure": {
|
|
22062
|
+
const alt = node.alt ?? "";
|
|
22063
|
+
const caption = alt ? `<figcaption>${esc(alt)}</figcaption>` : "";
|
|
22064
|
+
return `<figure>${caption}${inner}</figure>`;
|
|
22065
|
+
}
|
|
22066
|
+
case "BlockQuote":
|
|
22067
|
+
return inner ? `<blockquote>${inner}</blockquote>` : "";
|
|
22068
|
+
case "Code":
|
|
22069
|
+
return inner ? `<code>${inner}</code>` : "";
|
|
22070
|
+
// Inline / passthrough roles
|
|
22071
|
+
case "Span":
|
|
22072
|
+
case "Link":
|
|
22073
|
+
case "Reference":
|
|
22074
|
+
case "Note":
|
|
22075
|
+
case "Annot":
|
|
22076
|
+
case "Strong":
|
|
22077
|
+
case "Em":
|
|
22078
|
+
case "Sub":
|
|
22079
|
+
case "Sup":
|
|
22080
|
+
return inner;
|
|
22081
|
+
// Grouping roles — just pass through children
|
|
22082
|
+
default:
|
|
22083
|
+
return inner;
|
|
22084
|
+
}
|
|
22085
|
+
}
|
|
22086
|
+
async function structTreeToHtml(page) {
|
|
22087
|
+
let structTree;
|
|
22088
|
+
try {
|
|
22089
|
+
structTree = await page.getStructTree();
|
|
22090
|
+
} catch {
|
|
22091
|
+
return null;
|
|
22092
|
+
}
|
|
22093
|
+
if (!structTree || !structTree.children || structTree.children.length === 0) {
|
|
22094
|
+
return null;
|
|
22095
|
+
}
|
|
22096
|
+
if (countNodes(structTree, 5) < 5) return null;
|
|
22097
|
+
let textContent;
|
|
22098
|
+
try {
|
|
22099
|
+
textContent = await page.getTextContent({ includeMarkedContent: true });
|
|
22100
|
+
} catch {
|
|
22101
|
+
return null;
|
|
22102
|
+
}
|
|
22103
|
+
const mcidMap = buildMcidMap(textContent.items);
|
|
22104
|
+
const html = walkNode(structTree, mcidMap);
|
|
22105
|
+
const textOnly = html.replace(/<[^>]+>/g, "").trim();
|
|
22106
|
+
if (!textOnly) return null;
|
|
22107
|
+
return html;
|
|
22108
|
+
}
|
|
22109
|
+
|
|
21956
22110
|
// ../../src/shared/adapters/pdf-adapter.ts
|
|
21957
22111
|
var PdfParseError = class extends Error {
|
|
21958
22112
|
constructor(message, code, originalError) {
|
|
@@ -21969,6 +22123,52 @@ var FORM_LABEL_GAP_FACTOR = 3;
|
|
|
21969
22123
|
function escapeHtml(str) {
|
|
21970
22124
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
21971
22125
|
}
|
|
22126
|
+
function computeFontSize(transform) {
|
|
22127
|
+
return Math.sqrt(transform[2] ** 2 + transform[3] ** 2);
|
|
22128
|
+
}
|
|
22129
|
+
function normalizeLigatures(text) {
|
|
22130
|
+
return text.normalize("NFC").replace(/ff/g, "ff").replace(/fi/g, "fi").replace(/fl/g, "fl").replace(/ffi/g, "ffi").replace(/ffl/g, "ffl");
|
|
22131
|
+
}
|
|
22132
|
+
function hasStructTree(page) {
|
|
22133
|
+
return typeof page.getStructTree === "function";
|
|
22134
|
+
}
|
|
22135
|
+
function isSafeUrl(url) {
|
|
22136
|
+
return /^(?:https?|mailto|ftp):/i.test(url);
|
|
22137
|
+
}
|
|
22138
|
+
function detectFontStyle(fontName) {
|
|
22139
|
+
if (!fontName) return null;
|
|
22140
|
+
const bold = /(Bold|Black|Heavy|Semibold|Demi)/i.test(fontName) && !/Blackletter/i.test(fontName);
|
|
22141
|
+
const italic = /(Italic|Oblique|Slanted)/i.test(fontName);
|
|
22142
|
+
if (bold && italic) return "bold-italic";
|
|
22143
|
+
if (bold) return "bold";
|
|
22144
|
+
if (italic) return "italic";
|
|
22145
|
+
return null;
|
|
22146
|
+
}
|
|
22147
|
+
function buildOutlineSet(outline) {
|
|
22148
|
+
const set = /* @__PURE__ */ new Set();
|
|
22149
|
+
if (!outline) return set;
|
|
22150
|
+
function walk(items) {
|
|
22151
|
+
for (const item of items) {
|
|
22152
|
+
if (item.title) {
|
|
22153
|
+
set.add(normalizeLigatures(item.title).replace(/\s+/g, " ").trim().toLowerCase());
|
|
22154
|
+
}
|
|
22155
|
+
if (item.items) walk(item.items);
|
|
22156
|
+
}
|
|
22157
|
+
}
|
|
22158
|
+
walk(outline);
|
|
22159
|
+
return set;
|
|
22160
|
+
}
|
|
22161
|
+
function fuzzyMatchOutline(text, outlineTitles) {
|
|
22162
|
+
if (outlineTitles.size === 0) return false;
|
|
22163
|
+
for (const title of outlineTitles) {
|
|
22164
|
+
if (title.length < 3) continue;
|
|
22165
|
+
if (text.includes(title) || title.includes(text)) {
|
|
22166
|
+
const ratio = Math.min(text.length, title.length) / Math.max(text.length, title.length);
|
|
22167
|
+
if (ratio >= 0.8) return true;
|
|
22168
|
+
}
|
|
22169
|
+
}
|
|
22170
|
+
return false;
|
|
22171
|
+
}
|
|
21972
22172
|
function detectRotation(transform) {
|
|
21973
22173
|
const EPS = 1e-3;
|
|
21974
22174
|
const [sx, shy, shx, sy] = transform;
|
|
@@ -21992,6 +22192,7 @@ function textItemToPositioned(item) {
|
|
|
21992
22192
|
const descent = height * DESCENDER_BUDGET_FACTOR;
|
|
21993
22193
|
const y = ty - descent;
|
|
21994
22194
|
const paddedHeight = height + descent;
|
|
22195
|
+
const fs = computeFontSize(item.transform);
|
|
21995
22196
|
return {
|
|
21996
22197
|
str: item.str,
|
|
21997
22198
|
x: tx,
|
|
@@ -22001,7 +22202,8 @@ function textItemToPositioned(item) {
|
|
|
22001
22202
|
right: tx + width,
|
|
22002
22203
|
rotation,
|
|
22003
22204
|
fontName: item.fontName,
|
|
22004
|
-
source: "text"
|
|
22205
|
+
source: "text",
|
|
22206
|
+
fontSize: fs > 0 ? fs : rawHeight > 0 ? rawHeight : void 0
|
|
22005
22207
|
};
|
|
22006
22208
|
}
|
|
22007
22209
|
function widgetToPositionedItems(ann) {
|
|
@@ -22101,9 +22303,309 @@ function itemsToLinearText(items) {
|
|
|
22101
22303
|
}
|
|
22102
22304
|
return lines.join("\n").replace(/[ \t]+/g, " ").replace(/\n{3,}/g, "\n\n").trim();
|
|
22103
22305
|
}
|
|
22104
|
-
function
|
|
22306
|
+
function renderTextBlockEnhanced(items, medianPageFontSize, outlineTitles) {
|
|
22307
|
+
if (items.length === 0) return { htmlBlocks: [], textContent: "" };
|
|
22308
|
+
const sorted = [...items].sort(
|
|
22309
|
+
(a, b) => b.y + b.height - (a.y + a.height) || a.x - b.x
|
|
22310
|
+
);
|
|
22311
|
+
const rows = [];
|
|
22312
|
+
for (const it of sorted) {
|
|
22313
|
+
const last = rows[rows.length - 1];
|
|
22314
|
+
if (last && last.some(
|
|
22315
|
+
(li) => Math.max(
|
|
22316
|
+
0,
|
|
22317
|
+
Math.min(li.y + li.height, it.y + it.height) - Math.max(li.y, it.y)
|
|
22318
|
+
) / Math.max(Math.min(li.height, it.height), 1e-6) >= 0.5
|
|
22319
|
+
)) {
|
|
22320
|
+
last.push(it);
|
|
22321
|
+
} else {
|
|
22322
|
+
rows.push([it]);
|
|
22323
|
+
}
|
|
22324
|
+
}
|
|
22325
|
+
const htmlBlocks = [];
|
|
22326
|
+
const textLines = [];
|
|
22327
|
+
const col3Rows = getFeatureFlags().enablePdfMultiColumn ? detectAndReorderColumns(rows) : rows;
|
|
22328
|
+
const finalRows = repairRowHyphenation(col3Rows);
|
|
22329
|
+
let pendingListKind = null;
|
|
22330
|
+
const pendingListHtml = [];
|
|
22331
|
+
const flushPendingList = () => {
|
|
22332
|
+
if (pendingListHtml.length === 0) return;
|
|
22333
|
+
const tag = pendingListKind === "ol" ? "ol" : "ul";
|
|
22334
|
+
htmlBlocks.push(`<${tag}>${pendingListHtml.join("")}</${tag}>`);
|
|
22335
|
+
pendingListKind = null;
|
|
22336
|
+
pendingListHtml.length = 0;
|
|
22337
|
+
};
|
|
22338
|
+
for (const row of finalRows) {
|
|
22339
|
+
row.sort((a, b) => a.x - b.x);
|
|
22340
|
+
const fsSamples = row.map((it) => it.fontSize ?? 0).filter((f) => f > 0);
|
|
22341
|
+
const rowFs = fsSamples.length > 0 ? [...fsSamples].sort((a, b) => a - b)[Math.floor(fsSamples.length / 2)] : medianPageFontSize;
|
|
22342
|
+
const rowWidths = row.map((it) => it.str.length > 0 ? it.width / it.str.length : 0).filter((w) => w > 0);
|
|
22343
|
+
const rowMedianCharWidth = rowWidths.length ? [...rowWidths].sort((a, b) => a - b)[Math.floor(rowWidths.length / 2)] || 1 : 1;
|
|
22344
|
+
const rowLabelGap = rowMedianCharWidth * FORM_LABEL_GAP_FACTOR;
|
|
22345
|
+
let plainText = "";
|
|
22346
|
+
let inlineHtml = "";
|
|
22347
|
+
let hasAnyStyle = false;
|
|
22348
|
+
for (let i = 0; i < row.length; i++) {
|
|
22349
|
+
const it = row[i];
|
|
22350
|
+
let sep = "";
|
|
22351
|
+
if (i > 0) {
|
|
22352
|
+
const prev = row[i - 1];
|
|
22353
|
+
const gap = it.x - prev.right;
|
|
22354
|
+
const prevStr = prev.str.trimEnd();
|
|
22355
|
+
sep = /:$/.test(prevStr) && gap > rowLabelGap ? "\xA0\xA0" : " ";
|
|
22356
|
+
}
|
|
22357
|
+
plainText += sep + it.str;
|
|
22358
|
+
const escaped = escapeHtml(normalizeLigatures(it.str));
|
|
22359
|
+
const style = detectFontStyle(it.fontName);
|
|
22360
|
+
if (style) hasAnyStyle = true;
|
|
22361
|
+
let styledPart = style === "bold-italic" ? `<strong><em>${escaped}</em></strong>` : style === "bold" ? `<strong>${escaped}</strong>` : style === "italic" ? `<em>${escaped}</em>` : escaped;
|
|
22362
|
+
if (it.linkUrl && isSafeUrl(it.linkUrl)) {
|
|
22363
|
+
styledPart = `<a href="${escapeHtml(it.linkUrl)}">${styledPart}</a>`;
|
|
22364
|
+
}
|
|
22365
|
+
inlineHtml += (i > 0 ? escapeHtml(sep) : "") + styledPart;
|
|
22366
|
+
}
|
|
22367
|
+
plainText = plainText.replace(/[ \t]+/g, " ").trim();
|
|
22368
|
+
if (!plainText) continue;
|
|
22369
|
+
const normalizedPlain = normalizeLigatures(plainText);
|
|
22370
|
+
const normalized = normalizedPlain.replace(/\s+/g, " ").trim().toLowerCase();
|
|
22371
|
+
if (getFeatureFlags().enablePdfEnhanced) {
|
|
22372
|
+
const listMatch = detectListMarker(normalizedPlain);
|
|
22373
|
+
if (listMatch) {
|
|
22374
|
+
if (pendingListKind !== null && pendingListKind !== listMatch.kind) {
|
|
22375
|
+
flushPendingList();
|
|
22376
|
+
}
|
|
22377
|
+
pendingListKind = listMatch.kind;
|
|
22378
|
+
const escapedBody = escapeHtml(normalizeLigatures(listMatch.bodyText));
|
|
22379
|
+
pendingListHtml.push(`<li>${escapedBody}</li>`);
|
|
22380
|
+
textLines.push(normalizedPlain);
|
|
22381
|
+
continue;
|
|
22382
|
+
}
|
|
22383
|
+
}
|
|
22384
|
+
flushPendingList();
|
|
22385
|
+
const ratio = medianPageFontSize > 0 ? rowFs / medianPageFontSize : 1;
|
|
22386
|
+
let headingLevel = 0;
|
|
22387
|
+
if (ratio >= 1.5) headingLevel = 1;
|
|
22388
|
+
else if (ratio >= 1.25) headingLevel = 2;
|
|
22389
|
+
else if (ratio >= 1.1) headingLevel = 3;
|
|
22390
|
+
if (headingLevel === 0 && outlineTitles.size > 0) {
|
|
22391
|
+
if (outlineTitles.has(normalized) || fuzzyMatchOutline(normalized, outlineTitles)) {
|
|
22392
|
+
headingLevel = 2;
|
|
22393
|
+
}
|
|
22394
|
+
}
|
|
22395
|
+
textLines.push(normalizedPlain);
|
|
22396
|
+
if (headingLevel > 0) {
|
|
22397
|
+
htmlBlocks.push(`<h${headingLevel}>${inlineHtml}</h${headingLevel}>`);
|
|
22398
|
+
} else {
|
|
22399
|
+
const hasWideGap = /( {3,}|\u00A0\u00A0|\t)/.test(normalizedPlain);
|
|
22400
|
+
const isShort = normalizedPlain.length < 100 && !/[.,:;!?]$/.test(normalizedPlain) && !/\n/.test(normalizedPlain) && !hasWideGap;
|
|
22401
|
+
if (isShort && !hasAnyStyle) {
|
|
22402
|
+
htmlBlocks.push(`<p><strong>${inlineHtml}</strong></p>`);
|
|
22403
|
+
} else {
|
|
22404
|
+
htmlBlocks.push(`<p>${inlineHtml}</p>`);
|
|
22405
|
+
}
|
|
22406
|
+
}
|
|
22407
|
+
}
|
|
22408
|
+
flushPendingList();
|
|
22409
|
+
return {
|
|
22410
|
+
htmlBlocks,
|
|
22411
|
+
textContent: textLines.join("\n").replace(/[ \t]+/g, " ").replace(/\n{3,}/g, "\n\n").trim()
|
|
22412
|
+
};
|
|
22413
|
+
}
|
|
22414
|
+
function repairRowHyphenation(rows) {
|
|
22415
|
+
if (rows.length < 2) return rows;
|
|
22416
|
+
const result = [];
|
|
22417
|
+
let i = 0;
|
|
22418
|
+
while (i < rows.length) {
|
|
22419
|
+
if (i + 1 < rows.length) {
|
|
22420
|
+
const row = rows[i];
|
|
22421
|
+
const nextRow = rows[i + 1];
|
|
22422
|
+
const lastItem = [...row].sort((a, b) => b.right - a.right)[0];
|
|
22423
|
+
const firstNext = [...nextRow].sort((a, b) => a.x - b.x)[0];
|
|
22424
|
+
if (lastItem && firstNext && /-$/.test(lastItem.str) && new RegExp("^\\p{Ll}", "u").test(firstNext.str)) {
|
|
22425
|
+
const fixed = { ...lastItem, str: lastItem.str.slice(0, -1) };
|
|
22426
|
+
result.push([...row.map((it) => it === lastItem ? fixed : it), ...nextRow]);
|
|
22427
|
+
i += 2;
|
|
22428
|
+
continue;
|
|
22429
|
+
}
|
|
22430
|
+
}
|
|
22431
|
+
result.push(rows[i]);
|
|
22432
|
+
i++;
|
|
22433
|
+
}
|
|
22434
|
+
return result;
|
|
22435
|
+
}
|
|
22436
|
+
function detectListMarker(plainText) {
|
|
22437
|
+
const bulletMatch = /^[•◦◆▪▸–\-*·]\s+(.+)/u.exec(plainText);
|
|
22438
|
+
if (bulletMatch) return { kind: "ul", bodyText: bulletMatch[1] };
|
|
22439
|
+
const numberedMatch = /^\d+[.)]\s+(.+)/.exec(plainText);
|
|
22440
|
+
if (numberedMatch) return { kind: "ol", bodyText: numberedMatch[1] };
|
|
22441
|
+
const letteredMatch = /^[a-z][.)]\s+(.+)/.exec(plainText);
|
|
22442
|
+
if (letteredMatch) return { kind: "ol", bodyText: letteredMatch[1] };
|
|
22443
|
+
return null;
|
|
22444
|
+
}
|
|
22445
|
+
function detectAndReorderColumns(rows) {
|
|
22446
|
+
if (rows.length < 4) return rows;
|
|
22447
|
+
const allItems = rows.flat();
|
|
22448
|
+
const itemWidths = allItems.filter((it) => it.width > 0 && it.str.trim().length > 0).map((it) => it.width);
|
|
22449
|
+
if (itemWidths.length === 0) return rows;
|
|
22450
|
+
const sortedWidths = [...itemWidths].sort((a, b) => a - b);
|
|
22451
|
+
const medianWidth = sortedWidths[Math.floor(sortedWidths.length / 2)];
|
|
22452
|
+
const gutterThreshold = medianWidth * 3;
|
|
22453
|
+
const xMin = allItems.reduce((m, it) => Math.min(m, it.x), Infinity);
|
|
22454
|
+
const xMax = allItems.reduce((m, it) => Math.max(m, it.right), -Infinity);
|
|
22455
|
+
const midLeft = xMin + (xMax - xMin) * 0.25;
|
|
22456
|
+
const midRight = xMin + (xMax - xMin) * 0.75;
|
|
22457
|
+
const gutterMidpoints = [];
|
|
22458
|
+
for (const row of rows) {
|
|
22459
|
+
if (row.length < 2) continue;
|
|
22460
|
+
const rowSorted = [...row].sort((a, b) => a.x - b.x);
|
|
22461
|
+
for (let i = 1; i < rowSorted.length; i++) {
|
|
22462
|
+
const prev = rowSorted[i - 1];
|
|
22463
|
+
const curr = rowSorted[i];
|
|
22464
|
+
const gap = curr.x - prev.right;
|
|
22465
|
+
if (gap < gutterThreshold) continue;
|
|
22466
|
+
const midX = (prev.right + curr.x) / 2;
|
|
22467
|
+
if (midX >= midLeft && midX <= midRight) {
|
|
22468
|
+
gutterMidpoints.push(midX);
|
|
22469
|
+
break;
|
|
22470
|
+
}
|
|
22471
|
+
}
|
|
22472
|
+
}
|
|
22473
|
+
const multiItemRowCount = rows.filter((r) => r.length >= 2).length;
|
|
22474
|
+
const minVotes = Math.max(2, Math.ceil(multiItemRowCount * 0.35));
|
|
22475
|
+
if (gutterMidpoints.length < minVotes) return rows;
|
|
22476
|
+
const sortedGutters = [...gutterMidpoints].sort((a, b) => a - b);
|
|
22477
|
+
const gutterX = sortedGutters[Math.floor(sortedGutters.length / 2)];
|
|
22478
|
+
const leftRows = [];
|
|
22479
|
+
const rightRows = [];
|
|
22480
|
+
for (const row of rows) {
|
|
22481
|
+
const leftItems = row.filter((it) => it.x + it.width / 2 <= gutterX);
|
|
22482
|
+
const rightItems = row.filter((it) => it.x + it.width / 2 > gutterX);
|
|
22483
|
+
if (leftItems.length > 0) leftRows.push(leftItems);
|
|
22484
|
+
if (rightItems.length > 0) rightRows.push(rightItems);
|
|
22485
|
+
}
|
|
22486
|
+
if (leftRows.length < 2 || rightRows.length < 2) return rows;
|
|
22487
|
+
const sortTopDown = (arr) => [...arr].sort((a, b) => {
|
|
22488
|
+
const aTop = a.reduce((m, it) => Math.max(m, it.y + it.height), -Infinity);
|
|
22489
|
+
const bTop = b.reduce((m, it) => Math.max(m, it.y + it.height), -Infinity);
|
|
22490
|
+
return bTop - aTop;
|
|
22491
|
+
});
|
|
22492
|
+
return [...sortTopDown(leftRows), ...sortTopDown(rightRows)];
|
|
22493
|
+
}
|
|
22494
|
+
function buildHeaderFooterSuppressSet(pageDataArray) {
|
|
22495
|
+
const totalPages = pageDataArray.length;
|
|
22496
|
+
if (totalPages < 3) return /* @__PURE__ */ new Set();
|
|
22497
|
+
const HEADER_THRESHOLD = 0.92;
|
|
22498
|
+
const FOOTER_THRESHOLD = 0.08;
|
|
22499
|
+
const Y_TOLERANCE = 5;
|
|
22500
|
+
const MIN_PAGE_FRACTION = 0.4;
|
|
22501
|
+
const occurrences = /* @__PURE__ */ new Map();
|
|
22502
|
+
for (const { pageNum, items, viewportHeight } of pageDataArray) {
|
|
22503
|
+
for (const it of items) {
|
|
22504
|
+
const itemTop = it.y + it.height;
|
|
22505
|
+
const inHeader = itemTop > viewportHeight * HEADER_THRESHOLD;
|
|
22506
|
+
const inFooter = it.y < viewportHeight * FOOTER_THRESHOLD;
|
|
22507
|
+
if (!inHeader && !inFooter) continue;
|
|
22508
|
+
const normalized = it.str.replace(/\s+/g, " ").trim().toLowerCase();
|
|
22509
|
+
if (normalized.length === 0) continue;
|
|
22510
|
+
const yBucket = Math.round(it.y / Y_TOLERANCE) * Y_TOLERANCE;
|
|
22511
|
+
const key = `${normalized}@${yBucket}`;
|
|
22512
|
+
if (!occurrences.has(key)) occurrences.set(key, /* @__PURE__ */ new Set());
|
|
22513
|
+
occurrences.get(key).add(pageNum);
|
|
22514
|
+
}
|
|
22515
|
+
}
|
|
22516
|
+
const suppressSet = /* @__PURE__ */ new Set();
|
|
22517
|
+
for (const [key, pageSet] of occurrences) {
|
|
22518
|
+
if (pageSet.size / totalPages >= MIN_PAGE_FRACTION) {
|
|
22519
|
+
suppressSet.add(key);
|
|
22520
|
+
}
|
|
22521
|
+
}
|
|
22522
|
+
return suppressSet;
|
|
22523
|
+
}
|
|
22524
|
+
function isHeaderFooterItem(it, suppressSet, Y_TOLERANCE = 5) {
|
|
22525
|
+
if (suppressSet.size === 0) return false;
|
|
22526
|
+
const normalized = it.str.replace(/\s+/g, " ").trim().toLowerCase();
|
|
22527
|
+
if (normalized.length === 0) return false;
|
|
22528
|
+
const yBucket = Math.round(it.y / Y_TOLERANCE) * Y_TOLERANCE;
|
|
22529
|
+
return suppressSet.has(`${normalized}@${yBucket}`);
|
|
22530
|
+
}
|
|
22531
|
+
var PDF_OP = { moveTo: 13, lineTo: 14, closePath: 18, rectangle: 92 };
|
|
22532
|
+
function extractVectorLines(fnArray, argsArray, pageWidth, pageHeight) {
|
|
22533
|
+
const MIN_H_SPAN = pageWidth * 0.3;
|
|
22534
|
+
const MIN_V_SPAN = pageHeight * 0.3;
|
|
22535
|
+
const lines = [];
|
|
22536
|
+
let curX = 0;
|
|
22537
|
+
let curY = 0;
|
|
22538
|
+
let pathStartX = 0;
|
|
22539
|
+
let pathStartY = 0;
|
|
22540
|
+
const pushIfSignificant = (x0, y0, x1, y1) => {
|
|
22541
|
+
const dx = Math.abs(x1 - x0);
|
|
22542
|
+
const dy = Math.abs(y1 - y0);
|
|
22543
|
+
if (dy < 2 && dx >= MIN_H_SPAN) {
|
|
22544
|
+
lines.push({
|
|
22545
|
+
orientation: "h",
|
|
22546
|
+
position: (y0 + y1) / 2,
|
|
22547
|
+
span: [Math.min(x0, x1), Math.max(x0, x1)]
|
|
22548
|
+
});
|
|
22549
|
+
} else if (dx < 2 && dy >= MIN_V_SPAN) {
|
|
22550
|
+
lines.push({
|
|
22551
|
+
orientation: "v",
|
|
22552
|
+
position: (x0 + x1) / 2,
|
|
22553
|
+
span: [Math.min(y0, y1), Math.max(y0, y1)]
|
|
22554
|
+
});
|
|
22555
|
+
}
|
|
22556
|
+
};
|
|
22557
|
+
for (let i = 0; i < fnArray.length; i++) {
|
|
22558
|
+
const op = fnArray[i];
|
|
22559
|
+
const args = argsArray[i] ?? [];
|
|
22560
|
+
if (op === PDF_OP.moveTo) {
|
|
22561
|
+
curX = args[0] ?? 0;
|
|
22562
|
+
curY = args[1] ?? 0;
|
|
22563
|
+
pathStartX = curX;
|
|
22564
|
+
pathStartY = curY;
|
|
22565
|
+
} else if (op === PDF_OP.lineTo) {
|
|
22566
|
+
const nx = args[0] ?? 0;
|
|
22567
|
+
const ny = args[1] ?? 0;
|
|
22568
|
+
pushIfSignificant(curX, curY, nx, ny);
|
|
22569
|
+
curX = nx;
|
|
22570
|
+
curY = ny;
|
|
22571
|
+
} else if (op === PDF_OP.rectangle) {
|
|
22572
|
+
const rx = args[0] ?? 0;
|
|
22573
|
+
const ry = args[1] ?? 0;
|
|
22574
|
+
const rw = args[2] ?? 0;
|
|
22575
|
+
const rh = args[3] ?? 0;
|
|
22576
|
+
pushIfSignificant(rx, ry, rx + rw, ry);
|
|
22577
|
+
pushIfSignificant(rx, ry + rh, rx + rw, ry + rh);
|
|
22578
|
+
pushIfSignificant(rx, ry, rx, ry + rh);
|
|
22579
|
+
pushIfSignificant(rx + rw, ry, rx + rw, ry + rh);
|
|
22580
|
+
} else if (op === PDF_OP.closePath) {
|
|
22581
|
+
pushIfSignificant(curX, curY, pathStartX, pathStartY);
|
|
22582
|
+
curX = pathStartX;
|
|
22583
|
+
curY = pathStartY;
|
|
22584
|
+
}
|
|
22585
|
+
}
|
|
22586
|
+
return lines;
|
|
22587
|
+
}
|
|
22588
|
+
function applyLinkAnnotations(items, annotations) {
|
|
22589
|
+
const linkAnns = annotations.filter(
|
|
22590
|
+
(a) => a.subtype === "Link" && a.url && a.rect && a.rect.length === 4
|
|
22591
|
+
);
|
|
22592
|
+
if (linkAnns.length === 0) return;
|
|
22593
|
+
for (const it of items) {
|
|
22594
|
+
const itArea = Math.max(it.width * it.height, 1e-6);
|
|
22595
|
+
for (const ann of linkAnns) {
|
|
22596
|
+
const [llx, lly, urx, ury] = ann.rect;
|
|
22597
|
+
const ox = Math.max(0, Math.min(it.right, urx) - Math.max(it.x, llx));
|
|
22598
|
+
const oy = Math.max(0, Math.min(it.y + it.height, ury) - Math.max(it.y, lly));
|
|
22599
|
+
if (ox * oy / itArea >= 0.2) {
|
|
22600
|
+
it.linkUrl = ann.url;
|
|
22601
|
+
break;
|
|
22602
|
+
}
|
|
22603
|
+
}
|
|
22604
|
+
}
|
|
22605
|
+
}
|
|
22606
|
+
function renderPage(items, pageNum, nextPageNum, enableTableDetection, translate, pageBottomY, enhancedOpts, ruleSeparators) {
|
|
22105
22607
|
const warnings = [];
|
|
22106
|
-
const candidates = enableTableDetection ? findTableRegions(items, { pageBottomY }) : [];
|
|
22608
|
+
const candidates = enableTableDetection ? findTableRegions(items, { pageBottomY, ruleSeparators }) : [];
|
|
22107
22609
|
const htmlBlocks = [];
|
|
22108
22610
|
const candsByY = [...candidates].sort((a, b) => b.bbox.y1 - a.bbox.y1);
|
|
22109
22611
|
const itemOverlapsCandidate = (it, c) => {
|
|
@@ -22167,36 +22669,46 @@ function renderPage(items, pageNum, nextPageNum, enableTableDetection, translate
|
|
|
22167
22669
|
}
|
|
22168
22670
|
linearTextParts.push(tableToText(block.cand));
|
|
22169
22671
|
} else {
|
|
22170
|
-
|
|
22171
|
-
|
|
22172
|
-
|
|
22173
|
-
|
|
22174
|
-
|
|
22175
|
-
|
|
22176
|
-
|
|
22177
|
-
|
|
22178
|
-
|
|
22179
|
-
|
|
22180
|
-
|
|
22181
|
-
|
|
22182
|
-
|
|
22183
|
-
|
|
22184
|
-
|
|
22185
|
-
|
|
22186
|
-
|
|
22187
|
-
|
|
22188
|
-
|
|
22189
|
-
|
|
22190
|
-
|
|
22191
|
-
|
|
22192
|
-
|
|
22193
|
-
|
|
22194
|
-
const
|
|
22195
|
-
const
|
|
22196
|
-
|
|
22197
|
-
|
|
22198
|
-
|
|
22199
|
-
|
|
22672
|
+
if (enhancedOpts) {
|
|
22673
|
+
const { htmlBlocks: eBlocks, textContent: eText } = renderTextBlockEnhanced(
|
|
22674
|
+
block.items,
|
|
22675
|
+
enhancedOpts.medianFontSize,
|
|
22676
|
+
enhancedOpts.outlineTitles
|
|
22677
|
+
);
|
|
22678
|
+
if (eText) linearTextParts.push(eText);
|
|
22679
|
+
for (const b of eBlocks) htmlBlocks.push(b);
|
|
22680
|
+
} else {
|
|
22681
|
+
const text = itemsToLinearText(block.items);
|
|
22682
|
+
if (!text) continue;
|
|
22683
|
+
linearTextParts.push(text);
|
|
22684
|
+
const medH = (() => {
|
|
22685
|
+
const hs = block.items.map((i) => i.height).filter((h) => h > 0);
|
|
22686
|
+
if (hs.length === 0) return 10;
|
|
22687
|
+
return hs.sort((a, b) => a - b)[Math.floor(hs.length / 2)] || 10;
|
|
22688
|
+
})();
|
|
22689
|
+
const topY = block.items.reduce(
|
|
22690
|
+
(m, it) => Math.max(m, it.y + it.height),
|
|
22691
|
+
-Infinity
|
|
22692
|
+
);
|
|
22693
|
+
const topRowItems = block.items.filter(
|
|
22694
|
+
(it) => topY - (it.y + it.height) <= medH * 0.5
|
|
22695
|
+
);
|
|
22696
|
+
const topRowLooksTabular = topRowItems.length >= 4 && topRowItems.some((a) => topRowItems.some((b) => b.x - a.right > medH * 2));
|
|
22697
|
+
const paragraphs = text.split(/\n{2,}/);
|
|
22698
|
+
let paraIdx = 0;
|
|
22699
|
+
for (const para of paragraphs) {
|
|
22700
|
+
const trimmed = para.trim();
|
|
22701
|
+
paraIdx++;
|
|
22702
|
+
if (!trimmed) continue;
|
|
22703
|
+
const hasWideGap = /( {3,}|\u00A0\u00A0|\t)/.test(trimmed);
|
|
22704
|
+
const isFirstPara = paraIdx === 1;
|
|
22705
|
+
const looksTabular = hasWideGap || isFirstPara && topRowLooksTabular;
|
|
22706
|
+
const short = trimmed.length < 100 && !/[.,:;!?]$/.test(trimmed) && !/\n/.test(trimmed) && !looksTabular;
|
|
22707
|
+
if (short) {
|
|
22708
|
+
htmlBlocks.push(`<p><strong>${escapeHtml(trimmed)}</strong></p>`);
|
|
22709
|
+
} else {
|
|
22710
|
+
htmlBlocks.push(`<p>${escapeHtml(trimmed)}</p>`);
|
|
22711
|
+
}
|
|
22200
22712
|
}
|
|
22201
22713
|
}
|
|
22202
22714
|
}
|
|
@@ -22292,6 +22804,43 @@ var PdfAdapter = class {
|
|
|
22292
22804
|
}
|
|
22293
22805
|
} catch {
|
|
22294
22806
|
}
|
|
22807
|
+
let isTaggedPdf = false;
|
|
22808
|
+
let outlineTitles = /* @__PURE__ */ new Set();
|
|
22809
|
+
if (getFeatureFlags().enablePdfEnhanced) {
|
|
22810
|
+
try {
|
|
22811
|
+
const markInfo = await pdf.getMarkInfo();
|
|
22812
|
+
isTaggedPdf = markInfo?.Marked === true;
|
|
22813
|
+
} catch {
|
|
22814
|
+
}
|
|
22815
|
+
try {
|
|
22816
|
+
const outline = await pdf.getOutline();
|
|
22817
|
+
outlineTitles = buildOutlineSet(outline);
|
|
22818
|
+
} catch {
|
|
22819
|
+
}
|
|
22820
|
+
}
|
|
22821
|
+
let hfSuppressSet = /* @__PURE__ */ new Set();
|
|
22822
|
+
if (getFeatureFlags().enablePdfEnhanced && numPages >= 3 && numPages <= 200) {
|
|
22823
|
+
const hfCandidates = [];
|
|
22824
|
+
for (let pn = 1; pn <= numPages; pn++) {
|
|
22825
|
+
try {
|
|
22826
|
+
const hfPage = await pdf.getPage(pn);
|
|
22827
|
+
const hfViewport = hfPage.getViewport({ scale: 1 });
|
|
22828
|
+
const hfText = await hfPage.getTextContent();
|
|
22829
|
+
const hfAnns = await hfPage.getAnnotations().catch(() => []);
|
|
22830
|
+
const hfPositioned = [];
|
|
22831
|
+
for (const item of hfText.items) {
|
|
22832
|
+
if (!("str" in item) || typeof item.str !== "string") continue;
|
|
22833
|
+
const p = textItemToPositioned(item);
|
|
22834
|
+
if (p) hfPositioned.push(p);
|
|
22835
|
+
}
|
|
22836
|
+
const hfWidgets = hfAnns.flatMap(widgetToPositionedItems);
|
|
22837
|
+
const hfItems = hfWidgets.length > 0 ? [...dedupAgainstWidgets(hfPositioned, hfWidgets), ...hfWidgets] : hfPositioned;
|
|
22838
|
+
hfCandidates.push({ pageNum: pn, items: hfItems, viewportHeight: hfViewport.height });
|
|
22839
|
+
} catch {
|
|
22840
|
+
}
|
|
22841
|
+
}
|
|
22842
|
+
hfSuppressSet = buildHeaderFooterSuppressSet(hfCandidates);
|
|
22843
|
+
}
|
|
22295
22844
|
for (let pageNum = 1; pageNum <= numPages; pageNum++) {
|
|
22296
22845
|
onProgress?.(pageNum / numPages);
|
|
22297
22846
|
const page = await pdf.getPage(pageNum);
|
|
@@ -22314,14 +22863,75 @@ var PdfAdapter = class {
|
|
|
22314
22863
|
}
|
|
22315
22864
|
const widgetItems = annotations.flatMap(widgetToPositionedItems);
|
|
22316
22865
|
const items = widgetItems.length > 0 ? [...dedupAgainstWidgets(positionedText, widgetItems), ...widgetItems] : positionedText;
|
|
22866
|
+
if (getFeatureFlags().enablePdfEnhanced) {
|
|
22867
|
+
applyLinkAnnotations(items, annotations);
|
|
22868
|
+
}
|
|
22869
|
+
const renderItems = getFeatureFlags().enablePdfEnhanced && hfSuppressSet.size > 0 ? items.filter((it) => !isHeaderFooterItem(it, hfSuppressSet)) : items;
|
|
22870
|
+
if (getFeatureFlags().enablePdfEnhanced && isTaggedPdf) {
|
|
22871
|
+
let structHtml = null;
|
|
22872
|
+
try {
|
|
22873
|
+
if (hasStructTree(page)) {
|
|
22874
|
+
structHtml = await structTreeToHtml(page);
|
|
22875
|
+
}
|
|
22876
|
+
} catch {
|
|
22877
|
+
}
|
|
22878
|
+
if (structHtml !== null) {
|
|
22879
|
+
const structTextLen = structHtml.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim().length;
|
|
22880
|
+
const geoTextLen = renderItems.map((it) => it.str).join(" ").length;
|
|
22881
|
+
if (geoTextLen > 0 && structTextLen / geoTextLen < 0.7) {
|
|
22882
|
+
structHtml = null;
|
|
22883
|
+
}
|
|
22884
|
+
}
|
|
22885
|
+
if (structHtml !== null) {
|
|
22886
|
+
const plainText = structHtml.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
|
|
22887
|
+
totalTextLength += plainText.length;
|
|
22888
|
+
let hasImages2 = false;
|
|
22889
|
+
try {
|
|
22890
|
+
const opList = await page.getOperatorList();
|
|
22891
|
+
hasImages2 = opList.fnArray.some((op) => op === 85 || op === 86);
|
|
22892
|
+
} catch {
|
|
22893
|
+
}
|
|
22894
|
+
pages.push({
|
|
22895
|
+
pageNumber: pageNum,
|
|
22896
|
+
textContent: plainText,
|
|
22897
|
+
hasImages: hasImages2,
|
|
22898
|
+
viewportWidth: viewport.width,
|
|
22899
|
+
htmlBlocks: [structHtml],
|
|
22900
|
+
tablesDetected: 0
|
|
22901
|
+
});
|
|
22902
|
+
continue;
|
|
22903
|
+
}
|
|
22904
|
+
}
|
|
22905
|
+
let enhancedOpts;
|
|
22906
|
+
if (getFeatureFlags().enablePdfEnhanced) {
|
|
22907
|
+
const fsSamples = positionedText.map((it) => it.fontSize ?? 0).filter((f) => f > 0);
|
|
22908
|
+
const medianFontSize = fsSamples.length > 0 ? [...fsSamples].sort((a, b) => a - b)[Math.floor(fsSamples.length / 2)] : 12;
|
|
22909
|
+
enhancedOpts = { medianFontSize, outlineTitles };
|
|
22910
|
+
}
|
|
22317
22911
|
const pageBottomY = Array.isArray(page.view) && page.view.length >= 2 ? page.view[1] : 0;
|
|
22912
|
+
let pageOpList;
|
|
22913
|
+
let ruleSeparators;
|
|
22914
|
+
try {
|
|
22915
|
+
pageOpList = await page.getOperatorList();
|
|
22916
|
+
if (getFeatureFlags().enablePdfEnhanced && tableDetectionEnabled) {
|
|
22917
|
+
ruleSeparators = extractVectorLines(
|
|
22918
|
+
pageOpList.fnArray,
|
|
22919
|
+
pageOpList.argsArray ?? [],
|
|
22920
|
+
viewport.width,
|
|
22921
|
+
viewport.height
|
|
22922
|
+
);
|
|
22923
|
+
}
|
|
22924
|
+
} catch {
|
|
22925
|
+
}
|
|
22318
22926
|
const rendered = renderPage(
|
|
22319
|
-
|
|
22927
|
+
renderItems,
|
|
22320
22928
|
pageNum,
|
|
22321
22929
|
pageNum < numPages ? pageNum + 1 : void 0,
|
|
22322
22930
|
tableDetectionEnabled,
|
|
22323
22931
|
translate,
|
|
22324
|
-
pageBottomY
|
|
22932
|
+
pageBottomY,
|
|
22933
|
+
enhancedOpts,
|
|
22934
|
+
ruleSeparators
|
|
22325
22935
|
);
|
|
22326
22936
|
for (const w of rendered.warnings) warnings.push(w);
|
|
22327
22937
|
if (!hasMultiColumnWarning && !rendered.anyTableDetected && xPositions.length > 10) {
|
|
@@ -22345,12 +22955,7 @@ var PdfAdapter = class {
|
|
|
22345
22955
|
}
|
|
22346
22956
|
}
|
|
22347
22957
|
totalTextLength += rendered.textContent.length;
|
|
22348
|
-
|
|
22349
|
-
try {
|
|
22350
|
-
const operatorList = await page.getOperatorList();
|
|
22351
|
-
hasImages = operatorList.fnArray.some((op) => op === 85 || op === 86);
|
|
22352
|
-
} catch {
|
|
22353
|
-
}
|
|
22958
|
+
const hasImages = pageOpList?.fnArray.some((op) => op === 85 || op === 86) ?? false;
|
|
22354
22959
|
pages.push({
|
|
22355
22960
|
pageNumber: pageNum,
|
|
22356
22961
|
textContent: rendered.textContent,
|
|
@@ -24689,8 +25294,8 @@ import { readFileSync as readFileSync4 } from "fs";
|
|
|
24689
25294
|
import { resolve, dirname as dirname3 } from "path";
|
|
24690
25295
|
import { fileURLToPath } from "url";
|
|
24691
25296
|
var getVersion = () => {
|
|
24692
|
-
if ("1.0.
|
|
24693
|
-
return "1.0.
|
|
25297
|
+
if ("1.0.14") {
|
|
25298
|
+
return "1.0.14";
|
|
24694
25299
|
}
|
|
24695
25300
|
try {
|
|
24696
25301
|
const __dirname = dirname3(fileURLToPath(import.meta.url));
|