reamkit 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/esm/core/converter/facade.js +6 -1
- package/dist/esm/core/converter/ream.js +2 -1
- package/dist/esm/core/document-model/types.d.ts +9 -1
- package/dist/esm/core/spreadsheet-model/index.d.ts +1 -1
- package/dist/esm/core/spreadsheet-model/types.d.ts +5 -0
- package/dist/esm/excel/column-bands.d.ts +7 -0
- package/dist/esm/excel/column-bands.js +87 -0
- package/dist/esm/excel/conditional-format.js +22 -0
- package/dist/esm/excel/print-model.js +30 -11
- package/dist/esm/excel/worksheet-parser.js +26 -0
- package/dist/esm/excel/xlsx-writer.js +8 -1
- package/dist/esm/html/html-writer.js +100 -5
- package/dist/esm/layout/styled-layout.js +88 -19
- package/dist/esm/pdf-reader/cmap.d.ts +5 -0
- package/dist/esm/pdf-reader/cmap.js +72 -0
- package/dist/esm/pdf-reader/content.d.ts +14 -0
- package/dist/esm/pdf-reader/content.js +292 -0
- package/dist/esm/pdf-reader/document.d.ts +23 -0
- package/dist/esm/pdf-reader/document.js +230 -0
- package/dist/esm/pdf-reader/flow-build.d.ts +4 -0
- package/dist/esm/pdf-reader/flow-build.js +27 -0
- package/dist/esm/pdf-reader/font.d.ts +4 -0
- package/dist/esm/pdf-reader/font.js +69 -0
- package/dist/esm/pdf-reader/layout.d.ts +3 -0
- package/dist/esm/pdf-reader/layout.js +69 -0
- package/dist/esm/pdf-reader/lexer.d.ts +43 -0
- package/dist/esm/pdf-reader/lexer.js +250 -0
- package/dist/esm/pdf-reader/parser.d.ts +10 -0
- package/dist/esm/pdf-reader/parser.js +86 -0
- package/dist/esm/pdf-reader/reader.d.ts +4 -0
- package/dist/esm/pdf-reader/reader.js +43 -0
- package/dist/esm/pdf-reader/struct-tree.d.ts +14 -0
- package/dist/esm/pdf-reader/struct-tree.js +92 -0
- package/dist/esm/pdf-reader/tagged.d.ts +3 -0
- package/dist/esm/pdf-reader/tagged.js +88 -0
- package/dist/esm/pdf-reader/text.d.ts +3 -0
- package/dist/esm/pdf-reader/text.js +18 -0
- package/package.json +2 -2
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { pt } from "../core/ir/units.js";
|
|
2
|
+
import { buildFlowDoc, paragraphBlock } from "./flow-build.js";
|
|
3
|
+
import { extractPageText } from "./text.js";
|
|
4
|
+
import { readStructTree } from "./struct-tree.js";
|
|
5
|
+
//#region src/pdf-reader/tagged.ts
|
|
6
|
+
var ASSUMED_CONTENT_WIDTH_PT = 468;
|
|
7
|
+
function reconstructTaggedPdf(file) {
|
|
8
|
+
const root = readStructTree(file);
|
|
9
|
+
if (!root) return void 0;
|
|
10
|
+
const pageText = file.pages().map((page) => {
|
|
11
|
+
const byMcid = /* @__PURE__ */ new Map();
|
|
12
|
+
for (const run of extractPageText(file, page)) if (run.mcid !== void 0) byMcid.set(run.mcid, (byMcid.get(run.mcid) ?? "") + run.text);
|
|
13
|
+
return byMcid;
|
|
14
|
+
});
|
|
15
|
+
const textOf = (node) => squash(node.mcids.map(({ page, mcid }) => pageText[page]?.get(mcid) ?? "").join(" "));
|
|
16
|
+
const collectText = (node) => squash([textOf(node), ...node.children.map(collectText)].join(" "));
|
|
17
|
+
function emit(node, out) {
|
|
18
|
+
if (node.type === "Table") {
|
|
19
|
+
const table = buildTable(node);
|
|
20
|
+
if (table) out.push(table);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (node.type === "LI") {
|
|
24
|
+
const text = collectText(node);
|
|
25
|
+
if (text.length > 0) out.push(paragraphBlock(text, void 0));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (node.children.length === 0) {
|
|
29
|
+
const text = textOf(node);
|
|
30
|
+
if (text.length > 0) out.push(paragraphBlock(text, headingLevel(node.type)));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
for (const child of node.children) emit(child, out);
|
|
34
|
+
}
|
|
35
|
+
function buildTable(tableNode) {
|
|
36
|
+
const rows = [];
|
|
37
|
+
const collectRows = (n) => {
|
|
38
|
+
for (const child of n.children) if (child.type === "TR") rows.push(buildRow(child));
|
|
39
|
+
else if (child.type === "THead" || child.type === "TBody" || child.type === "TFoot") collectRows(child);
|
|
40
|
+
};
|
|
41
|
+
collectRows(tableNode);
|
|
42
|
+
if (rows.length === 0) return void 0;
|
|
43
|
+
const numCols = Math.max(1, ...rows.map((r) => r.cells.reduce((s, c) => s + (c.properties.colSpan ?? 1), 0)));
|
|
44
|
+
const colWidth = pt(Math.max(1, ASSUMED_CONTENT_WIDTH_PT / numCols));
|
|
45
|
+
return {
|
|
46
|
+
kind: "table",
|
|
47
|
+
table: {
|
|
48
|
+
properties: {},
|
|
49
|
+
grid: Array.from({ length: numCols }, () => colWidth),
|
|
50
|
+
rows
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function buildRow(trNode) {
|
|
55
|
+
const cells = [];
|
|
56
|
+
let allHeader = false;
|
|
57
|
+
for (const cell of trNode.children) {
|
|
58
|
+
if (cell.type !== "TH" && cell.type !== "TD") continue;
|
|
59
|
+
if (cells.length === 0) allHeader = true;
|
|
60
|
+
if (cell.type !== "TH") allHeader = false;
|
|
61
|
+
const content = [];
|
|
62
|
+
for (const child of cell.children) emit(child, content);
|
|
63
|
+
if (content.length === 0) content.push(paragraphBlock(textOf(cell), void 0));
|
|
64
|
+
const colSpan = cell.colSpan ?? 1;
|
|
65
|
+
cells.push({
|
|
66
|
+
properties: colSpan > 1 ? { colSpan } : {},
|
|
67
|
+
content
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
properties: allHeader && cells.length > 0 ? { isHeader: true } : {},
|
|
72
|
+
cells
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const body = [];
|
|
76
|
+
emit(root, body);
|
|
77
|
+
if (body.length === 0) return void 0;
|
|
78
|
+
return buildFlowDoc(body);
|
|
79
|
+
}
|
|
80
|
+
function squash(text) {
|
|
81
|
+
return text.replace(/\s+/g, " ").trim();
|
|
82
|
+
}
|
|
83
|
+
function headingLevel(type) {
|
|
84
|
+
const m = /^H([1-6])$/.exec(type);
|
|
85
|
+
return m ? Number(m[1]) - 1 : void 0;
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { reconstructTaggedPdf };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { interpretContent } from "./content.js";
|
|
2
|
+
import { buildContentFont } from "./font.js";
|
|
3
|
+
//#region src/pdf-reader/text.ts
|
|
4
|
+
function extractPageText(file, page) {
|
|
5
|
+
const fonts = /* @__PURE__ */ new Map();
|
|
6
|
+
if (page.resources) {
|
|
7
|
+
const fontContainer = file.get(page.resources, "Font");
|
|
8
|
+
if (fontContainer instanceof Map) for (const [fontName, fontRef] of fontContainer) {
|
|
9
|
+
const fontDict = file.resolve(fontRef);
|
|
10
|
+
if (fontDict instanceof Map) try {
|
|
11
|
+
fonts.set(fontName, buildContentFont(file, fontDict));
|
|
12
|
+
} catch {}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return interpretContent(file.pageContent(page), fonts);
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { extractPageText };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reamkit",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Ream — DOCX
|
|
3
|
+
"version": "1.6.0",
|
|
4
|
+
"description": "Ream — convert DOCX, XLSX and PDF to PDF, SVG, HTML, DOCX and XLSX, built from scratch on the ECMA-376 and ISO 32000 specifications. Parse once, convert anywhere.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Alex Krassavin <info@reamkit.dev>",
|
|
7
7
|
"repository": {
|