reamkit 0.1.0-alpha.0 → 1.0.1
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 +107 -30
- package/dist/esm/{bidi → core/bidi}/algorithm.js +1 -1
- package/dist/esm/{bidi → core/bidi}/char-types.js +1 -1
- package/dist/esm/{bidi → core/bidi}/index.d.ts +2 -0
- package/dist/esm/{bidi → core/bidi}/index.js +2 -1
- package/dist/esm/core/bidi/segments.d.ts +6 -0
- package/dist/esm/core/bidi/segments.js +41 -0
- package/dist/esm/core/bytes.d.ts +1 -0
- package/dist/esm/core/bytes.js +11 -0
- package/dist/esm/core/converter/facade.d.ts +45 -0
- package/dist/esm/core/converter/facade.js +89 -0
- package/dist/esm/core/converter/index.d.ts +4 -0
- package/dist/esm/core/converter/project.d.ts +4 -0
- package/dist/esm/core/converter/project.js +17 -0
- package/dist/esm/core/converter/ream.d.ts +35 -0
- package/dist/esm/core/converter/ream.js +101 -0
- package/dist/esm/{crypto → core/crypto}/asn1.js +1 -1
- package/dist/esm/{crypto → core/crypto}/cms.js +1 -1
- package/dist/esm/core/document-model/index.d.ts +1 -0
- package/dist/esm/{document-model → core/document-model}/types.d.ts +57 -41
- package/dist/esm/{ooxml → core}/drawingml/chart-parser.d.ts +1 -1
- package/dist/esm/{ooxml → core}/drawingml/chart-parser.js +6 -29
- package/dist/esm/{ooxml → core}/drawingml/colors.d.ts +3 -0
- package/dist/esm/{ooxml → core}/drawingml/colors.js +32 -2
- package/dist/esm/{ooxml → core}/drawingml/theme-parser.js +2 -2
- package/dist/esm/{font → core/font}/arabic-joining.js +1 -1
- package/dist/esm/{font → core/font}/binary-reader.js +1 -1
- package/dist/esm/{font → core/font}/font-registry.d.ts +1 -0
- package/dist/esm/{font → core/font}/font-registry.js +17 -16
- package/dist/esm/{font → core/font}/index.d.ts +3 -0
- package/dist/esm/core/font/measure.d.ts +7 -0
- package/dist/esm/core/font/measure.js +30 -0
- package/dist/esm/{font → core/font}/opentype-layout.js +1 -1
- package/dist/esm/{font → core/font}/ttf-parser.js +1 -1
- package/dist/esm/{font → core/font}/ttf-subset.js +1 -1
- package/dist/esm/core/fonts/provider.d.ts +60 -0
- package/dist/esm/core/fonts/provider.js +163 -0
- package/dist/esm/{fonts → core/fonts}/remote-fonts.js +1 -1
- package/dist/esm/{hyphenation → core/hyphenation}/index.js +1 -1
- package/dist/esm/{hyphenation → core/hyphenation}/liang.js +1 -1
- package/dist/esm/{hyphenation → core/hyphenation}/patterns-en-us.js +1 -1
- package/dist/esm/{hyphenation → core/hyphenation}/patterns-ru.js +1 -1
- package/dist/esm/core/images.d.ts +17 -0
- package/dist/esm/core/images.js +308 -0
- package/dist/esm/core/ir/adapters.d.ts +37 -0
- package/dist/esm/core/ir/features.d.ts +25 -0
- package/dist/esm/core/ir/features.js +24 -0
- package/dist/esm/core/ir/flow.d.ts +24 -0
- package/dist/esm/core/ir/index.d.ts +11 -0
- package/dist/esm/core/ir/loss.d.ts +22 -0
- package/dist/esm/core/ir/loss.js +15 -0
- package/dist/esm/core/ir/resources.d.ts +16 -0
- package/dist/esm/core/ir/resources.js +50 -0
- package/dist/esm/core/ir/units.d.ts +16 -0
- package/dist/esm/core/ir/units.js +41 -0
- package/dist/esm/core/line-breaker/index.d.ts +2 -0
- package/dist/esm/{line-breaker → core/line-breaker}/knuth-plass.d.ts +1 -0
- package/dist/esm/{line-breaker → core/line-breaker}/knuth-plass.js +3 -3
- package/dist/esm/core/numbering/apply.d.ts +3 -0
- package/dist/esm/core/numbering/apply.js +62 -0
- package/dist/esm/core/numbering/index.d.ts +2 -0
- package/dist/esm/{numbering → core/numbering}/state.js +1 -1
- package/dist/esm/{opc → core/opc}/core-properties.js +1 -1
- package/dist/esm/{opc → core/opc}/package.d.ts +2 -1
- package/dist/esm/{opc → core/opc}/package.js +7 -3
- package/dist/esm/{opc → core/opc}/relationship-types.js +1 -1
- package/dist/esm/{opc → core/opc}/relationships.js +1 -1
- package/dist/esm/{ooxml/wordproc → core}/po-helpers.js +1 -1
- package/dist/esm/core/style-cascade/index.d.ts +3 -0
- package/dist/esm/core/style-cascade/index.js +2 -0
- package/dist/esm/core/style-cascade/resolver.d.ts +7 -0
- package/dist/esm/{style-cascade → core/style-cascade}/resolver.js +82 -10
- package/dist/esm/{style-cascade → core/style-cascade}/types.d.ts +10 -8
- package/dist/esm/{style-cascade → core/style-cascade}/types.js +9 -8
- package/dist/esm/core/vector.d.ts +45 -0
- package/dist/esm/core/vector.js +48 -0
- package/dist/esm/{ooxml/spreadsheet → excel}/cell-reference.js +1 -1
- package/dist/esm/{ooxml/spreadsheet → excel}/defined-name-ref.js +1 -1
- package/dist/esm/{ooxml/spreadsheet → excel}/index.d.ts +1 -1
- package/dist/esm/{ooxml/spreadsheet → excel}/number-format.js +1 -1
- package/dist/esm/excel/print-model.d.ts +18 -0
- package/dist/esm/{converter/xlsx-to-pdf.js → excel/print-model.js} +39 -148
- package/dist/esm/{ooxml/spreadsheet → excel}/shared-strings-parser.js +1 -1
- package/dist/esm/{ooxml/spreadsheet → excel}/styles-parser.js +1 -1
- package/dist/esm/{ooxml/spreadsheet → excel}/workbook-parser.js +1 -1
- package/dist/esm/{ooxml/spreadsheet → excel}/worksheet-parser.js +1 -1
- package/dist/esm/excel/xlsx-reader.d.ts +4 -0
- package/dist/esm/excel/xlsx-reader.js +91 -0
- package/dist/esm/{converter → excel}/xlsx-to-pdf.d.ts +13 -2
- package/dist/esm/excel/xlsx-to-pdf.js +69 -0
- package/dist/esm/index.d.ts +23 -8
- package/dist/esm/index.js +18 -10
- package/dist/esm/{pdf → layout}/arc-to-bezier.d.ts +1 -1
- package/dist/esm/{pdf → layout}/arc-to-bezier.js +2 -2
- package/dist/esm/{pdf → layout}/chart-geometry.d.ts +1 -1
- package/dist/esm/{pdf → layout}/math-layout.d.ts +2 -2
- package/dist/esm/{pdf → layout}/math-layout.js +1 -1
- package/dist/esm/layout/page-doc.d.ts +133 -0
- package/dist/esm/layout/page-doc.js +38 -0
- package/dist/esm/{pdf → layout}/preset-geometry.d.ts +2 -2
- package/dist/esm/{pdf → layout}/preset-geometry.js +2 -2
- package/dist/esm/layout/styled-layout.d.ts +84 -0
- package/dist/esm/layout/styled-layout.js +1729 -0
- package/dist/esm/pdf/cid-font.d.ts +1 -1
- package/dist/esm/pdf/cid-font.js +6 -21
- package/dist/esm/pdf/image-xobject.d.ts +4 -5
- package/dist/esm/pdf/image-xobject.js +21 -324
- package/dist/esm/pdf/index.d.ts +2 -2
- package/dist/esm/pdf/index.js +1 -0
- package/dist/esm/pdf/signature.js +4 -4
- package/dist/esm/pdf/styled-page-emitter.d.ts +11 -0
- package/dist/esm/pdf/styled-page-emitter.js +557 -0
- package/dist/esm/pdf/styled-page-renderer.d.ts +4 -42
- package/dist/esm/pdf/styled-page-renderer.js +4 -2311
- package/dist/esm/pdf/text-page-renderer.d.ts +1 -1
- package/dist/esm/pdf/vector-graphics.d.ts +3 -45
- package/dist/esm/pdf/vector-graphics.js +2 -46
- package/dist/esm/svg/svg-writer.d.ts +8 -0
- package/dist/esm/svg/svg-writer.js +137 -0
- package/dist/esm/word/document-parser.d.ts +16 -0
- package/dist/esm/{ooxml/wordproc → word}/document-parser.js +55 -47
- package/dist/esm/word/docx-reader.d.ts +4 -0
- package/dist/esm/word/docx-reader.js +191 -0
- package/dist/esm/word/docx-to-pdf.d.ts +34 -0
- package/dist/esm/word/docx-to-pdf.js +112 -0
- package/dist/esm/{ooxml/wordproc → word}/drawing-parser.d.ts +10 -9
- package/dist/esm/{ooxml/wordproc → word}/drawing-parser.js +15 -42
- package/dist/esm/{ooxml/wordproc → word}/font-table.d.ts +2 -2
- package/dist/esm/{ooxml/wordproc → word}/font-table.js +2 -2
- package/dist/esm/{ooxml/wordproc → word}/index.d.ts +3 -2
- package/dist/esm/{ooxml/wordproc → word}/numbering-parser.d.ts +1 -1
- package/dist/esm/{ooxml/wordproc → word}/numbering-parser.js +1 -1
- package/dist/esm/{ooxml/math → word}/omml-parser.d.ts +2 -2
- package/dist/esm/{ooxml/math → word}/omml-parser.js +2 -2
- package/dist/esm/{ooxml/wordproc → word}/paragraph-properties.d.ts +1 -1
- package/dist/esm/{ooxml/wordproc → word}/paragraph-properties.js +9 -8
- package/dist/esm/{ooxml/wordproc → word}/po-to-flat.d.ts +1 -1
- package/dist/esm/{ooxml/wordproc → word}/po-to-flat.js +2 -2
- package/dist/esm/{ooxml/wordproc → word}/run-properties.d.ts +1 -1
- package/dist/esm/{ooxml/wordproc → word}/run-properties.js +3 -2
- package/dist/esm/{ooxml/wordproc → word}/settings-parser.js +2 -2
- package/dist/esm/word/styles-parser.d.ts +2 -0
- package/dist/esm/{ooxml/wordproc → word}/styles-parser.js +4 -7
- package/dist/esm/word/table-parser.d.ts +4 -0
- package/dist/esm/{ooxml/wordproc → word}/table-parser.js +80 -26
- package/dist/esm/{ooxml/wordproc → word}/xml-helpers.js +1 -1
- package/package.json +5 -6
- package/dist/esm/converter/docx-to-pdf.d.ts +0 -15
- package/dist/esm/converter/docx-to-pdf.js +0 -227
- package/dist/esm/converter/index.d.ts +0 -4
- package/dist/esm/converter/index.js +0 -2
- package/dist/esm/document-model/index.d.ts +0 -1
- package/dist/esm/line-breaker/index.d.ts +0 -2
- package/dist/esm/numbering/index.d.ts +0 -1
- package/dist/esm/ooxml/index.d.ts +0 -1
- package/dist/esm/ooxml/wordproc/document-parser.d.ts +0 -9
- package/dist/esm/ooxml/wordproc/styles-parser.d.ts +0 -3
- package/dist/esm/ooxml/wordproc/table-parser.d.ts +0 -3
- package/dist/esm/style-cascade/index.d.ts +0 -3
- package/dist/esm/style-cascade/resolver.d.ts +0 -4
- /package/dist/esm/{bidi → core/bidi}/algorithm.d.ts +0 -0
- /package/dist/esm/{bidi → core/bidi}/char-types.d.ts +0 -0
- /package/dist/esm/{crypto → core/crypto}/asn1.d.ts +0 -0
- /package/dist/esm/{crypto → core/crypto}/cms.d.ts +0 -0
- /package/dist/esm/{crypto → core/crypto}/index.d.ts +0 -0
- /package/dist/esm/{crypto → core/crypto}/index.js +0 -0
- /package/dist/esm/{document-model → core/document-model}/index.js +0 -0
- /package/dist/esm/{ooxml → core}/drawingml/theme-parser.d.ts +0 -0
- /package/dist/esm/{font → core/font}/arabic-joining.d.ts +0 -0
- /package/dist/esm/{font → core/font}/binary-reader.d.ts +0 -0
- /package/dist/esm/{font → core/font}/opentype-layout.d.ts +0 -0
- /package/dist/esm/{font → core/font}/ttf-parser.d.ts +0 -0
- /package/dist/esm/{font → core/font}/ttf-subset.d.ts +0 -0
- /package/dist/esm/{fonts → core/fonts}/index.d.ts +0 -0
- /package/dist/esm/{fonts → core/fonts}/remote-fonts.d.ts +0 -0
- /package/dist/esm/{hyphenation → core/hyphenation}/index.d.ts +0 -0
- /package/dist/esm/{hyphenation → core/hyphenation}/liang.d.ts +0 -0
- /package/dist/esm/{hyphenation → core/hyphenation}/patterns-en-us.d.ts +0 -0
- /package/dist/esm/{hyphenation → core/hyphenation}/patterns-ru.d.ts +0 -0
- /package/dist/esm/{numbering → core/numbering}/state.d.ts +0 -0
- /package/dist/esm/{opc → core/opc}/core-properties.d.ts +0 -0
- /package/dist/esm/{opc → core/opc}/index.d.ts +0 -0
- /package/dist/esm/{opc → core/opc}/index.js +0 -0
- /package/dist/esm/{opc → core/opc}/relationship-types.d.ts +0 -0
- /package/dist/esm/{opc → core/opc}/relationships.d.ts +0 -0
- /package/dist/esm/{ooxml/wordproc → core}/po-helpers.d.ts +0 -0
- /package/dist/esm/{ooxml/spreadsheet → excel}/cell-reference.d.ts +0 -0
- /package/dist/esm/{ooxml/spreadsheet → excel}/defined-name-ref.d.ts +0 -0
- /package/dist/esm/{ooxml/spreadsheet → excel}/index.js +0 -0
- /package/dist/esm/{ooxml/spreadsheet → excel}/number-format.d.ts +0 -0
- /package/dist/esm/{ooxml/spreadsheet → excel}/shared-strings-parser.d.ts +0 -0
- /package/dist/esm/{ooxml/spreadsheet → excel}/styles-parser.d.ts +0 -0
- /package/dist/esm/{ooxml/spreadsheet → excel}/workbook-parser.d.ts +0 -0
- /package/dist/esm/{ooxml/spreadsheet → excel}/worksheet-parser.d.ts +0 -0
- /package/dist/esm/{pdf → layout}/chart-geometry.js +0 -0
- /package/dist/esm/{ooxml/wordproc → word}/index.js +0 -0
- /package/dist/esm/{ooxml/wordproc → word}/settings-parser.d.ts +0 -0
- /package/dist/esm/{ooxml/wordproc → word}/text-extractor.d.ts +0 -0
- /package/dist/esm/{ooxml/wordproc → word}/text-extractor.js +0 -0
- /package/dist/esm/{ooxml/wordproc → word}/xml-helpers.d.ts +0 -0
|
@@ -1,46 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
readonly y: number;
|
|
5
|
-
} | {
|
|
6
|
-
readonly op: 'line';
|
|
7
|
-
readonly x: number;
|
|
8
|
-
readonly y: number;
|
|
9
|
-
} | {
|
|
10
|
-
readonly op: 'cubic';
|
|
11
|
-
readonly x1: number;
|
|
12
|
-
readonly y1: number;
|
|
13
|
-
readonly x2: number;
|
|
14
|
-
readonly y2: number;
|
|
15
|
-
readonly x: number;
|
|
16
|
-
readonly y: number;
|
|
17
|
-
} | {
|
|
18
|
-
readonly op: 'close';
|
|
19
|
-
};
|
|
20
|
-
export interface VectorPath {
|
|
21
|
-
readonly segments: ReadonlyArray<PathSegment>;
|
|
22
|
-
readonly fillRule?: 'nonzero' | 'evenodd';
|
|
23
|
-
}
|
|
24
|
-
export interface StrokeStyle {
|
|
25
|
-
readonly colorHex: string;
|
|
26
|
-
readonly widthPt: number;
|
|
27
|
-
readonly cap?: 'butt' | 'round' | 'square';
|
|
28
|
-
readonly join?: 'miter' | 'round' | 'bevel';
|
|
29
|
-
readonly dash?: ReadonlyArray<number>;
|
|
30
|
-
}
|
|
31
|
-
export interface VectorShape {
|
|
32
|
-
readonly paths: ReadonlyArray<VectorPath>;
|
|
33
|
-
readonly fillColorHex?: string;
|
|
34
|
-
readonly stroke?: StrokeStyle;
|
|
35
|
-
readonly transform: readonly [number, number, number, number, number, number];
|
|
36
|
-
}
|
|
37
|
-
export declare class PathBuilder {
|
|
38
|
-
private readonly segments;
|
|
39
|
-
moveTo(x: number, y: number): this;
|
|
40
|
-
lineTo(x: number, y: number): this;
|
|
41
|
-
cubicTo(x1: number, y1: number, x2: number, y2: number, x: number, y: number): this;
|
|
42
|
-
append(segments: ReadonlyArray<PathSegment>): this;
|
|
43
|
-
close(): this;
|
|
44
|
-
build(fillRule?: 'nonzero' | 'evenodd'): VectorPath;
|
|
45
|
-
}
|
|
1
|
+
import { VectorShape } from '../core/vector.js';
|
|
2
|
+
export type { PathSegment, StrokeStyle, VectorPath, VectorShape } from '../core/vector.js';
|
|
3
|
+
export { PathBuilder } from '../core/vector.js';
|
|
46
4
|
export declare function emitVectorShape(shape: VectorShape): Array<string>;
|
|
@@ -1,49 +1,5 @@
|
|
|
1
|
+
import "../core/vector.js";
|
|
1
2
|
//#region src/pdf/vector-graphics.ts
|
|
2
|
-
var PathBuilder = class {
|
|
3
|
-
segments = [];
|
|
4
|
-
moveTo(x, y) {
|
|
5
|
-
this.segments.push({
|
|
6
|
-
op: "move",
|
|
7
|
-
x,
|
|
8
|
-
y
|
|
9
|
-
});
|
|
10
|
-
return this;
|
|
11
|
-
}
|
|
12
|
-
lineTo(x, y) {
|
|
13
|
-
this.segments.push({
|
|
14
|
-
op: "line",
|
|
15
|
-
x,
|
|
16
|
-
y
|
|
17
|
-
});
|
|
18
|
-
return this;
|
|
19
|
-
}
|
|
20
|
-
cubicTo(x1, y1, x2, y2, x, y) {
|
|
21
|
-
this.segments.push({
|
|
22
|
-
op: "cubic",
|
|
23
|
-
x1,
|
|
24
|
-
y1,
|
|
25
|
-
x2,
|
|
26
|
-
y2,
|
|
27
|
-
x,
|
|
28
|
-
y
|
|
29
|
-
});
|
|
30
|
-
return this;
|
|
31
|
-
}
|
|
32
|
-
append(segments) {
|
|
33
|
-
for (const s of segments) this.segments.push(s);
|
|
34
|
-
return this;
|
|
35
|
-
}
|
|
36
|
-
close() {
|
|
37
|
-
this.segments.push({ op: "close" });
|
|
38
|
-
return this;
|
|
39
|
-
}
|
|
40
|
-
build(fillRule) {
|
|
41
|
-
return {
|
|
42
|
-
segments: this.segments.slice(),
|
|
43
|
-
...fillRule ? { fillRule } : {}
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
3
|
function emitVectorShape(shape) {
|
|
48
4
|
const out = [];
|
|
49
5
|
out.push("q");
|
|
@@ -100,4 +56,4 @@ function hexToRgb01(hex) {
|
|
|
100
56
|
];
|
|
101
57
|
}
|
|
102
58
|
//#endregion
|
|
103
|
-
export {
|
|
59
|
+
export { emitVectorShape };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DocumentWriter, WriteResult } from '../core/ir/adapters.js';
|
|
2
|
+
import { LaidOutDocument } from '../layout/page-doc.js';
|
|
3
|
+
export interface SvgWriteOptions {
|
|
4
|
+
/** Gap between stacked pages, in px/pt (default 12). */
|
|
5
|
+
readonly pageGap?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function writeSvg(laid: LaidOutDocument, opts?: SvgWriteOptions): WriteResult;
|
|
8
|
+
export declare const svgWriter: DocumentWriter<LaidOutDocument>;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { FEATURES } from "../core/ir/features.js";
|
|
2
|
+
import { paintPlan } from "../layout/page-doc.js";
|
|
3
|
+
//#region src/svg/svg-writer.ts
|
|
4
|
+
var PAGE_GAP = 12;
|
|
5
|
+
function writeSvg(laid, opts = {}) {
|
|
6
|
+
const gap = opts.pageGap ?? PAGE_GAP;
|
|
7
|
+
const losses = [];
|
|
8
|
+
const width = Math.max(1, ...laid.pages.map((p) => p.width));
|
|
9
|
+
const height = laid.pages.reduce((s, p) => s + p.height, 0) + gap * Math.max(0, laid.pages.length - 1);
|
|
10
|
+
const parts = [];
|
|
11
|
+
parts.push(`<svg xmlns="http://www.w3.org/2000/svg" width="${fmt(width)}" height="${fmt(height)}" viewBox="0 0 ${fmt(width)} ${fmt(height)}">`);
|
|
12
|
+
let yOffset = 0;
|
|
13
|
+
laid.pages.forEach((page, i) => {
|
|
14
|
+
parts.push(`<g transform="translate(0 ${fmt(yOffset)})" data-page="${i + 1}">`);
|
|
15
|
+
parts.push(`<rect x="0" y="0" width="${fmt(page.width)}" height="${fmt(page.height)}" fill="#ffffff" stroke="#cccccc"/>`);
|
|
16
|
+
emitPage(parts, page, laid, losses);
|
|
17
|
+
parts.push("</g>");
|
|
18
|
+
yOffset += page.height + gap;
|
|
19
|
+
});
|
|
20
|
+
parts.push("</svg>");
|
|
21
|
+
return {
|
|
22
|
+
bytes: new TextEncoder().encode(parts.join("\n")),
|
|
23
|
+
losses
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
var svgWriter = {
|
|
27
|
+
id: "svg",
|
|
28
|
+
consumes: "page",
|
|
29
|
+
supports: new Set([
|
|
30
|
+
FEATURES.text,
|
|
31
|
+
FEATURES.tables,
|
|
32
|
+
FEATURES.images,
|
|
33
|
+
FEATURES.shapes
|
|
34
|
+
]),
|
|
35
|
+
write: (doc, opts) => writeSvg(doc, opts ?? {})
|
|
36
|
+
};
|
|
37
|
+
function emitPage(out, page, laid, losses) {
|
|
38
|
+
const plan = paintPlan(page.commands);
|
|
39
|
+
for (const f of plan.fills) out.push(`<rect x="${fmt(f.x)}" y="${fmt(f.y)}" width="${fmt(f.width)}" height="${fmt(f.height)}" fill="#${f.fillColorHex}"/>`);
|
|
40
|
+
for (const img of plan.images) {
|
|
41
|
+
const href = imageHref(img.imageResourceName, laid);
|
|
42
|
+
if (!href) continue;
|
|
43
|
+
out.push(`<image x="${fmt(img.x)}" y="${fmt(img.y)}" width="${fmt(img.width)}" height="${fmt(img.height)}" href="${href}" preserveAspectRatio="none"/>`);
|
|
44
|
+
}
|
|
45
|
+
for (const b of plan.borders) {
|
|
46
|
+
const x2 = b.x + b.width;
|
|
47
|
+
const yTop = b.y;
|
|
48
|
+
const yBottom = b.y + b.height;
|
|
49
|
+
const [ax, ay, bx, by] = b.side === "top" ? [
|
|
50
|
+
b.x,
|
|
51
|
+
yTop,
|
|
52
|
+
x2,
|
|
53
|
+
yTop
|
|
54
|
+
] : b.side === "bottom" ? [
|
|
55
|
+
b.x,
|
|
56
|
+
yBottom,
|
|
57
|
+
x2,
|
|
58
|
+
yBottom
|
|
59
|
+
] : b.side === "left" ? [
|
|
60
|
+
b.x,
|
|
61
|
+
yTop,
|
|
62
|
+
b.x,
|
|
63
|
+
yBottom
|
|
64
|
+
] : [
|
|
65
|
+
x2,
|
|
66
|
+
yTop,
|
|
67
|
+
x2,
|
|
68
|
+
yBottom
|
|
69
|
+
];
|
|
70
|
+
out.push(`<line x1="${fmt(ax)}" y1="${fmt(ay)}" x2="${fmt(bx)}" y2="${fmt(by)}" stroke="#${b.borderColorHex}" stroke-width="${fmt(b.borderSizePt)}"/>`);
|
|
71
|
+
}
|
|
72
|
+
for (const sh of plan.shapes) emitShape(out, sh.shape);
|
|
73
|
+
for (const t of plan.lines) emitTextLine(out, t, losses);
|
|
74
|
+
}
|
|
75
|
+
function emitTextLine(out, item, losses) {
|
|
76
|
+
const y = item.baselineY;
|
|
77
|
+
let x = item.originX;
|
|
78
|
+
for (const tok of item.line.tokens) {
|
|
79
|
+
if (tok.kind === "image") {
|
|
80
|
+
x += tok.widthPt;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (tok.kind === "math") {
|
|
84
|
+
losses.push({
|
|
85
|
+
severity: "dropped",
|
|
86
|
+
feature: FEATURES.math,
|
|
87
|
+
detail: "inline math box not rendered by the SVG writer (v0)"
|
|
88
|
+
});
|
|
89
|
+
x += tok.widthPt;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (tok.text.trim().length > 0) out.push(`<text x="${fmt(x)}" y="${fmt(y)}" font-family="sans-serif" font-size="${fmt(tok.fontSizePt)}" fill="#${tok.resolvedRun.colorHex}">${escapeXml(tok.text)}</text>`);
|
|
93
|
+
x += tok.widthPt;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function emitShape(out, shape) {
|
|
97
|
+
const [a, b, c, d, e, f] = shape.transform;
|
|
98
|
+
const transform = `matrix(${fmt(a)} ${fmt(b)} ${fmt(c)} ${fmt(d)} ${fmt(e)} ${fmt(f)})`;
|
|
99
|
+
const fill = shape.fillColorHex ? `#${shape.fillColorHex}` : "none";
|
|
100
|
+
const stroke = shape.stroke ? ` stroke="#${shape.stroke.colorHex}" stroke-width="${fmt(shape.stroke.widthPt)}"` : "";
|
|
101
|
+
for (const path of shape.paths) {
|
|
102
|
+
const d2 = pathData(path.segments);
|
|
103
|
+
const rule = path.fillRule === "evenodd" ? " fill-rule=\"evenodd\"" : "";
|
|
104
|
+
out.push(`<path d="${d2}" fill="${fill}"${rule}${stroke} transform="${transform}"/>`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function pathData(segments) {
|
|
108
|
+
const parts = [];
|
|
109
|
+
for (const s of segments) if (s.op === "move") parts.push(`M ${fmt(s.x)} ${fmt(s.y)}`);
|
|
110
|
+
else if (s.op === "line") parts.push(`L ${fmt(s.x)} ${fmt(s.y)}`);
|
|
111
|
+
else if (s.op === "cubic") parts.push(`C ${fmt(s.x1)} ${fmt(s.y1)} ${fmt(s.x2)} ${fmt(s.y2)} ${fmt(s.x)} ${fmt(s.y)}`);
|
|
112
|
+
else parts.push("Z");
|
|
113
|
+
return parts.join(" ");
|
|
114
|
+
}
|
|
115
|
+
function imageHref(resourceName, laid) {
|
|
116
|
+
if (!resourceName) return void 0;
|
|
117
|
+
for (const [resourceId, res] of laid.imageResources) {
|
|
118
|
+
if (res.resourceName !== resourceName) continue;
|
|
119
|
+
const bytes = laid.resources.get(resourceId);
|
|
120
|
+
if (!bytes) return void 0;
|
|
121
|
+
return `data:${res.prepared.mimeType};base64,${toBase64(bytes)}`;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function toBase64(bytes) {
|
|
125
|
+
let bin = "";
|
|
126
|
+
for (const b of bytes) bin += String.fromCharCode(b);
|
|
127
|
+
return btoa(bin);
|
|
128
|
+
}
|
|
129
|
+
function escapeXml(s) {
|
|
130
|
+
return s.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """);
|
|
131
|
+
}
|
|
132
|
+
function fmt(n) {
|
|
133
|
+
const r = Math.round(n * 100) / 100;
|
|
134
|
+
return Object.is(r, -0) ? "0" : String(r);
|
|
135
|
+
}
|
|
136
|
+
//#endregion
|
|
137
|
+
export { svgWriter, writeSvg };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BodyElement, Section, SectionProperties } from '../core/document-model/index.js';
|
|
2
|
+
import { ColorResolver } from '../core/drawingml/colors.js';
|
|
3
|
+
import { ResourceId } from '../core/ir/index.js';
|
|
4
|
+
import { PoNode } from '../core/po-helpers.js';
|
|
5
|
+
export type ImageResolver = (relId: string) => ResourceId | undefined;
|
|
6
|
+
export interface ParseContext {
|
|
7
|
+
readonly resolveColor: ColorResolver;
|
|
8
|
+
readonly resolveImage?: ImageResolver;
|
|
9
|
+
}
|
|
10
|
+
export declare const DEFAULT_PARSE_CONTEXT: ParseContext;
|
|
11
|
+
export declare function parseDocument(documentXml: Uint8Array, ctx?: ParseContext): Array<BodyElement>;
|
|
12
|
+
export declare const EMPTY_SECTION: SectionProperties;
|
|
13
|
+
export declare function parseSection(documentXml: Uint8Array): SectionProperties;
|
|
14
|
+
export declare function parseSections(documentXml: Uint8Array): Array<Section>;
|
|
15
|
+
export declare function parseHeaderFooter(xml: Uint8Array, ctx?: ParseContext): Array<BodyElement>;
|
|
16
|
+
export declare function parseBodyElements(children: ReadonlyArray<PoNode>, ctx?: ParseContext): Array<BodyElement>;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { twipsToPt } from "../core/ir/units.js";
|
|
2
|
+
import { poAttr, poChildren, poFindByPath, poIntAttr, poIs, poText } from "../core/po-helpers.js";
|
|
3
|
+
import { defaultColorResolver } from "../core/drawingml/colors.js";
|
|
4
|
+
import { parseOMath } from "./omml-parser.js";
|
|
4
5
|
import { expandMcChildren, parseDrawing } from "./drawing-parser.js";
|
|
5
6
|
import { parseRunProperties } from "./run-properties.js";
|
|
6
7
|
import { parseParagraphProperties } from "./paragraph-properties.js";
|
|
7
8
|
import { poElementToFlat } from "./po-to-flat.js";
|
|
8
9
|
import { parseTable } from "./table-parser.js";
|
|
9
10
|
import { XMLParser } from "fast-xml-parser";
|
|
10
|
-
//#region src/
|
|
11
|
+
//#region src/word/document-parser.ts
|
|
11
12
|
var decoder = new TextDecoder("utf-8");
|
|
12
13
|
var parser = new XMLParser({
|
|
13
14
|
ignoreAttributes: false,
|
|
@@ -26,11 +27,12 @@ var RUN_CONTAINER_TAGS = new Set([
|
|
|
26
27
|
"w:ins",
|
|
27
28
|
"w:moveTo"
|
|
28
29
|
]);
|
|
29
|
-
|
|
30
|
+
var DEFAULT_PARSE_CONTEXT = { resolveColor: defaultColorResolver };
|
|
31
|
+
function parseDocument(documentXml, ctx = DEFAULT_PARSE_CONTEXT) {
|
|
30
32
|
const xml = decoder.decode(documentXml);
|
|
31
33
|
const body = poFindByPath(parser.parse(xml), ["w:document", "w:body"]);
|
|
32
34
|
if (!body) return [];
|
|
33
|
-
return parseBodyElements(poChildren(body),
|
|
35
|
+
return parseBodyElements(poChildren(body), ctx);
|
|
34
36
|
}
|
|
35
37
|
var HF_TYPES = new Set([
|
|
36
38
|
"default",
|
|
@@ -83,8 +85,8 @@ function parseSectPrNode(sectPr) {
|
|
|
83
85
|
const h = poIntAttr(child, "h");
|
|
84
86
|
const orientRaw = poAttr(child, "orient");
|
|
85
87
|
if (w !== void 0 && h !== void 0) pageSize = {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
width: twipsToPt(w),
|
|
89
|
+
height: twipsToPt(h),
|
|
88
90
|
...orientRaw === "portrait" || orientRaw === "landscape" ? { orientation: orientRaw } : {}
|
|
89
91
|
};
|
|
90
92
|
} else if (poIs(child, "w:pgMar")) {
|
|
@@ -95,12 +97,12 @@ function parseSectPrNode(sectPr) {
|
|
|
95
97
|
const header = poIntAttr(child, "header");
|
|
96
98
|
const footer = poIntAttr(child, "footer");
|
|
97
99
|
margins = {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
...header !== void 0 ? {
|
|
103
|
-
...footer !== void 0 ? {
|
|
100
|
+
top: twipsToPt(top ?? 1440),
|
|
101
|
+
right: twipsToPt(right ?? 1440),
|
|
102
|
+
bottom: twipsToPt(bottom ?? 1440),
|
|
103
|
+
left: twipsToPt(left ?? 1440),
|
|
104
|
+
...header !== void 0 ? { header: twipsToPt(header) } : {},
|
|
105
|
+
...footer !== void 0 ? { footer: twipsToPt(footer) } : {}
|
|
104
106
|
};
|
|
105
107
|
} else if (poIs(child, "w:headerReference")) pushHeaderFooter(child, headers);
|
|
106
108
|
else if (poIs(child, "w:footerReference")) pushHeaderFooter(child, footers);
|
|
@@ -126,26 +128,26 @@ function pushHeaderFooter(node, list) {
|
|
|
126
128
|
relationshipId: rId
|
|
127
129
|
});
|
|
128
130
|
}
|
|
129
|
-
function parseHeaderFooter(xml,
|
|
131
|
+
function parseHeaderFooter(xml, ctx = DEFAULT_PARSE_CONTEXT) {
|
|
130
132
|
const root = parser.parse(decoder.decode(xml)).find((n) => poIs(n, "w:hdr") || poIs(n, "w:ftr"));
|
|
131
133
|
if (!root) return [];
|
|
132
|
-
return parseBodyElements(poChildren(root),
|
|
134
|
+
return parseBodyElements(poChildren(root), ctx);
|
|
133
135
|
}
|
|
134
|
-
function parseBodyElements(children,
|
|
136
|
+
function parseBodyElements(children, ctx = DEFAULT_PARSE_CONTEXT) {
|
|
135
137
|
const out = [];
|
|
136
138
|
for (const child of children) if (poIs(child, "w:p")) {
|
|
137
|
-
const drawing = tryExtractDrawingFromParagraph(child,
|
|
139
|
+
const drawing = tryExtractDrawingFromParagraph(child, ctx);
|
|
138
140
|
out.push(drawing ?? {
|
|
139
141
|
kind: "paragraph",
|
|
140
|
-
paragraph: parseParagraph(child)
|
|
142
|
+
paragraph: parseParagraph(child, ctx)
|
|
141
143
|
});
|
|
142
144
|
} else if (poIs(child, "w:tbl")) out.push({
|
|
143
145
|
kind: "table",
|
|
144
|
-
table: parseTable(child)
|
|
146
|
+
table: parseTable(child, ctx)
|
|
145
147
|
});
|
|
146
148
|
return out;
|
|
147
149
|
}
|
|
148
|
-
function tryExtractDrawingFromParagraph(p,
|
|
150
|
+
function tryExtractDrawingFromParagraph(p, ctx) {
|
|
149
151
|
let drawing;
|
|
150
152
|
let hasText = false;
|
|
151
153
|
for (const child of poChildren(p)) {
|
|
@@ -156,27 +158,30 @@ function tryExtractDrawingFromParagraph(p, resolveColor) {
|
|
|
156
158
|
else if (poIs(runChild, "w:tab") || poIs(runChild, "w:br") || poIs(runChild, "w:noBreakHyphen")) hasText = true;
|
|
157
159
|
}
|
|
158
160
|
if (!drawing || hasText) return null;
|
|
159
|
-
const parseBody = (children) => parseBodyElements(children,
|
|
160
|
-
const content = parseDrawing(drawing, resolveColor, parseBody);
|
|
161
|
+
const parseBody = (children) => parseBodyElements(children, ctx);
|
|
162
|
+
const content = parseDrawing(drawing, ctx.resolveColor, parseBody);
|
|
161
163
|
if (!content) return null;
|
|
162
164
|
const pPrNode = poChildren(p).find((c) => poIs(c, "w:pPr"));
|
|
163
165
|
const paragraphProperties = pPrNode ? parseParagraphProperties(poElementToFlat(pPrNode)) : {};
|
|
164
|
-
if (content.kind === "image")
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
166
|
+
if (content.kind === "image") {
|
|
167
|
+
const resource = ctx.resolveImage?.(content.imageId);
|
|
168
|
+
return {
|
|
169
|
+
kind: "image",
|
|
170
|
+
image: {
|
|
171
|
+
...resource ? { resource } : {},
|
|
172
|
+
width: content.width,
|
|
173
|
+
height: content.height,
|
|
174
|
+
paragraphProperties,
|
|
175
|
+
...content.altText ? { altText: content.altText } : {}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
}
|
|
174
179
|
if (content.kind === "chart") return {
|
|
175
180
|
kind: "chart",
|
|
176
181
|
chart: {
|
|
177
182
|
chartRelId: content.chartRelId,
|
|
178
|
-
|
|
179
|
-
|
|
183
|
+
width: content.width,
|
|
184
|
+
height: content.height,
|
|
180
185
|
paragraphProperties,
|
|
181
186
|
...content.altText ? { altText: content.altText } : {}
|
|
182
187
|
}
|
|
@@ -190,7 +195,7 @@ function tryExtractDrawingFromParagraph(p, resolveColor) {
|
|
|
190
195
|
}
|
|
191
196
|
};
|
|
192
197
|
}
|
|
193
|
-
function parseParagraph(p) {
|
|
198
|
+
function parseParagraph(p, ctx) {
|
|
194
199
|
const pPr = poChildren(p).find((c) => poIs(c, "w:pPr"));
|
|
195
200
|
let properties = parseParagraphProperties(pPr ? poElementToFlat(pPr) : void 0);
|
|
196
201
|
const mathPara = poChildren(p).find((c) => poIs(c, "m:oMathPara"));
|
|
@@ -204,17 +209,17 @@ function parseParagraph(p) {
|
|
|
204
209
|
};
|
|
205
210
|
}
|
|
206
211
|
const runs = [];
|
|
207
|
-
collectRuns(p, runs);
|
|
212
|
+
collectRuns(p, runs, ctx);
|
|
208
213
|
return {
|
|
209
214
|
properties,
|
|
210
215
|
runs
|
|
211
216
|
};
|
|
212
217
|
}
|
|
213
|
-
function collectRuns(container, out) {
|
|
218
|
+
function collectRuns(container, out, ctx) {
|
|
214
219
|
for (const child of poChildren(container)) {
|
|
215
220
|
if (poIs(child, "w:pPr")) continue;
|
|
216
221
|
if (poIs(child, "w:r")) {
|
|
217
|
-
out.push(parseRun(child));
|
|
222
|
+
out.push(parseRun(child, ctx));
|
|
218
223
|
continue;
|
|
219
224
|
}
|
|
220
225
|
if (poIs(child, "m:oMath")) {
|
|
@@ -234,10 +239,10 @@ function collectRuns(container, out) {
|
|
|
234
239
|
continue;
|
|
235
240
|
}
|
|
236
241
|
const tag = elementTag(child);
|
|
237
|
-
if (tag && RUN_CONTAINER_TAGS.has(tag)) collectRuns(child, out);
|
|
242
|
+
if (tag && RUN_CONTAINER_TAGS.has(tag)) collectRuns(child, out, ctx);
|
|
238
243
|
}
|
|
239
244
|
}
|
|
240
|
-
function parseRun(r) {
|
|
245
|
+
function parseRun(r, ctx) {
|
|
241
246
|
const rPr = poChildren(r).find((c) => poIs(c, "w:rPr"));
|
|
242
247
|
const properties = parseRunProperties(rPr ? poElementToFlat(rPr) : void 0);
|
|
243
248
|
let text = "";
|
|
@@ -253,11 +258,14 @@ function parseRun(r) {
|
|
|
253
258
|
else if (poIs(child, "w:softHyphen")) text += "";
|
|
254
259
|
else if (poIs(child, "w:drawing")) {
|
|
255
260
|
const content = parseDrawing(child, defaultColorResolver);
|
|
256
|
-
if (content && content.kind === "image")
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
+
if (content && content.kind === "image") {
|
|
262
|
+
const resource = ctx.resolveImage?.(content.imageId);
|
|
263
|
+
inlineImage = {
|
|
264
|
+
...resource ? { resource } : {},
|
|
265
|
+
width: content.width,
|
|
266
|
+
height: content.height
|
|
267
|
+
};
|
|
268
|
+
}
|
|
261
269
|
}
|
|
262
270
|
}
|
|
263
271
|
return {
|
|
@@ -271,4 +279,4 @@ function elementTag(node) {
|
|
|
271
279
|
for (const key of Object.keys(node)) if (key !== ":@" && key !== "#text") return key;
|
|
272
280
|
}
|
|
273
281
|
//#endregion
|
|
274
|
-
export { EMPTY_SECTION, parseBodyElements, parseDocument, parseHeaderFooter, parseSections };
|
|
282
|
+
export { DEFAULT_PARSE_CONTEXT, EMPTY_SECTION, parseBodyElements, parseDocument, parseHeaderFooter, parseSections };
|