@kensio/colophon 0.2.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/LICENSE +201 -0
- package/README.md +198 -0
- package/dist/background.d.ts +8 -0
- package/dist/background.d.ts.map +1 -0
- package/dist/background.js +22 -0
- package/dist/background.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +74 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +64 -0
- package/dist/config.js.map +1 -0
- package/dist/content/index.d.ts +39 -0
- package/dist/content/index.d.ts.map +1 -0
- package/dist/content/index.js +99 -0
- package/dist/content/index.js.map +1 -0
- package/dist/generate.d.ts +42 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +56 -0
- package/dist/generate.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/render.d.ts +17 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +52 -0
- package/dist/render.js.map +1 -0
- package/dist/templates/banner.d.ts +9 -0
- package/dist/templates/banner.d.ts.map +1 -0
- package/dist/templates/banner.js +125 -0
- package/dist/templates/banner.js.map +1 -0
- package/dist/templates/card.d.ts +7 -0
- package/dist/templates/card.d.ts.map +1 -0
- package/dist/templates/card.js +82 -0
- package/dist/templates/card.js.map +1 -0
- package/dist/templates/index.d.ts +9 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +13 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/text.d.ts +56 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +78 -0
- package/dist/text.js.map +1 -0
- package/dist/types.d.ts +129 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import matter from "gray-matter";
|
|
4
|
+
const defaultPropsKey = "meta_img_props";
|
|
5
|
+
const defaultTemplateField = "template";
|
|
6
|
+
const defaultExtensions = [".md", ".markdown"];
|
|
7
|
+
function coerceString(value) {
|
|
8
|
+
if (typeof value === "string") {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
if (typeof value === "number" ||
|
|
12
|
+
typeof value === "boolean" ||
|
|
13
|
+
typeof value === "bigint") {
|
|
14
|
+
return String(value);
|
|
15
|
+
}
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
function isRecord(value) {
|
|
19
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Extract {@link MetaImageProps} from a parsed frontmatter object, or return
|
|
23
|
+
* `undefined` if this file should be skipped (no props object, or no usable
|
|
24
|
+
* template/title). Pure — no filesystem access.
|
|
25
|
+
*/
|
|
26
|
+
export function extractProps(frontmatter, options = {}) {
|
|
27
|
+
const propsKey = options.propsKey ?? defaultPropsKey;
|
|
28
|
+
const templateField = options.templateField ?? defaultTemplateField;
|
|
29
|
+
const record = frontmatter[propsKey];
|
|
30
|
+
if (!isRecord(record)) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const templateRaw = record[templateField];
|
|
34
|
+
const template = typeof templateRaw === "string" ? templateRaw : options.defaultTemplate;
|
|
35
|
+
if (template === undefined) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
const titleRaw = record["title"];
|
|
39
|
+
if (typeof titleRaw !== "string") {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
const subtitle = coerceString(record["subtitle"]);
|
|
43
|
+
const version = coerceString(record["version"]);
|
|
44
|
+
const extras = {};
|
|
45
|
+
for (const [key, value] of Object.entries(record)) {
|
|
46
|
+
if (key !== templateField &&
|
|
47
|
+
key !== "template" &&
|
|
48
|
+
key !== "title" &&
|
|
49
|
+
key !== "subtitle" &&
|
|
50
|
+
key !== "version") {
|
|
51
|
+
extras[key] = value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
...extras,
|
|
56
|
+
template,
|
|
57
|
+
title: titleRaw,
|
|
58
|
+
...(subtitle !== undefined && { subtitle }),
|
|
59
|
+
...(version !== undefined && { version }),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async function collectContentFiles(dir, extensions) {
|
|
63
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
64
|
+
const nested = await Promise.all(entries.map(async (entry) => {
|
|
65
|
+
const entryPath = path.join(dir, entry.name);
|
|
66
|
+
if (entry.isDirectory()) {
|
|
67
|
+
return collectContentFiles(entryPath, extensions);
|
|
68
|
+
}
|
|
69
|
+
if (entry.isFile() &&
|
|
70
|
+
extensions.some((extension) => entry.name.endsWith(extension))) {
|
|
71
|
+
return [entryPath];
|
|
72
|
+
}
|
|
73
|
+
return [];
|
|
74
|
+
}));
|
|
75
|
+
return nested.flat();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Walk a content tree, read each file's frontmatter with `gray-matter`, and
|
|
79
|
+
* return the files that declare image props. This is the host-project concern
|
|
80
|
+
* — finding content and reading frontmatter — kept separate from rendering.
|
|
81
|
+
*/
|
|
82
|
+
export async function walkContent(options) {
|
|
83
|
+
const extensions = options.extensions ?? defaultExtensions;
|
|
84
|
+
const filePaths = await collectContentFiles(options.dir, extensions);
|
|
85
|
+
const files = await Promise.all(filePaths.map(async (filePath) => {
|
|
86
|
+
const raw = await readFile(filePath, "utf8");
|
|
87
|
+
const props = extractProps(matter(raw).data, options);
|
|
88
|
+
if (props === undefined) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
contentPath: path.relative(options.dir, filePath),
|
|
93
|
+
absolutePath: filePath,
|
|
94
|
+
props,
|
|
95
|
+
};
|
|
96
|
+
}));
|
|
97
|
+
return files.filter((file) => file !== undefined);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ContentFile, WalkOptions } from "./content/index.js";
|
|
2
|
+
import type { ColophonConfig, Dimensions } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Outcome for one generated (or skipped) image.
|
|
5
|
+
*/
|
|
6
|
+
export interface GeneratedImage {
|
|
7
|
+
readonly contentPath: string;
|
|
8
|
+
readonly dimensions: Dimensions;
|
|
9
|
+
readonly outputPath: string;
|
|
10
|
+
/** True when an existing file was left in place (no `overwrite`). */
|
|
11
|
+
readonly skipped: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Options for {@link generate}.
|
|
15
|
+
*/
|
|
16
|
+
export interface GenerateOptions {
|
|
17
|
+
/** Root content directory to walk. */
|
|
18
|
+
readonly contentDir: string;
|
|
19
|
+
readonly config?: ColophonConfig;
|
|
20
|
+
/** Extra walk options (props key, template field, extensions, …). */
|
|
21
|
+
readonly walk?: Omit<WalkOptions, "dir">;
|
|
22
|
+
/** Override where each image is written. */
|
|
23
|
+
readonly outputPath?: (file: ContentFile, dimensions: Dimensions, index: number) => string;
|
|
24
|
+
/** Re-render even when the output file already exists. Default `false`. */
|
|
25
|
+
readonly overwrite?: boolean;
|
|
26
|
+
/** Called after each image is written or skipped. */
|
|
27
|
+
readonly onResult?: (result: GeneratedImage) => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Default output path: alongside the content file, named after the file (or
|
|
31
|
+
* its parent directory when the file is `index.*`). The first (square) size
|
|
32
|
+
* keeps the bare name; additional sizes get a `-WxH` suffix.
|
|
33
|
+
*/
|
|
34
|
+
export declare function defaultOutputPath(file: ContentFile, dimensions: Dimensions, index: number): string;
|
|
35
|
+
/**
|
|
36
|
+
* Walk a content tree and render meta images for every file that declares
|
|
37
|
+
* props, writing PNGs to disk. Existing files are skipped unless `overwrite`
|
|
38
|
+
* is set (matching the original script's behaviour), and skipped sizes are
|
|
39
|
+
* never rendered.
|
|
40
|
+
*/
|
|
41
|
+
export declare function generate(options: GenerateOptions): Promise<GeneratedImage[]>;
|
|
42
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGnE,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC,qEAAqE;IACrE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACzC,4CAA4C;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,CACpB,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,KACV,MAAM,CAAC;IACZ,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CACtD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,GACZ,MAAM,CAWR;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,EAAE,CAAC,CAmC3B"}
|
package/dist/generate.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { resolveConfig } from "./config.js";
|
|
5
|
+
import { walkContent } from "./content/index.js";
|
|
6
|
+
import { buildSvg, renderSvgToPng } from "./render.js";
|
|
7
|
+
/**
|
|
8
|
+
* Default output path: alongside the content file, named after the file (or
|
|
9
|
+
* its parent directory when the file is `index.*`). The first (square) size
|
|
10
|
+
* keeps the bare name; additional sizes get a `-WxH` suffix.
|
|
11
|
+
*/
|
|
12
|
+
export function defaultOutputPath(file, dimensions, index) {
|
|
13
|
+
const directory = path.dirname(file.absolutePath);
|
|
14
|
+
const extension = path.extname(file.contentPath);
|
|
15
|
+
const base = path.basename(file.contentPath, extension);
|
|
16
|
+
const stem = base === "index" ? path.basename(directory) : base;
|
|
17
|
+
const suffix = index === 0
|
|
18
|
+
? ""
|
|
19
|
+
: `-${String(dimensions.width)}x${String(dimensions.height)}`;
|
|
20
|
+
return path.join(directory, `${stem}${suffix}.png`);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Walk a content tree and render meta images for every file that declares
|
|
24
|
+
* props, writing PNGs to disk. Existing files are skipped unless `overwrite`
|
|
25
|
+
* is set (matching the original script's behaviour), and skipped sizes are
|
|
26
|
+
* never rendered.
|
|
27
|
+
*/
|
|
28
|
+
export async function generate(options) {
|
|
29
|
+
const resolved = resolveConfig(options.config);
|
|
30
|
+
const toOutputPath = options.outputPath ?? defaultOutputPath;
|
|
31
|
+
const files = await walkContent({ dir: options.contentDir, ...options.walk });
|
|
32
|
+
const jobs = files.flatMap((file) => resolved.dimensions.map((dimensions, index) => ({
|
|
33
|
+
file,
|
|
34
|
+
dimensions,
|
|
35
|
+
index,
|
|
36
|
+
})));
|
|
37
|
+
return Promise.all(jobs.map(async ({ file, dimensions, index }) => {
|
|
38
|
+
const outputPath = toOutputPath(file, dimensions, index);
|
|
39
|
+
const isSkipped = existsSync(outputPath) && options.overwrite !== true;
|
|
40
|
+
if (!isSkipped) {
|
|
41
|
+
const svg = buildSvg(file.props, resolved, dimensions);
|
|
42
|
+
const png = await renderSvgToPng(svg, dimensions);
|
|
43
|
+
await mkdir(path.dirname(outputPath), { recursive: true });
|
|
44
|
+
await writeFile(outputPath, png);
|
|
45
|
+
}
|
|
46
|
+
const result = {
|
|
47
|
+
contentPath: file.contentPath,
|
|
48
|
+
dimensions,
|
|
49
|
+
outputPath,
|
|
50
|
+
skipped: isSkipped,
|
|
51
|
+
};
|
|
52
|
+
options.onResult?.(result);
|
|
53
|
+
return result;
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAmCvD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAiB,EACjB,UAAsB,EACtB,KAAa;IAEb,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAChE,MAAM,MAAM,GACV,KAAK,KAAK,CAAC;QACT,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;IAElE,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,GAAG,MAAM,MAAM,CAAC,CAAC;AACtD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,OAAwB;IAExB,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC;IAC7D,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAE9E,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAClC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC9C,IAAI;QACJ,UAAU;QACV,KAAK;KACN,CAAC,CAAC,CACJ,CAAC;IAEF,OAAO,OAAO,CAAC,GAAG,CAChB,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE;QAC7C,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC;QAEvE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;YACvD,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAClD,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,MAAM,GAAmB;YAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU;YACV,UAAU;YACV,OAAO,EAAE,SAAS;SACnB,CAAC;QACF,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC;QAC3B,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { Background, Badge, BrandColors, ColophonConfig, Dimensions, GradientStop, MetaImageProps, RenderedMetaImage, ResolvedConfig, Template, TemplateContext, } from "./types.js";
|
|
2
|
+
export { DEFAULT_COLORS, DEFAULT_DIMENSIONS, DEFAULT_FONT_FAMILY, defineConfig, resolveConfig, } from "./config.js";
|
|
3
|
+
export { backgroundSvg } from "./background.js";
|
|
4
|
+
export { buildSvg, renderMetaImages, renderSvgToPng } from "./render.js";
|
|
5
|
+
export { bannerTemplate, builtinTemplates, cardTemplate, } from "./templates/index.js";
|
|
6
|
+
export { defaultOutputPath, generate } from "./generate.js";
|
|
7
|
+
export type { GeneratedImage, GenerateOptions } from "./generate.js";
|
|
8
|
+
export { escapeXml, wrapText } from "./text.js";
|
|
9
|
+
export { extractProps, walkContent } from "./content/index.js";
|
|
10
|
+
export type { ContentFile, WalkOptions } from "./content/index.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,KAAK,EACL,WAAW,EACX,cAAc,EACd,UAAU,EACV,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,QAAQ,EACR,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,YAAY,GACb,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC5D,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/D,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { DEFAULT_COLORS, DEFAULT_DIMENSIONS, DEFAULT_FONT_FAMILY, defineConfig, resolveConfig, } from "./config.js";
|
|
2
|
+
export { backgroundSvg } from "./background.js";
|
|
3
|
+
export { buildSvg, renderMetaImages, renderSvgToPng } from "./render.js";
|
|
4
|
+
export { bannerTemplate, builtinTemplates, cardTemplate, } from "./templates/index.js";
|
|
5
|
+
export { defaultOutputPath, generate } from "./generate.js";
|
|
6
|
+
export { escapeXml, wrapText } from "./text.js";
|
|
7
|
+
export { extractProps, walkContent } from "./content/index.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,YAAY,GACb,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG5D,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ColophonConfig, Dimensions, MetaImageProps, RenderedMetaImage, ResolvedConfig } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Build the complete SVG document for one image: the enclosing `<svg>` root,
|
|
4
|
+
* the config-driven background, and the template's foreground content.
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildSvg(props: MetaImageProps, config: ResolvedConfig, dimensions: Dimensions): string;
|
|
7
|
+
/**
|
|
8
|
+
* Rasterise an SVG string to a PNG buffer at the given dimensions.
|
|
9
|
+
*/
|
|
10
|
+
export declare function renderSvgToPng(svg: string, dimensions: Dimensions): Promise<Buffer>;
|
|
11
|
+
/**
|
|
12
|
+
* Render an image for every configured dimension from a single set of props.
|
|
13
|
+
* This is the reusable core: it takes props and config and returns rendered
|
|
14
|
+
* bytes, with no filesystem or content-discovery concerns.
|
|
15
|
+
*/
|
|
16
|
+
export declare function renderMetaImages(props: MetaImageProps, config?: ColophonConfig): Promise<RenderedMetaImage[]>;
|
|
17
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EACd,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,cAAc,EAEf,MAAM,YAAY,CAAC;AAmBpB;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,UAAU,GACrB,MAAM,CAWR;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,cAAc,EACrB,MAAM,CAAC,EAAE,cAAc,GACtB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAa9B"}
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import sharp from "sharp";
|
|
2
|
+
import { backgroundSvg } from "./background.js";
|
|
3
|
+
import { resolveConfig } from "./config.js";
|
|
4
|
+
const backgroundId = "colophon-bg";
|
|
5
|
+
function selectTemplate(config, name) {
|
|
6
|
+
const template = config.templates[name];
|
|
7
|
+
if (template === undefined) {
|
|
8
|
+
const available = Object.keys(config.templates)
|
|
9
|
+
.toSorted((a, b) => a.localeCompare(b))
|
|
10
|
+
.join(", ");
|
|
11
|
+
throw new Error(`Unknown template "${name}". Available templates: ${available}.`);
|
|
12
|
+
}
|
|
13
|
+
return template;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Build the complete SVG document for one image: the enclosing `<svg>` root,
|
|
17
|
+
* the config-driven background, and the template's foreground content.
|
|
18
|
+
*/
|
|
19
|
+
export function buildSvg(props, config, dimensions) {
|
|
20
|
+
const template = selectTemplate(config, props.template);
|
|
21
|
+
const background = backgroundSvg(config.background, dimensions, backgroundId);
|
|
22
|
+
const body = template.render({ props, config, dimensions });
|
|
23
|
+
const { width, height } = dimensions;
|
|
24
|
+
return (`<svg width="${String(width)}" height="${String(height)}"` +
|
|
25
|
+
` viewBox="0 0 ${String(width)} ${String(height)}"` +
|
|
26
|
+
` xmlns="http://www.w3.org/2000/svg">${background}${body}</svg>`);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Rasterise an SVG string to a PNG buffer at the given dimensions.
|
|
30
|
+
*/
|
|
31
|
+
export async function renderSvgToPng(svg, dimensions) {
|
|
32
|
+
return sharp(Buffer.from(svg))
|
|
33
|
+
.resize(dimensions.width, dimensions.height, { fit: "fill" })
|
|
34
|
+
.png()
|
|
35
|
+
.toBuffer();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Render an image for every configured dimension from a single set of props.
|
|
39
|
+
* This is the reusable core: it takes props and config and returns rendered
|
|
40
|
+
* bytes, with no filesystem or content-discovery concerns.
|
|
41
|
+
*/
|
|
42
|
+
export async function renderMetaImages(props, config) {
|
|
43
|
+
const resolved = resolveConfig(config);
|
|
44
|
+
// Validate the template once up front so a bad name fails fast.
|
|
45
|
+
selectTemplate(resolved, props.template);
|
|
46
|
+
return Promise.all(resolved.dimensions.map(async (dimensions) => {
|
|
47
|
+
const svg = buildSvg(props, resolved, dimensions);
|
|
48
|
+
const png = await renderSvgToPng(svg, dimensions);
|
|
49
|
+
return { dimensions, svg, png };
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAU5C,MAAM,YAAY,GAAG,aAAa,CAAC;AAEnC,SAAS,cAAc,CAAC,MAAsB,EAAE,IAAY;IAC1D,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAExC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;aAC5C,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;aACtC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,IAAI,KAAK,CACb,qBAAqB,IAAI,2BAA2B,SAAS,GAAG,CACjE,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAqB,EACrB,MAAsB,EACtB,UAAsB;IAEtB,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAC9E,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5D,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC;IAErC,OAAO,CACL,eAAe,MAAM,CAAC,KAAK,CAAC,aAAa,MAAM,CAAC,MAAM,CAAC,GAAG;QAC1D,iBAAiB,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG;QACnD,uCAAuC,UAAU,GAAG,IAAI,QAAQ,CACjE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,UAAsB;IAEtB,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAC3B,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;SAC5D,GAAG,EAAE;SACL,QAAQ,EAAE,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAqB,EACrB,MAAuB;IAEvB,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAEvC,gEAAgE;IAChE,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEzC,OAAO,OAAO,CAAC,GAAG,CAChB,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;QAC3C,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAClD,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAClD,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IAClC,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Template } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generalised "banner" template: a left-aligned title with an optional
|
|
4
|
+
* version and wrapped subtitle, an optional corner badge, and an optional
|
|
5
|
+
* footer. This is the configurable descendant of the original `npm_package`
|
|
6
|
+
* layout.
|
|
7
|
+
*/
|
|
8
|
+
export declare const bannerTemplate: Template;
|
|
9
|
+
//# sourceMappingURL=banner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/templates/banner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAS,QAAQ,EAAmB,MAAM,aAAa,CAAC;AA0DpE;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,QAwH5B,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { estimateCharsPerLine, layoutStack, textElement, wrapText, } from "../text.js";
|
|
2
|
+
const maxTitleLines = 3;
|
|
3
|
+
const maxSubtitleLines = 4;
|
|
4
|
+
function optionalString(value) {
|
|
5
|
+
if (typeof value === "string") {
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
if (typeof value === "number" ||
|
|
9
|
+
typeof value === "boolean" ||
|
|
10
|
+
typeof value === "bigint") {
|
|
11
|
+
return String(value);
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
function renderBadge(badge, fontFamily, brand, pad, height) {
|
|
16
|
+
const fontSize = Math.round(height * 0.6);
|
|
17
|
+
const padX = Math.round(height * 0.36);
|
|
18
|
+
const width = Math.round(badge.text.length * fontSize * 0.64 + padX * 2);
|
|
19
|
+
const radius = Math.round(height * 0.1);
|
|
20
|
+
const rect = `<rect x="${String(pad)}" y="${String(pad)}"` +
|
|
21
|
+
` width="${String(width)}" height="${String(height)}"` +
|
|
22
|
+
` rx="${String(radius)}" fill="${badge.background ?? "#ffffff"}"/>`;
|
|
23
|
+
const text = textElement(badge.text, {
|
|
24
|
+
x: pad + padX,
|
|
25
|
+
y: pad + Math.round(height * 0.72),
|
|
26
|
+
fontFamily,
|
|
27
|
+
fontSize,
|
|
28
|
+
fontWeight: 900,
|
|
29
|
+
fill: badge.color ?? brand,
|
|
30
|
+
});
|
|
31
|
+
return rect + text;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Generalised "banner" template: a left-aligned title with an optional
|
|
35
|
+
* version and wrapped subtitle, an optional corner badge, and an optional
|
|
36
|
+
* footer. This is the configurable descendant of the original `npm_package`
|
|
37
|
+
* layout.
|
|
38
|
+
*/
|
|
39
|
+
export const bannerTemplate = {
|
|
40
|
+
name: "banner",
|
|
41
|
+
render({ props, config, dimensions }) {
|
|
42
|
+
const { width, height } = dimensions;
|
|
43
|
+
const { fontFamily } = config;
|
|
44
|
+
const fg = config.colors.foreground;
|
|
45
|
+
const pad = Math.round(width * 0.075);
|
|
46
|
+
const contentWidth = width - pad * 2;
|
|
47
|
+
const title = props.title;
|
|
48
|
+
const subtitle = optionalString(props.subtitle);
|
|
49
|
+
const version = optionalString(props.version);
|
|
50
|
+
const hasSubtitle = subtitle !== undefined && subtitle !== "";
|
|
51
|
+
const titleFs = Math.round(height * (hasSubtitle ? 0.078 : 0.092));
|
|
52
|
+
const versionFs = Math.round(height * 0.04);
|
|
53
|
+
const subFs = Math.round(height * 0.05);
|
|
54
|
+
const footerFs = Math.round(height * 0.034);
|
|
55
|
+
const badgeHeight = Math.round(height * 0.072);
|
|
56
|
+
const titleLines = wrapText(title, estimateCharsPerLine(contentWidth, titleFs, 0.6)).slice(0, maxTitleLines);
|
|
57
|
+
const subtitleLines = hasSubtitle
|
|
58
|
+
? wrapText(subtitle, estimateCharsPerLine(contentWidth, subFs, 0.55)).slice(0, maxSubtitleLines)
|
|
59
|
+
: [];
|
|
60
|
+
// Extra breathing room between the title, version and subtitle groups so
|
|
61
|
+
// they don't read as one squashed block.
|
|
62
|
+
const versionGap = Math.round(height * 0.03);
|
|
63
|
+
const subtitleGap = Math.round(height * 0.045);
|
|
64
|
+
const lines = titleLines.map((text) => ({
|
|
65
|
+
text,
|
|
66
|
+
fontSize: titleFs,
|
|
67
|
+
fontWeight: 800,
|
|
68
|
+
opacity: 0.98,
|
|
69
|
+
}));
|
|
70
|
+
if (version !== undefined && version !== "") {
|
|
71
|
+
lines.push({
|
|
72
|
+
text: `v${version}`,
|
|
73
|
+
fontSize: versionFs,
|
|
74
|
+
fontWeight: 700,
|
|
75
|
+
opacity: 0.85,
|
|
76
|
+
gapBefore: versionGap,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
for (const [index, text] of subtitleLines.entries()) {
|
|
80
|
+
lines.push({
|
|
81
|
+
text,
|
|
82
|
+
fontSize: subFs,
|
|
83
|
+
fontWeight: 500,
|
|
84
|
+
opacity: 0.86,
|
|
85
|
+
...(index === 0 && { gapBefore: subtitleGap }),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const hasBadge = config.badge !== undefined;
|
|
89
|
+
const hasFooter = config.footer !== undefined && config.footer !== "";
|
|
90
|
+
const top = pad + (hasBadge ? badgeHeight + Math.round(height * 0.03) : 0);
|
|
91
|
+
const bottom = height - pad - (hasFooter ? footerFs + Math.round(height * 0.02) : 0);
|
|
92
|
+
const placed = layoutStack(lines.map((line) => ({
|
|
93
|
+
fontSize: line.fontSize,
|
|
94
|
+
lineHeight: 1.15,
|
|
95
|
+
...(line.gapBefore !== undefined && { gapBefore: line.gapBefore }),
|
|
96
|
+
})), top, bottom);
|
|
97
|
+
const body = lines
|
|
98
|
+
.map((line, index) => textElement(line.text, {
|
|
99
|
+
x: pad,
|
|
100
|
+
y: placed[index]?.y ?? top,
|
|
101
|
+
fontFamily,
|
|
102
|
+
fontSize: line.fontSize,
|
|
103
|
+
fontWeight: line.fontWeight,
|
|
104
|
+
fill: fg,
|
|
105
|
+
fillOpacity: line.opacity,
|
|
106
|
+
}))
|
|
107
|
+
.join("");
|
|
108
|
+
const badge = config.badge === undefined
|
|
109
|
+
? ""
|
|
110
|
+
: renderBadge(config.badge, fontFamily, config.colors.brand, pad, badgeHeight);
|
|
111
|
+
const footer = config.footer !== undefined && config.footer !== ""
|
|
112
|
+
? textElement(config.footer, {
|
|
113
|
+
x: pad,
|
|
114
|
+
y: height - pad,
|
|
115
|
+
fontFamily,
|
|
116
|
+
fontSize: footerFs,
|
|
117
|
+
fontWeight: 500,
|
|
118
|
+
fill: fg,
|
|
119
|
+
fillOpacity: 0.78,
|
|
120
|
+
})
|
|
121
|
+
: "";
|
|
122
|
+
return badge + body + footer;
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/templates/banner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Template } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal "card" template: a centred title with an optional subtitle. No
|
|
4
|
+
* badge or version — a clean, quieter alternative to `banner`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const cardTemplate: Template;
|
|
7
|
+
//# sourceMappingURL=card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../src/templates/card.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAmB,MAAM,aAAa,CAAC;AA4B7D;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,QAsF1B,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { estimateCharsPerLine, layoutStack, textElement, wrapText, } from "../text.js";
|
|
2
|
+
const maxTitleLines = 3;
|
|
3
|
+
const maxSubtitleLines = 3;
|
|
4
|
+
function optionalString(value) {
|
|
5
|
+
if (typeof value === "string") {
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
if (typeof value === "number" ||
|
|
9
|
+
typeof value === "boolean" ||
|
|
10
|
+
typeof value === "bigint") {
|
|
11
|
+
return String(value);
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Minimal "card" template: a centred title with an optional subtitle. No
|
|
17
|
+
* badge or version — a clean, quieter alternative to `banner`.
|
|
18
|
+
*/
|
|
19
|
+
export const cardTemplate = {
|
|
20
|
+
name: "card",
|
|
21
|
+
render({ props, config, dimensions }) {
|
|
22
|
+
const { width, height } = dimensions;
|
|
23
|
+
const { fontFamily } = config;
|
|
24
|
+
const fg = config.colors.foreground;
|
|
25
|
+
const pad = Math.round(width * 0.09);
|
|
26
|
+
const contentWidth = width - pad * 2;
|
|
27
|
+
const centreX = Math.round(width / 2);
|
|
28
|
+
const title = props.title;
|
|
29
|
+
const subtitle = optionalString(props.subtitle);
|
|
30
|
+
const hasSubtitle = subtitle !== undefined && subtitle !== "";
|
|
31
|
+
const titleFs = Math.round(height * 0.1);
|
|
32
|
+
const subFs = Math.round(height * 0.045);
|
|
33
|
+
const footerFs = Math.round(height * 0.032);
|
|
34
|
+
const titleLines = wrapText(title, estimateCharsPerLine(contentWidth, titleFs, 0.58)).slice(0, maxTitleLines);
|
|
35
|
+
const subtitleLines = hasSubtitle
|
|
36
|
+
? wrapText(subtitle, estimateCharsPerLine(contentWidth, subFs, 0.52)).slice(0, maxSubtitleLines)
|
|
37
|
+
: [];
|
|
38
|
+
const lines = [
|
|
39
|
+
...titleLines.map((text) => ({
|
|
40
|
+
text,
|
|
41
|
+
fontSize: titleFs,
|
|
42
|
+
fontWeight: 800,
|
|
43
|
+
opacity: 1,
|
|
44
|
+
})),
|
|
45
|
+
...subtitleLines.map((text) => ({
|
|
46
|
+
text,
|
|
47
|
+
fontSize: subFs,
|
|
48
|
+
fontWeight: 500,
|
|
49
|
+
opacity: 0.85,
|
|
50
|
+
})),
|
|
51
|
+
];
|
|
52
|
+
const hasFooter = config.footer !== undefined && config.footer !== "";
|
|
53
|
+
const bottom = height - pad - (hasFooter ? footerFs + Math.round(height * 0.02) : 0);
|
|
54
|
+
const placed = layoutStack(lines.map((line) => ({ fontSize: line.fontSize, lineHeight: 1.2 })), pad, bottom);
|
|
55
|
+
const body = lines
|
|
56
|
+
.map((line, index) => textElement(line.text, {
|
|
57
|
+
x: centreX,
|
|
58
|
+
y: placed[index]?.y ?? pad,
|
|
59
|
+
fontFamily,
|
|
60
|
+
fontSize: line.fontSize,
|
|
61
|
+
fontWeight: line.fontWeight,
|
|
62
|
+
fill: fg,
|
|
63
|
+
fillOpacity: line.opacity,
|
|
64
|
+
anchor: "middle",
|
|
65
|
+
}))
|
|
66
|
+
.join("");
|
|
67
|
+
const footer = config.footer !== undefined && config.footer !== ""
|
|
68
|
+
? textElement(config.footer, {
|
|
69
|
+
x: centreX,
|
|
70
|
+
y: height - pad,
|
|
71
|
+
fontFamily,
|
|
72
|
+
fontSize: footerFs,
|
|
73
|
+
fontWeight: 500,
|
|
74
|
+
fill: fg,
|
|
75
|
+
fillOpacity: 0.75,
|
|
76
|
+
anchor: "middle",
|
|
77
|
+
})
|
|
78
|
+
: "";
|
|
79
|
+
return body + footer;
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.js","sourceRoot":"","sources":["../../src/templates/card.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Template } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Templates registered out of the box. Projects can add to or override these
|
|
4
|
+
* via `config.templates`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const builtinTemplates: Readonly<Record<string, Template>>;
|
|
7
|
+
export { bannerTemplate } from "./banner.js";
|
|
8
|
+
export { cardTemplate } from "./card.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAI5C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAG/D,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { bannerTemplate } from "./banner.js";
|
|
2
|
+
import { cardTemplate } from "./card.js";
|
|
3
|
+
/**
|
|
4
|
+
* Templates registered out of the box. Projects can add to or override these
|
|
5
|
+
* via `config.templates`.
|
|
6
|
+
*/
|
|
7
|
+
export const builtinTemplates = {
|
|
8
|
+
[bannerTemplate.name]: bannerTemplate,
|
|
9
|
+
[cardTemplate.name]: cardTemplate,
|
|
10
|
+
};
|
|
11
|
+
export { bannerTemplate } from "./banner.js";
|
|
12
|
+
export { cardTemplate } from "./card.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAuC;IAClE,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,cAAc;IACrC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,YAAY;CAClC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|