@intentic/fileq 1.317.0 → 1.318.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/NOTICE +208 -0
- package/README.md +24 -3
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +15 -1
- package/dist/app.js.map +1 -1
- package/dist/commands/check.command.d.ts +3 -0
- package/dist/commands/check.command.d.ts.map +1 -0
- package/dist/commands/check.command.js +80 -0
- package/dist/commands/check.command.js.map +1 -0
- package/dist/commands/render.command.d.ts +3 -0
- package/dist/commands/render.command.d.ts.map +1 -0
- package/dist/commands/render.command.js +67 -0
- package/dist/commands/render.command.js.map +1 -0
- package/dist/lib/check/check.d.ts +15 -0
- package/dist/lib/check/check.d.ts.map +1 -0
- package/dist/lib/check/check.js +35 -0
- package/dist/lib/check/check.js.map +1 -0
- package/dist/lib/check/docx.d.ts +3 -0
- package/dist/lib/check/docx.d.ts.map +1 -0
- package/dist/lib/check/docx.js +329 -0
- package/dist/lib/check/docx.js.map +1 -0
- package/dist/lib/check/finding.d.ts +20 -0
- package/dist/lib/check/finding.d.ts.map +1 -0
- package/dist/lib/check/finding.js +27 -0
- package/dist/lib/check/finding.js.map +1 -0
- package/dist/lib/check/package.d.ts +25 -0
- package/dist/lib/check/package.d.ts.map +1 -0
- package/dist/lib/check/package.js +139 -0
- package/dist/lib/check/package.js.map +1 -0
- package/dist/lib/check/pdf.d.ts +3 -0
- package/dist/lib/check/pdf.d.ts.map +1 -0
- package/dist/lib/check/pdf.js +160 -0
- package/dist/lib/check/pdf.js.map +1 -0
- package/dist/lib/check/pptx.d.ts +3 -0
- package/dist/lib/check/pptx.d.ts.map +1 -0
- package/dist/lib/check/pptx.js +497 -0
- package/dist/lib/check/pptx.js.map +1 -0
- package/dist/lib/check/text-fit.d.ts +18 -0
- package/dist/lib/check/text-fit.d.ts.map +1 -0
- package/dist/lib/check/text-fit.js +69 -0
- package/dist/lib/check/text-fit.js.map +1 -0
- package/dist/lib/check/xlsx.d.ts +3 -0
- package/dist/lib/check/xlsx.d.ts.map +1 -0
- package/dist/lib/check/xlsx.js +131 -0
- package/dist/lib/check/xlsx.js.map +1 -0
- package/dist/lib/check/xml-tree.d.ts +15 -0
- package/dist/lib/check/xml-tree.d.ts.map +1 -0
- package/dist/lib/check/xml-tree.js +131 -0
- package/dist/lib/check/xml-tree.js.map +1 -0
- package/dist/lib/derivers/image.d.ts.map +1 -1
- package/dist/lib/derivers/image.js.map +1 -1
- package/dist/lib/formats.d.ts +1 -0
- package/dist/lib/formats.d.ts.map +1 -1
- package/dist/lib/formats.js +1 -0
- package/dist/lib/formats.js.map +1 -1
- package/dist/lib/render/convert.d.ts +11 -0
- package/dist/lib/render/convert.d.ts.map +1 -0
- package/dist/lib/render/convert.js +107 -0
- package/dist/lib/render/convert.js.map +1 -0
- package/dist/lib/render/pages.d.ts +11 -0
- package/dist/lib/render/pages.d.ts.map +1 -0
- package/dist/lib/render/pages.js +43 -0
- package/dist/lib/render/pages.js.map +1 -0
- package/dist/lib/render/render.d.ts +29 -0
- package/dist/lib/render/render.d.ts.map +1 -0
- package/dist/lib/render/render.js +142 -0
- package/dist/lib/render/render.js.map +1 -0
- package/dist/skill-authoring.d.ts +2 -0
- package/dist/skill-authoring.d.ts.map +1 -0
- package/dist/skill-authoring.js +20 -0
- package/dist/skill-authoring.js.map +1 -0
- package/dist/skill.d.ts.map +1 -1
- package/dist/skill.js +24 -1
- package/dist/skill.js.map +1 -1
- package/dist/testing.d.ts +67 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +151 -0
- package/dist/testing.js.map +1 -1
- package/package.json +20 -7
- package/src/app.ts +15 -1
- package/src/cli.integration.test.ts +63 -1
- package/src/commands/check.command.ts +97 -0
- package/src/commands/render.command.ts +80 -0
- package/src/lib/check/check.test.ts +446 -0
- package/src/lib/check/check.ts +49 -0
- package/src/lib/check/docx.ts +434 -0
- package/src/lib/check/finding.ts +63 -0
- package/src/lib/check/package.ts +199 -0
- package/src/lib/check/pdf.ts +228 -0
- package/src/lib/check/pptx.ts +641 -0
- package/src/lib/check/text-fit.ts +105 -0
- package/src/lib/check/xlsx.ts +163 -0
- package/src/lib/check/xml-tree.ts +186 -0
- package/src/lib/derivers/image.ts +2 -1
- package/src/lib/formats.ts +6 -0
- package/src/lib/render/convert.ts +133 -0
- package/src/lib/render/pages.test.ts +38 -0
- package/src/lib/render/pages.ts +58 -0
- package/src/lib/render/render.ts +198 -0
- package/src/render.integration.test.ts +217 -0
- package/src/skill-authoring.ts +27 -0
- package/src/skill.ts +28 -1
- package/src/testing.ts +287 -0
- package/dist/lib/flags.d.ts +0 -2
- package/dist/lib/flags.d.ts.map +0 -1
- package/dist/lib/flags.js +0 -8
- package/dist/lib/flags.js.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -3
- package/dist/version.js.map +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type Format } from "../formats.js";
|
|
2
|
+
import { type PageRange } from "./pages.js";
|
|
3
|
+
export declare const RENDERED_DIR = ".intentic/local/cache/rendered";
|
|
4
|
+
export declare const DEFAULT_PAGE_CAP = 20;
|
|
5
|
+
export declare const DEFAULT_SIZE = 1600;
|
|
6
|
+
export declare class NotRenderable extends Error {
|
|
7
|
+
}
|
|
8
|
+
export interface RenderRequest {
|
|
9
|
+
readonly absPath: string;
|
|
10
|
+
readonly pages: readonly PageRange[] | undefined;
|
|
11
|
+
readonly outDir: string | undefined;
|
|
12
|
+
readonly size: number;
|
|
13
|
+
}
|
|
14
|
+
export interface RenderedPage {
|
|
15
|
+
readonly page: number;
|
|
16
|
+
readonly path: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RenderResult {
|
|
19
|
+
readonly format: Format;
|
|
20
|
+
readonly unit: "slide" | "page";
|
|
21
|
+
readonly total: number;
|
|
22
|
+
readonly images: RenderedPage[];
|
|
23
|
+
readonly outDir: string;
|
|
24
|
+
readonly reused: boolean;
|
|
25
|
+
readonly notes: string[];
|
|
26
|
+
}
|
|
27
|
+
export declare const defaultOutDir: (absPath: string, workspaceRoot: string | undefined) => string;
|
|
28
|
+
export declare const renderDocument: (request: RenderRequest, workspaceRoot: string | undefined) => Promise<RenderResult>;
|
|
29
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/lib/render/render.ts"],"names":[],"mappings":"AAQA,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAG3D,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAQnE,eAAO,MAAM,YAAY,mCAAsC,CAAC;AAIhE,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,YAAY,OAAO,CAAC;AAKjC,qBAAa,aAAc,SAAQ,KAAK;CAAG;AAE3C,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAAC;IAEjD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAEpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;CAC5B;AAWD,eAAO,MAAM,aAAa,YAAa,MAAM,iBAAiB,MAAM,GAAG,SAAS,KAAG,MAOlF,CAAC;AAyEF,eAAO,MAAM,cAAc,YAAmB,aAAa,iBAAiB,MAAM,GAAG,SAAS,KAAG,OAAO,CAAC,YAAY,CAkDpH,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { copyFile, mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { basename, join } from "node:path";
|
|
5
|
+
import { toolOutDir } from "@intentic/agent-cli/env";
|
|
6
|
+
import { STATE_DIR } from "@intentic/constants";
|
|
7
|
+
import { getDocumentProxy } from "unpdf";
|
|
8
|
+
import { relPathIn } from "../derive.js";
|
|
9
|
+
import { claimedFormat } from "../formats.js";
|
|
10
|
+
import { sha256OfFile } from "../sidecar.js";
|
|
11
|
+
import { ConvertFailed, listDir, office, rasterizer, toPdf, toPngs } from "./convert.js";
|
|
12
|
+
import { BadPages, pagesWithin } from "./pages.js";
|
|
13
|
+
export const RENDERED_DIR = `${STATE_DIR}/local/cache/rendered`;
|
|
14
|
+
export const DEFAULT_PAGE_CAP = 20;
|
|
15
|
+
export const DEFAULT_SIZE = 1600;
|
|
16
|
+
const VIA_OFFICE = new Set(["docx", "pptx", "xlsx", "odt", "ods", "odp", "rtf"]);
|
|
17
|
+
const SLIDES = new Set(["pptx", "odp"]);
|
|
18
|
+
export class NotRenderable extends Error {
|
|
19
|
+
}
|
|
20
|
+
const STAMP_FILE = ".fileq-render.json";
|
|
21
|
+
export const defaultOutDir = (absPath, workspaceRoot) => {
|
|
22
|
+
const relPath = workspaceRoot === undefined ? undefined : relPathIn(workspaceRoot, absPath);
|
|
23
|
+
if (workspaceRoot !== undefined && relPath !== undefined) {
|
|
24
|
+
return join(workspaceRoot, RENDERED_DIR, relPath);
|
|
25
|
+
}
|
|
26
|
+
const hash = createHash("sha256").update(absPath).digest("hex").slice(0, 8);
|
|
27
|
+
return join(toolOutDir("fileq"), "rendered", `${basename(absPath).toLowerCase().replaceAll(/[^a-z0-9.]+/g, "-")}-${hash}`);
|
|
28
|
+
};
|
|
29
|
+
const readStamp = async (dir) => {
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(await readFile(join(dir, STAMP_FILE), "utf8"));
|
|
32
|
+
return parsed.sha256 === undefined || parsed.size === undefined || parsed.total === undefined ? undefined : { sha256: parsed.sha256, size: parsed.size, total: parsed.total };
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const clearImages = async (dir) => {
|
|
39
|
+
const names = await listDir(dir);
|
|
40
|
+
await Promise.all(names.filter((name) => /^(?:slide|page)-\d+\.png$/.test(name)).map((name) => rm(join(dir, name), { force: true })));
|
|
41
|
+
};
|
|
42
|
+
const ignoreInGit = async (workspaceRoot, outDir) => {
|
|
43
|
+
if (workspaceRoot === undefined || !outDir.startsWith(join(workspaceRoot, RENDERED_DIR))) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
await writeFile(join(workspaceRoot, RENDERED_DIR, ".gitignore"), "# fileq's rendered pages; regenerated on demand.\n*\n", { flag: "wx" });
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const pageCount = async (pdfPath) => {
|
|
53
|
+
try {
|
|
54
|
+
const pdf = await getDocumentProxy(new Uint8Array(await readFile(pdfPath)));
|
|
55
|
+
return pdf.numPages;
|
|
56
|
+
}
|
|
57
|
+
catch (cause) {
|
|
58
|
+
const locked = cause instanceof Error && cause.name === "PasswordException";
|
|
59
|
+
throw new ConvertFailed(locked ? "the PDF is password-protected" : "the PDF cannot be read");
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const formatOf = async (absPath) => {
|
|
63
|
+
const format = await claimedFormat(absPath);
|
|
64
|
+
if (format === "pdf" || (format !== undefined && VIA_OFFICE.has(format))) {
|
|
65
|
+
return format;
|
|
66
|
+
}
|
|
67
|
+
if (format === "image") {
|
|
68
|
+
throw new NotRenderable("an image is already pixels: Read it directly");
|
|
69
|
+
}
|
|
70
|
+
throw new NotRenderable(`fileq render draws pdf, docx, pptx, xlsx, odt, odp, ods and rtf; this is ${format ?? "none of them"}`);
|
|
71
|
+
};
|
|
72
|
+
const choosePages = (request, total, unit, notes) => {
|
|
73
|
+
if (request.pages === undefined) {
|
|
74
|
+
const pages = pagesWithin([{ from: 1, to: DEFAULT_PAGE_CAP }], total);
|
|
75
|
+
if (total > DEFAULT_PAGE_CAP) {
|
|
76
|
+
notes.push(`drew the first ${DEFAULT_PAGE_CAP} of ${total} ${unit}s: pass --pages ${DEFAULT_PAGE_CAP + 1}-${total} for the rest`);
|
|
77
|
+
}
|
|
78
|
+
return pages;
|
|
79
|
+
}
|
|
80
|
+
const pages = pagesWithin(request.pages, total);
|
|
81
|
+
if (pages.length === 0) {
|
|
82
|
+
throw new BadPages(`the document has ${total} ${unit}${total === 1 ? "" : "s"}; --pages names none of them`);
|
|
83
|
+
}
|
|
84
|
+
const asked = request.pages.some((range) => (range.to ?? range.from) > total);
|
|
85
|
+
if (asked) {
|
|
86
|
+
notes.push(`the document has ${total} ${unit}${total === 1 ? "" : "s"}; drew the ones --pages named within that`);
|
|
87
|
+
}
|
|
88
|
+
return pages;
|
|
89
|
+
};
|
|
90
|
+
export const renderDocument = async (request, workspaceRoot) => {
|
|
91
|
+
const format = await formatOf(request.absPath);
|
|
92
|
+
const unit = SLIDES.has(format) ? "slide" : "page";
|
|
93
|
+
const tool = rasterizer();
|
|
94
|
+
const binary = format === "pdf" ? undefined : office(format);
|
|
95
|
+
const outDir = request.outDir ?? defaultOutDir(request.absPath, workspaceRoot);
|
|
96
|
+
const notes = [];
|
|
97
|
+
const sha256 = await sha256OfFile(request.absPath);
|
|
98
|
+
const cached = request.outDir === undefined ? await readStamp(outDir) : undefined;
|
|
99
|
+
const current = cached !== undefined && cached.sha256 === sha256 && cached.size === request.size;
|
|
100
|
+
if (current) {
|
|
101
|
+
const pages = choosePages(request, cached.total, unit, notes);
|
|
102
|
+
const existing = new Set(await listDir(outDir));
|
|
103
|
+
if (pages.every((page) => existing.has(`${unit}-${page}.png`))) {
|
|
104
|
+
return { format, unit, total: cached.total, images: pages.map((page) => ({ page, path: join(outDir, `${unit}-${page}.png`) })), outDir, reused: true, notes };
|
|
105
|
+
}
|
|
106
|
+
notes.length = 0;
|
|
107
|
+
}
|
|
108
|
+
const work = await mkdtemp(join(tmpdir(), "fileq-render-"));
|
|
109
|
+
try {
|
|
110
|
+
const pdf = binary === undefined ? request.absPath : await toPdf(binary, request.absPath, format, work);
|
|
111
|
+
const total = await pageCount(pdf);
|
|
112
|
+
const pages = choosePages(request, total, unit, notes);
|
|
113
|
+
const raster = join(work, "png");
|
|
114
|
+
await mkdir(raster, { recursive: true });
|
|
115
|
+
const drawn = await toPngs(tool, pdf, pages, request.size, raster);
|
|
116
|
+
await mkdir(outDir, { recursive: true });
|
|
117
|
+
await ignoreInGit(workspaceRoot, outDir);
|
|
118
|
+
if (request.outDir === undefined && !current) {
|
|
119
|
+
await clearImages(outDir);
|
|
120
|
+
}
|
|
121
|
+
const images = [];
|
|
122
|
+
for (const page of pages) {
|
|
123
|
+
const from = drawn.get(page);
|
|
124
|
+
if (from !== undefined) {
|
|
125
|
+
const path = join(outDir, `${unit}-${page}.png`);
|
|
126
|
+
await copyFile(from, path);
|
|
127
|
+
images.push({ page, path });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (images.length < pages.length) {
|
|
131
|
+
notes.push(`${pages.length - images.length} of the ${unit}s asked for drew nothing`);
|
|
132
|
+
}
|
|
133
|
+
if (request.outDir === undefined) {
|
|
134
|
+
await writeFile(join(outDir, STAMP_FILE), `${JSON.stringify({ sha256, size: request.size, total })}\n`);
|
|
135
|
+
}
|
|
136
|
+
return { format, unit, total, images, outDir, reused: false, notes };
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
await rm(work, { recursive: true, force: true });
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/lib/render/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const AUTHORING_RULES = "## Making a document someone will open\nRules that decide whether a generated file looks right (adapted from SurfSense's document skills, Apache-2.0):\n- **Decks**: one purpose per slide, at most about six short bullets; titles 32\u201340 pt, body at least 18 pt;\n 0.5 in outer margins, and every shape on the slide (no parking shapes off-canvas, no hidden spare slides).\n Fill every placeholder you keep or delete it; no prompt text, TODOs or design notes on a slide. Size each\n box to its text instead of relying on autofit, which PowerPoint and LibreOffice resolve differently: shorten\n or split the slide. Keep an image's proportions: set one side and derive the other, crop rather than stretch.\n- **Word documents**: built-in heading styles, real list numbering (never a typed \"\u2022\"), a page break as its\n own paragraph, margins of at least 18 mm, one page size and orientation. A table of contents only when asked,\n and say its page numbers fill in when Word updates fields. No image wider than the text column.\n- **Spreadsheets**: save every formula with its computed value (XlsxWriter's `write_formula(cell, formula,\n format, value)`; openpyxl saves none, so recalculate its output with LibreOffice). Leave no error value\n (#REF!, #DIV/0!, #N/A) in a cell. Name sheets for the reader, set column widths, freeze header rows.\n- **PDFs**: embed the fonts (register a TTF in ReportLab; WeasyPrint embeds on its own); A4 or US Letter by\n locale, margins of at least 18 mm. To turn an office file into a PDF:\n `soffice --headless -env:UserInstallation=file:///tmp/lo-$$ --convert-to pdf --outdir <dir> <file>`\n (its own profile per run; the output is named after the source).\n- Fonts: prefer Arial, Times New Roman or Courier New where the layout is tight: LibreOffice substitutes their\n metric-compatible Liberation fonts, so lines break the same. Any other font gets about 10% spare room.";
|
|
2
|
+
//# sourceMappingURL=skill-authoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-authoring.d.ts","sourceRoot":"","sources":["../src/skill-authoring.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,eAAe,04DAkB6E,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const AUTHORING_RULES = `## Making a document someone will open
|
|
2
|
+
Rules that decide whether a generated file looks right (adapted from SurfSense's document skills, Apache-2.0):
|
|
3
|
+
- **Decks**: one purpose per slide, at most about six short bullets; titles 32–40 pt, body at least 18 pt;
|
|
4
|
+
0.5 in outer margins, and every shape on the slide (no parking shapes off-canvas, no hidden spare slides).
|
|
5
|
+
Fill every placeholder you keep or delete it; no prompt text, TODOs or design notes on a slide. Size each
|
|
6
|
+
box to its text instead of relying on autofit, which PowerPoint and LibreOffice resolve differently: shorten
|
|
7
|
+
or split the slide. Keep an image's proportions: set one side and derive the other, crop rather than stretch.
|
|
8
|
+
- **Word documents**: built-in heading styles, real list numbering (never a typed "•"), a page break as its
|
|
9
|
+
own paragraph, margins of at least 18 mm, one page size and orientation. A table of contents only when asked,
|
|
10
|
+
and say its page numbers fill in when Word updates fields. No image wider than the text column.
|
|
11
|
+
- **Spreadsheets**: save every formula with its computed value (XlsxWriter's \`write_formula(cell, formula,
|
|
12
|
+
format, value)\`; openpyxl saves none, so recalculate its output with LibreOffice). Leave no error value
|
|
13
|
+
(#REF!, #DIV/0!, #N/A) in a cell. Name sheets for the reader, set column widths, freeze header rows.
|
|
14
|
+
- **PDFs**: embed the fonts (register a TTF in ReportLab; WeasyPrint embeds on its own); A4 or US Letter by
|
|
15
|
+
locale, margins of at least 18 mm. To turn an office file into a PDF:
|
|
16
|
+
\`soffice --headless -env:UserInstallation=file:///tmp/lo-$$ --convert-to pdf --outdir <dir> <file>\`
|
|
17
|
+
(its own profile per run; the output is named after the source).
|
|
18
|
+
- Fonts: prefer Arial, Times New Roman or Courier New where the layout is tight: LibreOffice substitutes their
|
|
19
|
+
metric-compatible Liberation fonts, so lines break the same. Any other font gets about 10% spare room.`;
|
|
20
|
+
//# sourceMappingURL=skill-authoring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-authoring.js","sourceRoot":"","sources":["../src/skill-authoring.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;yGAkB0E,CAAC"}
|
package/dist/skill.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,cAAc;IAE3B,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,YAAY,CAAC;CAC3C;AAmCD,eAAO,MAAM,UAAU,aAAc,cAAc,KAAG,MAqErD,CAAC"}
|
package/dist/skill.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DERIVED_DIR } from "./lib/sidecar.js";
|
|
2
|
+
import { AUTHORING_RULES } from "./skill-authoring.js";
|
|
2
3
|
const OCR_FORMAT = {
|
|
3
4
|
sandbox: "a scan is OCR'd when the image carries tesseract",
|
|
4
5
|
standalone: "a scan is OCR'd when `tesseract` is on PATH",
|
|
@@ -11,6 +12,13 @@ const OCR_REFUSAL = {
|
|
|
11
12
|
rather than an empty page; images say "no visual description". Treat those notes as "not generated",
|
|
12
13
|
never as "nothing there". Installing tesseract turns the first into OCR.`,
|
|
13
14
|
};
|
|
15
|
+
const RENDER_TOOLS = {
|
|
16
|
+
sandbox: `It needs LibreOffice (\`soffice\`) for office formats and \`pdftoppm\` for every format, both in the opt-in
|
|
17
|
+
\`office\` image pack. If it exits 2 naming one, run the \`environment propose office --pack\` it prints (the owner
|
|
18
|
+
approves, a rebuild brings it), say the document was checked but not seen, and do not claim it looks right.`,
|
|
19
|
+
standalone: `It needs LibreOffice (\`soffice\`) for office formats and \`pdftoppm\` (poppler-utils) or \`mutool\` for
|
|
20
|
+
every format. If it exits 2 naming one, install it or tell the user the document was checked but not seen.`,
|
|
21
|
+
};
|
|
14
22
|
const TEXTCONV = `## What changed in a document
|
|
15
23
|
\`git diff\`, \`git show\` and \`git log -p\` on a .docx, .xlsx, .pptx, .pdf or .ipynb print the change to its
|
|
16
24
|
text, not "Binary files differ": every derivable extension is routed through fileq as git's textconv. Read the
|
|
@@ -19,7 +27,7 @@ diff; do not convert both versions by hand.
|
|
|
19
27
|
`;
|
|
20
28
|
export const fileqSkill = ({ host }) => `---
|
|
21
29
|
name: fileq
|
|
22
|
-
description: Read binary
|
|
30
|
+
description: Read binary files (docx, xlsx, pptx, pdf, odt, epub, ipynb, images, audio, archives, V8 profiles) as budgeted markdown with \`fileq\`, size up csv, json or logs too big to cat, and check and render a docx, pptx, xlsx or pdf you made. Use instead of guessing from a filename, ad-hoc converters, or delivering it unseen.
|
|
23
31
|
---
|
|
24
32
|
|
|
25
33
|
# fileq: binary files as markdown
|
|
@@ -53,6 +61,21 @@ ${OCR_REFUSAL[host]}
|
|
|
53
61
|
|
|
54
62
|
${host === "sandbox" ? TEXTCONV : ""}Exit codes: 0 content, 1 nothing derivable, 2 broken invocation or install.
|
|
55
63
|
|
|
64
|
+
## After you produce a document
|
|
65
|
+
A deck, report, spreadsheet or PDF made for someone is not finished until you have checked it and looked at it.
|
|
66
|
+
1. \`fileq check <file>\` (docx, pptx, xlsx, pdf) lists what a reader would meet, each with where it is:
|
|
67
|
+
\`slide 3 · "Title 1"\`, \`'Q3 plan'!C4\`, \`page 7\`, \`paragraph 12 · "…"\`. Exit 1 means an error (a missing
|
|
68
|
+
image, a #REF!, a broken link, leftover "Click to add title"): fix every one and check again. Warnings are
|
|
69
|
+
judgement calls (a TODO, a hidden slide) or estimates (text overflowing its box): settle those by looking.
|
|
70
|
+
2. \`fileq render <file> [--pages 1-3]\` draws the pages or slides as PNGs (the first 20 unless you say) and
|
|
71
|
+
prints one path per line; Read them. An unchanged file answers from its last render. Office formats are laid
|
|
72
|
+
out by LibreOffice, so a font the machine lacks is substituted: judge overflow and spacing, not the typeface.
|
|
73
|
+
${RENDER_TOOLS[host].replaceAll("\n", "\n ")}
|
|
74
|
+
Fix what you find in whatever generated the file, regenerate, and check again; after two rounds, stop and tell
|
|
75
|
+
the user what is left rather than looping.
|
|
76
|
+
|
|
77
|
+
${AUTHORING_RULES}
|
|
78
|
+
|
|
56
79
|
## Text-shaped files that are too big to cat
|
|
57
80
|
The commonest way to lose a context window is \`cat\` on a file you have not sized. Stat first, then read
|
|
58
81
|
the shape, then only what the question needs:
|
package/dist/skill.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAavD,MAAM,UAAU,GAA2C;IACvD,OAAO,EAAE,kDAAkD;IAC3D,UAAU,EAAE,6CAA6C;CAC5D,CAAC;AAEF,MAAM,WAAW,GAA2C;IACxD,OAAO,EAAE;;iGAEoF;IAC7F,UAAU,EAAE;;2EAE2D;CAC1E,CAAC;AAKF,MAAM,YAAY,GAAG;IACjB,OAAO,EAAE;;4GAE+F;IACxG,UAAU,EAAE;2GAC2F;CACzD,CAAC;AAGnD,MAAM,QAAQ,GAAG;;;;;CAKhB,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EAAE,IAAI,EAAkB,EAAU,EAAE,CAAC;;;;;;;;;;;;;;;qBAe3C,UAAU,CAAC,IAAI,CAAC;;;;;;;;;;wCAUG,WAAW;;;;;EAKjD,WAAW,CAAC,IAAI,CAAC;;;;EAIjB,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;KAW/B,YAAY,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;;;;EAI/C,eAAe;;;;;;;;;;;;;;;;;;;;CAoBhB,CAAC"}
|
package/dist/testing.d.ts
CHANGED
|
@@ -22,4 +22,71 @@ export declare const zipBytes: (files: Readonly<Record<string, string>>) => Uint
|
|
|
22
22
|
export declare const tarBytes: (files: Readonly<Record<string, string>>) => Uint8Array;
|
|
23
23
|
export declare const gzipBytes: (name: string, content: Uint8Array | string) => Uint8Array;
|
|
24
24
|
export declare const pngBytes: () => Uint8Array;
|
|
25
|
+
export interface FixtureRel {
|
|
26
|
+
readonly type: string;
|
|
27
|
+
readonly target: string;
|
|
28
|
+
readonly external?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface Frame {
|
|
31
|
+
readonly x: number;
|
|
32
|
+
readonly y: number;
|
|
33
|
+
readonly w: number;
|
|
34
|
+
readonly h: number;
|
|
35
|
+
}
|
|
36
|
+
export interface TextBoxOptions {
|
|
37
|
+
readonly size?: number;
|
|
38
|
+
readonly ph?: {
|
|
39
|
+
readonly type?: string;
|
|
40
|
+
readonly idx?: number;
|
|
41
|
+
};
|
|
42
|
+
readonly autofit?: "shrink" | "grow";
|
|
43
|
+
}
|
|
44
|
+
export declare const textBox: (name: string, frame: Frame | undefined, lines: readonly string[], options?: TextBoxOptions) => string;
|
|
45
|
+
export declare const pictureFrame: (name: string, frame: Frame, rId: string, crop?: {
|
|
46
|
+
readonly l?: number;
|
|
47
|
+
readonly r?: number;
|
|
48
|
+
readonly t?: number;
|
|
49
|
+
readonly b?: number;
|
|
50
|
+
}) => string;
|
|
51
|
+
export declare const tableFrame: (name: string, frame: Frame, rows: readonly (readonly string[])[], height: number, size?: number) => string;
|
|
52
|
+
export interface DeckSlide {
|
|
53
|
+
readonly drawings: readonly string[];
|
|
54
|
+
readonly rels?: Readonly<Record<string, FixtureRel>>;
|
|
55
|
+
readonly hidden?: boolean;
|
|
56
|
+
readonly partNumber?: number;
|
|
57
|
+
}
|
|
58
|
+
export interface DeckOptions {
|
|
59
|
+
readonly slides: readonly DeckSlide[];
|
|
60
|
+
readonly media?: Readonly<Record<string, Uint8Array>>;
|
|
61
|
+
readonly width?: number;
|
|
62
|
+
readonly height?: number;
|
|
63
|
+
readonly untypedMedia?: boolean;
|
|
64
|
+
}
|
|
65
|
+
export declare const deckBytes: (options: DeckOptions) => Uint8Array;
|
|
66
|
+
export declare const pngOfSize: (width: number, height: number) => Uint8Array;
|
|
67
|
+
export declare const para: (text: string, style?: string) => string;
|
|
68
|
+
export declare const inlinePicture: (rId: string, width: number, height: number) => string;
|
|
69
|
+
export declare const field: (instruction: string, result: string | undefined) => string;
|
|
70
|
+
export interface WordOptions {
|
|
71
|
+
readonly body: readonly string[];
|
|
72
|
+
readonly rels?: Readonly<Record<string, FixtureRel>>;
|
|
73
|
+
readonly media?: Readonly<Record<string, Uint8Array>>;
|
|
74
|
+
readonly comments?: readonly string[];
|
|
75
|
+
}
|
|
76
|
+
export declare const wordBytes: (options: WordOptions) => Uint8Array;
|
|
77
|
+
export interface SheetFixture {
|
|
78
|
+
readonly name: string;
|
|
79
|
+
readonly rows: string;
|
|
80
|
+
}
|
|
81
|
+
export declare const workbookBytes: (sheets: readonly SheetFixture[], options?: {
|
|
82
|
+
readonly definedNames?: string;
|
|
83
|
+
readonly calcPr?: string;
|
|
84
|
+
}) => Uint8Array;
|
|
85
|
+
export interface PdfPageFixture {
|
|
86
|
+
readonly content: string;
|
|
87
|
+
readonly font?: string;
|
|
88
|
+
readonly extra?: string;
|
|
89
|
+
readonly size?: readonly [number, number];
|
|
90
|
+
}
|
|
91
|
+
export declare const pdfPagesBytes: (pages: readonly PdfPageFixture[]) => Uint8Array;
|
|
25
92
|
//# sourceMappingURL=testing.d.ts.map
|
package/dist/testing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,SAAS,YAAa,MAAM,cAAc,SAAS,MAAM,EAAE,KAAG,UAiB1E,CAAC;AASF,eAAO,MAAM,SAAS,WAAY,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,KAAG,UAgBlE,CAAC;AAMF,eAAO,MAAM,QAAQ,SAAU,MAAM,KAAG,UAwBvC,CAAC;AAGF,eAAO,MAAM,QAAQ,QAAO,UA0B3B,CAAC;AAMF,eAAO,MAAM,QAAQ,YAAa,MAAM,cAAc,SAAS,MAAM,EAAE,KAAG,UA0BpE,CAAC;AAoBP,eAAO,MAAM,QAAQ,WAAY,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAA;CAAE,EAAE,KAAG,UAgBlH,CAAC;AAGN,eAAO,MAAM,QAAQ,WAAY,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,KAAG,UAc9H,CAAC;AAGN,eAAO,MAAM,QAAQ,eAAgB,SAAS,MAAM,EAAE,KAAG,UAKpD,CAAC;AAGN,eAAO,MAAM,SAAS,UAAW,MAAM,YAAY,SAAS;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,KAAG,UAyBjH,CAAC;AAGF,eAAO,MAAM,SAAS,UAAW,MAAM,QAAQ,MAAM,eAAe,SAAS,MAAM,EAAE,KAAG,MAkBlF,CAAC;AAGP,eAAO,MAAM,QAAQ,UAAW,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAG,UACgC,CAAC;AAkCpG,eAAO,MAAM,QAAQ,UAAW,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAG,UAkBlE,CAAC;AAGF,eAAO,MAAM,SAAS,SAAU,MAAM,WAAW,UAAU,GAAG,MAAM,KAAG,UACmB,CAAC;AAG3F,eAAO,MAAM,QAAQ,QAAO,UACkH,CAAC"}
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
|
package/dist/testing.js
CHANGED
|
@@ -217,4 +217,155 @@ export const tarBytes = (files) => {
|
|
|
217
217
|
};
|
|
218
218
|
export const gzipBytes = (name, content) => gzipSync(typeof content === "string" ? strToU8(content) : content, { filename: name });
|
|
219
219
|
export const pngBytes = () => Uint8Array.from(Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==", "base64"));
|
|
220
|
+
const EMU = 914_400;
|
|
221
|
+
const NS_P = 'xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"';
|
|
222
|
+
const REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
223
|
+
const relsXml = (rels) => `<?xml version="1.0" encoding="UTF-8"?>
|
|
224
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${Object.entries(rels)
|
|
225
|
+
.map(([id, rel]) => `<Relationship Id="${id}" Type="${REL_TYPE}/${rel.type}" Target="${xmlEscape(rel.target)}"${rel.external === true ? ' TargetMode="External"' : ""}/>`)
|
|
226
|
+
.join("")}</Relationships>`;
|
|
227
|
+
const xfrm = (frame, tag = "a:xfrm") => `<${tag}><a:off x="${Math.round(frame.x * EMU)}" y="${Math.round(frame.y * EMU)}"/><a:ext cx="${Math.round(frame.w * EMU)}" cy="${Math.round(frame.h * EMU)}"/></${tag}>`;
|
|
228
|
+
let drawingId = 10;
|
|
229
|
+
export const textBox = (name, frame, lines, options = {}) => {
|
|
230
|
+
drawingId += 1;
|
|
231
|
+
const ph = options.ph === undefined ? "" : `<p:ph${options.ph.type === undefined ? "" : ` type="${options.ph.type}"`}${options.ph.idx === undefined ? "" : ` idx="${options.ph.idx}"`}/>`;
|
|
232
|
+
const fit = options.autofit === "shrink" ? "<a:normAutofit/>" : options.autofit === "grow" ? "<a:spAutoFit/>" : "";
|
|
233
|
+
const size = options.size === undefined ? "" : ` sz="${options.size * 100}"`;
|
|
234
|
+
const paragraphs = lines.length === 0 ? "<a:p/>" : lines.map((line) => `<a:p><a:r><a:rPr lang="en-US"${size}/><a:t>${xmlEscape(line)}</a:t></a:r></a:p>`).join("");
|
|
235
|
+
return `<p:sp><p:nvSpPr><p:cNvPr id="${drawingId}" name="${xmlEscape(name)}"/><p:cNvSpPr/><p:nvPr>${ph}</p:nvPr></p:nvSpPr><p:spPr>${frame === undefined ? "" : xfrm(frame)}</p:spPr><p:txBody><a:bodyPr wrap="square">${fit}</a:bodyPr><a:lstStyle/>${paragraphs}</p:txBody></p:sp>`;
|
|
236
|
+
};
|
|
237
|
+
export const pictureFrame = (name, frame, rId, crop) => {
|
|
238
|
+
drawingId += 1;
|
|
239
|
+
const src = crop === undefined ? "" : `<a:srcRect l="${crop.l ?? 0}" r="${crop.r ?? 0}" t="${crop.t ?? 0}" b="${crop.b ?? 0}"/>`;
|
|
240
|
+
return `<p:pic><p:nvPicPr><p:cNvPr id="${drawingId}" name="${xmlEscape(name)}"/><p:cNvPicPr/><p:nvPr/></p:nvPicPr><p:blipFill><a:blip r:embed="${rId}"/>${src}<a:stretch><a:fillRect/></a:stretch></p:blipFill><p:spPr>${xfrm(frame)}<a:prstGeom prst="rect"><a:avLst/></a:prstGeom></p:spPr></p:pic>`;
|
|
241
|
+
};
|
|
242
|
+
export const tableFrame = (name, frame, rows, height, size = 18) => {
|
|
243
|
+
drawingId += 1;
|
|
244
|
+
const columns = Math.max(1, ...rows.map((row) => row.length));
|
|
245
|
+
const columnWidth = Math.round((frame.w * EMU) / columns);
|
|
246
|
+
const cells = (row) => row.map((cell) => `<a:tc><a:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:rPr lang="en-US" sz="${size * 100}"/><a:t>${xmlEscape(cell)}</a:t></a:r></a:p></a:txBody><a:tcPr/></a:tc>`).join("");
|
|
247
|
+
return `<p:graphicFrame><p:nvGraphicFramePr><p:cNvPr id="${drawingId}" name="${xmlEscape(name)}"/><p:cNvGraphicFramePr/><p:nvPr/></p:nvGraphicFramePr>${xfrm(frame, "p:xfrm")}<a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/table"><a:tbl><a:tblGrid>${Array.from({ length: columns }, () => `<a:gridCol w="${columnWidth}"/>`).join("")}</a:tblGrid>${rows.map((row) => `<a:tr h="${Math.round(height * EMU)}">${cells(row)}</a:tr>`).join("")}</a:tbl></a:graphicData></a:graphic></p:graphicFrame>`;
|
|
248
|
+
};
|
|
249
|
+
const MASTER = `<?xml version="1.0" encoding="UTF-8"?>
|
|
250
|
+
<p:sldMaster ${NS_P}><p:cSld><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/>
|
|
251
|
+
<p:sp><p:nvSpPr><p:cNvPr id="2" name="Title Placeholder 1"/><p:cNvSpPr/><p:nvPr><p:ph type="title"/></p:nvPr></p:nvSpPr><p:spPr>${xfrm({ x: 0.92, y: 0.4, w: 11.5, h: 1.45 })}</p:spPr><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>Click to edit Master title style</a:t></a:r></a:p></p:txBody></p:sp>
|
|
252
|
+
<p:sp><p:nvSpPr><p:cNvPr id="3" name="Text Placeholder 2"/><p:cNvSpPr/><p:nvPr><p:ph type="body" idx="1"/></p:nvPr></p:nvSpPr><p:spPr>${xfrm({ x: 0.92, y: 2, w: 11.5, h: 4.75 })}</p:spPr><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>Click to edit Master text styles</a:t></a:r></a:p></p:txBody></p:sp>
|
|
253
|
+
</p:spTree></p:cSld><p:clrMap bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/><p:sldLayoutIdLst><p:sldLayoutId id="2147483649" r:id="rId1"/></p:sldLayoutIdLst>
|
|
254
|
+
<p:txStyles><p:titleStyle><a:lvl1pPr><a:defRPr sz="4400"/></a:lvl1pPr></p:titleStyle><p:bodyStyle><a:lvl1pPr><a:defRPr sz="2800"/></a:lvl1pPr><a:lvl2pPr><a:defRPr sz="2400"/></a:lvl2pPr></p:bodyStyle><p:otherStyle/></p:txStyles></p:sldMaster>`;
|
|
255
|
+
const LAYOUT = `<?xml version="1.0" encoding="UTF-8"?>
|
|
256
|
+
<p:sldLayout ${NS_P} type="obj"><p:cSld name="Title and Content"><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/>
|
|
257
|
+
<p:sp><p:nvSpPr><p:cNvPr id="2" name="Title 1"/><p:cNvSpPr/><p:nvPr><p:ph type="title"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>Click to edit Master title style</a:t></a:r></a:p></p:txBody></p:sp>
|
|
258
|
+
<p:sp><p:nvSpPr><p:cNvPr id="3" name="Content Placeholder 2"/><p:cNvSpPr/><p:nvPr><p:ph idx="1"/></p:nvPr></p:nvSpPr><p:spPr/><p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>Click to edit Master text styles</a:t></a:r></a:p></p:txBody></p:sp>
|
|
259
|
+
</p:spTree></p:cSld></p:sldLayout>`;
|
|
260
|
+
export const deckBytes = (options) => {
|
|
261
|
+
const width = Math.round((options.width ?? 13.333) * EMU);
|
|
262
|
+
const height = Math.round((options.height ?? 7.5) * EMU);
|
|
263
|
+
const numbers = options.slides.map((slide, index) => slide.partNumber ?? index + 1);
|
|
264
|
+
const types = [
|
|
265
|
+
'<Override PartName="/ppt/presentation.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"/>',
|
|
266
|
+
'<Override PartName="/ppt/slideMasters/slideMaster1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"/>',
|
|
267
|
+
'<Override PartName="/ppt/slideLayouts/slideLayout1.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"/>',
|
|
268
|
+
...numbers.map((number) => `<Override PartName="/ppt/slides/slide${number}.xml" ContentType="application/vnd.openxmlformats-officedocument.presentationml.slide+xml"/>`),
|
|
269
|
+
options.untypedMedia === true ? "" : '<Default Extension="png" ContentType="image/png"/>',
|
|
270
|
+
].join("");
|
|
271
|
+
const files = new Map([
|
|
272
|
+
["[Content_Types].xml", strToU8(CONTENT_TYPES(types))],
|
|
273
|
+
["_rels/.rels", strToU8(RELS("ppt/presentation.xml"))],
|
|
274
|
+
["ppt/presentation.xml", strToU8(`<?xml version="1.0" encoding="UTF-8"?>
|
|
275
|
+
<p:presentation ${NS_P}><p:sldMasterIdLst><p:sldMasterId id="2147483648" r:id="rId1"/></p:sldMasterIdLst><p:sldIdLst>${numbers.map((number, index) => `<p:sldId id="${256 + index}" r:id="rId${number + 1}"/>`).join("")}</p:sldIdLst><p:sldSz cx="${width}" cy="${height}"/><p:notesSz cx="6858000" cy="9144000"/></p:presentation>`)],
|
|
276
|
+
["ppt/_rels/presentation.xml.rels", strToU8(relsXml({
|
|
277
|
+
rId1: { type: "slideMaster", target: "slideMasters/slideMaster1.xml" },
|
|
278
|
+
...Object.fromEntries(numbers.map((number) => [`rId${number + 1}`, { type: "slide", target: `slides/slide${number}.xml` }])),
|
|
279
|
+
}))],
|
|
280
|
+
["ppt/slideMasters/slideMaster1.xml", strToU8(MASTER)],
|
|
281
|
+
["ppt/slideMasters/_rels/slideMaster1.xml.rels", strToU8(relsXml({ rId1: { type: "slideLayout", target: "../slideLayouts/slideLayout1.xml" } }))],
|
|
282
|
+
["ppt/slideLayouts/slideLayout1.xml", strToU8(LAYOUT)],
|
|
283
|
+
["ppt/slideLayouts/_rels/slideLayout1.xml.rels", strToU8(relsXml({ rId1: { type: "slideMaster", target: "../slideMasters/slideMaster1.xml" } }))],
|
|
284
|
+
]);
|
|
285
|
+
options.slides.forEach((slide, index) => {
|
|
286
|
+
const number = numbers[index] ?? index + 1;
|
|
287
|
+
files.set(`ppt/slides/slide${number}.xml`, strToU8(`<?xml version="1.0" encoding="UTF-8"?>
|
|
288
|
+
<p:sld ${NS_P}${slide.hidden === true ? ' show="0"' : ""}><p:cSld><p:spTree><p:nvGrpSpPr><p:cNvPr id="1" name=""/><p:cNvGrpSpPr/><p:nvPr/></p:nvGrpSpPr><p:grpSpPr/>${slide.drawings.join("")}</p:spTree></p:cSld></p:sld>`));
|
|
289
|
+
files.set(`ppt/slides/_rels/slide${number}.xml.rels`, strToU8(relsXml({ rId1: { type: "slideLayout", target: "../slideLayouts/slideLayout1.xml" }, ...slide.rels })));
|
|
290
|
+
});
|
|
291
|
+
for (const [name, bytes] of Object.entries(options.media ?? {})) {
|
|
292
|
+
files.set(`ppt/media/${name}`, bytes);
|
|
293
|
+
}
|
|
294
|
+
return zipSync(Object.fromEntries(files));
|
|
295
|
+
};
|
|
296
|
+
export const pngOfSize = (width, height) => {
|
|
297
|
+
const png = pngBytes().slice();
|
|
298
|
+
const view = new DataView(png.buffer, png.byteOffset, png.byteLength);
|
|
299
|
+
view.setUint32(16, width);
|
|
300
|
+
view.setUint32(20, height);
|
|
301
|
+
return png;
|
|
302
|
+
};
|
|
303
|
+
const NS_W = 'xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"';
|
|
304
|
+
export const para = (text, style) => `<w:p>${style === undefined ? "" : `<w:pPr><w:pStyle w:val="${style}"/></w:pPr>`}${text === "" ? "" : `<w:r><w:t xml:space="preserve">${xmlEscape(text)}</w:t></w:r>`}</w:p>`;
|
|
305
|
+
export const inlinePicture = (rId, width, height) => `<w:p><w:r><w:drawing><wp:inline><wp:extent cx="${Math.round(width * EMU)}" cy="${Math.round(height * EMU)}"/><wp:docPr id="1" name="Picture 1"/><a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic><pic:blipFill><a:blip r:embed="${rId}"/></pic:blipFill></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>`;
|
|
306
|
+
export const field = (instruction, result) => `<w:p><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText xml:space="preserve"> ${xmlEscape(instruction)} </w:instrText></w:r>${result === undefined ? "" : `<w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r><w:t>${xmlEscape(result)}</w:t></w:r>`}<w:r><w:fldChar w:fldCharType="end"/></w:r></w:p>`;
|
|
307
|
+
const STYLES = `<?xml version="1.0" encoding="UTF-8"?>
|
|
308
|
+
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:style w:type="paragraph" w:default="1" w:styleId="Normal"><w:name w:val="Normal"/></w:style><w:style w:type="paragraph" w:styleId="berschrift1"><w:name w:val="heading 1"/><w:basedOn w:val="Normal"/></w:style><w:style w:type="paragraph" w:styleId="berschrift2"><w:name w:val="heading 2"/><w:basedOn w:val="Normal"/></w:style><w:style w:type="paragraph" w:styleId="Callout"><w:name w:val="Callout"/><w:basedOn w:val="berschrift2"/></w:style></w:styles>`;
|
|
309
|
+
export const wordBytes = (options) => {
|
|
310
|
+
const commentRels = options.comments === undefined ? {} : { rIdComments: { type: "comments", target: "comments.xml" } };
|
|
311
|
+
const files = new Map([
|
|
312
|
+
["[Content_Types].xml", strToU8(CONTENT_TYPES([
|
|
313
|
+
'<Default Extension="png" ContentType="image/png"/>',
|
|
314
|
+
'<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>',
|
|
315
|
+
'<Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/>',
|
|
316
|
+
options.comments === undefined ? "" : '<Override PartName="/word/comments.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml"/>',
|
|
317
|
+
].join("")))],
|
|
318
|
+
["_rels/.rels", strToU8(RELS("word/document.xml"))],
|
|
319
|
+
["word/styles.xml", strToU8(STYLES)],
|
|
320
|
+
["word/document.xml", strToU8(`<?xml version="1.0" encoding="UTF-8"?>
|
|
321
|
+
<w:document ${NS_W}><w:body>${options.body.join("")}<w:sectPr><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:gutter="0"/></w:sectPr></w:body></w:document>`)],
|
|
322
|
+
]);
|
|
323
|
+
if (options.comments !== undefined) {
|
|
324
|
+
files.set("word/comments.xml", strToU8(`<?xml version="1.0" encoding="UTF-8"?>
|
|
325
|
+
<w:comments xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">${options.comments.map((text, index) => `<w:comment w:id="${index}" w:author="Reviewer"><w:p><w:r><w:t>${xmlEscape(text)}</w:t></w:r></w:p></w:comment>`).join("")}</w:comments>`));
|
|
326
|
+
}
|
|
327
|
+
files.set("word/_rels/document.xml.rels", strToU8(relsXml({ rIdStyles: { type: "styles", target: "styles.xml" }, ...options.rels, ...commentRels })));
|
|
328
|
+
for (const [name, bytes] of Object.entries(options.media ?? {})) {
|
|
329
|
+
files.set(`word/media/${name}`, bytes);
|
|
330
|
+
}
|
|
331
|
+
return zipSync(Object.fromEntries(files));
|
|
332
|
+
};
|
|
333
|
+
export const workbookBytes = (sheets, options = {}) => {
|
|
334
|
+
const files = new Map([
|
|
335
|
+
["[Content_Types].xml", strToU8(CONTENT_TYPES([
|
|
336
|
+
'<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>',
|
|
337
|
+
...sheets.map((_, index) => `<Override PartName="/xl/worksheets/sheet${index + 1}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>`),
|
|
338
|
+
].join("")))],
|
|
339
|
+
["_rels/.rels", strToU8(RELS("xl/workbook.xml"))],
|
|
340
|
+
["xl/workbook.xml", strToU8(`<?xml version="1.0" encoding="UTF-8"?>
|
|
341
|
+
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><sheets>${sheets.map((sheet, index) => `<sheet name="${xmlEscape(sheet.name)}" sheetId="${index + 1}" r:id="rId${index + 1}"/>`).join("")}</sheets>${options.definedNames === undefined ? "" : `<definedNames>${options.definedNames}</definedNames>`}${options.calcPr ?? ""}</workbook>`)],
|
|
342
|
+
["xl/_rels/workbook.xml.rels", strToU8(relsXml(Object.fromEntries(sheets.map((_, index) => [`rId${index + 1}`, { type: "worksheet", target: `worksheets/sheet${index + 1}.xml` }]))))],
|
|
343
|
+
]);
|
|
344
|
+
sheets.forEach((sheet, index) => {
|
|
345
|
+
files.set(`xl/worksheets/sheet${index + 1}.xml`, strToU8(`<?xml version="1.0" encoding="UTF-8"?>
|
|
346
|
+
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><sheetData>${sheet.rows}</sheetData></worksheet>`));
|
|
347
|
+
});
|
|
348
|
+
return zipSync(Object.fromEntries(files));
|
|
349
|
+
};
|
|
350
|
+
export const pdfPagesBytes = (pages) => {
|
|
351
|
+
const objects = ["", ""];
|
|
352
|
+
const add = (body) => objects.push(body);
|
|
353
|
+
const kids = pages.map((page) => {
|
|
354
|
+
const font = add(`<< /Type /Font /Subtype /${page.font === undefined ? "Type1" : "TrueType"} /BaseFont /${page.font ?? "Helvetica"} >>`);
|
|
355
|
+
const content = add(`<< /Length ${page.content.length} >>\nstream\n${page.content}\nendstream`);
|
|
356
|
+
const [width, height] = page.size ?? [612, 792];
|
|
357
|
+
return add(`<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${width} ${height}] /Contents ${content} 0 R /Resources << /Font << /F1 ${font} 0 R >> >> ${page.extra ?? ""} >>`);
|
|
358
|
+
});
|
|
359
|
+
objects[0] = "<< /Type /Catalog /Pages 2 0 R >>";
|
|
360
|
+
objects[1] = `<< /Type /Pages /Kids [${kids.map((kid) => `${kid} 0 R`).join(" ")}] /Count ${kids.length} >>`;
|
|
361
|
+
let out = "%PDF-1.4\n";
|
|
362
|
+
const offsets = objects.map((body, index) => {
|
|
363
|
+
const offset = out.length;
|
|
364
|
+
out += `${index + 1} 0 obj\n${body}\nendobj\n`;
|
|
365
|
+
return offset;
|
|
366
|
+
});
|
|
367
|
+
const xref = out.length;
|
|
368
|
+
out += `xref\n0 ${objects.length + 1}\n0000000000 65535 f \n${offsets.map((offset) => `${String(offset).padStart(10, "0")} 00000 n `).join("\n")}\ntrailer\n<< /Size ${objects.length + 1} /Root 1 0 R >>\nstartxref\n${xref}\n%%EOF\n`;
|
|
369
|
+
return strToU8(out);
|
|
370
|
+
};
|
|
220
371
|
//# sourceMappingURL=testing.js.map
|