gutterpress 0.11.17-alpha.2 → 0.11.17-alpha.3

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.
Files changed (49) hide show
  1. package/dist/api/index.d.ts +4 -0
  2. package/dist/api/index.js +10 -2
  3. package/dist/{build-1p999cmg.js → build-394c1ee1.js} +4 -4
  4. package/dist/checks/pdf/index.d.ts +1 -0
  5. package/dist/checks/pdf/signature.d.ts +3 -0
  6. package/dist/{cli-70xgehq2.js → cli-3p1e95zc.js} +1 -1
  7. package/dist/{cli-6z5zthzt.js → cli-9nba5ve6.js} +562 -211
  8. package/dist/{cli-ppc0vz4b.js → cli-d57bsfpb.js} +1 -1
  9. package/dist/{cli-gymfg04q.js → cli-jyy9pqf3.js} +15 -10
  10. package/dist/cli.js +12 -12
  11. package/dist/{doctor-reqpnn3h.js → doctor-c459qv5j.js} +2 -2
  12. package/dist/engine/compiler/build.d.ts +3 -2
  13. package/dist/engine/compiler/postprocess.d.ts +6 -4
  14. package/dist/engine/shared/synthesis.d.ts +29 -5
  15. package/dist/{engine-5jzhjjvv.js → engine-3xqgm82d.js} +2 -2
  16. package/dist/{engine-078ggczp.js → engine-zdb41ay1.js} +1 -1
  17. package/dist/{ext-dsbfejt3.js → ext-ha7gg8h9.js} +4 -4
  18. package/dist/{gutterpress-viewer-zkv2stfy.js → gutterpress-viewer-1n793gwd.js} +5 -3
  19. package/dist/{index-c275p061.js → index-bscfmg5r.js} +1714 -1054
  20. package/dist/{index-5dcj1vts.js → index-hrx0gfkj.js} +23 -684
  21. package/dist/index-q1xqxrh9.js +949 -0
  22. package/dist/index.js +11 -3
  23. package/dist/lib/black-text-gray.d.ts +38 -8
  24. package/dist/lib/build-fingerprint.d.ts +2 -0
  25. package/dist/lib/engine.d.ts +2 -1
  26. package/dist/lib/lint-rules.d.ts +9 -0
  27. package/dist/lib/markdown/assemble.d.ts +3 -5
  28. package/dist/lib/markdown/index.d.ts +3 -8
  29. package/dist/lib/markdown/renderer.d.ts +9 -1
  30. package/dist/lib/page-size.d.ts +66 -0
  31. package/dist/lib/pdf-inspect.d.ts +6 -0
  32. package/dist/lib/printsafe.d.ts +8 -1
  33. package/dist/lib/project-scaffold.d.ts +3 -9
  34. package/dist/lib/remote-auth/github-repos.d.ts +7 -0
  35. package/dist/lib/remote-auth/online-backup.d.ts +51 -0
  36. package/dist/lib/snippets.d.ts +3 -0
  37. package/dist/{manifest.schema-40sfq49z.json → manifest.schema-gh0jjve9.json} +14 -2
  38. package/dist/{new-m5y2wepr.js → new-kky3z7kv.js} +4 -4
  39. package/dist/{plugin.js-m4a7m3t4.tpl → plugin.js-cswq7wvd.tpl} +4 -1
  40. package/dist/{plugin.test.js-6n8ct5e3.tpl → plugin.test.js-xgxrd8hf.tpl} +4 -1
  41. package/dist/{preflight-bwpqwwny.js → preflight-t8v6szq6.js} +4 -4
  42. package/dist/preview/file-watcher.d.ts +2 -4
  43. package/dist/{preview-62y7qhkp.js → preview-cxab4y5x.js} +4 -4
  44. package/dist/{publish-k2zyt3x6.js → publish-s2mtenb5.js} +4 -4
  45. package/dist/render.js +30 -5
  46. package/dist/schema/manifest.types.d.ts +17 -0
  47. package/dist/{validate-fgwwxtbn.js → validate-xaajdw4x.js} +4 -4
  48. package/package.json +1 -1
  49. package/dist/index-eyaj6nkc.js +0 -267
package/dist/render.js CHANGED
@@ -354,7 +354,7 @@ function resolveContainerShape(name, pluginName, decl) {
354
354
  throw new Error(`Plugin "${pluginName}"'s marker "@${name}" has a \`section\` that is not a boolean.`);
355
355
  }
