dom-docx 0.1.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/API.md +533 -0
- package/LICENSE +21 -0
- package/README.md +236 -0
- package/dist/browser.d.ts +34 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +35 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +118 -0
- package/dist/cli.js.map +1 -0
- package/dist/converter/bordered-block.d.ts +54 -0
- package/dist/converter/bordered-block.d.ts.map +1 -0
- package/dist/converter/bordered-block.js +124 -0
- package/dist/converter/bordered-block.js.map +1 -0
- package/dist/converter/build-docx.d.ts +46 -0
- package/dist/converter/build-docx.d.ts.map +1 -0
- package/dist/converter/build-docx.js +161 -0
- package/dist/converter/build-docx.js.map +1 -0
- package/dist/converter/computed-style-snapshot.browser.js +73 -0
- package/dist/converter/computed-style-snapshot.d.ts +10 -0
- package/dist/converter/computed-style-snapshot.d.ts.map +1 -0
- package/dist/converter/computed-style-snapshot.js +78 -0
- package/dist/converter/computed-style-snapshot.js.map +1 -0
- package/dist/converter/constants.d.ts +51 -0
- package/dist/converter/constants.d.ts.map +1 -0
- package/dist/converter/constants.js +163 -0
- package/dist/converter/constants.js.map +1 -0
- package/dist/converter/css.d.ts +112 -0
- package/dist/converter/css.d.ts.map +1 -0
- package/dist/converter/css.js +621 -0
- package/dist/converter/css.js.map +1 -0
- package/dist/converter/flex.d.ts +59 -0
- package/dist/converter/flex.d.ts.map +1 -0
- package/dist/converter/flex.js +252 -0
- package/dist/converter/flex.js.map +1 -0
- package/dist/converter/image.d.ts +38 -0
- package/dist/converter/image.d.ts.map +1 -0
- package/dist/converter/image.js +159 -0
- package/dist/converter/image.js.map +1 -0
- package/dist/converter/inline.d.ts +18 -0
- package/dist/converter/inline.d.ts.map +1 -0
- package/dist/converter/inline.js +213 -0
- package/dist/converter/inline.js.map +1 -0
- package/dist/converter/ooxml-patch.d.ts +23 -0
- package/dist/converter/ooxml-patch.d.ts.map +1 -0
- package/dist/converter/ooxml-patch.js +54 -0
- package/dist/converter/ooxml-patch.js.map +1 -0
- package/dist/converter/style-path.d.ts +4 -0
- package/dist/converter/style-path.d.ts.map +1 -0
- package/dist/converter/style-path.js +17 -0
- package/dist/converter/style-path.js.map +1 -0
- package/dist/converter/style-resolver-node.d.ts +7 -0
- package/dist/converter/style-resolver-node.d.ts.map +1 -0
- package/dist/converter/style-resolver-node.js +26 -0
- package/dist/converter/style-resolver-node.js.map +1 -0
- package/dist/converter/style-resolver.d.ts +24 -0
- package/dist/converter/style-resolver.d.ts.map +1 -0
- package/dist/converter/style-resolver.js +122 -0
- package/dist/converter/style-resolver.js.map +1 -0
- package/dist/converter/svg.d.ts +11 -0
- package/dist/converter/svg.d.ts.map +1 -0
- package/dist/converter/svg.js +116 -0
- package/dist/converter/svg.js.map +1 -0
- package/dist/converter/table.d.ts +8 -0
- package/dist/converter/table.d.ts.map +1 -0
- package/dist/converter/table.js +745 -0
- package/dist/converter/table.js.map +1 -0
- package/dist/converter/text-metrics.d.ts +17 -0
- package/dist/converter/text-metrics.d.ts.map +1 -0
- package/dist/converter/text-metrics.js +51 -0
- package/dist/converter/text-metrics.js.map +1 -0
- package/dist/converter/types.d.ts +82 -0
- package/dist/converter/types.d.ts.map +1 -0
- package/dist/converter/types.js +9 -0
- package/dist/converter/types.js.map +1 -0
- package/dist/converter/visitor.d.ts +11 -0
- package/dist/converter/visitor.d.ts.map +1 -0
- package/dist/converter/visitor.js +910 -0
- package/dist/converter/visitor.js.map +1 -0
- package/dist/converter.d.ts +28 -0
- package/dist/converter.d.ts.map +1 -0
- package/dist/converter.js +44 -0
- package/dist/converter.js.map +1 -0
- package/dist/html-wrap.d.ts +3 -0
- package/dist/html-wrap.d.ts.map +1 -0
- package/dist/html-wrap.js +26 -0
- package/dist/html-wrap.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/examples/README.md +39 -0
- package/examples/balance-sheet/compare_side_by_side.png +0 -0
- package/examples/balance-sheet/input.html +41 -0
- package/examples/balance-sheet/output.docx +0 -0
- package/examples/balance-sheet/preview.png +0 -0
- package/examples/invoice/compare_side_by_side.png +0 -0
- package/examples/invoice/input.html +88 -0
- package/examples/invoice/logo.png +0 -0
- package/examples/invoice/output.docx +0 -0
- package/examples/invoice/preview.png +0 -0
- package/examples/javascript-essay/compare_side_by_side.png +0 -0
- package/examples/javascript-essay/input.html +39 -0
- package/examples/javascript-essay/output.docx +0 -0
- package/examples/javascript-essay/preview.png +0 -0
- package/examples/product-launch-brief/compare_side_by_side.png +0 -0
- package/examples/product-launch-brief/input.html +120 -0
- package/examples/product-launch-brief/output.docx +0 -0
- package/examples/product-launch-brief/preview.png +0 -0
- package/examples/quarterly-financials/compare_side_by_side.png +0 -0
- package/examples/quarterly-financials/input.html +27 -0
- package/examples/quarterly-financials/output.docx +0 -0
- package/examples/quarterly-financials/preview.png +0 -0
- package/examples/react-dashboard/compare_side_by_side.png +0 -0
- package/examples/react-dashboard/input.html +1 -0
- package/examples/react-dashboard/output.docx +0 -0
- package/examples/react-dashboard/preview.html +107 -0
- package/examples/react-dashboard/preview.png +0 -0
- package/examples/regional-sales-dashboard/compare_side_by_side.png +0 -0
- package/examples/regional-sales-dashboard/input.html +129 -0
- package/examples/regional-sales-dashboard/output.docx +0 -0
- package/examples/regional-sales-dashboard/preview.png +0 -0
- package/examples/sales-contract/compare_side_by_side.png +0 -0
- package/examples/sales-contract/input.html +68 -0
- package/examples/sales-contract/output.docx +0 -0
- package/examples/sales-contract/preview.png +0 -0
- package/examples/sprint-retrospective/compare_side_by_side.png +0 -0
- package/examples/sprint-retrospective/input.html +51 -0
- package/examples/sprint-retrospective/output.docx +0 -0
- package/examples/sprint-retrospective/preview.png +0 -0
- package/package.json +108 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Table } from "docx";
|
|
2
|
+
import type { Element } from "domhandler";
|
|
3
|
+
import { type ParsedCss } from "./css.js";
|
|
4
|
+
import type { StyleResolver } from "./style-resolver.js";
|
|
5
|
+
import type { BlockLayout, DocxBlock, FlexLayout } from "./types.js";
|
|
6
|
+
export declare function borderlessTableBorders(): {
|
|
7
|
+
top: {
|
|
8
|
+
style: "none";
|
|
9
|
+
size: number;
|
|
10
|
+
color: string;
|
|
11
|
+
};
|
|
12
|
+
bottom: {
|
|
13
|
+
style: "none";
|
|
14
|
+
size: number;
|
|
15
|
+
color: string;
|
|
16
|
+
};
|
|
17
|
+
left: {
|
|
18
|
+
style: "none";
|
|
19
|
+
size: number;
|
|
20
|
+
color: string;
|
|
21
|
+
};
|
|
22
|
+
right: {
|
|
23
|
+
style: "none";
|
|
24
|
+
size: number;
|
|
25
|
+
color: string;
|
|
26
|
+
};
|
|
27
|
+
insideHorizontal: {
|
|
28
|
+
style: "none";
|
|
29
|
+
size: number;
|
|
30
|
+
color: string;
|
|
31
|
+
};
|
|
32
|
+
insideVertical: {
|
|
33
|
+
style: "none";
|
|
34
|
+
size: number;
|
|
35
|
+
color: string;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
export interface FlexItemContent {
|
|
39
|
+
layout: BlockLayout;
|
|
40
|
+
blocks: DocxBlock[];
|
|
41
|
+
/** Shrink-wrapped column width when flex items have no flex-grow. */
|
|
42
|
+
intrinsicWidthTwips?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Estimated tight content height (twips) for card-style items with block children.
|
|
45
|
+
* LibreOffice sizes rows by natural font metrics (ignoring EXACT line spacing), so an
|
|
46
|
+
* explicit exact row height is needed to keep cards from inflating vertically.
|
|
47
|
+
*/
|
|
48
|
+
contentHeightTwips?: number;
|
|
49
|
+
}
|
|
50
|
+
export declare function estimateFlexItemWidthTwips(element: Element, layout: BlockLayout, styleResolver?: StyleResolver): number;
|
|
51
|
+
export declare function parseFlexLayoutFromCss(css: ParsedCss): FlexLayout | null;
|
|
52
|
+
export declare function parseFlexLayout(css: ParsedCss): FlexLayout | null;
|
|
53
|
+
export declare function isFlexContainer(element: Element, styleResolver?: StyleResolver): boolean;
|
|
54
|
+
export declare function flexItemElements(element: Element, styleResolver?: StyleResolver): Element[];
|
|
55
|
+
/** Horizontal flex → single-row borderless table with explicit gap columns. */
|
|
56
|
+
export declare function makeFlexRowTable(items: FlexItemContent[], gap: number | undefined, containerLayout: BlockLayout): Table;
|
|
57
|
+
/** Vertical flex → multi-row borderless table; gap via unshaded exact-height spacer rows. */
|
|
58
|
+
export declare function makeFlexColumnTable(items: FlexItemContent[], gap: number | undefined, containerLayout: BlockLayout): Table;
|
|
59
|
+
//# sourceMappingURL=flex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flex.d.ts","sourceRoot":"","sources":["../../src/converter/flex.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,EAKN,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,YAAY,CAAC;AAGnD,OAAO,EAA4E,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AACpH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIrE,wBAAgB,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASrC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,qEAAqE;IACrE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAiBD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,WAAW,EACnB,aAAa,GAAE,aAAqC,GACnD,MAAM,CAUR;AAwDD,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,SAAS,GAAG,UAAU,GAAG,IAAI,CAMxE;AAED,wBAAgB,eAAe,CAC7B,GAAG,EAAE,SAAS,GACb,UAAU,GAAG,IAAI,CAEnB;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,aAAa,GAAE,aAAqC,GACnD,OAAO,CAET;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,aAAa,GAAE,aAAqC,GACnD,OAAO,EAAE,CAIX;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,eAAe,EAAE,EACxB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,eAAe,EAAE,WAAW,GAC3B,KAAK,CAuDP;AAyED,6FAA6F;AAC7F,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,eAAe,EAAE,EACxB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,eAAe,EAAE,WAAW,GAC3B,KAAK,CA8CP"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { BorderStyle, HeightRule, LineRuleType, Paragraph, ShadingType, Table, TableCell, TableRow, VerticalAlign, WidthType, } from "docx";
|
|
2
|
+
import { PRINTABLE_CONTENT_WIDTH_TWIPS } from "./constants.js";
|
|
3
|
+
import { visibleCellBorders } from "./bordered-block.js";
|
|
4
|
+
import { isHiddenElement, layoutForNativeShadedBlock, pxToTwips } from "./css.js";
|
|
5
|
+
import { INLINE_STYLE_RESOLVER } from "./style-resolver.js";
|
|
6
|
+
import { estimateTextWidthTwips, minContentWidthTwips } from "./text-metrics.js";
|
|
7
|
+
const BORDERLESS = { style: BorderStyle.NONE, size: 0, color: "auto" };
|
|
8
|
+
export function borderlessTableBorders() {
|
|
9
|
+
return {
|
|
10
|
+
top: BORDERLESS,
|
|
11
|
+
bottom: BORDERLESS,
|
|
12
|
+
left: BORDERLESS,
|
|
13
|
+
right: BORDERLESS,
|
|
14
|
+
insideHorizontal: BORDERLESS,
|
|
15
|
+
insideVertical: BORDERLESS,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function elementPlainText(element) {
|
|
19
|
+
const parts = [];
|
|
20
|
+
function walk(nodes) {
|
|
21
|
+
for (const node of nodes) {
|
|
22
|
+
if (node.type === "text")
|
|
23
|
+
parts.push(node.data ?? "");
|
|
24
|
+
else if (node.type === "tag")
|
|
25
|
+
walk(node.children ?? []);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
walk(element.children ?? []);
|
|
29
|
+
return parts.join("").replace(/\s+/g, " ").trim();
|
|
30
|
+
}
|
|
31
|
+
/** Word/LibreOffice Arial runs slightly wider than our glyph estimate — pad shrink-wrapped flex columns. */
|
|
32
|
+
const FLEX_ITEM_WIDTH_SAFETY_TWIPS = pxToTwips(8);
|
|
33
|
+
export function estimateFlexItemWidthTwips(element, layout, styleResolver = INLINE_STYLE_RESOLVER) {
|
|
34
|
+
const text = elementPlainText(element);
|
|
35
|
+
const css = styleResolver.getCss(element);
|
|
36
|
+
const bold = css.fontWeight === "bold" || Number(css.fontWeight) >= 600;
|
|
37
|
+
const padX = (layout.paddingLeft ?? 0) + (layout.paddingRight ?? 0);
|
|
38
|
+
const content = Math.max(minContentWidthTwips(32), estimateTextWidthTwips(text, { bold, fontSizeHalfPoints: css.fontSize }));
|
|
39
|
+
return padX + content + FLEX_ITEM_WIDTH_SAFETY_TWIPS;
|
|
40
|
+
}
|
|
41
|
+
function distributeFlexItemWidths(weights, total) {
|
|
42
|
+
if (weights.length === 0)
|
|
43
|
+
return [];
|
|
44
|
+
const sum = weights.reduce((acc, w) => acc + w, 0);
|
|
45
|
+
if (sum <= 0) {
|
|
46
|
+
const base = Math.floor(total / weights.length);
|
|
47
|
+
const equal = Array.from({ length: weights.length }, () => base);
|
|
48
|
+
for (let i = 0; i < total - base * weights.length; i++) {
|
|
49
|
+
equal[i] += 1;
|
|
50
|
+
}
|
|
51
|
+
return equal;
|
|
52
|
+
}
|
|
53
|
+
const scaled = weights.map((w) => (w / sum) * total);
|
|
54
|
+
const columnWidths = scaled.map((w) => Math.floor(w));
|
|
55
|
+
let remainder = total - columnWidths.reduce((acc, w) => acc + w, 0);
|
|
56
|
+
const fractional = scaled
|
|
57
|
+
.map((w, index) => ({ index, fraction: w - Math.floor(w) }))
|
|
58
|
+
.sort((a, b) => b.fraction - a.fraction);
|
|
59
|
+
for (let i = 0; remainder > 0; i++, remainder--) {
|
|
60
|
+
columnWidths[fractional[i % fractional.length].index] += 1;
|
|
61
|
+
}
|
|
62
|
+
return columnWidths;
|
|
63
|
+
}
|
|
64
|
+
function rowColumnPlan(items, gapTwips) {
|
|
65
|
+
const itemCount = items.length;
|
|
66
|
+
const gapTotal = gapTwips * Math.max(0, itemCount - 1);
|
|
67
|
+
const available = Math.max(0, PRINTABLE_CONTENT_WIDTH_TWIPS - gapTotal);
|
|
68
|
+
const weights = items.map((item) => Math.max(minContentWidthTwips(32), item.intrinsicWidthTwips ?? 0));
|
|
69
|
+
// Browsers shrink-wrap row items (no flex-grow parsing) — keep intrinsic
|
|
70
|
+
// widths and only scale down when they would overflow the printable width.
|
|
71
|
+
const wanted = weights.reduce((acc, w) => acc + w, 0);
|
|
72
|
+
const itemWidths = wanted > available ? distributeFlexItemWidths(weights, available) : weights;
|
|
73
|
+
const columnWidths = [];
|
|
74
|
+
let totalWidth = 0;
|
|
75
|
+
itemWidths.forEach((width, index) => {
|
|
76
|
+
columnWidths.push(width);
|
|
77
|
+
totalWidth += width;
|
|
78
|
+
if (index < itemCount - 1 && gapTwips > 0) {
|
|
79
|
+
columnWidths.push(gapTwips);
|
|
80
|
+
totalWidth += gapTwips;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
return { columnWidths, totalWidth };
|
|
84
|
+
}
|
|
85
|
+
export function parseFlexLayoutFromCss(css) {
|
|
86
|
+
if (css.display !== "flex" && css.display !== "inline-flex")
|
|
87
|
+
return null;
|
|
88
|
+
return {
|
|
89
|
+
direction: css.flexDirection === "column" ? "column" : "row",
|
|
90
|
+
gap: css.gap,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export function parseFlexLayout(css) {
|
|
94
|
+
return parseFlexLayoutFromCss(css);
|
|
95
|
+
}
|
|
96
|
+
export function isFlexContainer(element, styleResolver = INLINE_STYLE_RESOLVER) {
|
|
97
|
+
return parseFlexLayoutFromCss(styleResolver.getCss(element)) !== null;
|
|
98
|
+
}
|
|
99
|
+
export function flexItemElements(element, styleResolver = INLINE_STYLE_RESOLVER) {
|
|
100
|
+
return (element.children ?? []).filter((node) => node.type === "tag" && !isHiddenElement(node, styleResolver));
|
|
101
|
+
}
|
|
102
|
+
/** Horizontal flex → single-row borderless table with explicit gap columns. */
|
|
103
|
+
export function makeFlexRowTable(items, gap, containerLayout) {
|
|
104
|
+
const gapTwips = gap ?? 0;
|
|
105
|
+
const { columnWidths, totalWidth } = rowColumnPlan(items, gapTwips);
|
|
106
|
+
const cells = [];
|
|
107
|
+
items.forEach((item, index) => {
|
|
108
|
+
const width = columnWidths[cells.length];
|
|
109
|
+
cells.push(new TableCell({
|
|
110
|
+
width: { size: width, type: WidthType.DXA },
|
|
111
|
+
// Card items (stacked block children) flow from the top like the browser;
|
|
112
|
+
// simple inline items stay vertically centered.
|
|
113
|
+
verticalAlign: item.contentHeightTwips ? VerticalAlign.TOP : VerticalAlign.CENTER,
|
|
114
|
+
shading: item.layout.shading
|
|
115
|
+
? { type: ShadingType.CLEAR, ...item.layout.shading }
|
|
116
|
+
: undefined,
|
|
117
|
+
...(item.layout.borders ? { borders: visibleCellBorders(item.layout.borders) } : {}),
|
|
118
|
+
margins: {
|
|
119
|
+
top: item.layout.paddingTop ?? 0,
|
|
120
|
+
bottom: item.layout.paddingBottom ?? 0,
|
|
121
|
+
left: item.layout.paddingLeft ?? 0,
|
|
122
|
+
right: item.layout.paddingRight ?? 0,
|
|
123
|
+
},
|
|
124
|
+
children: item.blocks.length > 0 ? item.blocks : [new Paragraph({ children: [] })],
|
|
125
|
+
}));
|
|
126
|
+
if (index < items.length - 1 && gapTwips > 0) {
|
|
127
|
+
cells.push(new TableCell({
|
|
128
|
+
width: { size: gapTwips, type: WidthType.DXA },
|
|
129
|
+
margins: { top: 0, bottom: 0, left: 0, right: 0 },
|
|
130
|
+
children: [new Paragraph({ children: [] })],
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
// Card rows: LibreOffice sizes rows by natural font metrics, inflating cards. Force an
|
|
135
|
+
// exact row height = the tallest item's tight content height so cards match the browser.
|
|
136
|
+
const maxContentHeight = Math.max(0, ...items.map((it) => it.contentHeightTwips ?? 0));
|
|
137
|
+
const rowOptions = maxContentHeight > 0
|
|
138
|
+
? { children: cells, height: { value: maxContentHeight, rule: HeightRule.EXACT } }
|
|
139
|
+
: { children: cells };
|
|
140
|
+
const inner = new Table({
|
|
141
|
+
width: { size: totalWidth, type: WidthType.DXA },
|
|
142
|
+
columnWidths,
|
|
143
|
+
layout: "fixed",
|
|
144
|
+
borders: borderlessTableBorders(),
|
|
145
|
+
rows: [new TableRow(rowOptions)],
|
|
146
|
+
});
|
|
147
|
+
return wrapInnerTable(inner, containerLayout);
|
|
148
|
+
}
|
|
149
|
+
function containerPaddingMargins(layout) {
|
|
150
|
+
return {
|
|
151
|
+
top: layout.paddingTop ?? 0,
|
|
152
|
+
bottom: layout.paddingBottom ?? 0,
|
|
153
|
+
left: layout.paddingLeft ?? 0,
|
|
154
|
+
right: layout.paddingRight ?? 0,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function wrapInnerTable(inner, containerLayout) {
|
|
158
|
+
const needsWrapper = Boolean(containerLayout.shading?.fill) ||
|
|
159
|
+
Boolean(containerLayout.paddingTop ||
|
|
160
|
+
containerLayout.paddingBottom ||
|
|
161
|
+
containerLayout.paddingLeft ||
|
|
162
|
+
containerLayout.paddingRight);
|
|
163
|
+
if (!needsWrapper)
|
|
164
|
+
return inner;
|
|
165
|
+
const padLayout = containerLayout.shading
|
|
166
|
+
? layoutForNativeShadedBlock(containerLayout)
|
|
167
|
+
: containerLayout;
|
|
168
|
+
return new Table({
|
|
169
|
+
width: { size: PRINTABLE_CONTENT_WIDTH_TWIPS, type: WidthType.DXA },
|
|
170
|
+
columnWidths: [PRINTABLE_CONTENT_WIDTH_TWIPS],
|
|
171
|
+
layout: "fixed",
|
|
172
|
+
borders: borderlessTableBorders(),
|
|
173
|
+
rows: [
|
|
174
|
+
new TableRow({
|
|
175
|
+
children: [
|
|
176
|
+
new TableCell({
|
|
177
|
+
width: { size: PRINTABLE_CONTENT_WIDTH_TWIPS, type: WidthType.DXA },
|
|
178
|
+
shading: containerLayout.shading
|
|
179
|
+
? { type: ShadingType.CLEAR, ...containerLayout.shading }
|
|
180
|
+
: undefined,
|
|
181
|
+
margins: containerPaddingMargins(padLayout),
|
|
182
|
+
children: [inner],
|
|
183
|
+
}),
|
|
184
|
+
],
|
|
185
|
+
}),
|
|
186
|
+
],
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Unshaded spacer row of exact `gapTwips` height — renders the flex `gap` as a band of
|
|
191
|
+
* the container's own fill (nested cells without shading are transparent, so the wrapper
|
|
192
|
+
* cell's background shows through). Gap-as-cell-margin does NOT work: cell margins are
|
|
193
|
+
* painted with the cell's shading, which visually fuses adjacent shaded items.
|
|
194
|
+
*/
|
|
195
|
+
function gapSpacerRow(widthTwips, gapTwips) {
|
|
196
|
+
return new TableRow({
|
|
197
|
+
height: { value: gapTwips, rule: HeightRule.EXACT },
|
|
198
|
+
children: [
|
|
199
|
+
new TableCell({
|
|
200
|
+
width: { size: widthTwips, type: WidthType.DXA },
|
|
201
|
+
margins: { top: 0, bottom: 0, left: 0, right: 0 },
|
|
202
|
+
children: [
|
|
203
|
+
new Paragraph({
|
|
204
|
+
spacing: { before: 0, after: 0, line: gapTwips, lineRule: LineRuleType.EXACT },
|
|
205
|
+
children: [],
|
|
206
|
+
}),
|
|
207
|
+
],
|
|
208
|
+
}),
|
|
209
|
+
],
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/** Vertical flex → multi-row borderless table; gap via unshaded exact-height spacer rows. */
|
|
213
|
+
export function makeFlexColumnTable(items, gap, containerLayout) {
|
|
214
|
+
const gapTwips = gap ?? 0;
|
|
215
|
+
// The inner table sits inside the wrapper cell, inset by the container's padding —
|
|
216
|
+
// sizing it to the full printable width would overflow the wrapper to the page edge.
|
|
217
|
+
const innerWidth = Math.max(0, PRINTABLE_CONTENT_WIDTH_TWIPS -
|
|
218
|
+
(containerLayout.paddingLeft ?? 0) -
|
|
219
|
+
(containerLayout.paddingRight ?? 0));
|
|
220
|
+
const rows = [];
|
|
221
|
+
items.forEach((item, index) => {
|
|
222
|
+
if (index > 0 && gapTwips > 0) {
|
|
223
|
+
rows.push(gapSpacerRow(innerWidth, gapTwips));
|
|
224
|
+
}
|
|
225
|
+
rows.push(new TableRow({
|
|
226
|
+
children: [
|
|
227
|
+
new TableCell({
|
|
228
|
+
width: { size: innerWidth, type: WidthType.DXA },
|
|
229
|
+
shading: item.layout.shading
|
|
230
|
+
? { type: ShadingType.CLEAR, ...item.layout.shading }
|
|
231
|
+
: undefined,
|
|
232
|
+
margins: {
|
|
233
|
+
top: item.layout.paddingTop ?? 0,
|
|
234
|
+
bottom: item.layout.paddingBottom ?? 0,
|
|
235
|
+
left: item.layout.paddingLeft ?? 0,
|
|
236
|
+
right: item.layout.paddingRight ?? 0,
|
|
237
|
+
},
|
|
238
|
+
children: item.blocks.length > 0 ? item.blocks : [new Paragraph({ children: [] })],
|
|
239
|
+
}),
|
|
240
|
+
],
|
|
241
|
+
}));
|
|
242
|
+
});
|
|
243
|
+
const inner = new Table({
|
|
244
|
+
width: { size: innerWidth, type: WidthType.DXA },
|
|
245
|
+
columnWidths: [innerWidth],
|
|
246
|
+
layout: "fixed",
|
|
247
|
+
borders: borderlessTableBorders(),
|
|
248
|
+
rows,
|
|
249
|
+
});
|
|
250
|
+
return wrapInnerTable(inner, containerLayout);
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=flex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flex.js","sourceRoot":"","sources":["../../src/converter/flex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ImageRun } from "docx";
|
|
2
|
+
import type { CheerioAPI } from "cheerio";
|
|
3
|
+
import type { Element } from "domhandler";
|
|
4
|
+
type ImageType = "png" | "jpg" | "gif" | "bmp";
|
|
5
|
+
/** Raw image bytes a caller's {@link ImageResolver} returns for a non-`data:` `src`. */
|
|
6
|
+
export interface ResolvedImage {
|
|
7
|
+
/** Encoded image bytes (not base64 — the raw file contents). */
|
|
8
|
+
readonly data: Uint8Array | ArrayBuffer;
|
|
9
|
+
readonly type: ImageType;
|
|
10
|
+
/** Optional intrinsic size (px); used only when the `<img>` omits width/height. */
|
|
11
|
+
readonly width?: number;
|
|
12
|
+
readonly height?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Caller-supplied hook to resolve non-`data:` `<img src>` (e.g. `http(s):` / `file:`).
|
|
16
|
+
* The library never fetches on its own — the caller owns the network/filesystem access
|
|
17
|
+
* and its security policy (host allowlist, SSRF/private-IP blocking, auth, size caps).
|
|
18
|
+
* Return `null` to skip an image (it falls back to alt text).
|
|
19
|
+
*/
|
|
20
|
+
export type ImageResolver = (src: string) => Promise<ResolvedImage | null> | ResolvedImage | null;
|
|
21
|
+
/** Encode a resolved image as a `data:` URL so the sync conversion path handles it uniformly. */
|
|
22
|
+
export declare function resolvedImageToDataUrl(resolved: ResolvedImage): string;
|
|
23
|
+
/**
|
|
24
|
+
* Pre-resolution pass (run before the synchronous tree walk): for every `<img>` whose
|
|
25
|
+
* `src` is not already a `data:` URL, ask the caller's resolver for bytes and, if given,
|
|
26
|
+
* rewrite `src` to an inline `data:` URL. Unresolved images keep their `src` and fall
|
|
27
|
+
* back to alt text. Resolver errors are swallowed per-image (never abort the conversion).
|
|
28
|
+
*/
|
|
29
|
+
export declare function applyImageResolver($: CheerioAPI, resolver: ImageResolver): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Build a docx `ImageRun` from an `<img>` element. Supports base64 `data:` raster
|
|
32
|
+
* URLs (png/jpg/gif/bmp). Display size comes from `width`/`height` attributes,
|
|
33
|
+
* falling back to the image's natural size (aspect-preserved if only one is given).
|
|
34
|
+
* Returns null for unsupported sources (e.g. remote URLs) — caller drops to alt text.
|
|
35
|
+
*/
|
|
36
|
+
export declare function imageRunFromElement(element: Element): ImageRun | null;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/converter/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAiB/C,wFAAwF;AACxF,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,MAAM,KACR,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,aAAa,GAAG,IAAI,CAAC;AAmB1D,iGAAiG;AACjG,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAEtE;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,CAAC,EAAE,UAAU,EACb,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CAqBf;AAgED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CA0BrE"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { ImageRun } from "docx";
|
|
2
|
+
const MIME_TO_TYPE = {
|
|
3
|
+
"image/png": "png",
|
|
4
|
+
"image/jpeg": "jpg",
|
|
5
|
+
"image/jpg": "jpg",
|
|
6
|
+
"image/gif": "gif",
|
|
7
|
+
"image/bmp": "bmp",
|
|
8
|
+
};
|
|
9
|
+
const TYPE_TO_MIME = {
|
|
10
|
+
png: "image/png",
|
|
11
|
+
jpg: "image/jpeg",
|
|
12
|
+
gif: "image/gif",
|
|
13
|
+
bmp: "image/bmp",
|
|
14
|
+
};
|
|
15
|
+
function toBase64(data) {
|
|
16
|
+
const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
17
|
+
if (typeof Buffer !== "undefined")
|
|
18
|
+
return Buffer.from(bytes).toString("base64");
|
|
19
|
+
// Browser-safe fallback.
|
|
20
|
+
let binary = "";
|
|
21
|
+
for (let i = 0; i < bytes.length; i++)
|
|
22
|
+
binary += String.fromCharCode(bytes[i]);
|
|
23
|
+
return btoa(binary);
|
|
24
|
+
}
|
|
25
|
+
function decodeBase64(base64) {
|
|
26
|
+
if (typeof Buffer !== "undefined")
|
|
27
|
+
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
28
|
+
const binary = atob(base64);
|
|
29
|
+
const bytes = new Uint8Array(binary.length);
|
|
30
|
+
for (let i = 0; i < binary.length; i++)
|
|
31
|
+
bytes[i] = binary.charCodeAt(i);
|
|
32
|
+
return bytes;
|
|
33
|
+
}
|
|
34
|
+
/** Encode a resolved image as a `data:` URL so the sync conversion path handles it uniformly. */
|
|
35
|
+
export function resolvedImageToDataUrl(resolved) {
|
|
36
|
+
return `data:${TYPE_TO_MIME[resolved.type]};base64,${toBase64(resolved.data)}`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Pre-resolution pass (run before the synchronous tree walk): for every `<img>` whose
|
|
40
|
+
* `src` is not already a `data:` URL, ask the caller's resolver for bytes and, if given,
|
|
41
|
+
* rewrite `src` to an inline `data:` URL. Unresolved images keep their `src` and fall
|
|
42
|
+
* back to alt text. Resolver errors are swallowed per-image (never abort the conversion).
|
|
43
|
+
*/
|
|
44
|
+
export async function applyImageResolver($, resolver) {
|
|
45
|
+
const targets = $("img")
|
|
46
|
+
.toArray()
|
|
47
|
+
.filter((el) => {
|
|
48
|
+
const src = el.attribs?.src;
|
|
49
|
+
return typeof src === "string" && src.length > 0 && !/^data:/i.test(src);
|
|
50
|
+
});
|
|
51
|
+
await Promise.all(targets.map(async (el) => {
|
|
52
|
+
try {
|
|
53
|
+
const resolved = await resolver(el.attribs.src);
|
|
54
|
+
if (!resolved)
|
|
55
|
+
return;
|
|
56
|
+
el.attribs.src = resolvedImageToDataUrl(resolved);
|
|
57
|
+
if (resolved.width && !el.attribs.width)
|
|
58
|
+
el.attribs.width = String(resolved.width);
|
|
59
|
+
if (resolved.height && !el.attribs.height)
|
|
60
|
+
el.attribs.height = String(resolved.height);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Leave src untouched → alt-text fallback. The caller's resolver owns errors.
|
|
64
|
+
}
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
/** Parse a `data:<mime>;base64,<payload>` URL into raw bytes + docx image type. */
|
|
68
|
+
function parseDataUrl(src) {
|
|
69
|
+
const match = /^data:([^;,]+)?(;base64)?,(.*)$/is.exec(src.trim());
|
|
70
|
+
if (!match)
|
|
71
|
+
return null;
|
|
72
|
+
const mime = (match[1] ?? "image/png").toLowerCase();
|
|
73
|
+
const isBase64 = Boolean(match[2]);
|
|
74
|
+
const type = MIME_TO_TYPE[mime];
|
|
75
|
+
if (!type || !isBase64)
|
|
76
|
+
return null; // only base64 raster data URLs for now
|
|
77
|
+
try {
|
|
78
|
+
return { type, data: decodeBase64(match[3]) };
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Natural pixel dimensions from a decoded raster header (PNG / GIF / BMP / JPEG). */
|
|
85
|
+
function naturalSize(type, data) {
|
|
86
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
87
|
+
try {
|
|
88
|
+
if (type === "png" && data.length >= 24) {
|
|
89
|
+
// IHDR width/height are big-endian uint32 at byte 16 / 20.
|
|
90
|
+
return { w: view.getUint32(16), h: view.getUint32(20) };
|
|
91
|
+
}
|
|
92
|
+
if (type === "gif" && data.length >= 10) {
|
|
93
|
+
// Logical screen width/height are little-endian uint16 at byte 6 / 8.
|
|
94
|
+
return { w: view.getUint16(6, true), h: view.getUint16(8, true) };
|
|
95
|
+
}
|
|
96
|
+
if (type === "bmp" && data.length >= 26) {
|
|
97
|
+
return { w: view.getInt32(18, true), h: Math.abs(view.getInt32(22, true)) };
|
|
98
|
+
}
|
|
99
|
+
if (type === "jpg") {
|
|
100
|
+
// Scan SOF markers for frame dimensions.
|
|
101
|
+
let off = 2;
|
|
102
|
+
while (off + 9 < data.length) {
|
|
103
|
+
if (view.getUint8(off) !== 0xff) {
|
|
104
|
+
off++;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const marker = view.getUint8(off + 1);
|
|
108
|
+
if (marker >= 0xc0 && marker <= 0xcf && marker !== 0xc4 && marker !== 0xc8 && marker !== 0xcc) {
|
|
109
|
+
return { h: view.getUint16(off + 5), w: view.getUint16(off + 7) };
|
|
110
|
+
}
|
|
111
|
+
off += 2 + view.getUint16(off + 2);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
function attrPx(value) {
|
|
121
|
+
if (!value)
|
|
122
|
+
return undefined;
|
|
123
|
+
const n = parseFloat(value);
|
|
124
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Build a docx `ImageRun` from an `<img>` element. Supports base64 `data:` raster
|
|
128
|
+
* URLs (png/jpg/gif/bmp). Display size comes from `width`/`height` attributes,
|
|
129
|
+
* falling back to the image's natural size (aspect-preserved if only one is given).
|
|
130
|
+
* Returns null for unsupported sources (e.g. remote URLs) — caller drops to alt text.
|
|
131
|
+
*/
|
|
132
|
+
export function imageRunFromElement(element) {
|
|
133
|
+
const src = element.attribs?.src;
|
|
134
|
+
if (!src)
|
|
135
|
+
return null;
|
|
136
|
+
const decoded = parseDataUrl(src);
|
|
137
|
+
if (!decoded)
|
|
138
|
+
return null;
|
|
139
|
+
const natural = naturalSize(decoded.type, decoded.data);
|
|
140
|
+
let width = attrPx(element.attribs?.width);
|
|
141
|
+
let height = attrPx(element.attribs?.height);
|
|
142
|
+
if (width && !height)
|
|
143
|
+
height = natural ? Math.round((width / natural.w) * natural.h) : width;
|
|
144
|
+
else if (height && !width)
|
|
145
|
+
width = natural ? Math.round((height / natural.h) * natural.w) : height;
|
|
146
|
+
else if (!width && !height) {
|
|
147
|
+
width = natural?.w ?? 200;
|
|
148
|
+
height = natural?.h ?? 150;
|
|
149
|
+
}
|
|
150
|
+
return new ImageRun({
|
|
151
|
+
type: decoded.type,
|
|
152
|
+
data: decoded.data,
|
|
153
|
+
transformation: { width: width, height: height },
|
|
154
|
+
altText: element.attribs?.alt
|
|
155
|
+
? { title: element.attribs.alt, description: element.attribs.alt, name: element.attribs.alt }
|
|
156
|
+
: undefined,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/converter/image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAMhC,MAAM,YAAY,GAA8B;IAC9C,WAAW,EAAE,KAAK;IAClB,YAAY,EAAE,KAAK;IACnB,WAAW,EAAE,KAAK;IAClB,WAAW,EAAE,KAAK;IAClB,WAAW,EAAE,KAAK;CACnB,CAAC;AAEF,MAAM,YAAY,GAA8B;IAC9C,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,YAAY;IACjB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,WAAW;CACjB,CAAC;AAsBF,SAAS,QAAQ,CAAC,IAA8B;IAC9C,MAAM,KAAK,GAAG,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;IACvE,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChF,yBAAyB;IACzB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,YAAY,CAAC,MAAc;IAClC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACxF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACxE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,sBAAsB,CAAC,QAAuB;IAC5D,OAAO,QAAQ,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;AACjF,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,CAAa,EACb,QAAuB;IAEvB,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC;SACrB,OAAO,EAAE;SACT,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;QACb,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC;QAC5B,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEL,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACvB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAChD,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACtB,EAAE,CAAC,OAAO,CAAC,GAAG,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,QAAQ,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK;gBAAE,EAAE,CAAC,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACnF,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM;gBAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACzF,CAAC;QAAC,MAAM,CAAC;YACP,8EAA8E;QAChF,CAAC;IACH,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAOD,mFAAmF;AACnF,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,KAAK,GAAG,mCAAmC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACnE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;IACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC,CAAC,uCAAuC;IAC5E,IAAI,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,SAAS,WAAW,CAAC,IAAe,EAAE,IAAgB;IACpD,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACzE,IAAI,CAAC;QACH,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACxC,2DAA2D;YAC3D,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;QAC1D,CAAC;QACD,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACxC,sEAAsE;YACtE,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;QACpE,CAAC;QACD,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QAC9E,CAAC;QACD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,yCAAyC;YACzC,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,OAAO,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC7B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;oBAChC,GAAG,EAAE,CAAC;oBACN,SAAS;gBACX,CAAC;gBACD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;gBACtC,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;oBAC9F,OAAO,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;gBACpE,CAAC;gBACD,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,MAAM,CAAC,KAAyB;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;IACjC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,IAAI,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE7C,IAAI,KAAK,IAAI,CAAC,MAAM;QAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;SACxF,IAAI,MAAM,IAAI,CAAC,KAAK;QAAE,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;SAC9F,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,KAAK,GAAG,OAAO,EAAE,CAAC,IAAI,GAAG,CAAC;QAC1B,MAAM,GAAG,OAAO,EAAE,CAAC,IAAI,GAAG,CAAC;IAC7B,CAAC;IAED,OAAO,IAAI,QAAQ,CAAC;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,cAAc,EAAE,EAAE,KAAK,EAAE,KAAM,EAAE,MAAM,EAAE,MAAO,EAAE;QAClD,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG;YAC3B,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE;YAC7F,CAAC,CAAC,SAAS;KACd,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ParagraphChild } from "docx";
|
|
2
|
+
import type { AnyNode, Element } from "domhandler";
|
|
3
|
+
import { isBlockElement, typographyFromBlockElement } from "./css.js";
|
|
4
|
+
import type { StyleResolver } from "./style-resolver.js";
|
|
5
|
+
import type { RunTypography } from "./types.js";
|
|
6
|
+
export declare function typographyToTextRunOptions(style: RunTypography, defaultSize?: number): Record<string, unknown>;
|
|
7
|
+
interface InlineRunState {
|
|
8
|
+
leadingTextDone: boolean;
|
|
9
|
+
needsSpaceBeforeNext: boolean;
|
|
10
|
+
/** After `<br>` — trim HTML source indentation on the next line. */
|
|
11
|
+
afterLineBreak: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function collectInlineRunsFromNodes(childNodes: AnyNode[], inherited?: RunTypography, state?: InlineRunState, styleResolver?: StyleResolver, defaultSize?: number): ParagraphChild[];
|
|
14
|
+
export declare function hasDirectBlockChild(element: Element, styleResolver?: StyleResolver): boolean;
|
|
15
|
+
export declare function getDirectBlockChildren(element: Element, styleResolver?: StyleResolver): Element[];
|
|
16
|
+
export declare function getInlineOrTextNodes(element: Element, styleResolver?: StyleResolver): AnyNode[];
|
|
17
|
+
export { isBlockElement, typographyFromBlockElement };
|
|
18
|
+
//# sourceMappingURL=inline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../../src/converter/inline.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,MAAM,CAAC;AACd,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGnD,OAAO,EAEL,cAAc,EAGd,0BAA0B,EAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAe,aAAa,EAAE,MAAM,YAAY,CAAC;AAsC7D,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,aAAa,EACpB,WAAW,GAAE,MAA8B,GAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAsBzB;AA6BD,UAAU,cAAc;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,oEAAoE;IACpE,cAAc,EAAE,OAAO,CAAC;CACzB;AAsBD,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,OAAO,EAAE,EACrB,SAAS,GAAE,aAAkB,EAC7B,KAAK,GAAE,cAA+F,EACtG,aAAa,GAAE,aAAqC,EACpD,WAAW,GAAE,MAA8B,GAC1C,cAAc,EAAE,CAwGlB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,aAAa,GAAE,aAAqC,GACnD,OAAO,CAET;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,aAAa,GAAE,aAAqC,GACnD,OAAO,EAAE,CAIX;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,aAAa,GAAE,aAAqC,GACnD,OAAO,EAAE,CAMX;AAED,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC"}
|