@office-kit/pptx-dev 0.13.0 → 0.14.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 +12 -1
- package/dist/cli.mjs +45 -2
- package/dist/cli.mjs.map +1 -1
- package/dist/editor-chunks/{agent-tools-emRGeP2H-WN4XUNCN.js → agent-tools-EU7Eb-FV-IILR6JNI.js} +40 -27
- package/dist/editor-chunks/chunk-NVCAI6A2.js +32 -0
- package/dist/editor.js +708 -2
- package/dist/index.mjs +1 -1
- package/dist/{src-DASlwPDd.mjs → src-C1VTVnr6.mjs} +6 -3
- package/dist/src-C1VTVnr6.mjs.map +1 -0
- package/package.json +5 -5
- package/dist/editor-chunks/chunk-Q3KT5ZGJ.js +0 -738
- package/dist/src-DASlwPDd.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -131,7 +131,17 @@ npm run check
|
|
|
131
131
|
npm run build
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
`check` runs TypeScript
|
|
134
|
+
`check` runs TypeScript, then `office-pptx check`, which builds the deck and
|
|
135
|
+
measures every text box with the preview's layout engine. It fails on text that
|
|
136
|
+
runs out of its shape, and warns about text that only spills into the box's inner
|
|
137
|
+
margins, text smaller than 10pt (`--min-font-size` changes the floor), a word split
|
|
138
|
+
across lines, and a wrapped paragraph that ends on a line of one or two characters.
|
|
139
|
+
When a width had to be estimated (a font the preview does not bundle, such as any
|
|
140
|
+
Japanese font), it fails only on text more than a line's height out of its shape
|
|
141
|
+
(counting what spills above and below a centred box together) and warns about
|
|
142
|
+
smaller overflows. Table and chart text is not
|
|
143
|
+
measured. `build`
|
|
144
|
+
writes `deck.pptx`. Compilation alone does not
|
|
135
145
|
perform TypeScript checking, so run both before delivery. Exported charts, text,
|
|
136
146
|
images and tables remain editable. The renderer previews the serialized PPTX,
|
|
137
147
|
but is not a guarantee of identical rendering in desktop presentation apps.
|
|
@@ -323,6 +333,7 @@ the amount of PPTX evaluation.
|
|
|
323
333
|
- `office-pptx init <new-directory>` creates a TSX project without overwriting an existing directory.
|
|
324
334
|
- `office-pptx dev <deck.tsx> [--port 4173]` watches the entry file's directory recursively.
|
|
325
335
|
- `office-pptx build <deck.tsx> [--out deck.pptx]` writes a PPTX.
|
|
336
|
+
- `office-pptx check <deck.tsx> [--min-font-size 10]` reports text overflow, text below the minimum size, split words and one- or two-character last lines; it exits with 1 when text runs out of its shape.
|
|
326
337
|
- `office-pptx inspect <template.pptx>` prints slides, shape targets and layout references as JSON.
|
|
327
338
|
|
|
328
339
|
Keep imported components, source PPTX files and images inside the watched
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as editorStore, i as initProject, n as exportDeck, o as sourceFingerprint, r as inspectTemplate, s as createDeckBuilder } from "./src-
|
|
2
|
+
import { a as editorStore, i as initProject, n as exportDeck, o as sourceFingerprint, r as inspectTemplate, s as createDeckBuilder, t as buildDeck } from "./src-C1VTVnr6.mjs";
|
|
3
3
|
import { n as renderDeck } from "./build-cpmt-r9Q.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { chmod, lstat, mkdir, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
@@ -7,12 +7,14 @@ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "nod
|
|
|
7
7
|
import { watch } from "node:fs";
|
|
8
8
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
9
9
|
import { getGroupChildren, getShapeBounds, getShapeId, getShapeKind, getShapeRotation, getShapeXmlString, getSlideShapes, getSlideXmlString, getSlides, loadPresentation } from "@office-kit/pptx";
|
|
10
|
+
import { auditTextLayout } from "@office-kit/pptx-preview";
|
|
10
11
|
import { mergeDecks } from "@office-kit/pptx-editor/merge";
|
|
11
12
|
import { planPropEdit, planTextEdit, verifyTextEdit } from "@office-kit/pptx-dsl/source-edit";
|
|
12
13
|
import { chromium } from "playwright";
|
|
13
14
|
import { createServer } from "node:http";
|
|
14
15
|
import MarkdownIt from "markdown-it";
|
|
15
16
|
import { spawn } from "node:child_process";
|
|
17
|
+
import { buildFontkitMeasurer } from "@office-kit/pptx-preview/node";
|
|
16
18
|
//#region src/history.ts
|
|
17
19
|
const SNAPSHOT_LIMIT = 64 * 1024 * 1024;
|
|
18
20
|
const HISTORY_LIMIT = 128 * 1024 * 1024;
|
|
@@ -3276,18 +3278,51 @@ async function serveDeck(entry, port = 4173) {
|
|
|
3276
3278
|
}
|
|
3277
3279
|
};
|
|
3278
3280
|
}
|
|
3281
|
+
const OVERFLOW_TOLERANCE_PX = 1;
|
|
3282
|
+
/** Builds the deck and measures its text: overflow, split words, stranded last lines, small type. */
|
|
3283
|
+
async function checkDeck(entry, minFontSizePt = 10) {
|
|
3284
|
+
const { bytes } = await buildDeck(entry);
|
|
3285
|
+
return auditTextLayout(await loadPresentation(bytes), {
|
|
3286
|
+
measureText: buildFontkitMeasurer(),
|
|
3287
|
+
reportBadWraps: true,
|
|
3288
|
+
minFontSizePt
|
|
3289
|
+
}).map((issue) => ({
|
|
3290
|
+
severity: isError(issue) ? "error" : "warning",
|
|
3291
|
+
message: `Slide ${issue.slideIndex + 1}, ${issue.shapeName ? `"${issue.shapeName}"` : "unnamed shape"}: ${describe(issue, minFontSizePt)}${issue.approximate ? " (estimated width)" : ""}`
|
|
3292
|
+
}));
|
|
3293
|
+
}
|
|
3294
|
+
function isError(issue) {
|
|
3295
|
+
if (issue.kind !== "overflow-x" && issue.kind !== "overflow-y") return false;
|
|
3296
|
+
return issue.shapeOverflowPx > (issue.approximate ? issue.lineHeightPx : OVERFLOW_TOLERANCE_PX);
|
|
3297
|
+
}
|
|
3298
|
+
function describe(issue, minFontSizePt) {
|
|
3299
|
+
switch (issue.kind) {
|
|
3300
|
+
case "overflow-x": return issue.shapeOverflowPx > 0 ? `text runs ${issue.shapeOverflowPx}px past the sides of its shape` : `text spills ${issue.overflowPx}px into the side margins of its box`;
|
|
3301
|
+
case "overflow-y": return issue.shapeOverflowPx > 0 ? `text runs ${issue.shapeOverflowPx}px past the top or bottom of its shape` : `text spills ${issue.overflowPx}px into the top or bottom margin of its box`;
|
|
3302
|
+
case "soft-wrap": return `paragraph ${issue.paragraphIndex + 1} wraps onto ${issue.extraLines} more line(s)`;
|
|
3303
|
+
case "word-break": return `paragraph ${issue.paragraphIndex + 1} breaks the word "${issue.text}" across lines`;
|
|
3304
|
+
case "short-last-line": return `paragraph ${issue.paragraphIndex + 1} ends on a line of only "${issue.text}"`;
|
|
3305
|
+
case "small-font": return `text at ${issue.sizePt}pt is below ${minFontSizePt}pt`;
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3279
3308
|
//#endregion
|
|
3280
3309
|
//#region src/cli.ts
|
|
3281
3310
|
const usage = `Usage: office-pptx init <new-directory>
|
|
3282
3311
|
office-pptx dev <deck.tsx> [--port 4173]
|
|
3283
3312
|
office-pptx build <deck.tsx> [--out deck.pptx]
|
|
3313
|
+
office-pptx check <deck.tsx> [--min-font-size 10]
|
|
3284
3314
|
office-pptx inspect <template.pptx>`;
|
|
3315
|
+
const OPTIONS = new Map([
|
|
3316
|
+
["build", "--out"],
|
|
3317
|
+
["dev", "--port"],
|
|
3318
|
+
["check", "--min-font-size"]
|
|
3319
|
+
]);
|
|
3285
3320
|
const [command, entry, ...args] = process.argv.slice(2);
|
|
3286
3321
|
try {
|
|
3287
3322
|
if (command === "--help" || command === "-h") console.log(usage);
|
|
3288
3323
|
else {
|
|
3289
3324
|
if (!entry) throw new Error(usage);
|
|
3290
|
-
const option = command
|
|
3325
|
+
const option = OPTIONS.get(command);
|
|
3291
3326
|
if (args.length && (args.length !== 2 || !option || args[0] !== option || !args[1])) throw new Error(`Unexpected arguments: ${args.join(" ")}\n${usage}`);
|
|
3292
3327
|
if (command === "init") {
|
|
3293
3328
|
const directory = await initProject(entry);
|
|
@@ -3297,6 +3332,14 @@ try {
|
|
|
3297
3332
|
const output = resolve(args[1] ?? "deck.pptx");
|
|
3298
3333
|
const result = await exportDeck(entry, output);
|
|
3299
3334
|
console.log(`Wrote ${output} (${result.slides.length} slides)`);
|
|
3335
|
+
} else if (command === "check") {
|
|
3336
|
+
const minFontSizePt = args[1] === void 0 ? void 0 : Number(args[1]);
|
|
3337
|
+
if (minFontSizePt !== void 0 && !(minFontSizePt > 0)) throw new Error("Minimum font size must be a positive number of points.");
|
|
3338
|
+
const findings = await checkDeck(entry, minFontSizePt);
|
|
3339
|
+
for (const finding of findings) console.log(`${finding.severity}: ${finding.message}`);
|
|
3340
|
+
const errors = findings.filter((finding) => finding.severity === "error").length;
|
|
3341
|
+
console.log(`${errors} error(s), ${findings.length - errors} warning(s) in the slide text layout.`);
|
|
3342
|
+
if (errors > 0) process.exitCode = 1;
|
|
3300
3343
|
} else if (command === "dev") {
|
|
3301
3344
|
const port = args[1] === void 0 ? 4173 : Number(args[1]);
|
|
3302
3345
|
if (!Number.isInteger(port) || port < 0 || port > 65535) throw new Error("Port must be an integer between 0 and 65535.");
|