356
356
  if (decl.section) {
357
- for (const field of ["tag", "label", "autoCloseAt"]) {
357
+ for (const field of ["tag", "label", "autoCloseAt", "selfClosing"]) {
358
358
  if (decl[field] !== undefined) {
359
359
  throw new Error(`Plugin "${pluginName}"'s marker "@${name}" sets \`section: true\` and \`${field}\` — a section ` + `marker is a core @section, so \`${field}\` does not apply. Remove one of them.`);
360
360
  }
@@ -411,11 +411,26 @@ function resolveContainerShape(name, pluginName, decl) {
411
411
  }
412
412
  autoCloseAtEof = decl.autoCloseAt.includes("eof");
413
413
  }
414
+ if (decl.selfClosing !== undefined && typeof decl.selfClosing !== "boolean") {
415
+ throw new Error(`Plugin "${pluginName}"'s marker "@${name}" has a \`selfClosing\` that is not a boolean.`);
416
+ }
417
+ if (decl.selfClosing && decl.autoCloseAt !== undefined) {
418
+ throw new Error(`Plugin "${pluginName}"'s marker "@${name}" sets \`selfClosing: true\` and \`autoCloseAt\` — a ` + `self-closing marker has no open container to auto-close. Remove one of them.`);
419
+ }
414
420
  if (decl.validate !== undefined && typeof decl.validate !== "function") {
415
421
  throw new Error(`Plugin "${pluginName}"'s marker "@${name}" has a \`validate\` that is not a function.`);
416
422
  }
417
423
  const check = decl.validate ? { validate: decl.validate, validateOwner: pluginName } : {};
418
- return { tag, classBase, variants, label, autoCloseAtEof, ...decl.section ? { section: true } : {}, ...check };
424
+ return {
425
+ tag,
426
+ classBase,
427
+ variants,
428
+ label,
429
+ autoCloseAtEof,
430
+ ...decl.section ? { section: true } : {},
431
+ ...decl.selfClosing ? { selfClosing: true } : {},
432
+ ...check
433
+ };
419
434
  }
420
435
  function resolveMarkerDeclaration(name, rawDecl, rawRegistry, originOf) {
421
436
  const pluginName = originOf.get(name);
@@ -674,7 +689,8 @@ function plugin(md, pluginOptions = {}) {
674
689
  addClasses(t, baseClass, meta.attrs && meta.attrs.class ? meta.attrs.class : "");
675
690
  attachDataAttrs(t, decl.baseKind, variant, meta.attrs || {});
676
691
  out.push(t);
677
- declaredFrames.push({ kind: decl.baseKind, tag: decl.tag, decl, line: meta.__line });
692
+ if (!decl.selfClosing)
693
+ declaredFrames.push({ kind: decl.baseKind, tag: decl.tag, decl, line: meta.__line });
678
694
  if (decl.label) {
679
695
  const value = meta.attrs && meta.attrs[decl.label.attr];
680
696
  if (value) {
@@ -685,6 +701,8 @@ function plugin(md, pluginOptions = {}) {
685
701
  t.meta.labelled = true;
686
702
  }
687
703
  }
704
+ if (decl.selfClosing)
705
+ out.push(new state.Token("layout_component_close", decl.tag, -1));
688
706
  }
689
707
  const stack = {
690
708
  frames: [],
@@ -963,7 +981,7 @@ function plugin(md, pluginOptions = {}) {
963
981
  continue;
964
982
  }
965
983
  if (!closeDeclaredFrame(closeDecl.baseKind)) {
966
- warn(state.env, line, "declared_marker_close_without_open", `@${kind} used without an open @${closeDecl.baseKind}; ignoring marker.`, meta);
984
+ warn(state.env, line, "declared_marker_close_without_open", closeDecl.selfClosing ? `@${kind} is not a marker: @${closeDecl.baseKind} is self-closing and has nothing to close; ignoring marker.` : `@${kind} used without an open @${closeDecl.baseKind}; ignoring marker.`, meta);
967
985
  }
968
986
  continue;
969
987
  }
@@ -2077,6 +2095,12 @@ function collectPluginCss(plugins) {
2077
2095
  `);
2078
2096
  }
2079
2097
 
2098
+ // src/engine/shared/synthesis.ts
2099
+ function lastPageMode(print) {
2100
+ return print.lastPage ?? (print.reserveLastPage ? "blank" : undefined);
2101
+ }
2102
+ var WHICH_VALUES = new Set(["first", "start", "last", "first-except"]);
2103
+
2080
2104
  // src/lib/markdown/assemble.ts
2081
2105
  async function assembleBookHtml(opts) {
2082
2106
  const title = opts.title ?? "Document";
@@ -2134,7 +2158,8 @@ ${projectCss.trim()}` : null
2134
2158
  `);
2135
2159
  const preloadTags = (opts.preloadImages ?? []).map((href) => `
2136
2160
  <link rel="preload" as="image" href="${href}">`).join("");
2137
- const printAttrs = (opts.print?.signature && opts.print.signature > 1 ? ` data-gp-signature="${opts.print.signature}"` : "") + (opts.print?.reserveLastPage ? " data-gp-reserve-last-page" : "");
2161
+ const lastPage = opts.print && lastPageMode(opts.print);
2162
+ const printAttrs = (opts.print?.signature && opts.print.signature > 1 ? ` data-gp-signature="${opts.print.signature}"` : "") + (lastPage ? ` data-gp-last-page="${lastPage}"` : "");
2138
2163
  return `<!DOCTYPE html>
2139
2164
  <html lang="en"${printAttrs}>
2140
2165
  <head>
@@ -1,3 +1,4 @@
1
+ import type { LastPageMode } from "../engine/shared/synthesis";
1
2
  type CheckSeverity = "error" | "warning" | "info";
2
3
  /**
3
4
  * The object form of an `extensions:` entry (#265) — only for an entry that
@@ -132,6 +133,14 @@ export interface GutterpressManifest {
132
133
  * DriveThruRPG reserve the last page for printer info.
133
134
  */
134
135
  reserveLastPage?: boolean;
136
+ /**
137
+ * What the interior's last page is for a printer that reserves it:
138
+ * `blank` (an empty page the build adds — what `reserveLastPage: true`
139
+ * means) or `short-by-one` (one page short of a multiple of `signature`,
140
+ * the printer supplies the last page). When set it wins over
141
+ * `reserveLastPage`.
142
+ */
143
+ lastPage?: LastPageMode;
135
144
  };
136
145
  page?: {
137
146
  width?: number;
@@ -145,6 +154,12 @@ export interface GutterpressManifest {
145
154
  lint?: {
146
155
  enabled?: boolean;
147
156
  configPath?: string | null;
157
+ /**
158
+ * Per-rule level overrides, keyed by rule id (`printsafe/*`, or a check id
159
+ * such as `source.accessibility.heading-order`). `off` silences the rule;
160
+ * `warn` / `error` set its severity. Unknown ids are ignored.
161
+ */
162
+ rules?: Record<string, "off" | "warn" | "error">;
148
163
  };
149
164
  validate?: {
150
165
  enabled?: boolean;
@@ -240,6 +255,7 @@ export interface ResolvedConfig {
240
255
  print: {
241
256
  signature: number;
242
257
  reserveLastPage: boolean;
258
+ lastPage?: LastPageMode;
243
259
  };
244
260
  page: {
245
261
  width: number;
@@ -253,6 +269,7 @@ export interface ResolvedConfig {
253
269
  lint: {
254
270
  enabled: boolean;
255
271
  configPath: string | null;
272
+ rules: Record<string, "off" | "warn" | "error">;
256
273
  };
257
274
  validate: {
258
275
  enabled: boolean;
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  executeAndReport
3
- } from "./cli-6z5zthzt.js";
3
+ } from "./cli-9nba5ve6.js";
4
4
  import {
5
5
  log
6
- } from "./cli-70xgehq2.js";
6
+ } from "./cli-3p1e95zc.js";
7
7
  import {
8
8
  UsageError,
9
9
  rejectExtraPositionals,
10
10
  rejectUnknownFlags
11
- } from "./cli-ppc0vz4b.js";
12
- import"./cli-gymfg04q.js";
11
+ } from "./cli-d57bsfpb.js";
12
+ import"./cli-jyy9pqf3.js";
13
13
  import {
14
14
  BuildError,
15
15
  EXIT_CODES
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gutterpress",
3
- "version": "0.11.17-alpha.2",
3
+ "version": "0.11.17-alpha.3",
4
4
  "description": "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
5
5
  "author": "itlackey",
6
6
  "license": "MPL-2.0",
@@ -1,267 +0,0 @@
1
- // src/lib/build-error.ts
2
- var EXIT_CODES = {
3
- OK: 0,
4
- FINDINGS: 1,
5
- USAGE: 2,
6
- PIPELINE: 3
7
- };
8
-
9
- class BuildError extends Error {
10
- exitCode;
11
- constructor(message, exitCode = EXIT_CODES.PIPELINE, options) {
12
- super(message, options);
13
- this.name = "BuildError";
14
- this.exitCode = exitCode;
15
- }
16
- }
17
-
18
- // src/lib/embedded-assets.ts
19
- import { existsSync } from "node:fs";
20
- import { mkdtemp, mkdir, writeFile, readFile } from "node:fs/promises";
21
- import { tmpdir } from "node:os";
22
- import { dirname, join, resolve } from "node:path";
23
- import { fileURLToPath } from "node:url";
24
-
25
- // src/assets/favicon.ico
26
- var favicon_default = "./favicon-wkbm9cjn.ico";
27
-
28
- // src/assets/manifest.schema.json
29
- var manifest_schema_default = "./manifest.schema-40sfq49z.json";
30
-
31
- // src/assets/preview/scripts/preview-interface.js
32
- var preview_interface_default = "./preview-interface-c44qk17f.js";
33
-
34
- // src/assets/preview/scripts/preview-bridge.js
35
- var preview_bridge_default = "./preview-bridge-8jhd1wpb.js";
36
-
37
- // src/assets/preview/scripts/preview-shell.js
38
- var preview_shell_default = "./preview-shell-xwn84kqr.js";
39
-
40
- // profiles/CGATS21_CRPC1.icc
41
- var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
42
-
43
- // src/assets/engine/gutterpress-viewer.js
44
- var gutterpress_viewer_default = "./gutterpress-viewer-zkv2stfy.js";
45
-
46
- // src/assets/engine/gutterpress-agent.js
47
- var gutterpress_agent_default = "./gutterpress-agent-cazqstr1.js";
48
-
49
- // src/assets/templates/book/manifest.yaml
50
- var manifest_default = "./manifest-n1gh3qw5.yaml";
51
-
52
- // src/assets/templates/book/chapter-01.md
53
- var chapter_01_default = "./chapter-01-rkpyvjna.md";
54
-
55
- // src/assets/templates/zine/manifest.yaml
56
- var manifest_default2 = "./manifest-n1gh3qw5.yaml";
57
-
58
- // src/assets/templates/zine/chapter-01.md
59
- var chapter_01_default2 = "./chapter-01-7jwqg1ct.md";
60
-
61
- // src/assets/templates/technical/manifest.yaml
62
- var manifest_default3 = "./manifest-n1gh3qw5.yaml";
63
-
64
- // src/assets/templates/technical/chapter-01.md
65
- var chapter_01_default3 = "./chapter-01-6fn9pvd0.md";
66
-
67
- // src/assets/extension-templates/plugin/package.json
68
- var package_default = "./package-9rv69pxm.json";
69
-
70
- // src/assets/extension-templates/plugin/README.md
71
- var README_default = "./README-vsnsc1b3.md";
72
-
73
- // src/assets/extension-templates/plugin/plugin.js.tpl
74
- var plugin_js_default = "./plugin.js-m4a7m3t4.tpl";
75
-
76
- // src/assets/extension-templates/plugin/styles/plugin.css
77
- var plugin_default = "./plugin-spbcem4j.css";
78
-
79
- // src/assets/extension-templates/plugin/snippets/term-box.md
80
- var term_box_default = "./term-box-4y0w7y32.md";
81
-
82
- // src/assets/extension-templates/plugin/test/fixture.md
83
- var fixture_default = "./fixture-2qnyqgb5.md";
84
-
85
- // src/assets/extension-templates/plugin/test/expected.html
86
- var expected_default = "./expected-ycmacem8.html";
87
-
88
- // src/assets/extension-templates/plugin/test/plugin.test.js.tpl
89
- var plugin_test_js_default = "./plugin.test.js-6n8ct5e3.tpl";
90
-
91
- // src/assets/extension-templates/theme/package.json
92
- var package_default2 = "./package-aenwjew3.json";
93
-
94
- // src/assets/extension-templates/theme/README.md
95
- var README_default2 = "./README-3nj919rm.md";
96
-
97
- // src/assets/extension-templates/theme/components.yaml
98
- var components_default = "./components-dhgv2sm7.yaml";
99
-
100
- // src/assets/extension-templates/theme/snippets/callout.md
101
- var callout_default = "./callout-hv56m16h.md";
102
-
103
- // src/assets/extension-templates/theme/styles/tokens.css
104
- var tokens_default = "./tokens-7984461t.css";
105
-
106
- // src/assets/extension-templates/theme/styles/base.css
107
- var base_default = "./base-ypqh9n7f.css";
108
-
109
- // src/assets/extension-templates/theme/styles/components.css
110
- var components_default2 = "./components-aam0fe2z.css";
111
-
112
- // src/assets/extension-templates/theme/styles/page-templates.css
113
- var page_templates_default = "./page-templates-7md4ev7d.css";
114
-
115
- // src/assets/extension-templates/theme/styles/page-rules.css
116
- var page_rules_default = "./page-rules-nsj3aw42.css";
117
-
118
- // src/assets/extension-templates/theme/styles/book.css
119
- var book_default = "./book-ted3tzrp.css";
120
-
121
- // src/assets/themes/clean-book/theme.css
122
- var theme_default = "./theme-j2bagrfx.css";
123
-
124
- // src/assets/themes/clean-book/package.json
125
- var package_default3 = "./package-97gm31sg.json";
126
-
127
- // src/assets/themes/zine/theme.css
128
- var theme_default2 = "./theme-h5recz6c.css";
129
-
130
- // src/assets/themes/zine/package.json
131
- var package_default4 = "./package-gag6ykwn.json";
132
-
133
- // src/assets/themes/technical-doc/theme.css
134
- var theme_default3 = "./theme-nn6d53zy.css";
135
-
136
- // src/assets/themes/technical-doc/package.json
137
- var package_default5 = "./package-nrhkwf2m.json";
138
-
139
- // src/lib/embedded-assets.ts
140
- var __libdir = dirname(fileURLToPath(import.meta.url));
141
- var abs = (p) => resolve(__libdir, p);
142
- var filePath = (v) => v;
143
- var EMBEDDED_ASSETS = {
144
- "favicon.ico": abs(favicon_default),
145
- "manifest.schema.json": abs(filePath(manifest_schema_default)),
146
- "preview/scripts/preview-interface.js": abs(filePath(preview_interface_default)),
147
- "preview/scripts/preview-bridge.js": abs(filePath(preview_bridge_default)),
148
- "preview/scripts/preview-shell.js": abs(filePath(preview_shell_default)),
149
- "profiles/CGATS21_CRPC1.icc": abs(filePath(CGATS21_CRPC1_default)),
150
- "engine/gutterpress-viewer.js": abs(filePath(gutterpress_viewer_default)),
151
- "engine/gutterpress-agent.js": abs(filePath(gutterpress_agent_default)),
152
- "templates/book/manifest.yaml": abs(filePath(manifest_default)),
153
- "templates/book/chapter-01.md": abs(filePath(chapter_01_default)),
154
- "templates/zine/manifest.yaml": abs(filePath(manifest_default2)),
155
- "templates/zine/chapter-01.md": abs(filePath(chapter_01_default2)),
156
- "templates/technical/manifest.yaml": abs(filePath(manifest_default3)),
157
- "templates/technical/chapter-01.md": abs(filePath(chapter_01_default3)),
158
- "extension-templates/plugin/package.json": abs(filePath(package_default)),
159
- "extension-templates/plugin/README.md": abs(filePath(README_default)),
160
- "extension-templates/plugin/plugin.js.tpl": abs(filePath(plugin_js_default)),
161
- "extension-templates/plugin/styles/plugin.css": abs(filePath(plugin_default)),
162
- "extension-templates/plugin/snippets/term-box.md": abs(filePath(term_box_default)),
163
- "extension-templates/plugin/test/fixture.md": abs(filePath(fixture_default)),
164
- "extension-templates/plugin/test/expected.html": abs(filePath(expected_default)),
165
- "extension-templates/plugin/test/plugin.test.js.tpl": abs(filePath(plugin_test_js_default)),
166
- "extension-templates/theme/package.json": abs(filePath(package_default2)),
167
- "extension-templates/theme/README.md": abs(filePath(README_default2)),
168
- "extension-templates/theme/components.yaml": abs(filePath(components_default)),
169
- "extension-templates/theme/snippets/callout.md": abs(filePath(callout_default)),
170
- "extension-templates/theme/styles/tokens.css": abs(filePath(tokens_default)),
171
- "extension-templates/theme/styles/base.css": abs(filePath(base_default)),
172
- "extension-templates/theme/styles/components.css": abs(filePath(components_default2)),
173
- "extension-templates/theme/styles/page-templates.css": abs(filePath(page_templates_default)),
174
- "extension-templates/theme/styles/page-rules.css": abs(filePath(page_rules_default)),
175
- "extension-templates/theme/styles/book.css": abs(filePath(book_default)),
176
- "themes/clean-book/theme.css": abs(filePath(theme_default)),
177
- "themes/clean-book/package.json": abs(filePath(package_default3)),
178
- "themes/zine/theme.css": abs(filePath(theme_default2)),
179
- "themes/zine/package.json": abs(filePath(package_default4)),
180
- "themes/technical-doc/theme.css": abs(filePath(theme_default3)),
181
- "themes/technical-doc/package.json": abs(filePath(package_default5))
182
- };
183
- var extractPromise = null;
184
- async function extractAssets() {
185
- const root = await mkdtemp(join(tmpdir(), "gutterpress-assets-"));
186
- for (const [relPath, srcPath] of Object.entries(EMBEDDED_ASSETS)) {
187
- const dest = join(root, relPath);
188
- await mkdir(dirname(dest), { recursive: true });
189
- const bytes = await readFile(srcPath);
190
- await writeFile(dest, bytes);
191
- }
192
- return root;
193
- }
194
- var SENTINEL_ASSET = "engine/gutterpress-viewer.js";
195
- async function getAssetsDir() {
196
- if (extractPromise) {
197
- try {
198
- const root = await extractPromise;
199
- if (existsSync(join(root, SENTINEL_ASSET))) {
200
- return root;
201
- }
202
- } catch {}
203
- extractPromise = null;
204
- }
205
- extractPromise = extractAssets();
206
- return extractPromise;
207
- }
208
- async function getAssetPath(relPath) {
209
- const root = await getAssetsDir();
210
- return join(root, relPath);
211
- }
212
-
213
- // src/engine/shared/margin-box-support.ts
214
- var MARGIN_BOX_IGNORED_PROPERTIES = new Set([
215
- "transform",
216
- "rotate",
217
- "translate",
218
- "scale",
219
- "perspective",
220
- "box-shadow",
221
- "opacity",
222
- "outline",
223
- "outline-color",
224
- "outline-style",
225
- "outline-width",
226
- "outline-offset",
227
- "filter",
228
- "backdrop-filter",
229
- "mix-blend-mode",
230
- "clip-path"
231
- ]);
232
- function isIgnoredMarginBoxProperty(property) {
233
- return MARGIN_BOX_IGNORED_PROPERTIES.has(property.toLowerCase());
234
- }
235
- function marginBoxRectPt(name, g) {
236
- const { top, right, bottom, left } = g.margin;
237
- const cw = g.width - left - right;
238
- const ch = g.height - top - bottom;
239
- const third = (n) => n / 3;
240
- const T = {
241
- "top-left-corner": [0, 0, left, top],
242
- "top-left": [left, 0, third(cw), top],
243
- "top-center": [left + third(cw), 0, third(cw), top],
244
- "top-right": [left + 2 * third(cw), 0, third(cw), top],
245
- "top-right-corner": [g.width - right, 0, right, top],
246
- "bottom-left-corner": [0, g.height - bottom, left, bottom],
247
- "bottom-left": [left, g.height - bottom, third(cw), bottom],
248
- "bottom-center": [left + third(cw), g.height - bottom, third(cw), bottom],
249
- "bottom-right": [left + 2 * third(cw), g.height - bottom, third(cw), bottom],
250
- "bottom-right-corner": [g.width - right, g.height - bottom, right, bottom],
251
- "left-top": [0, top, left, third(ch)],
252
- "left-middle": [0, top + third(ch), left, third(ch)],
253
- "left-bottom": [0, top + 2 * third(ch), left, third(ch)],
254
- "right-top": [g.width - right, top, right, third(ch)],
255
- "right-middle": [g.width - right, top + third(ch), right, third(ch)],
256
- "right-bottom": [g.width - right, top + 2 * third(ch), right, third(ch)]
257
- };
258
- const [x, y, w, h] = T[name] ?? [0, 0, 0, 0];
259
- return { x, y, w, h };
260
- }
261
- function marginBoxAlign(name) {
262
- if (name.includes("center") || name.includes("middle"))
263
- return "center";
264
- return /right/.test(name) ? "end" : "start";
265
- }
266
-
267
- export { EXIT_CODES, BuildError, getAssetsDir, getAssetPath, MARGIN_BOX_IGNORED_PROPERTIES, isIgnoredMarginBoxProperty, marginBoxRectPt, marginBoxAlign };