@docmentis/udoc-wasm 0.0.0-stage → 0.8.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 +434 -0
- package/README.md +53 -2
- package/dist/error.d.ts +16 -0
- package/dist/error.js +36 -0
- package/dist/font-fulfill.d.ts +92 -0
- package/dist/font-fulfill.js +203 -0
- package/dist/fonts/Caladea-Bold.ttf +0 -0
- package/dist/fonts/Caladea-BoldItalic.ttf +0 -0
- package/dist/fonts/Caladea-Italic.ttf +0 -0
- package/dist/fonts/Caladea-Regular.ttf +0 -0
- package/dist/fonts/Carlito-Bold.ttf +0 -0
- package/dist/fonts/Carlito-BoldItalic.ttf +0 -0
- package/dist/fonts/Carlito-Italic.ttf +0 -0
- package/dist/fonts/Carlito-Regular.ttf +0 -0
- package/dist/fonts/LICENSE-Liberation.txt +102 -0
- package/dist/fonts/LiberationMono-Bold.ttf +0 -0
- package/dist/fonts/LiberationMono-BoldItalic.ttf +0 -0
- package/dist/fonts/LiberationMono-Italic.ttf +0 -0
- package/dist/fonts/LiberationMono-Regular.ttf +0 -0
- package/dist/fonts/LiberationSans-Bold.ttf +0 -0
- package/dist/fonts/LiberationSans-BoldItalic.ttf +0 -0
- package/dist/fonts/LiberationSans-Italic.ttf +0 -0
- package/dist/fonts/LiberationSans-Regular.ttf +0 -0
- package/dist/fonts/LiberationSerif-Bold.ttf +0 -0
- package/dist/fonts/LiberationSerif-BoldItalic.ttf +0 -0
- package/dist/fonts/LiberationSerif-Italic.ttf +0 -0
- package/dist/fonts/LiberationSerif-Regular.ttf +0 -0
- package/dist/fonts/OFL-Caladea.txt +93 -0
- package/dist/fonts/OFL-Carlito.txt +94 -0
- package/dist/google-font-catalog.d.ts +21 -0
- package/dist/google-font-catalog.js +1860 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.js +150 -0
- package/dist/meta-url.d.ts +3 -0
- package/dist/meta-url.js +46 -0
- package/dist/office-compatible-fonts.d.ts +3 -0
- package/dist/office-compatible-fonts.js +33 -0
- package/dist/wasm/THIRD-PARTY-NOTICES.txt +9395 -0
- package/dist/wasm/udoc.d.ts +20260 -0
- package/dist/wasm/udoc.js +4600 -0
- package/dist/wasm/udoc_bg.wasm +0 -0
- package/package.json +41 -5
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { WasmSession } from "./wasm/udoc.js";
|
|
2
|
+
import type { GoogleFontFamily, SessionConfig, UrlFont } from "./wasm/udoc.js";
|
|
3
|
+
export * from "./wasm/udoc.js";
|
|
4
|
+
export { default } from "./wasm/udoc.js";
|
|
5
|
+
export { GOOGLE_FONT_CATALOG } from "./google-font-catalog.js";
|
|
6
|
+
export { OFFICE_COMPATIBLE_FONTS } from "./office-compatible-fonts.js";
|
|
7
|
+
export { CSS2_ENDPOINT, createFontFetchMemory, fetchFontBinaries } from "./font-fulfill.js";
|
|
8
|
+
export type { Fetcher, FontFetchMemory } from "./font-fulfill.js";
|
|
9
|
+
export { UDocError } from "./error.js";
|
|
10
|
+
export type { UDocErrorCode, UDocErrorDetail } from "./error.js";
|
|
11
|
+
/**
|
|
12
|
+
* Where this package's office-compatible fonts are served: the directory its
|
|
13
|
+
* `dist/` is served as, which each font's path resolves against (a host's own
|
|
14
|
+
* copy, a CDN), or each path's own URL (`meta-url`'s `bundledFontUrls`, which
|
|
15
|
+
* a bundler emits file by file).
|
|
16
|
+
*/
|
|
17
|
+
export type FontLocation = string | Readonly<Record<string, string>>;
|
|
18
|
+
/** The {@link OFFICE_COMPATIBLE_FONTS}, each at its URL in `fonts`. */
|
|
19
|
+
export declare function officeCompatibleFontsAt(fonts: FontLocation): UrlFont[];
|
|
20
|
+
/**
|
|
21
|
+
* Start a session as the glue's `startSession` does, offering it this
|
|
22
|
+
* package's fonts: the {@link OFFICE_COMPATIBLE_FONTS} by URL, from `fonts`,
|
|
23
|
+
* and `googleFontFamilies` — the {@link GOOGLE_FONT_CATALOG} unless given, `[]`
|
|
24
|
+
* for no Google Fonts at all. Rejects, with no session left behind, when the
|
|
25
|
+
* license refuses or the list isn't a list of `GoogleFontFamily`.
|
|
26
|
+
*
|
|
27
|
+
* It shadows the glue's export of the same name, so every host that starts a
|
|
28
|
+
* session through this module offers both unless it says otherwise.
|
|
29
|
+
*/
|
|
30
|
+
export declare function startSession(config: SessionConfig, fonts: FontLocation, googleFontFamilies?: readonly GoogleFontFamily[]): Promise<WasmSession>;
|
|
31
|
+
declare module "./wasm/udoc.js" {
|
|
32
|
+
interface WasmSession {
|
|
33
|
+
readonly portable: DocNamespace<"portable">;
|
|
34
|
+
readonly presentation: DocNamespace<"presentation">;
|
|
35
|
+
readonly spreadsheet: DocNamespace<"spreadsheet">;
|
|
36
|
+
readonly wordprocessing: DocNamespace<"wordprocessing">;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** `session.<Doc>`: its methods' names parsed into levels. */
|
|
40
|
+
type DocNamespace<Doc extends string> = Level<Extract<keyof WasmSession, `__${Doc}_${string}`>, `__${Doc}`, []>;
|
|
41
|
+
/** The level at the name prefix `At`, among the methods `K`; `Taken` holds the
|
|
42
|
+
* arguments the calls on the way took. */
|
|
43
|
+
type Level<K extends keyof WasmSession & string, At extends string, Taken extends unknown[]> = {
|
|
44
|
+
readonly [S in PropertyStep<K, At> | CallStep<K, At> | LastStep<K, At>]: S extends LastStep<K, At> ? Last<WasmSession[`${At}_${S}` & keyof WasmSession], Taken> : S extends CallStep<K, At> ? (arg: Argument<WasmSession[Extract<K, `${At}__${S}_${string}`>], Taken>) => Level<K, `${At}__${S}`, [...Taken, unknown]> : Level<K, `${At}_${S}`, Taken>;
|
|
45
|
+
};
|
|
46
|
+
/** The property steps at `At`: `_step` followed by more. */
|
|
47
|
+
type PropertyStep<K extends string, At extends string> = K extends `${At}_${infer S}_${string}` ? S extends "" ? never : S : never;
|
|
48
|
+
/** The call steps at `At`: `__step` followed by more. */
|
|
49
|
+
type CallStep<K extends string, At extends string> = K extends `${At}__${infer S}_${string}` ? S extends "" ? never : S : never;
|
|
50
|
+
/** The last steps at `At`: `_step` ending the name. */
|
|
51
|
+
type LastStep<K extends string, At extends string> = K extends `${At}_${infer S}` ? S extends "" | `${string}_${string}` ? never : S : never;
|
|
52
|
+
/** The argument a call step takes: the parameter of each method under it after
|
|
53
|
+
* the ones `Taken` already covers. */
|
|
54
|
+
type Argument<M, Taken extends unknown[]> = M extends (...args: infer P) => unknown ? P[Taken["length"]] : never;
|
|
55
|
+
/** A last step: its method, less the parameters the calls on the way took. */
|
|
56
|
+
type Last<M, Taken extends unknown[]> = Taken extends [] ? M : M extends (...args: infer P) => infer R ? (...args: Drop<P, Taken>) => R : never;
|
|
57
|
+
/** `P` without as many leading elements as `Taken` has. */
|
|
58
|
+
type Drop<P extends unknown[], Taken extends unknown[]> = Taken extends [unknown, ...infer T] ? P extends [unknown, ...infer R] ? Drop<R, T> : [] : P;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// The package root: the wasm-bindgen glue (`wasm/udoc.js`), re-exported whole,
|
|
2
|
+
// with each doc type's reads grouped under `session.<doc>` on its `WasmSession`.
|
|
3
|
+
//
|
|
4
|
+
// The glue declares every read flat, as a private `__<doc>…` method. This module
|
|
5
|
+
// groups them by name onto the class's prototype, so every session
|
|
6
|
+
// `startSession` returns carries them, however a host loaded this module —
|
|
7
|
+
// nothing wraps the session. A read's name is its path:
|
|
8
|
+
//
|
|
9
|
+
// __portable_model_root_pageIds() session.portable.model.root.pageIds()
|
|
10
|
+
// __portable_model__page_shapeInfo(p, s) session.portable.model.page(p).shapeInfo(s)
|
|
11
|
+
//
|
|
12
|
+
// After `__<doc>`, `_step` is a property and `__step` a call taking one
|
|
13
|
+
// argument. The last step is always a call, written `_step`, taking every
|
|
14
|
+
// argument left. A step is a middle step or a last one, never both. The runtime
|
|
15
|
+
// below parses the names off the prototype and the types parse them out of
|
|
16
|
+
// `udoc.d.ts`, so a new read in Rust needs no line here.
|
|
17
|
+
//
|
|
18
|
+
// The glue is imported by relative path, not by package name, so this module
|
|
19
|
+
// still resolves it when served unbundled from a CDN or a host's own directory.
|
|
20
|
+
//
|
|
21
|
+
// Beside the glue it exports the two font offers the package ships — the
|
|
22
|
+
// office-compatible fonts and the Google font catalog, which its own
|
|
23
|
+
// `startSession` offers every session it starts — what fills a session's font
|
|
24
|
+
// orders, and `UDocError`, the error every failure is reported as.
|
|
25
|
+
import { WasmSession, startSession as startGlueSession } from "./wasm/udoc.js";
|
|
26
|
+
import { UDocError } from "./error.js";
|
|
27
|
+
import { GOOGLE_FONT_CATALOG } from "./google-font-catalog.js";
|
|
28
|
+
import { OFFICE_COMPATIBLE_FONTS } from "./office-compatible-fonts.js";
|
|
29
|
+
export * from "./wasm/udoc.js";
|
|
30
|
+
export { default } from "./wasm/udoc.js";
|
|
31
|
+
export { GOOGLE_FONT_CATALOG } from "./google-font-catalog.js";
|
|
32
|
+
export { OFFICE_COMPATIBLE_FONTS } from "./office-compatible-fonts.js";
|
|
33
|
+
export { CSS2_ENDPOINT, createFontFetchMemory, fetchFontBinaries } from "./font-fulfill.js";
|
|
34
|
+
export { UDocError } from "./error.js";
|
|
35
|
+
/** The {@link OFFICE_COMPATIBLE_FONTS}, each at its URL in `fonts`. */
|
|
36
|
+
export function officeCompatibleFontsAt(fonts) {
|
|
37
|
+
return OFFICE_COMPATIBLE_FONTS.map((font) => {
|
|
38
|
+
const url = typeof fonts === "string" ? new URL(font.url, fonts).href : fonts[font.url];
|
|
39
|
+
if (url === undefined)
|
|
40
|
+
throw new UDocError("invalidRequest", `no URL is given for the font ${font.url}`);
|
|
41
|
+
return { ...font, url };
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Start a session as the glue's `startSession` does, offering it this
|
|
46
|
+
* package's fonts: the {@link OFFICE_COMPATIBLE_FONTS} by URL, from `fonts`,
|
|
47
|
+
* and `googleFontFamilies` — the {@link GOOGLE_FONT_CATALOG} unless given, `[]`
|
|
48
|
+
* for no Google Fonts at all. Rejects, with no session left behind, when the
|
|
49
|
+
* license refuses or the list isn't a list of `GoogleFontFamily`.
|
|
50
|
+
*
|
|
51
|
+
* It shadows the glue's export of the same name, so every host that starts a
|
|
52
|
+
* session through this module offers both unless it says otherwise.
|
|
53
|
+
*/
|
|
54
|
+
export async function startSession(config, fonts, googleFontFamilies = GOOGLE_FONT_CATALOG) {
|
|
55
|
+
const officeCompatibleFonts = officeCompatibleFontsAt(fonts);
|
|
56
|
+
const session = await startGlueSession(config);
|
|
57
|
+
try {
|
|
58
|
+
session.setGoogleFontFamilies(googleFontFamilies);
|
|
59
|
+
session.registerUrlFonts(officeCompatibleFonts);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
session.free();
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
return session;
|
|
66
|
+
}
|
|
67
|
+
/** The doc types grouped under `session.<doc>` — named, not found, because
|
|
68
|
+
* wasm-bindgen's own `__destroy_into_raw` sits on the same prototype. */
|
|
69
|
+
const DOCS = [
|
|
70
|
+
"portable",
|
|
71
|
+
"presentation",
|
|
72
|
+
"spreadsheet",
|
|
73
|
+
"wordprocessing",
|
|
74
|
+
];
|
|
75
|
+
/** One separator and the step it introduces: `_step` or `__step`. */
|
|
76
|
+
const SEGMENT = /(__?)([^_]+)/y;
|
|
77
|
+
/** The steps under `session.<doc>`, parsed from the names of its methods. */
|
|
78
|
+
function parse(doc) {
|
|
79
|
+
const root = new Map();
|
|
80
|
+
const prefix = `__${doc}`;
|
|
81
|
+
for (const name of Object.getOwnPropertyNames(WasmSession.prototype)) {
|
|
82
|
+
if (!name.startsWith(`${prefix}_`))
|
|
83
|
+
continue;
|
|
84
|
+
const method = Object.getOwnPropertyDescriptor(WasmSession.prototype, name).value;
|
|
85
|
+
const path = segments(name, prefix.length);
|
|
86
|
+
let steps = root;
|
|
87
|
+
path.forEach(([separator, step], i) => {
|
|
88
|
+
const existing = steps.get(step);
|
|
89
|
+
if (i === path.length - 1) {
|
|
90
|
+
if (separator !== "_")
|
|
91
|
+
throw new Error(`WasmSession.${name}: the last step is written \`_${step}\``);
|
|
92
|
+
if (existing)
|
|
93
|
+
throw new Error(`WasmSession.${name}: \`${step}\` is already a step`);
|
|
94
|
+
steps.set(step, { kind: "last", method });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const kind = separator === "_" ? "property" : "call";
|
|
98
|
+
if (!existing) {
|
|
99
|
+
const next = new Map();
|
|
100
|
+
steps.set(step, { kind, next });
|
|
101
|
+
steps = next;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (existing.kind === "last" || existing.kind !== kind) {
|
|
105
|
+
throw new Error(`WasmSession.${name}: \`${step}\` is already a different step`);
|
|
106
|
+
}
|
|
107
|
+
steps = existing.next;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return root;
|
|
111
|
+
}
|
|
112
|
+
/** `name` from `from` on, as `[separator, step]` pairs. */
|
|
113
|
+
function segments(name, from) {
|
|
114
|
+
const found = [];
|
|
115
|
+
SEGMENT.lastIndex = from;
|
|
116
|
+
let at = from;
|
|
117
|
+
for (let match = SEGMENT.exec(name); match; match = SEGMENT.exec(name)) {
|
|
118
|
+
found.push([match[1], match[2]]);
|
|
119
|
+
at = SEGMENT.lastIndex;
|
|
120
|
+
}
|
|
121
|
+
if (found.length === 0 || at !== name.length)
|
|
122
|
+
throw new Error(`WasmSession.${name}: not a namespace path`);
|
|
123
|
+
return found;
|
|
124
|
+
}
|
|
125
|
+
/** `steps` bound to `session`, `args` holding what the calls on the way took. */
|
|
126
|
+
function bind(steps, session, args) {
|
|
127
|
+
const level = {};
|
|
128
|
+
for (const [name, step] of steps) {
|
|
129
|
+
switch (step.kind) {
|
|
130
|
+
case "property":
|
|
131
|
+
level[name] = bind(step.next, session, args);
|
|
132
|
+
break;
|
|
133
|
+
case "call":
|
|
134
|
+
level[name] = (arg) => bind(step.next, session, [...args, arg]);
|
|
135
|
+
break;
|
|
136
|
+
case "last":
|
|
137
|
+
level[name] = (...rest) => step.method.apply(session, [...args, ...rest]);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return level;
|
|
142
|
+
}
|
|
143
|
+
for (const doc of DOCS) {
|
|
144
|
+
const steps = parse(doc);
|
|
145
|
+
Object.defineProperty(WasmSession.prototype, doc, {
|
|
146
|
+
get() {
|
|
147
|
+
return bind(steps, this, []);
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
package/dist/meta-url.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// `import.meta.url`-based resolution of the bundled WASM artifacts.
|
|
2
|
+
//
|
|
3
|
+
// `scripts/copy-wasm.mjs` copies the wasm-bindgen output into `dist/wasm/`, and
|
|
4
|
+
// `scripts/copy-fonts.mjs` the office-compatible fonts into `dist/fonts/`, so
|
|
5
|
+
// they sit next to the compiled JS. We resolve each against this module's URL,
|
|
6
|
+
// which keeps the package self-contained: the browser at runtime, or Node,
|
|
7
|
+
// finds them beside this module, and a consumer's bundler emits each one as an
|
|
8
|
+
// asset, since every file is named by its own literal `new URL(…,
|
|
9
|
+
// import.meta.url)` — a pattern Vite and webpack follow, where a computed path
|
|
10
|
+
// would not be.
|
|
11
|
+
//
|
|
12
|
+
// Isolated in its own file and loaded **only via dynamic `import()`** (from
|
|
13
|
+
// udoc-ui's `worker/wasm-loader.ts`) so environments that don't support
|
|
14
|
+
// `import.meta` at parse time (e.g. StackBlitz's turbo_modules) don't choke.
|
|
15
|
+
function abs(u) {
|
|
16
|
+
// Some bundlers emit a root-relative path; make it absolute against the
|
|
17
|
+
// current origin so a worker (different base URL) resolves it the same way.
|
|
18
|
+
if (u.startsWith("/") && typeof globalThis.location !== "undefined") {
|
|
19
|
+
return globalThis.location.origin + u;
|
|
20
|
+
}
|
|
21
|
+
return u;
|
|
22
|
+
}
|
|
23
|
+
export const bundledWasmUrl = abs(new URL("./wasm/udoc_bg.wasm", import.meta.url).href);
|
|
24
|
+
/** Each office-compatible font's URL, by its path in `OFFICE_COMPATIBLE_FONTS`. */
|
|
25
|
+
export const bundledFontUrls = {
|
|
26
|
+
"fonts/LiberationSans-Regular.ttf": abs(new URL("./fonts/LiberationSans-Regular.ttf", import.meta.url).href),
|
|
27
|
+
"fonts/LiberationSans-Bold.ttf": abs(new URL("./fonts/LiberationSans-Bold.ttf", import.meta.url).href),
|
|
28
|
+
"fonts/LiberationSans-Italic.ttf": abs(new URL("./fonts/LiberationSans-Italic.ttf", import.meta.url).href),
|
|
29
|
+
"fonts/LiberationSans-BoldItalic.ttf": abs(new URL("./fonts/LiberationSans-BoldItalic.ttf", import.meta.url).href),
|
|
30
|
+
"fonts/LiberationSerif-Regular.ttf": abs(new URL("./fonts/LiberationSerif-Regular.ttf", import.meta.url).href),
|
|
31
|
+
"fonts/LiberationSerif-Bold.ttf": abs(new URL("./fonts/LiberationSerif-Bold.ttf", import.meta.url).href),
|
|
32
|
+
"fonts/LiberationSerif-Italic.ttf": abs(new URL("./fonts/LiberationSerif-Italic.ttf", import.meta.url).href),
|
|
33
|
+
"fonts/LiberationSerif-BoldItalic.ttf": abs(new URL("./fonts/LiberationSerif-BoldItalic.ttf", import.meta.url).href),
|
|
34
|
+
"fonts/LiberationMono-Regular.ttf": abs(new URL("./fonts/LiberationMono-Regular.ttf", import.meta.url).href),
|
|
35
|
+
"fonts/LiberationMono-Bold.ttf": abs(new URL("./fonts/LiberationMono-Bold.ttf", import.meta.url).href),
|
|
36
|
+
"fonts/LiberationMono-Italic.ttf": abs(new URL("./fonts/LiberationMono-Italic.ttf", import.meta.url).href),
|
|
37
|
+
"fonts/LiberationMono-BoldItalic.ttf": abs(new URL("./fonts/LiberationMono-BoldItalic.ttf", import.meta.url).href),
|
|
38
|
+
"fonts/Carlito-Regular.ttf": abs(new URL("./fonts/Carlito-Regular.ttf", import.meta.url).href),
|
|
39
|
+
"fonts/Carlito-Bold.ttf": abs(new URL("./fonts/Carlito-Bold.ttf", import.meta.url).href),
|
|
40
|
+
"fonts/Carlito-Italic.ttf": abs(new URL("./fonts/Carlito-Italic.ttf", import.meta.url).href),
|
|
41
|
+
"fonts/Carlito-BoldItalic.ttf": abs(new URL("./fonts/Carlito-BoldItalic.ttf", import.meta.url).href),
|
|
42
|
+
"fonts/Caladea-Regular.ttf": abs(new URL("./fonts/Caladea-Regular.ttf", import.meta.url).href),
|
|
43
|
+
"fonts/Caladea-Bold.ttf": abs(new URL("./fonts/Caladea-Bold.ttf", import.meta.url).href),
|
|
44
|
+
"fonts/Caladea-Italic.ttf": abs(new URL("./fonts/Caladea-Italic.ttf", import.meta.url).href),
|
|
45
|
+
"fonts/Caladea-BoldItalic.ttf": abs(new URL("./fonts/Caladea-BoldItalic.ttf", import.meta.url).href),
|
|
46
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// The metric-compatible office fonts — Liberation, Carlito, Caladea — that a
|
|
2
|
+
// native build of the engine bundles and this wasm build leaves to its host.
|
|
3
|
+
//
|
|
4
|
+
// `scripts/copy-fonts.mjs` copies them from the drawing crate into `dist/fonts/`
|
|
5
|
+
// at build time. Each `url` here is the file's path in `dist/`: `startSession`
|
|
6
|
+
// takes where `dist/` is served, or each file's own URL (`meta-url`'s
|
|
7
|
+
// `bundledFontUrls`), and offers the fonts by URL to every session it starts,
|
|
8
|
+
// so a document fetches only the faces its layout asks for. A host with no
|
|
9
|
+
// fetching offers the same files as bytes as well.
|
|
10
|
+
//
|
|
11
|
+
// Each family is registered under its own true name, never under the Microsoft
|
|
12
|
+
// font it stands in for: mapping Arial → Liberation Sans is the engine's
|
|
13
|
+
// substitute table's job.
|
|
14
|
+
/** The bold / italic variants of a family, and the suffix of each one's file. */
|
|
15
|
+
const STYLES = [
|
|
16
|
+
["Regular", false, false],
|
|
17
|
+
["Bold", true, false],
|
|
18
|
+
["Italic", false, true],
|
|
19
|
+
["BoldItalic", true, true],
|
|
20
|
+
];
|
|
21
|
+
/** Each family's true name, and the prefix of its files. */
|
|
22
|
+
const FAMILIES = [
|
|
23
|
+
["Liberation Sans", "LiberationSans"],
|
|
24
|
+
["Liberation Serif", "LiberationSerif"],
|
|
25
|
+
["Liberation Mono", "LiberationMono"],
|
|
26
|
+
["Carlito", "Carlito"],
|
|
27
|
+
["Caladea", "Caladea"],
|
|
28
|
+
];
|
|
29
|
+
/** Every face this package ships, each `url` its path in `dist/`. */
|
|
30
|
+
export const OFFICE_COMPATIBLE_FONTS = FAMILIES.flatMap(([family, file]) => STYLES.map(([style, bold, italic]) => ({
|
|
31
|
+
descriptor: { family, bold, italic },
|
|
32
|
+
url: `fonts/${file}-${style}.ttf`,
|
|
33
|
+
})));
|