@pollium/vyva-convert 0.0.0-stage → 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/README.md +88 -2
- package/dist/attachment.d.ts +3 -0
- package/dist/attachment.js +8 -0
- package/dist/clean-content.d.ts +6 -0
- package/dist/clean-content.js +58 -0
- package/dist/clean-html.d.ts +3 -0
- package/dist/clean-html.js +161 -0
- package/dist/errors.d.ts +7 -0
- package/dist/errors.js +11 -0
- package/dist/export/bundle.d.ts +34 -0
- package/dist/export/bundle.js +41 -0
- package/dist/export/docx.d.ts +5 -0
- package/dist/export/docx.js +382 -0
- package/dist/export/fonts.d.ts +16 -0
- package/dist/export/fonts.js +37 -0
- package/dist/export/html-blocks.d.ts +58 -0
- package/dist/export/html-blocks.js +170 -0
- package/dist/export/html.d.ts +8 -0
- package/dist/export/html.js +31 -0
- package/dist/export/image-size.d.ts +8 -0
- package/dist/export/image-size.js +83 -0
- package/dist/export/pdf.d.ts +28 -0
- package/dist/export/pdf.js +84 -0
- package/dist/export/pptx.d.ts +5 -0
- package/dist/export/pptx.js +310 -0
- package/dist/export.d.ts +19 -0
- package/dist/export.js +39 -0
- package/dist/font-widths.d.ts +8 -0
- package/dist/font-widths.js +3430 -0
- package/dist/gotenberg.d.ts +8 -0
- package/dist/gotenberg.js +39 -0
- package/dist/import/documents.d.ts +12 -0
- package/dist/import/documents.js +44 -0
- package/dist/import/html-to-blocks.d.ts +6 -0
- package/dist/import/html-to-blocks.js +58 -0
- package/dist/import/images.d.ts +10 -0
- package/dist/import/images.js +23 -0
- package/dist/import/pptx-package.d.ts +22 -0
- package/dist/import/pptx-package.js +61 -0
- package/dist/import/pptx-placeholders.d.ts +11 -0
- package/dist/import/pptx-placeholders.js +44 -0
- package/dist/import/pptx-slide.d.ts +19 -0
- package/dist/import/pptx-slide.js +324 -0
- package/dist/import/pptx-theme.d.ts +18 -0
- package/dist/import/pptx-theme.js +161 -0
- package/dist/import/pptx-xml.d.ts +23 -0
- package/dist/import/pptx-xml.js +27 -0
- package/dist/import/pptx.d.ts +9 -0
- package/dist/import/pptx.js +112 -0
- package/dist/import/titles.d.ts +3 -0
- package/dist/import/titles.js +6 -0
- package/dist/import.d.ts +14 -0
- package/dist/import.js +66 -0
- package/dist/text-measure.d.ts +4 -0
- package/dist/text-measure.js +98 -0
- package/package.json +49 -3
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ConvertError } from "./errors.js";
|
|
2
|
+
//#region src/gotenberg.ts
|
|
3
|
+
const DEFAULT_TIMEOUT_MS = 6e4;
|
|
4
|
+
const CONVERT_PATH = "/forms/chromium/convert/html";
|
|
5
|
+
const inches = (value) => String(Number(value.toFixed(3)));
|
|
6
|
+
const formOf = ({ html, files, footerHtml, page }) => {
|
|
7
|
+
const form = new FormData();
|
|
8
|
+
form.append("files", new Blob([html], { type: "text/html" }), "index.html");
|
|
9
|
+
for (const file of files) form.append("files", new Blob([new Uint8Array(file.data)], { type: file.contentType }), file.name);
|
|
10
|
+
if (footerHtml !== null) form.append("files", new Blob([footerHtml], { type: "text/html" }), "footer.html");
|
|
11
|
+
const { margins } = page;
|
|
12
|
+
const sizes = {
|
|
13
|
+
paperWidth: page.width,
|
|
14
|
+
paperHeight: page.height,
|
|
15
|
+
marginTop: margins.top,
|
|
16
|
+
marginBottom: margins.bottom,
|
|
17
|
+
marginLeft: margins.left,
|
|
18
|
+
marginRight: margins.right
|
|
19
|
+
};
|
|
20
|
+
for (const [field, value] of Object.entries(sizes)) form.append(field, inches(value));
|
|
21
|
+
form.append("printBackground", "true");
|
|
22
|
+
form.append("preferCssPageSize", "false");
|
|
23
|
+
form.append("waitDelay", "0.5s");
|
|
24
|
+
return form;
|
|
25
|
+
};
|
|
26
|
+
const gotenberg = ({ url, timeoutMs = DEFAULT_TIMEOUT_MS }) => async (job) => {
|
|
27
|
+
const endpoint = `${url.replace(/\/+$/, "")}${CONVERT_PATH}`;
|
|
28
|
+
const response = await fetch(endpoint, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
body: formOf(job),
|
|
31
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
32
|
+
}).catch((error) => {
|
|
33
|
+
throw new ConvertError("pdf-failed", `Gotenberg at ${url} could not be reached`, { cause: error });
|
|
34
|
+
});
|
|
35
|
+
if (!response.ok) throw new ConvertError("pdf-failed", `Gotenberg answered ${response.status}: ${await response.text().catch(() => "")}`);
|
|
36
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
export { gotenberg };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SaveImage } from "./images.js";
|
|
2
|
+
import { DocumentContent } from "@pollium/vyva-core/content";
|
|
3
|
+
//#region src/import/documents.d.ts
|
|
4
|
+
export interface ImportedDocument {
|
|
5
|
+
title: string;
|
|
6
|
+
content: DocumentContent;
|
|
7
|
+
}
|
|
8
|
+
export declare const importDocx: (buffer: Buffer, filename: string, saveImage: SaveImage) => Promise<ImportedDocument>;
|
|
9
|
+
export declare const importMarkdown: (text: string, filename: string) => ImportedDocument;
|
|
10
|
+
export declare const importPlainText: (text: string, filename: string) => ImportedDocument;
|
|
11
|
+
export declare const importPdf: (buffer: Buffer, filename: string) => Promise<ImportedDocument>;
|
|
12
|
+
//#endregion
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { htmlToBlocks, paragraphsHtml, titleFrom } from "./html-to-blocks.js";
|
|
2
|
+
import { imageSaver } from "./images.js";
|
|
3
|
+
import { markdownToBlocks } from "@pollium/vyva-core/markdown-blocks";
|
|
4
|
+
import { DEFAULT_DOCUMENT_DESIGN } from "@pollium/vyva-core/themes";
|
|
5
|
+
import mammoth from "mammoth";
|
|
6
|
+
import { extractText, getDocumentProxy } from "unpdf";
|
|
7
|
+
//#region src/import/documents.ts
|
|
8
|
+
const MAX_IMAGES = 60;
|
|
9
|
+
const PAGE_BREAK = "<div data-type=\"page-break\"></div>";
|
|
10
|
+
const documentOf = (blocks, filename) => ({
|
|
11
|
+
title: titleFrom(blocks, filename),
|
|
12
|
+
content: {
|
|
13
|
+
kind: "document",
|
|
14
|
+
design: DEFAULT_DOCUMENT_DESIGN,
|
|
15
|
+
blocks
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
const importDocx = async (buffer, filename, saveImage) => {
|
|
19
|
+
const save = imageSaver(saveImage, filename, MAX_IMAGES);
|
|
20
|
+
const failures = [];
|
|
21
|
+
const result = await mammoth.convertToHtml({ buffer }, { convertImage: mammoth.images.imgElement(async (image) => {
|
|
22
|
+
const data = await image.readAsBuffer();
|
|
23
|
+
const fileId = await save(data, image.contentType).catch((error) => {
|
|
24
|
+
failures.push(error);
|
|
25
|
+
return null;
|
|
26
|
+
});
|
|
27
|
+
return fileId === null ? { src: "" } : {
|
|
28
|
+
src: "",
|
|
29
|
+
"data-file-id": fileId,
|
|
30
|
+
alt: ""
|
|
31
|
+
};
|
|
32
|
+
}) });
|
|
33
|
+
if (failures.length > 0) throw failures[0];
|
|
34
|
+
return documentOf(htmlToBlocks(result.value), filename);
|
|
35
|
+
};
|
|
36
|
+
const importMarkdown = (text, filename) => documentOf(markdownToBlocks(text), filename);
|
|
37
|
+
const importPlainText = (text, filename) => documentOf(htmlToBlocks(paragraphsHtml(text)), filename);
|
|
38
|
+
const importPdf = async (buffer, filename) => {
|
|
39
|
+
const { text } = await extractText(await getDocumentProxy(new Uint8Array(buffer)), { mergePages: false });
|
|
40
|
+
const html = text.map((page) => paragraphsHtml(page)).filter((page) => page !== "").join(PAGE_BREAK);
|
|
41
|
+
return documentOf(htmlToBlocks(html), filename);
|
|
42
|
+
};
|
|
43
|
+
//#endregion
|
|
44
|
+
export { importDocx, importMarkdown, importPdf, importPlainText };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DocumentBlock } from "@pollium/vyva-core/content";
|
|
2
|
+
//#region src/import/html-to-blocks.d.ts
|
|
3
|
+
export declare const htmlToBlocks: (html: string) => DocumentBlock[];
|
|
4
|
+
export declare const titleFrom: (blocks: DocumentBlock[], filename: string) => string;
|
|
5
|
+
export declare const paragraphsHtml: (text: string) => string;
|
|
6
|
+
//#endregion
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { cleanHtml } from "../clean-html.js";
|
|
2
|
+
import { titleOf } from "./titles.js";
|
|
3
|
+
import { newId } from "@pollium/vyva-core/ids";
|
|
4
|
+
import { DomUtils, parseDocument } from "htmlparser2";
|
|
5
|
+
//#region src/import/html-to-blocks.ts
|
|
6
|
+
const BLOCK_TAGS = /* @__PURE__ */ new Set([
|
|
7
|
+
"p",
|
|
8
|
+
"h1",
|
|
9
|
+
"h2",
|
|
10
|
+
"h3",
|
|
11
|
+
"h4",
|
|
12
|
+
"ul",
|
|
13
|
+
"ol",
|
|
14
|
+
"table",
|
|
15
|
+
"pre",
|
|
16
|
+
"blockquote",
|
|
17
|
+
"hr",
|
|
18
|
+
"div",
|
|
19
|
+
"img"
|
|
20
|
+
]);
|
|
21
|
+
const HEADINGS = /* @__PURE__ */ new Set(["h5", "h6"]);
|
|
22
|
+
const ENTITIES = {
|
|
23
|
+
"&": "&",
|
|
24
|
+
"<": "<",
|
|
25
|
+
">": ">",
|
|
26
|
+
""": "\"",
|
|
27
|
+
"'": "'"
|
|
28
|
+
};
|
|
29
|
+
const htmlToBlocks = (html) => {
|
|
30
|
+
const blocks = [];
|
|
31
|
+
let loose = [];
|
|
32
|
+
const push = (outer) => {
|
|
33
|
+
const cleaned = cleanHtml(outer);
|
|
34
|
+
if (cleaned !== "" && cleaned !== "<p></p>") blocks.push({
|
|
35
|
+
id: newId(),
|
|
36
|
+
html: cleaned
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
const flush = () => {
|
|
40
|
+
const inner = loose.map((node) => DomUtils.getOuterHTML(node)).join("").trim();
|
|
41
|
+
loose = [];
|
|
42
|
+
if (inner !== "") push(`<p>${inner}</p>`);
|
|
43
|
+
};
|
|
44
|
+
for (const node of parseDocument(html).children) if (DomUtils.isTag(node) && (BLOCK_TAGS.has(node.name) || HEADINGS.has(node.name))) {
|
|
45
|
+
flush();
|
|
46
|
+
push(HEADINGS.has(node.name) ? `<h4>${DomUtils.getInnerHTML(node)}</h4>` : DomUtils.getOuterHTML(node));
|
|
47
|
+
} else loose.push(node);
|
|
48
|
+
flush();
|
|
49
|
+
return blocks;
|
|
50
|
+
};
|
|
51
|
+
const titleFrom = (blocks, filename) => {
|
|
52
|
+
const heading = blocks.find((block) => /^<h[1-3]/.test(block.html));
|
|
53
|
+
const text = heading === void 0 ? "" : heading.html.replace(/<[^>]+>/g, "").replace(/&(?:amp|lt|gt|quot|#39);/g, (entity) => ENTITIES[entity] ?? entity);
|
|
54
|
+
return titleOf(text, filename);
|
|
55
|
+
};
|
|
56
|
+
const paragraphsHtml = (text) => text.replace(/\r\n?/g, "\n").split(/\n{2,}/).map((part) => part.trim()).filter((part) => part !== "").map((part) => `<p>${part.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\n/g, "<br>")}</p>`).join("");
|
|
57
|
+
//#endregion
|
|
58
|
+
export { htmlToBlocks, paragraphsHtml, titleFrom };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/import/images.d.ts
|
|
2
|
+
export interface NewImage {
|
|
3
|
+
name: string;
|
|
4
|
+
data: Uint8Array;
|
|
5
|
+
contentType: string;
|
|
6
|
+
}
|
|
7
|
+
export type SaveImage = (image: NewImage) => Promise<string | null>;
|
|
8
|
+
export type ImageSaver = (data: Uint8Array, contentType: string) => Promise<string | null>;
|
|
9
|
+
export declare const imageSaver: (saveImage: SaveImage, filename: string, limit: number) => ImageSaver;
|
|
10
|
+
//#endregion
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/import/images.ts
|
|
2
|
+
const EXTENSIONS = {
|
|
3
|
+
"image/png": "png",
|
|
4
|
+
"image/jpeg": "jpg",
|
|
5
|
+
"image/gif": "gif",
|
|
6
|
+
"image/webp": "webp"
|
|
7
|
+
};
|
|
8
|
+
const imageSaver = (saveImage, filename, limit) => {
|
|
9
|
+
const base = filename.replace(/\.[a-z0-9]+$/i, "");
|
|
10
|
+
let taken = 0;
|
|
11
|
+
return async (data, contentType) => {
|
|
12
|
+
const extension = EXTENSIONS[contentType];
|
|
13
|
+
if (extension === void 0 || taken >= limit) return null;
|
|
14
|
+
taken += 1;
|
|
15
|
+
return saveImage({
|
|
16
|
+
name: `${base} (image ${taken}).${extension}`,
|
|
17
|
+
data,
|
|
18
|
+
contentType
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
export { imageSaver };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PackageFiles, Relations, XmlDocument, XmlElement } from "./pptx-xml.js";
|
|
2
|
+
import Palette from "./pptx-theme.js";
|
|
3
|
+
//#region src/import/pptx-package.d.ts
|
|
4
|
+
export interface SlidePart {
|
|
5
|
+
root: XmlElement;
|
|
6
|
+
tree: XmlElement | undefined;
|
|
7
|
+
relations: Relations;
|
|
8
|
+
palette: Palette;
|
|
9
|
+
}
|
|
10
|
+
export interface SlideParts {
|
|
11
|
+
slide: SlidePart;
|
|
12
|
+
layout: SlidePart | null;
|
|
13
|
+
master: SlidePart | null;
|
|
14
|
+
}
|
|
15
|
+
export default class PptxPackage {
|
|
16
|
+
#private;
|
|
17
|
+
constructor(files: PackageFiles);
|
|
18
|
+
document(path: string): XmlDocument | undefined;
|
|
19
|
+
relationsOf(path: string): Relations;
|
|
20
|
+
parts(slidePath: string): SlideParts | null;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { first, relatedPart, relationsOf, xml } from "./pptx-xml.js";
|
|
2
|
+
import Palette, { colorMapOf, themeOf } from "./pptx-theme.js";
|
|
3
|
+
import { DomUtils } from "htmlparser2";
|
|
4
|
+
import { strFromU8 } from "fflate";
|
|
5
|
+
//#region src/import/pptx-package.ts
|
|
6
|
+
var PptxPackage = class {
|
|
7
|
+
#files;
|
|
8
|
+
#documents = /* @__PURE__ */ new Map();
|
|
9
|
+
#palettes = /* @__PURE__ */ new Map();
|
|
10
|
+
constructor(files) {
|
|
11
|
+
this.#files = files;
|
|
12
|
+
}
|
|
13
|
+
document(path) {
|
|
14
|
+
const known = this.#documents.get(path);
|
|
15
|
+
if (known !== void 0) return known;
|
|
16
|
+
const data = this.#files[path];
|
|
17
|
+
if (data === void 0) return void 0;
|
|
18
|
+
const document = xml(strFromU8(data));
|
|
19
|
+
this.#documents.set(path, document);
|
|
20
|
+
return document;
|
|
21
|
+
}
|
|
22
|
+
relationsOf(path) {
|
|
23
|
+
return relationsOf(this.#files, path);
|
|
24
|
+
}
|
|
25
|
+
parts(slidePath) {
|
|
26
|
+
const slideRelations = relationsOf(this.#files, slidePath);
|
|
27
|
+
const layoutPath = relatedPart(slideRelations, "slideLayout");
|
|
28
|
+
const layoutRelations = layoutPath === null ? {} : relationsOf(this.#files, layoutPath);
|
|
29
|
+
const masterPath = layoutPath === null ? null : relatedPart(layoutRelations, "slideMaster");
|
|
30
|
+
const palette = this.#palette(masterPath);
|
|
31
|
+
const slide = this.#part(slidePath, slideRelations, palette);
|
|
32
|
+
if (slide === null) return null;
|
|
33
|
+
return {
|
|
34
|
+
slide,
|
|
35
|
+
layout: layoutPath === null ? null : this.#part(layoutPath, layoutRelations, palette),
|
|
36
|
+
master: masterPath === null ? null : this.#part(masterPath, relationsOf(this.#files, masterPath), palette)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
#part(path, relations, palette) {
|
|
40
|
+
const root = this.document(path)?.children.find((node) => DomUtils.isTag(node));
|
|
41
|
+
if (root === void 0) return null;
|
|
42
|
+
return {
|
|
43
|
+
root,
|
|
44
|
+
tree: first(root, "p:spTree"),
|
|
45
|
+
relations,
|
|
46
|
+
palette
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
#palette(masterPath) {
|
|
50
|
+
const key = masterPath ?? "";
|
|
51
|
+
const known = this.#palettes.get(key);
|
|
52
|
+
if (known !== void 0) return known;
|
|
53
|
+
const masterRoot = (masterPath === null ? void 0 : this.document(masterPath))?.children.find((node) => DomUtils.isTag(node));
|
|
54
|
+
const themePath = masterPath === null ? null : relatedPart(relationsOf(this.#files, masterPath), "theme");
|
|
55
|
+
const palette = new Palette(themeOf(themePath === null ? void 0 : this.document(themePath)), colorMapOf(masterRoot));
|
|
56
|
+
this.#palettes.set(key, palette);
|
|
57
|
+
return palette;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { PptxPackage as default };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { XmlElement } from "./pptx-xml.js";
|
|
2
|
+
import { SlidePart, SlideParts } from "./pptx-package.js";
|
|
3
|
+
//#region src/import/pptx-placeholders.d.ts
|
|
4
|
+
export declare const TITLE_TYPES: string[];
|
|
5
|
+
export declare const isDefined: <T>(value: T | undefined) => value is T;
|
|
6
|
+
export declare const placeholderChain: (shape: XmlElement, placeholder: XmlElement, parts: SlideParts) => XmlElement[];
|
|
7
|
+
export declare const levelOf: (shape: XmlElement) => XmlElement | undefined;
|
|
8
|
+
export declare const masterLevel: (parts: SlideParts, type: string | null) => XmlElement | undefined;
|
|
9
|
+
export declare const bulletsByDefault: (levels: XmlElement[]) => boolean;
|
|
10
|
+
export declare const decorOf: (parts: SlideParts) => SlidePart[];
|
|
11
|
+
//#endregion
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { all, attr, first, kid, kids } from "./pptx-xml.js";
|
|
2
|
+
//#region src/import/pptx-placeholders.ts
|
|
3
|
+
const TITLE_TYPES = ["title", "ctrTitle"];
|
|
4
|
+
const MASTER_TYPES = {
|
|
5
|
+
ctrTitle: "title",
|
|
6
|
+
subTitle: "body",
|
|
7
|
+
obj: "body"
|
|
8
|
+
};
|
|
9
|
+
const isDefined = (value) => value !== void 0;
|
|
10
|
+
const placeholderType = (shape) => attr(first(shape, "p:ph"), "type") ?? "body";
|
|
11
|
+
const masterType = (type) => MASTER_TYPES[type] ?? type;
|
|
12
|
+
const placeholdersOf = (part) => part?.tree === void 0 ? [] : all(part.tree, "p:sp").filter((shape) => first(shape, "p:ph") !== void 0);
|
|
13
|
+
const placeholderChain = (shape, placeholder, parts) => {
|
|
14
|
+
const type = attr(placeholder, "type") ?? "body";
|
|
15
|
+
const idx = attr(placeholder, "idx");
|
|
16
|
+
const layoutShapes = placeholdersOf(parts.layout);
|
|
17
|
+
const inLayout = (idx === void 0 ? void 0 : layoutShapes.find((candidate) => attr(first(candidate, "p:ph"), "idx") === idx)) ?? layoutShapes.find((candidate) => placeholderType(candidate) === type);
|
|
18
|
+
const wanted = masterType(inLayout === void 0 ? type : placeholderType(inLayout));
|
|
19
|
+
return [
|
|
20
|
+
shape,
|
|
21
|
+
inLayout,
|
|
22
|
+
placeholdersOf(parts.master).find((candidate) => masterType(placeholderType(candidate)) === wanted)
|
|
23
|
+
].filter(isDefined);
|
|
24
|
+
};
|
|
25
|
+
const levelOf = (shape) => kid(kid(kid(shape, "p:txBody"), "a:lstStyle"), "a:lvl1pPr");
|
|
26
|
+
const masterLevel = (parts, type) => {
|
|
27
|
+
if (type === null || parts.master === null) return void 0;
|
|
28
|
+
const style = TITLE_TYPES.includes(type) ? "p:titleStyle" : masterType(type) === "body" ? "p:bodyStyle" : "p:otherStyle";
|
|
29
|
+
return kid(first(parts.master.root, style), "a:lvl1pPr");
|
|
30
|
+
};
|
|
31
|
+
const bulletsByDefault = (levels) => {
|
|
32
|
+
for (const level of levels) {
|
|
33
|
+
if (kids(level, "a:buNone").length > 0) return false;
|
|
34
|
+
if (kids(level, "a:buChar").length > 0 || kids(level, "a:buAutoNum").length > 0) return true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
};
|
|
38
|
+
const showsMasterShapes = (part) => attr(part.root, "showMasterSp") !== "0";
|
|
39
|
+
const decorOf = (parts) => {
|
|
40
|
+
if (!showsMasterShapes(parts.slide) || parts.layout === null) return [];
|
|
41
|
+
return parts.master !== null && showsMasterShapes(parts.layout) ? [parts.master, parts.layout] : [parts.layout];
|
|
42
|
+
};
|
|
43
|
+
//#endregion
|
|
44
|
+
export { TITLE_TYPES, bulletsByDefault, decorOf, isDefined, levelOf, masterLevel, placeholderChain };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SlideParts } from "./pptx-package.js";
|
|
2
|
+
import { DeckTheme, Slide } from "@pollium/vyva-core/content";
|
|
3
|
+
//#region src/import/pptx-slide.d.ts
|
|
4
|
+
export interface SlideReaderOptions {
|
|
5
|
+
scale: number;
|
|
6
|
+
fontScale: number;
|
|
7
|
+
theme: DeckTheme;
|
|
8
|
+
image: (path: string) => Promise<string | null>;
|
|
9
|
+
}
|
|
10
|
+
export interface ReadSlide {
|
|
11
|
+
slide: Slide;
|
|
12
|
+
title: string;
|
|
13
|
+
}
|
|
14
|
+
export default class SlideReader {
|
|
15
|
+
#private;
|
|
16
|
+
constructor(options: SlideReaderOptions);
|
|
17
|
+
read(parts: SlideParts): Promise<ReadSlide>;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|