deckjsx 0.5.0 → 0.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 +21 -15
- package/dist/{pptxgenjs-BTMKb1WX.mjs → adapter-BbtteJ7s.mjs} +232 -131
- package/dist/adapter-C8xw46nz.d.mts +22 -0
- package/dist/adapter.d.mts +2 -0
- package/dist/adapter.mjs +2 -0
- package/dist/{index-sb451NVh.d.mts → index-C5l8PX5V.d.mts} +5 -7
- package/dist/index.d.mts +57 -4
- package/dist/index.mjs +7277 -5425
- package/dist/inspect.d.mts +3 -3
- package/dist/{jsx-CK-x7PLd.mjs → jsx-C671yNZa.mjs} +103 -103
- package/dist/jsx-dev-runtime.d.mts +2 -2
- package/dist/jsx-dev-runtime.mjs +1 -1
- package/dist/{jsx-runtime-Bk7Wx3AL.d.mts → jsx-runtime-DwfBuBkY.d.mts} +1 -1
- package/dist/jsx-runtime.d.mts +2 -2
- package/dist/jsx-runtime.mjs +1 -1
- package/dist/pptx-PzEK54aA.d.mts +448 -0
- package/package.json +2 -2
- package/dist/deck-CvTHG5ik.d.mts +0 -78
- package/dist/index-_eBM2cs3.d.mts +0 -245
- package/dist/legacy.d.mts +0 -6
- package/dist/legacy.mjs +0 -2
package/README.md
CHANGED
|
@@ -7,18 +7,19 @@ The intended architecture is:
|
|
|
7
7
|
|
|
8
8
|
```text
|
|
9
9
|
JSX
|
|
10
|
-
->
|
|
11
|
-
->
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
-> Author Tree
|
|
11
|
+
-> Semantic Author Graph
|
|
12
|
+
-> Output Projection
|
|
13
|
+
-> Output Writer
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
This project is being designed as a compiler, not as a thin `PptxGenJS` wrapper.
|
|
17
|
-
The API uses a class-based compiler with callback-based `.add()`, `.
|
|
18
|
-
Authoring uses typed JSX elements with
|
|
17
|
+
The API uses a class-based compiler with callback-based `.add()`, `.compile()`, `.project()`, and
|
|
18
|
+
`.render()`. Authoring uses typed JSX elements with CSS-like style and class semantics.
|
|
19
19
|
|
|
20
20
|
The implementation preserves the compiler model with explicit module boundaries for authoring,
|
|
21
|
-
|
|
21
|
+
semantic graph construction, style resolution, output projection, writer adapters, and runtime
|
|
22
|
+
output.
|
|
22
23
|
|
|
23
24
|
## Install
|
|
24
25
|
|
|
@@ -26,7 +27,7 @@ style normalization, layout, IR, backend emission, and Node runtime output.
|
|
|
26
27
|
npm install deckjsx
|
|
27
28
|
```
|
|
28
29
|
|
|
29
|
-
The package currently targets
|
|
30
|
+
The package currently targets PPTX output and ships a temporary `pptxgenjs` writer adapter.
|
|
30
31
|
|
|
31
32
|
## Usage
|
|
32
33
|
|
|
@@ -59,8 +60,7 @@ deck.add(({ composition }) => (
|
|
|
59
60
|
|
|
60
61
|
<section style={{ display: "grid", gridTemplateColumns: "1fr 1fr", columnGap: 0.35 }}>
|
|
61
62
|
<p style={{ fontSize: 18, color: "#334155", fit: "shrink" }}>
|
|
62
|
-
Author slides with typed JSX, inspect the
|
|
63
|
-
backend boundary.
|
|
63
|
+
Author slides with typed JSX, inspect the projected document model, and render PPTX files.
|
|
64
64
|
</p>
|
|
65
65
|
<figure style={{ backgroundColor: "#E0F2FE", borderRadius: 0.15, padding: 0.25 }}>
|
|
66
66
|
<img src="chart.png" style={{ width: "100%", height: "100%", fit: "contain" }} />
|
|
@@ -78,12 +78,12 @@ deck.add(({ composition }) => (
|
|
|
78
78
|
</Slide>
|
|
79
79
|
));
|
|
80
80
|
|
|
81
|
-
const
|
|
82
|
-
await deck.
|
|
81
|
+
const project = deck.project();
|
|
82
|
+
await deck.render({ output: "quarterly-review.pptx" });
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
Use `deck.
|
|
86
|
-
`deck.
|
|
85
|
+
Use `deck.compile()` for authoring semantics, `deck.project()` for output-facing inspection, and
|
|
86
|
+
`deck.render({ output })` when writing a PowerPoint file.
|
|
87
87
|
|
|
88
88
|
## JSX elements
|
|
89
89
|
|
|
@@ -118,7 +118,13 @@ Image elements compile to images and require either `src` or `data`:
|
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
Primitive string and number children inside view-like elements are normalized to implicit text
|
|
121
|
-
nodes. Inline rich text
|
|
121
|
+
nodes. Inline rich text uses `span` inside text-like elements:
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
<p>
|
|
125
|
+
Revenue grew <span style={{ color: "#16A34A", fontWeight: 700 }}>12%</span>.
|
|
126
|
+
</p>
|
|
127
|
+
```
|
|
122
128
|
|
|
123
129
|
## View Layout Semantics
|
|
124
130
|
|
|
@@ -25,9 +25,64 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
27
27
|
//#endregion
|
|
28
|
-
//#region src/
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
//#region src/diagnostics/format.ts
|
|
29
|
+
function formatSpan(path) {
|
|
30
|
+
return ` at ${path}`;
|
|
31
|
+
}
|
|
32
|
+
function formatDiagnostic(diagnostic) {
|
|
33
|
+
const lines = [`${diagnostic.severity}[${diagnostic.code}]: ${diagnostic.title}`];
|
|
34
|
+
if (diagnostic.message) lines.push(` ${diagnostic.message}`);
|
|
35
|
+
for (const label of diagnostic.labels) {
|
|
36
|
+
lines.push(formatSpan(label.path));
|
|
37
|
+
lines.push(` = ${label.message}`);
|
|
38
|
+
}
|
|
39
|
+
for (const note of diagnostic.notes ?? []) lines.push(`note: ${note}`);
|
|
40
|
+
for (const help of diagnostic.help ?? []) lines.push(`help: ${help}`);
|
|
41
|
+
return lines.join("\n");
|
|
42
|
+
}
|
|
43
|
+
function formatDiagnostics(diagnostics) {
|
|
44
|
+
return diagnostics.items.map((item) => formatDiagnostic(item)).join("\n\n");
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/diagnostics/errors.ts
|
|
48
|
+
var DeckDiagnosticError = class extends Error {
|
|
49
|
+
diagnostics;
|
|
50
|
+
constructor(message, diagnostics) {
|
|
51
|
+
super(message);
|
|
52
|
+
this.name = "DeckDiagnosticError";
|
|
53
|
+
this.diagnostics = diagnostics;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var SemanticGraphDiagnosticError = class extends DeckDiagnosticError {
|
|
57
|
+
constructor(diagnostics) {
|
|
58
|
+
super(formatDiagnostics(diagnostics), diagnostics);
|
|
59
|
+
this.name = "SemanticGraphDiagnosticError";
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var CompositionDiagnosticError = class extends DeckDiagnosticError {
|
|
63
|
+
constructor(diagnostics) {
|
|
64
|
+
super(formatDiagnostics(diagnostics), diagnostics);
|
|
65
|
+
this.name = "CompositionDiagnosticError";
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var StyleDiagnosticError = class extends DeckDiagnosticError {
|
|
69
|
+
constructor(diagnostics) {
|
|
70
|
+
super(formatDiagnostics(diagnostics), diagnostics);
|
|
71
|
+
this.name = "StyleDiagnosticError";
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/diagnostics/index.ts
|
|
76
|
+
function createDiagnostics(items = []) {
|
|
77
|
+
return {
|
|
78
|
+
items,
|
|
79
|
+
hasErrors: items.some((item) => item.severity === "error"),
|
|
80
|
+
hasWarnings: items.some((item) => item.severity === "warning")
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function diagnostic(input) {
|
|
84
|
+
return input;
|
|
85
|
+
}
|
|
31
86
|
//#endregion
|
|
32
87
|
//#region node_modules/inherits/inherits_browser.js
|
|
33
88
|
var require_inherits_browser = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -10314,9 +10369,13 @@ var require_lib = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
10314
10369
|
module.exports = JSZip;
|
|
10315
10370
|
}));
|
|
10316
10371
|
//#endregion
|
|
10317
|
-
//#region src/
|
|
10372
|
+
//#region src/types.ts
|
|
10318
10373
|
var import_dist = require_dist();
|
|
10319
10374
|
var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
|
|
10375
|
+
const EMU_PER_INCH = 914400;
|
|
10376
|
+
const POINTS_PER_INCH = 72;
|
|
10377
|
+
//#endregion
|
|
10378
|
+
//#region src/writers/pptxgenjs-xml-patches.ts
|
|
10320
10379
|
function emuToInches$1(value) {
|
|
10321
10380
|
return value / EMU_PER_INCH;
|
|
10322
10381
|
}
|
|
@@ -10717,14 +10776,15 @@ function patchSlideBlocks(xml, patch) {
|
|
|
10717
10776
|
}
|
|
10718
10777
|
return patchedXml;
|
|
10719
10778
|
}
|
|
10720
|
-
function buildSlideXmlPatchPlan(
|
|
10721
|
-
const
|
|
10722
|
-
const
|
|
10779
|
+
function buildSlideXmlPatchPlan(slidePart) {
|
|
10780
|
+
const slide = slidePart.payload;
|
|
10781
|
+
const images = [...collectBackgroundLayerImages(slide.backgroundLayers), ...collectRenderableImages(slide.elements)];
|
|
10782
|
+
const texts = collectRenderableTextNodes(slide.elements);
|
|
10723
10783
|
return {
|
|
10724
10784
|
pictureSrcRects: images.map((image) => resolveImageSrcRect(image)),
|
|
10725
|
-
shapeFills: [...
|
|
10726
|
-
shapeLines: collectShapeLinePatches(
|
|
10727
|
-
slideBackgroundFill: buildGradientFillXml(
|
|
10785
|
+
shapeFills: [...slide.backgroundLayers?.map((layer) => buildBackgroundLayerFillXml(layer)) ?? [], ...collectShapeFillPatches(slide.elements)],
|
|
10786
|
+
shapeLines: collectShapeLinePatches(slide.elements),
|
|
10787
|
+
slideBackgroundFill: buildGradientFillXml(slide.background),
|
|
10728
10788
|
textIndentsEmu: texts.map((text) => text.style.textIndentPt === void 0 ? void 0 : pointsToEmu$1(text.style.textIndentPt))
|
|
10729
10789
|
};
|
|
10730
10790
|
}
|
|
@@ -10765,10 +10825,10 @@ function applySlideXmlPatchPlan(slideXml, plan) {
|
|
|
10765
10825
|
}
|
|
10766
10826
|
});
|
|
10767
10827
|
}
|
|
10768
|
-
async function patchPresentationXml(data,
|
|
10828
|
+
async function patchPresentationXml(data, projection) {
|
|
10769
10829
|
const zip = await import_lib.default.loadAsync(data);
|
|
10770
|
-
for (const [slideIndex,
|
|
10771
|
-
const patchPlan = buildSlideXmlPatchPlan(
|
|
10830
|
+
for (const [slideIndex, slide] of projection.slides.entries()) {
|
|
10831
|
+
const patchPlan = buildSlideXmlPatchPlan(slide);
|
|
10772
10832
|
if (!hasSlideXmlPatchPlan(patchPlan)) continue;
|
|
10773
10833
|
const slidePath = `ppt/slides/slide${slideIndex + 1}.xml`;
|
|
10774
10834
|
const slideFile = zip.file(slidePath);
|
|
@@ -10779,7 +10839,8 @@ async function patchPresentationXml(data, ir) {
|
|
|
10779
10839
|
return zip.generateAsync({ type: "uint8array" });
|
|
10780
10840
|
}
|
|
10781
10841
|
//#endregion
|
|
10782
|
-
//#region src/
|
|
10842
|
+
//#region src/writers/pptxgenjs.ts
|
|
10843
|
+
const PPTX_MIME_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
|
10783
10844
|
const TRANSPARENT_FILL = {
|
|
10784
10845
|
color: "FFFFFF",
|
|
10785
10846
|
transparency: 100
|
|
@@ -10789,7 +10850,6 @@ const TRANSPARENT_LINE = {
|
|
|
10789
10850
|
transparency: 100,
|
|
10790
10851
|
width: 0
|
|
10791
10852
|
};
|
|
10792
|
-
const PPTX_MIME_TYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
|
10793
10853
|
function resolvePptxGenJSConstructor(moduleValue) {
|
|
10794
10854
|
if (typeof moduleValue === "function") return moduleValue;
|
|
10795
10855
|
if (typeof moduleValue === "object" && moduleValue !== null && "default" in moduleValue) {
|
|
@@ -10799,6 +10859,11 @@ function resolvePptxGenJSConstructor(moduleValue) {
|
|
|
10799
10859
|
throw new Error("Unable to resolve PptxGenJS constructor.");
|
|
10800
10860
|
}
|
|
10801
10861
|
const PptxGenJS = resolvePptxGenJSConstructor(PptxGenJSModule);
|
|
10862
|
+
function normalizeBuffer(data) {
|
|
10863
|
+
if (data instanceof Uint8Array) return data;
|
|
10864
|
+
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
|
10865
|
+
throw new Error("Unsupported PptxGenJS output type received.");
|
|
10866
|
+
}
|
|
10802
10867
|
function emuToInches(value) {
|
|
10803
10868
|
return value / EMU_PER_INCH;
|
|
10804
10869
|
}
|
|
@@ -10814,14 +10879,6 @@ function combineTransparency(transparency, opacity) {
|
|
|
10814
10879
|
function combineOpacities(parentOpacity, nodeOpacity) {
|
|
10815
10880
|
return (parentOpacity ?? 1) * (nodeOpacity ?? 1);
|
|
10816
10881
|
}
|
|
10817
|
-
function normalizeBuffer(data) {
|
|
10818
|
-
if (data instanceof Uint8Array) return data;
|
|
10819
|
-
if (data instanceof ArrayBuffer) return new Uint8Array(data);
|
|
10820
|
-
throw new Error("Unsupported PptxGenJS output type received.");
|
|
10821
|
-
}
|
|
10822
|
-
function assertNever(value) {
|
|
10823
|
-
throw new Error(`Unhandled PptxGenJS backend value: ${String(value)}`);
|
|
10824
|
-
}
|
|
10825
10882
|
function mapShapeName(shape, radiusEmu) {
|
|
10826
10883
|
if (shape === "rect") return radiusEmu && radiusEmu > 0 ? "roundRect" : "rect";
|
|
10827
10884
|
if (shape === "ellipse") return "ellipse";
|
|
@@ -10829,15 +10886,11 @@ function mapShapeName(shape, radiusEmu) {
|
|
|
10829
10886
|
}
|
|
10830
10887
|
function toPptxFill(fill, opacity) {
|
|
10831
10888
|
if (!fill) return;
|
|
10832
|
-
|
|
10833
|
-
|
|
10834
|
-
|
|
10835
|
-
|
|
10836
|
-
|
|
10837
|
-
case "linear-gradient":
|
|
10838
|
-
case "radial-gradient": return TRANSPARENT_FILL;
|
|
10839
|
-
default: return assertNever(fill);
|
|
10840
|
-
}
|
|
10889
|
+
if (fill.kind !== "solid") return TRANSPARENT_FILL;
|
|
10890
|
+
return {
|
|
10891
|
+
color: fill.color,
|
|
10892
|
+
transparency: combineTransparency(fill.transparency, opacity)
|
|
10893
|
+
};
|
|
10841
10894
|
}
|
|
10842
10895
|
function toPptxLine(stroke, opacity) {
|
|
10843
10896
|
if (!stroke) return;
|
|
@@ -10859,6 +10912,14 @@ function toPptxShadow(shadow, opacity) {
|
|
|
10859
10912
|
angle: shadow.angle
|
|
10860
10913
|
};
|
|
10861
10914
|
}
|
|
10915
|
+
function toPptxUnderline(style) {
|
|
10916
|
+
if (!style.underline && !style.underlineStyle && !style.underlineColor) return;
|
|
10917
|
+
if (!style.underlineStyle && !style.underlineColor) return style.underline;
|
|
10918
|
+
return {
|
|
10919
|
+
...style.underlineStyle ? { style: style.underlineStyle } : {},
|
|
10920
|
+
...style.underlineColor ? { color: style.underlineColor } : {}
|
|
10921
|
+
};
|
|
10922
|
+
}
|
|
10862
10923
|
function toPptxBullet(list) {
|
|
10863
10924
|
if (!list) return;
|
|
10864
10925
|
if (list.type === "none") return false;
|
|
@@ -10876,21 +10937,6 @@ function toPptxBullet(list) {
|
|
|
10876
10937
|
...list.indentPt !== void 0 ? { indent: list.indentPt } : {}
|
|
10877
10938
|
};
|
|
10878
10939
|
}
|
|
10879
|
-
function toPptxUnderline(style) {
|
|
10880
|
-
if (!style.underline && !style.underlineStyle && !style.underlineColor) return;
|
|
10881
|
-
if (!style.underlineStyle && !style.underlineColor) return style.underline;
|
|
10882
|
-
return {
|
|
10883
|
-
...style.underlineStyle ? { style: style.underlineStyle } : {},
|
|
10884
|
-
...style.underlineColor ? { color: style.underlineColor } : {}
|
|
10885
|
-
};
|
|
10886
|
-
}
|
|
10887
|
-
function toPptxTabStops(tabStops) {
|
|
10888
|
-
if (!tabStops || tabStops.length === 0) return;
|
|
10889
|
-
return tabStops.map((tabStop) => ({
|
|
10890
|
-
position: tabStop.positionIn,
|
|
10891
|
-
...tabStop.alignment ? { alignment: tabStop.alignment } : {}
|
|
10892
|
-
}));
|
|
10893
|
-
}
|
|
10894
10940
|
function toPptxTextRunOptions(style) {
|
|
10895
10941
|
if (!style) return;
|
|
10896
10942
|
const options = {
|
|
@@ -10906,27 +10952,26 @@ function toPptxTextRunOptions(style) {
|
|
|
10906
10952
|
subscript: style.subscript,
|
|
10907
10953
|
breakLine: false
|
|
10908
10954
|
};
|
|
10909
|
-
|
|
10910
|
-
return options;
|
|
10955
|
+
return Object.values(options).every((value) => value === void 0 || value === false) ? void 0 : options;
|
|
10911
10956
|
}
|
|
10912
|
-
function emitOutlineShape(slide, shapeName,
|
|
10913
|
-
if (!outline) return;
|
|
10914
|
-
const insetEmu = pointsToEmu(outline.widthPt) / 2;
|
|
10957
|
+
function emitOutlineShape(slide, shapeName, node, effectiveOpacity) {
|
|
10958
|
+
if (!node.outline) return;
|
|
10959
|
+
const insetEmu = pointsToEmu(node.outline.widthPt) / 2;
|
|
10915
10960
|
slide.addShape(shapeName, {
|
|
10916
|
-
x: emuToInches(frame.xEmu - insetEmu),
|
|
10917
|
-
y: emuToInches(frame.yEmu - insetEmu),
|
|
10918
|
-
w: emuToInches(frame.widthEmu + insetEmu * 2),
|
|
10919
|
-
h: emuToInches(frame.heightEmu + insetEmu * 2),
|
|
10961
|
+
x: emuToInches(node.frame.xEmu - insetEmu),
|
|
10962
|
+
y: emuToInches(node.frame.yEmu - insetEmu),
|
|
10963
|
+
w: emuToInches(node.frame.widthEmu + insetEmu * 2),
|
|
10964
|
+
h: emuToInches(node.frame.heightEmu + insetEmu * 2),
|
|
10920
10965
|
fill: TRANSPARENT_FILL,
|
|
10921
|
-
line: toPptxLine(outline, effectiveOpacity),
|
|
10922
|
-
radius: radiusEmu ? emuToInches(radiusEmu + insetEmu) : void 0,
|
|
10923
|
-
rotate: rotation,
|
|
10924
|
-
flipH,
|
|
10925
|
-
flipV
|
|
10966
|
+
line: toPptxLine(node.outline, effectiveOpacity),
|
|
10967
|
+
radius: node.radiusEmu ? emuToInches(node.radiusEmu + insetEmu) : void 0,
|
|
10968
|
+
rotate: node.rotation,
|
|
10969
|
+
flipH: node.flipH,
|
|
10970
|
+
flipV: node.flipV
|
|
10926
10971
|
});
|
|
10927
10972
|
}
|
|
10928
|
-
function emitEdgeStrokes(slide,
|
|
10929
|
-
if (!edgeStrokes) return;
|
|
10973
|
+
function emitEdgeStrokes(slide, node, effectiveOpacity) {
|
|
10974
|
+
if (!node.edgeStrokes) return;
|
|
10930
10975
|
const emitLine = (stroke, xEmu, yEmu, widthEmu, heightEmu) => {
|
|
10931
10976
|
if (!stroke) return;
|
|
10932
10977
|
slide.addShape("line", {
|
|
@@ -10935,19 +10980,19 @@ function emitEdgeStrokes(slide, frame, edgeStrokes, effectiveOpacity, rotation,
|
|
|
10935
10980
|
w: emuToInches(widthEmu),
|
|
10936
10981
|
h: emuToInches(heightEmu),
|
|
10937
10982
|
line: toPptxLine(stroke, effectiveOpacity),
|
|
10938
|
-
rotate: rotation,
|
|
10939
|
-
flipH,
|
|
10940
|
-
flipV
|
|
10983
|
+
rotate: node.rotation,
|
|
10984
|
+
flipH: node.flipH,
|
|
10985
|
+
flipV: node.flipV
|
|
10941
10986
|
});
|
|
10942
10987
|
};
|
|
10943
|
-
emitLine(edgeStrokes.top, frame.xEmu, frame.yEmu, frame.widthEmu, 0);
|
|
10944
|
-
emitLine(edgeStrokes.right, frame.xEmu + frame.widthEmu, frame.yEmu, 0, frame.heightEmu);
|
|
10945
|
-
emitLine(edgeStrokes.bottom, frame.xEmu, frame.yEmu + frame.heightEmu, frame.widthEmu, 0);
|
|
10946
|
-
emitLine(edgeStrokes.left, frame.xEmu, frame.yEmu, 0, frame.heightEmu);
|
|
10988
|
+
emitLine(node.edgeStrokes.top, node.frame.xEmu, node.frame.yEmu, node.frame.widthEmu, 0);
|
|
10989
|
+
emitLine(node.edgeStrokes.right, node.frame.xEmu + node.frame.widthEmu, node.frame.yEmu, 0, node.frame.heightEmu);
|
|
10990
|
+
emitLine(node.edgeStrokes.bottom, node.frame.xEmu, node.frame.yEmu + node.frame.heightEmu, node.frame.widthEmu, 0);
|
|
10991
|
+
emitLine(node.edgeStrokes.left, node.frame.xEmu, node.frame.yEmu, 0, node.frame.heightEmu);
|
|
10947
10992
|
}
|
|
10948
|
-
function emitBackgroundLayers(slide,
|
|
10949
|
-
if (!backgroundLayers || backgroundLayers.length === 0) return;
|
|
10950
|
-
for (const layer of backgroundLayers) {
|
|
10993
|
+
function emitBackgroundLayers(slide, node, shapeName, effectiveOpacity) {
|
|
10994
|
+
if (!node.backgroundLayers || node.backgroundLayers.length === 0) return;
|
|
10995
|
+
for (const layer of node.backgroundLayers) {
|
|
10951
10996
|
if (isBackgroundImageLayer(layer)) {
|
|
10952
10997
|
for (const tile of expandBackgroundImageLayer(layer)) slide.addImage({
|
|
10953
10998
|
x: emuToInches(tile.frame.xEmu),
|
|
@@ -10957,13 +11002,13 @@ function emitBackgroundLayers(slide, frame, backgroundLayers, shapeName, radiusE
|
|
|
10957
11002
|
path: tile.source.kind === "path" ? tile.source.path : void 0,
|
|
10958
11003
|
data: tile.source.kind === "data" ? tile.source.data : void 0,
|
|
10959
11004
|
transparency: combineTransparency(layer.transparency, effectiveOpacity),
|
|
10960
|
-
rotate: rotation,
|
|
10961
|
-
flipH,
|
|
10962
|
-
flipV
|
|
11005
|
+
rotate: node.rotation,
|
|
11006
|
+
flipH: node.flipH,
|
|
11007
|
+
flipV: node.flipV
|
|
10963
11008
|
});
|
|
10964
11009
|
continue;
|
|
10965
11010
|
}
|
|
10966
|
-
const layerFrame = "frame" in layer && layer.frame ? layer.frame : frame;
|
|
11011
|
+
const layerFrame = "frame" in layer && layer.frame ? layer.frame : node.frame;
|
|
10967
11012
|
slide.addShape(shapeName, {
|
|
10968
11013
|
x: emuToInches(layerFrame.xEmu),
|
|
10969
11014
|
y: emuToInches(layerFrame.yEmu),
|
|
@@ -10971,18 +11016,19 @@ function emitBackgroundLayers(slide, frame, backgroundLayers, shapeName, radiusE
|
|
|
10971
11016
|
h: emuToInches(layerFrame.heightEmu),
|
|
10972
11017
|
fill: toPptxFill(layer, effectiveOpacity),
|
|
10973
11018
|
line: TRANSPARENT_LINE,
|
|
10974
|
-
radius: radiusEmu ? emuToInches(radiusEmu) : void 0,
|
|
10975
|
-
rotate: rotation,
|
|
10976
|
-
flipH,
|
|
10977
|
-
flipV
|
|
11019
|
+
radius: node.radiusEmu ? emuToInches(node.radiusEmu) : void 0,
|
|
11020
|
+
rotate: node.rotation,
|
|
11021
|
+
flipH: node.flipH,
|
|
11022
|
+
flipV: node.flipV
|
|
10978
11023
|
});
|
|
10979
11024
|
}
|
|
10980
11025
|
}
|
|
10981
11026
|
function emitText(slide, node, inheritedOpacity) {
|
|
10982
11027
|
const effectiveOpacity = combineOpacities(inheritedOpacity, node.opacity);
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
11028
|
+
const shapeName = node.radiusEmu && node.radiusEmu > 0 ? "roundRect" : "rect";
|
|
11029
|
+
emitOutlineShape(slide, shapeName, node, effectiveOpacity);
|
|
11030
|
+
emitEdgeStrokes(slide, node, effectiveOpacity);
|
|
11031
|
+
emitBackgroundLayers(slide, node, shapeName, effectiveOpacity);
|
|
10986
11032
|
const textContent = node.content.runs ? node.content.runs.map((run) => {
|
|
10987
11033
|
const options = toPptxTextRunOptions(run.style);
|
|
10988
11034
|
return {
|
|
@@ -11009,7 +11055,10 @@ function emitText(slide, node, inheritedOpacity) {
|
|
|
11009
11055
|
lineSpacingMultiple: node.style.lineSpacingMultiple,
|
|
11010
11056
|
paraSpaceBefore: node.style.paragraphSpacingBefore,
|
|
11011
11057
|
paraSpaceAfter: node.style.paragraphSpacingAfter,
|
|
11012
|
-
tabStops:
|
|
11058
|
+
tabStops: node.style.tabStops?.map((tabStop) => ({
|
|
11059
|
+
position: tabStop.positionIn,
|
|
11060
|
+
...tabStop.alignment ? { alignment: tabStop.alignment } : {}
|
|
11061
|
+
})),
|
|
11013
11062
|
charSpacing: node.style.charSpacing,
|
|
11014
11063
|
bullet: toPptxBullet(node.style.list),
|
|
11015
11064
|
rtlMode: node.style.rtlMode,
|
|
@@ -11018,7 +11067,7 @@ function emitText(slide, node, inheritedOpacity) {
|
|
|
11018
11067
|
subscript: node.style.subscript,
|
|
11019
11068
|
fit: node.style.fit,
|
|
11020
11069
|
wrap: node.style.wrap,
|
|
11021
|
-
shape:
|
|
11070
|
+
shape: shapeName,
|
|
11022
11071
|
fill: toPptxFill(node.fill, effectiveOpacity),
|
|
11023
11072
|
line: toPptxLine(node.stroke, effectiveOpacity),
|
|
11024
11073
|
shadow: toPptxShadow(node.shadow, effectiveOpacity),
|
|
@@ -11050,10 +11099,11 @@ function emitImage(slide, node, inheritedOpacity) {
|
|
|
11050
11099
|
}
|
|
11051
11100
|
function emitShape(slide, node, inheritedOpacity) {
|
|
11052
11101
|
const effectiveOpacity = combineOpacities(inheritedOpacity, node.opacity);
|
|
11053
|
-
|
|
11054
|
-
|
|
11055
|
-
|
|
11056
|
-
slide
|
|
11102
|
+
const shapeName = mapShapeName(node.shape, node.radiusEmu);
|
|
11103
|
+
emitOutlineShape(slide, shapeName, node, effectiveOpacity);
|
|
11104
|
+
emitEdgeStrokes(slide, node, effectiveOpacity);
|
|
11105
|
+
emitBackgroundLayers(slide, node, shapeName, effectiveOpacity);
|
|
11106
|
+
slide.addShape(shapeName, {
|
|
11057
11107
|
x: emuToInches(node.frame.xEmu),
|
|
11058
11108
|
y: emuToInches(node.frame.yEmu),
|
|
11059
11109
|
w: emuToInches(node.frame.widthEmu),
|
|
@@ -11069,10 +11119,11 @@ function emitShape(slide, node, inheritedOpacity) {
|
|
|
11069
11119
|
}
|
|
11070
11120
|
function emitGroup(slide, node, inheritedOpacity) {
|
|
11071
11121
|
const effectiveOpacity = combineOpacities(inheritedOpacity, node.opacity);
|
|
11072
|
-
|
|
11073
|
-
|
|
11074
|
-
|
|
11075
|
-
|
|
11122
|
+
const shapeName = mapShapeName("rect", node.radiusEmu);
|
|
11123
|
+
emitOutlineShape(slide, shapeName, node, effectiveOpacity);
|
|
11124
|
+
emitEdgeStrokes(slide, node, effectiveOpacity);
|
|
11125
|
+
emitBackgroundLayers(slide, node, shapeName, effectiveOpacity);
|
|
11126
|
+
if (node.fill || node.stroke || node.shadow) slide.addShape(shapeName, {
|
|
11076
11127
|
x: emuToInches(node.frame.xEmu),
|
|
11077
11128
|
y: emuToInches(node.frame.yEmu),
|
|
11078
11129
|
w: emuToInches(node.frame.widthEmu),
|
|
@@ -11084,60 +11135,110 @@ function emitGroup(slide, node, inheritedOpacity) {
|
|
|
11084
11135
|
flipH: node.flipH,
|
|
11085
11136
|
flipV: node.flipV
|
|
11086
11137
|
});
|
|
11087
|
-
for (const child of node.children)
|
|
11138
|
+
for (const child of node.children) emitElement(slide, child, effectiveOpacity);
|
|
11088
11139
|
}
|
|
11089
|
-
function
|
|
11140
|
+
function emitElement(slide, node, inheritedOpacity) {
|
|
11090
11141
|
if (node.visibility === "hidden") return;
|
|
11091
11142
|
switch (node.kind) {
|
|
11092
11143
|
case "group":
|
|
11093
11144
|
emitGroup(slide, node, inheritedOpacity);
|
|
11094
11145
|
return;
|
|
11095
|
-
case "text":
|
|
11096
|
-
emitText(slide, node, inheritedOpacity);
|
|
11097
|
-
return;
|
|
11098
11146
|
case "image":
|
|
11099
11147
|
emitImage(slide, node, inheritedOpacity);
|
|
11100
11148
|
return;
|
|
11101
11149
|
case "shape":
|
|
11102
11150
|
emitShape(slide, node, inheritedOpacity);
|
|
11103
11151
|
return;
|
|
11104
|
-
|
|
11152
|
+
case "text":
|
|
11153
|
+
emitText(slide, node, inheritedOpacity);
|
|
11154
|
+
return;
|
|
11105
11155
|
}
|
|
11106
11156
|
}
|
|
11107
|
-
function
|
|
11157
|
+
function emitSlideBackgroundLayers(slide, projection, backgroundLayers) {
|
|
11158
|
+
if (!backgroundLayers || backgroundLayers.length === 0) return;
|
|
11159
|
+
for (const layer of backgroundLayers) {
|
|
11160
|
+
if (isBackgroundImageLayer(layer)) {
|
|
11161
|
+
for (const tile of expandBackgroundImageLayer(layer)) slide.addImage({
|
|
11162
|
+
x: emuToInches(tile.frame.xEmu),
|
|
11163
|
+
y: emuToInches(tile.frame.yEmu),
|
|
11164
|
+
w: emuToInches(tile.frame.widthEmu),
|
|
11165
|
+
h: emuToInches(tile.frame.heightEmu),
|
|
11166
|
+
path: tile.source.kind === "path" ? tile.source.path : void 0,
|
|
11167
|
+
data: tile.source.kind === "data" ? tile.source.data : void 0,
|
|
11168
|
+
transparency: layer.transparency
|
|
11169
|
+
});
|
|
11170
|
+
continue;
|
|
11171
|
+
}
|
|
11172
|
+
const layerFrame = "frame" in layer && layer.frame ? layer.frame : {
|
|
11173
|
+
xEmu: 0,
|
|
11174
|
+
yEmu: 0,
|
|
11175
|
+
widthEmu: projection.size.widthEmu,
|
|
11176
|
+
heightEmu: projection.size.heightEmu
|
|
11177
|
+
};
|
|
11178
|
+
slide.addShape("rect", {
|
|
11179
|
+
x: emuToInches(layerFrame.xEmu),
|
|
11180
|
+
y: emuToInches(layerFrame.yEmu),
|
|
11181
|
+
w: emuToInches(layerFrame.widthEmu),
|
|
11182
|
+
h: emuToInches(layerFrame.heightEmu),
|
|
11183
|
+
fill: toPptxFill(layer),
|
|
11184
|
+
line: TRANSPARENT_LINE
|
|
11185
|
+
});
|
|
11186
|
+
}
|
|
11187
|
+
}
|
|
11188
|
+
function adapterDiagnostics() {
|
|
11189
|
+
return createDiagnostics([diagnostic({
|
|
11190
|
+
severity: "warning",
|
|
11191
|
+
code: "W_PPTXGENJS_TEMPORARY_ADAPTER",
|
|
11192
|
+
title: "pptxgenjs adapter is temporary",
|
|
11193
|
+
message: "The pptxgenjs adapter consumes the Pptx Package Model directly, but it cannot serialize every projected package-part detail yet.",
|
|
11194
|
+
labels: [{
|
|
11195
|
+
path: "render.adapter",
|
|
11196
|
+
message: "Some package metadata is adapter-limited."
|
|
11197
|
+
}]
|
|
11198
|
+
})]);
|
|
11199
|
+
}
|
|
11200
|
+
async function renderPptxPackageWithPptxGenjs(projection) {
|
|
11201
|
+
const pptx = new PptxGenJS();
|
|
11202
|
+
const layoutName = "DECKJSX_CUSTOM";
|
|
11203
|
+
pptx.defineLayout({
|
|
11204
|
+
name: layoutName,
|
|
11205
|
+
width: projection.size.widthEmu / EMU_PER_INCH,
|
|
11206
|
+
height: projection.size.heightEmu / EMU_PER_INCH
|
|
11207
|
+
});
|
|
11208
|
+
pptx.layout = layoutName;
|
|
11209
|
+
if (projection.meta?.author) pptx.author = projection.meta.author;
|
|
11210
|
+
if (projection.meta?.title) pptx.title = projection.meta.title;
|
|
11211
|
+
if (projection.meta?.subject) pptx.subject = projection.meta.subject;
|
|
11212
|
+
for (const slidePart of projection.slides) {
|
|
11213
|
+
const slide = pptx.addSlide();
|
|
11214
|
+
if (slidePart.payload.background) slide.background = toPptxFill(slidePart.payload.background);
|
|
11215
|
+
emitSlideBackgroundLayers(slide, projection, slidePart.payload.backgroundLayers);
|
|
11216
|
+
for (const element of slidePart.payload.elements) emitElement(slide, element);
|
|
11217
|
+
}
|
|
11218
|
+
const bytes = await patchPresentationXml(normalizeBuffer(await pptx.write({ outputType: "uint8array" })), projection);
|
|
11219
|
+
return {
|
|
11220
|
+
diagnostics: adapterDiagnostics(),
|
|
11221
|
+
artifact: {
|
|
11222
|
+
format: "pptx",
|
|
11223
|
+
mediaType: PPTX_MIME_TYPE,
|
|
11224
|
+
extension: "pptx",
|
|
11225
|
+
bytes
|
|
11226
|
+
}
|
|
11227
|
+
};
|
|
11228
|
+
}
|
|
11229
|
+
//#endregion
|
|
11230
|
+
//#region src/adapter.ts
|
|
11231
|
+
function pptxgenjs(options = {}) {
|
|
11108
11232
|
return {
|
|
11233
|
+
kind: "deckjsx.writerAdapter",
|
|
11109
11234
|
name: "pptxgenjs",
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
11113
|
-
|
|
11114
|
-
|
|
11115
|
-
width: ir.size.widthEmu / EMU_PER_INCH,
|
|
11116
|
-
height: ir.size.heightEmu / EMU_PER_INCH
|
|
11117
|
-
});
|
|
11118
|
-
pptx.layout = layoutName;
|
|
11119
|
-
if (ir.meta?.author) pptx.author = ir.meta.author;
|
|
11120
|
-
if (ir.meta?.title) pptx.title = ir.meta.title;
|
|
11121
|
-
if (ir.meta?.subject) pptx.subject = ir.meta.subject;
|
|
11122
|
-
for (const slideIR of ir.slides) {
|
|
11123
|
-
const slide = pptx.addSlide();
|
|
11124
|
-
if (slideIR.background) slide.background = toPptxFill(slideIR.background);
|
|
11125
|
-
emitBackgroundLayers(slide, {
|
|
11126
|
-
xEmu: 0,
|
|
11127
|
-
yEmu: 0,
|
|
11128
|
-
widthEmu: ir.size.widthEmu,
|
|
11129
|
-
heightEmu: ir.size.heightEmu
|
|
11130
|
-
}, slideIR.backgroundLayers, "rect");
|
|
11131
|
-
for (const node of slideIR.nodes) emitNode(slide, node);
|
|
11132
|
-
}
|
|
11133
|
-
return {
|
|
11134
|
-
kind: "buffer",
|
|
11135
|
-
mimeType: PPTX_MIME_TYPE,
|
|
11136
|
-
data: await patchPresentationXml(normalizeBuffer(await pptx.write({ outputType: "uint8array" })), ir),
|
|
11137
|
-
extension: "pptx"
|
|
11138
|
-
};
|
|
11235
|
+
projectionFormat: "pptx",
|
|
11236
|
+
format: "pptx",
|
|
11237
|
+
options,
|
|
11238
|
+
async render(projection) {
|
|
11239
|
+
return renderPptxPackageWithPptxGenjs(projection);
|
|
11139
11240
|
}
|
|
11140
11241
|
};
|
|
11141
11242
|
}
|
|
11142
11243
|
//#endregion
|
|
11143
|
-
export { EMU_PER_INCH as n, POINTS_PER_INCH as r,
|
|
11244
|
+
export { diagnostic as a, SemanticGraphDiagnosticError as c, formatDiagnostics as d, createDiagnostics as i, StyleDiagnosticError as l, EMU_PER_INCH as n, CompositionDiagnosticError as o, POINTS_PER_INCH as r, DeckDiagnosticError as s, pptxgenjs as t, formatDiagnostic as u };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Yt as Diagnostics } from "./index-C5l8PX5V.mjs";
|
|
2
|
+
import { F as OutputFormat, L as ProjectionFormat, s as PptxPackageModel, z as RenderedArtifact } from "./pptx-PzEK54aA.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/adapter.d.ts
|
|
5
|
+
type RenderOptions = {
|
|
6
|
+
readonly output?: string;
|
|
7
|
+
};
|
|
8
|
+
type WriterAdapterResult<TFormat extends OutputFormat = OutputFormat> = {
|
|
9
|
+
readonly diagnostics: Diagnostics;
|
|
10
|
+
readonly artifact?: RenderedArtifact<TFormat>;
|
|
11
|
+
};
|
|
12
|
+
type WriterAdapter<TProjection = unknown, TFormat extends OutputFormat = OutputFormat> = {
|
|
13
|
+
readonly kind: "deckjsx.writerAdapter";
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly projectionFormat: ProjectionFormat;
|
|
16
|
+
readonly format: TFormat;
|
|
17
|
+
readonly options: RenderOptions;
|
|
18
|
+
render(projection: TProjection): Promise<WriterAdapterResult<TFormat>>;
|
|
19
|
+
};
|
|
20
|
+
declare function pptxgenjs(options?: RenderOptions): WriterAdapter<PptxPackageModel, "pptx">;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { pptxgenjs as i, WriterAdapter as n, WriterAdapterResult as r, RenderOptions as t };
|
package/dist/adapter.mjs
ADDED