gutterpress 0.11.23-alpha.2 → 0.11.23-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 (55) hide show
  1. package/README.md +6 -7
  2. package/dist/{README-8ef336pp.md → README-8db7btxb.md} +13 -19
  3. package/dist/api/index.d.ts +1 -1
  4. package/dist/api/index.js +4 -4
  5. package/dist/{build-encgnv0c.js → build-m78jcpf7.js} +7 -7
  6. package/dist/{cli-xq6djqbj.js → cli-1h17ktsg.js} +84 -113
  7. package/dist/{cli-kh8v4vvw.js → cli-5jzyw06s.js} +1 -1
  8. package/dist/{cli-sdmv4bba.js → cli-h4x81x97.js} +112 -8
  9. package/dist/{cli-evg8sbht.js → cli-n2tsxqpn.js} +1 -1
  10. package/dist/{cli-aqh6brew.js → cli-s6djx4ma.js} +1 -1
  11. package/dist/{cli-pwwfxdgb.js → cli-t8be9yeb.js} +9 -20
  12. package/dist/{cli-pz4bn98t.js → cli-xsrffqzt.js} +19 -13
  13. package/dist/cli.js +12 -12
  14. package/dist/{doctor-5gtpgpd1.js → doctor-j71jqce3.js} +3 -3
  15. package/dist/engine/shared/gcpm-extract.d.ts +8 -0
  16. package/dist/engine/shared/print-area.d.ts +16 -4
  17. package/dist/{engine-tn13gk0b.js → engine-1r6q80tq.js} +2 -2
  18. package/dist/{engine-mc5br8g8.js → engine-m4y10shc.js} +1 -1
  19. package/dist/{ext-wn2a5afq.js → ext-fq2hg9va.js} +7 -7
  20. package/dist/{extension-restore-s3x1618g.js → extension-restore-9dh7c4tp.js} +2 -2
  21. package/dist/{extension-restore-g8jnmmzq.js → extension-restore-tmxtzkm0.js} +4 -4
  22. package/dist/{gutterpress-viewer-701vf4qp.js → gutterpress-viewer-mafsby5k.js} +9 -2
  23. package/dist/{index-2bjcghze.js → index-0wee4408.js} +9 -20
  24. package/dist/{index-x3ema2w3.js → index-7pck1q9c.js} +124 -17
  25. package/dist/{index-0skhjx3e.js → index-nedd07bk.js} +19 -13
  26. package/dist/{index-4x6y8krm.js → index-nvmf22rt.js} +1 -1
  27. package/dist/{index-j5z86r4a.js → index-prqvz3xm.js} +213 -276
  28. package/dist/index.js +5 -5
  29. package/dist/lib/extension-manager.d.ts +8 -7
  30. package/dist/lib/extension-manifest.d.ts +1 -13
  31. package/dist/lib/manifest.d.ts +15 -1
  32. package/dist/lib/markdown/assemble.d.ts +4 -3
  33. package/dist/lib/page-size.d.ts +34 -27
  34. package/dist/lib/printsafe.d.ts +1 -0
  35. package/dist/lib/project-templates.d.ts +9 -0
  36. package/dist/manifest-8afhrk30.yaml +19 -0
  37. package/dist/manifest-d4f9q79e.yaml +23 -0
  38. package/dist/{manifest-eagfhba6.yaml → manifest-gf13sjp8.yaml} +10 -2
  39. package/dist/manifest-my7mdv8j.yaml +23 -0
  40. package/dist/{manifest.schema-t7nx2stg.json → manifest.schema-650pe0d1.json} +15 -3
  41. package/dist/{new-mhs46pw3.js → new-s4zcaepg.js} +7 -7
  42. package/dist/{package-aenwjew3.json → package-awwkt7sa.json} +0 -1
  43. package/dist/{page-rules-nsj3aw42.css → page-rules-fj09xct5.css} +12 -40
  44. package/dist/{plugin.test.js-xgxrd8hf.tpl → plugin.test.js-gxzqqfdh.tpl} +0 -1
  45. package/dist/{plugins-1sxe0dkz.js → plugins-4vaf27n9.js} +3 -3
  46. package/dist/{plugins-2cek4mz1.js → plugins-80emnf31.js} +1 -1
  47. package/dist/{preflight-3k2b1x8e.js → preflight-c7w1xdn3.js} +7 -7
  48. package/dist/{preview-6p9v6rht.js → preview-mzytcwyk.js} +7 -7
  49. package/dist/{publish-qgsngy8s.js → publish-fez14ad4.js} +7 -7
  50. package/dist/render.js +24 -561
  51. package/dist/schema/manifest.types.d.ts +22 -0
  52. package/dist/{tokens-7984461t.css → tokens-ye64p899.css} +5 -12
  53. package/dist/{validate-0v7xw6wa.js → validate-p2chr6hr.js} +7 -7
  54. package/package.json +1 -1
  55. package/dist/manifest-n1gh3qw5.yaml +0 -9
@@ -368,7 +368,8 @@
368
368
  mediaPrintBodies: () => mediaPrintBodies,
369
369
  extract: () => extract,
370
370
  PAGE_SIZES: () => PAGE_SIZES,
371
- MARGIN_BOX_NAMES: () => MARGIN_BOX_NAMES
371
+ MARGIN_BOX_NAMES: () => MARGIN_BOX_NAMES,
372
+ DEFAULT_PAGE_MARGIN_PT: () => DEFAULT_PAGE_MARGIN_PT
372
373
  });
373
374
  var MARGIN_BOX_NAMES = [
374
375
  "top-left-corner",
@@ -923,12 +924,18 @@
923
924
  const d = parts[3] ?? b;
924
925
  return { top: a, right: b, bottom: c, left: d };
925
926
  }
927
+ var DEFAULT_PAGE_MARGIN_PT = 72;
926
928
  function resolvePage(model, ctx = {}) {
927
929
  const wanted = new Set(ctx.pseudos ?? []);
928
930
  const applicable = model.pageRules.filter((r) => r.name ? r.name === ctx.name : true).filter((r) => r.pseudos.every((p) => wanted.has(p))).sort((a, b) => specificity(a) - specificity(b));
929
931
  const decls = {};
930
932
  const marginBoxes = {};
931
- const margin = { top: 72, right: 72, bottom: 72, left: 72 };
933
+ const margin = {
934
+ top: DEFAULT_PAGE_MARGIN_PT,
935
+ right: DEFAULT_PAGE_MARGIN_PT,
936
+ bottom: DEFAULT_PAGE_MARGIN_PT,
937
+ left: DEFAULT_PAGE_MARGIN_PT
938
+ };
932
939
  for (const rule of applicable) {
933
940
  for (const [prop, value] of Object.entries(rule.decls)) {
934
941
  if (prop === "margin")
@@ -20,6 +20,7 @@ import { pathToFileURL } from "node:url";
20
20
  var theme_default = `/* =============================================================================
21
21
  Clean Book — gutterpress built-in theme (theme.css)
22
22
  A calm, classic long-form book look. Change the :root tokens from the book's own stylesheet.
23
+ The page SIZE comes from the manifest (Setup > Details), so it is deliberately not set here.
23
24
  ============================================================================= */
24
25
 
25
26
  :root {
@@ -38,11 +39,7 @@ var theme_default = `/* ========================================================
38
39
  --fs-h2: 1.5rem;
39
40
  --fs-h3: 1.2rem;
40
41
  --leading: 1.55;
41
- }
42
42
 
43
- @page {
44
- size: 6in 9in;
45
- margin: 0.85in 0.75in;
46
43
  }
47
44
 
48
45
  body {
@@ -82,6 +79,7 @@ hr { border: 0; border-top: 1px solid var(--color-rule); margin: 1.5em 0; }
82
79
  var theme_default2 = `/* =============================================================================
83
80
  Zine — gutterpress built-in theme (theme.css)
84
81
  High-contrast, punchy, photocopier-friendly. Change the :root tokens from the book's own stylesheet.
82
+ The page SIZE comes from the manifest (Setup > Details), so it is deliberately not set here.
85
83
  ============================================================================= */
86
84
 
87
85
  :root {
@@ -100,11 +98,7 @@ var theme_default2 = `/* =======================================================
100
98
  --fs-h2: 1.8rem;
101
99
  --fs-h3: 1.3rem;
102
100
  --leading: 1.4;
103
- }
104
101
 
105
- @page {
106
- size: 5.5in 8.5in;
107
- margin: 0.4in;
108
102
  }
109
103
 
110
104
  body {
@@ -146,6 +140,7 @@ code, pre { font-family: var(--font-mono); font-size: 0.95em; }
146
140
  var theme_default3 = `/* =============================================================================
147
141
  Technical Document — gutterpress built-in theme (theme.css)
148
142
  Clean sans-serif manual look with clear hierarchy. Change the :root tokens from the book's own stylesheet.
143
+ The page SIZE comes from the manifest (Setup > Details), so it is deliberately not set here.
149
144
  ============================================================================= */
150
145
 
151
146
  :root {
@@ -153,6 +148,7 @@ var theme_default3 = `/* =======================================================
153
148
  --color-ink-muted: #5a5f66; /* captions, secondary text */
154
149
  --color-accent: #0b5fff; /* headings, links */
155
150
  --color-paper: #ffffff; /* page background */
151
+ /* @label Note and code background */
156
152
  --color-tint: #f3f5f9; /* code / note fill */
157
153
  --color-rule: #d6dae0; /* borders, rules */
158
154
 
@@ -165,11 +161,7 @@ var theme_default3 = `/* =======================================================
165
161
  --fs-h2: 1.45rem;
166
162
  --fs-h3: 1.15rem;
167
163
  --leading: 1.5;
168
- }
169
164
 
170
- @page {
171
- size: 8.5in 11in;
172
- margin: 0.9in 1in;
173
165
  }
174
166
 
175
167
  body {
@@ -242,10 +234,10 @@ var theme_default4 = `/* =======================================================
242
234
  --fs-h2: 1.2em;
243
235
  --fs-h3: 1em;
244
236
  --leading: 1.38;
237
+
245
238
  }
246
239
 
247
240
  @page {
248
- margin: 1in;
249
241
  @bottom-center { content: counter(page); font-family: var(--font-body); font-size: 9pt; }
250
242
  }
251
243
 
@@ -406,7 +398,7 @@ import { satisfies, validRange } from "semver";
406
398
  // package.json
407
399
  var package_default = {
408
400
  name: "gutterpress",
409
- version: "0.11.23-alpha.2",
401
+ version: "0.11.23-alpha.3",
410
402
  description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
411
403
  author: "itlackey",
412
404
  license: "MPL-2.0",
@@ -541,7 +533,6 @@ function metaFromPackageJson(raw) {
541
533
  ...str(object(pkg.engines)?.gutterpress) ? { gutterpressRange: str(object(pkg.engines)?.gutterpress) } : {},
542
534
  ..."preview" in gp ? { preview: str(gp.preview) ?? null } : {},
543
535
  ...Array.isArray(gp.styles) ? { styles: declaredList(gp.styles) } : {},
544
- ...str(gp.tokensFile) ? { tokensFile: str(gp.tokensFile) } : {},
545
536
  ...str(gp.markdown) ? { markdown: str(gp.markdown) } : {},
546
537
  ...str(gp.components) ? { components: str(gp.components) } : {},
547
538
  ...str(gp.snippets) ? { snippets: str(gp.snippets) } : {},
@@ -607,8 +598,7 @@ function assertExtensionContained(meta) {
607
598
  ...entry ? [entry] : [],
608
599
  ...meta.publish && meta.main?.trim() ? [meta.main.trim()] : [],
609
600
  ...meta.components ? [meta.components] : [],
610
- ...meta.snippets ? [meta.snippets] : [],
611
- ...meta.tokensFile ? [meta.tokensFile] : []
601
+ ...meta.snippets ? [meta.snippets] : []
612
602
  ];
613
603
  for (const rel of declared) {
614
604
  if (pathEscapesFolder(rel)) {
@@ -625,7 +615,6 @@ function resolveExtension(dir, meta, subject) {
625
615
  return {
626
616
  ...markdown ? { markdown } : {},
627
617
  ...styles ? { styles } : {},
628
- ...meta.tokensFile?.trim() ? { tokensFile: meta.tokensFile.trim() } : {},
629
618
  ...components ? { components } : {},
630
619
  ...snippets ? { snippets } : {}
631
620
  };
@@ -3753,9 +3742,9 @@ async function loadNpmPackage(packageName, baseDir, version) {
3753
3742
  const looksLikeJsFilename = /\.(m?js|cjs)$/i.test(packageName);
3754
3743
  const suggestedPath = looksLikeJsFilename ? `./${packageName}` : `./plugins/${packageName}.js`;
3755
3744
  if (!looksLikeJsFilename && (!version || !isExactNpmVersion(version))) {
3756
- throw new Error(`Extension "${packageName}${version ? `@${version}` : ""}" is not pinned to an exact version, so it can't be downloaded automatically. Run \`gutterpress ext add ${packageName}\` (or use Book settings > Features in the desktop app) to download it and pin its version in your manifest.`);
3745
+ throw new Error(`Extension "${packageName}${version ? `@${version}` : ""}" is not pinned to an exact version, so it can't be downloaded automatically. Run \`gutterpress ext add ${packageName}\` (or use Book setup > Looks & features > Advanced in the desktop app) to download it and pin its version in your manifest.`);
3757
3746
  }
3758
- throw new Error(`Extension "${packageName}" not found. Install it with \`gutterpress ext add ${version ? `${packageName}@${version}` : packageName}\` (or Book settings > Features > Advanced in the desktop app),
3747
+ throw new Error(`Extension "${packageName}" not found. Install it with \`gutterpress ext add ${version ? `${packageName}@${version}` : packageName}\` (or Book setup > Looks & features > Advanced in the desktop app),
3759
3748
  or reference a local file under \`extensions:\`:
3760
3749
  extensions:
3761
3750
  - ${suggestedPath}`);
@@ -14,7 +14,7 @@ import {
14
14
  readExtensionMeta,
15
15
  resolveExtension,
16
16
  slugify
17
- } from "./index-2bjcghze.js";
17
+ } from "./index-0wee4408.js";
18
18
  import {
19
19
  BuildError,
20
20
  EXIT_CODES
@@ -91,6 +91,87 @@ import { existsSync, statSync } from "node:fs";
91
91
  import { resolve, dirname } from "node:path";
92
92
  import { parse as parseYaml, YAMLParseError } from "yaml";
93
93
 
94
+ // src/engine/shared/print-area.ts
95
+ function isPositivePoints(value) {
96
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
97
+ }
98
+ function isNonNegativePoints(value) {
99
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
100
+ }
101
+ var round3 = (n) => Math.round(n * 1000) / 1000;
102
+ function cssLength(pt) {
103
+ const inches = round3(pt / 72);
104
+ return Math.abs(inches * 72 - pt) < 0.000001 ? `${inches}in` : `${round3(pt)}pt`;
105
+ }
106
+ function formatPageSize(page) {
107
+ return `${cssLength(page.width)} ${cssLength(page.height)}`;
108
+ }
109
+ function printAreaMeta(page) {
110
+ const area = JSON.stringify({
111
+ width: page.width,
112
+ height: page.height,
113
+ bleed: page.bleed ?? 0,
114
+ safe: page.safe ?? 0,
115
+ artSafe: page.artSafe,
116
+ gutter: page.gutter,
117
+ preset: page.preset,
118
+ spec: page.spec
119
+ });
120
+ return `<meta name="gp-print-area" content='${area.replace(/&/g, "&amp;").replace(/'/g, "&#39;")}'>`;
121
+ }
122
+ function pageBoxes(area, side, scale = 1) {
123
+ const w = area.width * scale;
124
+ const h = area.height * scale;
125
+ const b = Math.max(0, area.bleed) * scale;
126
+ const s = Math.max(0, area.safe) * scale;
127
+ const a = Math.max(0, area.artSafe) * scale;
128
+ const g = Math.max(0, area.gutter) * scale;
129
+ const [textLeft, textRight] = side === "verso" ? [s, g] : [g, s];
130
+ const [artLeft, artRight] = side === "verso" ? [a, g] : [g, a];
131
+ const trim = { x: side === "verso" ? b : 0, y: b, w: Math.max(0, w - b), h: Math.max(0, h - 2 * b) };
132
+ return {
133
+ sheet: { x: 0, y: 0, w, h },
134
+ trim,
135
+ safe: {
136
+ x: trim.x + textLeft,
137
+ y: trim.y + s,
138
+ w: Math.max(0, trim.w - textLeft - textRight),
139
+ h: Math.max(0, trim.h - 2 * s)
140
+ },
141
+ safeArt: {
142
+ x: trim.x + artLeft,
143
+ y: trim.y + a,
144
+ w: Math.max(0, trim.w - artLeft - artRight),
145
+ h: Math.max(0, trim.h - 2 * a)
146
+ },
147
+ bleed: b
148
+ };
149
+ }
150
+ var SEVERITY = { inside: 0, unsafe: 1, bleed: 2, "off-page": 3 };
151
+ function judgeRect(r, boxes, rule, tol = 0) {
152
+ const { sheet, trim } = boxes;
153
+ const safe = rule === "art" ? boxes.safeArt : boxes.safe;
154
+ const sides = [
155
+ ["left", -r.x, -safe.x, -trim.x, -sheet.x],
156
+ ["right", r.x + r.w, safe.x + safe.w, trim.x + trim.w, sheet.x + sheet.w],
157
+ ["top", -r.y, -safe.y, -trim.y, -sheet.y],
158
+ ["bottom", r.y + r.h, safe.y + safe.h, trim.y + trim.h, sheet.y + sheet.h]
159
+ ];
160
+ let worst = { kind: "inside", gap: 0, need: 0, edge: null };
161
+ let beyond = 0;
162
+ for (const [edge, ink, limit, trimEdge, sheetEdge] of sides) {
163
+ const past = ink - limit;
164
+ if (past <= tol || rule === "art" && ink >= sheetEdge - tol)
165
+ continue;
166
+ const kind = ink > sheetEdge + tol ? "off-page" : ink > trimEdge + tol ? "bleed" : "unsafe";
167
+ if (SEVERITY[kind] > SEVERITY[worst.kind] || kind === worst.kind && past > beyond) {
168
+ worst = { kind, gap: trimEdge - ink, need: trimEdge - limit, edge };
169
+ beyond = past;
170
+ }
171
+ }
172
+ return worst;
173
+ }
174
+
94
175
  // src/constants.ts
95
176
  var NETWORK = {
96
177
  DEFAULT_PORT: 3579
@@ -151,7 +232,8 @@ var DTRPG_PRESET = {
151
232
  bleed: 9,
152
233
  safe: 36,
153
234
  artSafe: 18,
154
- gutter: 36
235
+ gutter: 36,
236
+ margin: undefined
155
237
  },
156
238
  ink: {
157
239
  maxTac: 240,
@@ -237,7 +319,8 @@ var BOOK_PRESET = {
237
319
  bleed: undefined,
238
320
  safe: 18,
239
321
  artSafe: undefined,
240
- gutter: undefined
322
+ gutter: undefined,
323
+ margin: undefined
241
324
  },
242
325
  ink: {
243
326
  maxTac: 400,
@@ -609,9 +692,28 @@ function resolveCustomPage(c, m) {
609
692
  bleed: c.page?.bleed ?? m.page?.bleed,
610
693
  safe: c.page?.safe ?? m.page?.safe,
611
694
  artSafe: c.page?.artSafe ?? m.page?.artSafe,
612
- gutter: c.page?.gutter ?? m.page?.gutter
695
+ gutter: c.page?.gutter ?? m.page?.gutter,
696
+ margin: c.page?.margin ?? m.page?.margin
613
697
  };
614
698
  }
699
+ var MARGIN_EDGES = ["top", "bottom", "inside", "outside"];
700
+ function validatePageMargin(margin, size) {
701
+ const edges = isPlainObject(margin) && Object.keys(margin).every((k) => MARGIN_EDGES.includes(k)) && MARGIN_EDGES.every((e) => isNonNegativePoints(margin[e]));
702
+ if (!edges) {
703
+ throw new UsageError("Manifest field `page.margin` must set all four edges in points (72pt = 1in), for example\n" + ` page:
704
+ margin:
705
+ top: 54
706
+ bottom: 54
707
+ inside: 54
708
+ outside: 54
709
+ ` + `got ${JSON.stringify(margin)}.`);
710
+ }
711
+ const m = margin;
712
+ if (m.inside + m.outside >= size.width || m.top + m.bottom >= size.height) {
713
+ throw new UsageError(`Manifest field \`page.margin\` leaves no room for text on a ${size.width} x ${size.height}pt page ` + `(inside ${m.inside} + outside ${m.outside} across, top ${m.top} + bottom ${m.bottom} down).`);
714
+ }
715
+ return m;
716
+ }
615
717
  function resolveWithPreset(cliOverrides, manifest, preset) {
616
718
  const m = manifest;
617
719
  const c = cliOverrides;
@@ -664,6 +766,9 @@ function resolveWithPreset(cliOverrides, manifest, preset) {
664
766
  throw new UsageError("Manifest field `extensions` must be a list of specifiers.");
665
767
  }
666
768
  const extensions = rawExtensions.map((entry, index) => ({ entry, index })).filter(({ entry }) => typeof entry === "string" || entry?.enabled !== false).map(({ entry, index }) => normalizeExtensionEntry(entry, index));
769
+ const page = preset.page ? mergeShape(c.page, m.page, preset.page) : resolveCustomPage(c, m);
770
+ if (page.margin !== undefined && page.margin !== null)
771
+ validatePageMargin(page.margin, page);
667
772
  return {
668
773
  title: c.title ?? m.title ?? "Document",
669
774
  authors: c.authors ?? m.authors ?? [],
@@ -676,7 +781,7 @@ function resolveWithPreset(cliOverrides, manifest, preset) {
676
781
  source: mergeShape(c.source, m.source, preset.source),
677
782
  pdfx: mergeShape(c.pdfx, m.pdfx, preset.pdfx),
678
783
  print: mergeShape(c.print, m.print, preset.print),
679
- page: preset.page ? mergeShape(c.page, m.page, preset.page) : resolveCustomPage(c, m),
784
+ page,
680
785
  ink: mergeShape(c.ink, m.ink, preset.ink),
681
786
  lint: {
682
787
  ...mergeShape(c.lint, m.lint, preset.lint),
@@ -1535,7 +1640,6 @@ async function describeFolder(dir, base, fallbackLabel, labelFrom = prettify) {
1535
1640
  ...meta.description?.trim() ? { description: meta.description.trim() } : {},
1536
1641
  ...meta.author?.trim() ? { author: meta.author.trim() } : {},
1537
1642
  ...meta.preview !== undefined ? { preview: meta.preview } : {},
1538
- ...meta.tokensFile?.trim() ? { tokensFile: meta.tokensFile.trim() } : {},
1539
1643
  ...styles.length > 0 ? { styles } : {},
1540
1644
  carries: extensionCarries(meta),
1541
1645
  dir
@@ -2009,22 +2113,25 @@ async function validateProjectExtensions(projectDir) {
2009
2113
  return out;
2010
2114
  }
2011
2115
  async function readExtensionCss(projectDir, use) {
2116
+ const direct = bundledExtension(use)?.css;
2117
+ if (direct !== undefined)
2118
+ return direct;
2012
2119
  const entry = await describeExtension(projectDir, use);
2013
2120
  if (!entry)
2014
2121
  throw new Error(`Extension "${use}" is not in the manifest.`);
2015
- const bundledCss = entry.kind === "bundled" ? bundledExtension(entry.name)?.css : undefined;
2016
- if (bundledCss !== undefined)
2017
- return bundledCss;
2122
+ return readEntryCss(entry);
2123
+ }
2124
+ async function readEntryCss(entry) {
2125
+ const direct = bundledExtension(entry.use)?.css;
2126
+ if (direct !== undefined)
2127
+ return direct;
2018
2128
  if (!entry.dir)
2019
- throw new Error(`Extension "${use}" has no stylesheets to preview.`);
2129
+ throw new Error(`Extension "${entry.use}" has no stylesheets to preview.`);
2020
2130
  const meta = await readExtensionMeta(entry.dir);
2021
- const sheets = resolveExtension(entry.dir, meta, `Extension "${use}"`).styles ?? [];
2131
+ const sheets = resolveExtension(entry.dir, meta, `Extension "${entry.use}"`).styles ?? [];
2022
2132
  if (sheets.length === 0)
2023
- throw new Error(`Extension "${use}" declares no stylesheets.`);
2024
- const parts = [];
2025
- for (const sheet of sheets)
2026
- parts.push(await readFile5(sheet, "utf8"));
2027
- return parts.join(`
2133
+ throw new Error(`Extension "${entry.use}" declares no stylesheets.`);
2134
+ return (await Promise.all(sheets.map((sheet) => readFile5(sheet, "utf8")))).join(`
2028
2135
 
2029
2136
  `);
2030
2137
  }
@@ -2146,4 +2253,4 @@ async function restoreForCommand(dir, options) {
2146
2253
  log.warn(problem);
2147
2254
  }
2148
2255
 
2149
- export { DEBOUNCE, UsageError, resolvePort, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, resolveTargets, applyDefaultPdfStrictChecks, MANIFEST_FILENAMES, hasProjectManifest, loadManifest, loadManifestWithPath, resolveConfig, resolveConfigForTarget, FriendlyHttpError, withFetchTimeout, loadManifestDoc, writeManifestDoc, ensureSeq, scalarString, DEFAULT_NPM_REGISTRY, npmRegistryUrl, ensureProjectGitignore, sameExtension, listProjectExtensions, describeExtension, extensionConfigFor, setExtensionEnabled, reorderExtensions, removeExtension, addExtension, listNpmVersions, checkExtensionUpdates, updateExtensions, listBundledExtensions, uniqueExtensionId, validateProjectExtensions, readExtensionCss, restorePinnedExtensions, restoreFailureMessage, restoreOfflineMessage, restoreForCommand };
2256
+ export { isPositivePoints, isNonNegativePoints, round3, cssLength, formatPageSize, printAreaMeta, pageBoxes, judgeRect, DEBOUNCE, UsageError, resolvePort, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, resolveTargets, applyDefaultPdfStrictChecks, MANIFEST_FILENAMES, hasProjectManifest, loadManifest, loadManifestWithPath, resolveConfig, resolveConfigForTarget, MARGIN_EDGES, validatePageMargin, FriendlyHttpError, withFetchTimeout, loadManifestDoc, writeManifestDoc, scalarString, DEFAULT_NPM_REGISTRY, npmRegistryUrl, ensureProjectGitignore, sameExtension, listProjectExtensions, describeExtension, extensionConfigFor, setExtensionEnabled, reorderExtensions, removeExtension, addExtension, listNpmVersions, checkExtensionUpdates, updateExtensions, listBundledExtensions, uniqueExtensionId, validateProjectExtensions, readExtensionCss, readEntryCss, restorePinnedExtensions, restoreFailureMessage, restoreOfflineMessage, restoreForCommand };
@@ -643,12 +643,18 @@ function parseMargin(value) {
643
643
  const d = parts[3] ?? b;
644
644
  return { top: a, right: b, bottom: c, left: d };
645
645
  }
646
+ var DEFAULT_PAGE_MARGIN_PT = 72;
646
647
  function resolvePage(model, ctx = {}) {
647
648
  const wanted = new Set(ctx.pseudos ?? []);
648
649
  const applicable = model.pageRules.filter((r) => r.name ? r.name === ctx.name : true).filter((r) => r.pseudos.every((p) => wanted.has(p))).sort((a, b) => specificity(a) - specificity(b));
649
650
  const decls = {};
650
651
  const marginBoxes = {};
651
- const margin = { top: 72, right: 72, bottom: 72, left: 72 };
652
+ const margin = {
653
+ top: DEFAULT_PAGE_MARGIN_PT,
654
+ right: DEFAULT_PAGE_MARGIN_PT,
655
+ bottom: DEFAULT_PAGE_MARGIN_PT,
656
+ left: DEFAULT_PAGE_MARGIN_PT
657
+ };
652
658
  for (const rule of applicable) {
653
659
  for (const [prop, value] of Object.entries(rule.decls)) {
654
660
  if (prop === "margin")
@@ -691,7 +697,7 @@ import { fileURLToPath } from "node:url";
691
697
  var favicon_default = "./favicon-272ga6y0.ico";
692
698
 
693
699
  // src/assets/manifest.schema.json
694
- var manifest_schema_default = "./manifest.schema-t7nx2stg.json";
700
+ var manifest_schema_default = "./manifest.schema-650pe0d1.json";
695
701
 
696
702
  // src/assets/preview/scripts/preview-interface.js
697
703
  var preview_interface_default = "./preview-interface-nnmrxyqm.js";
@@ -706,31 +712,31 @@ var preview_shell_default = "./preview-shell-wk9k3gcd.js";
706
712
  var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
707
713
 
708
714
  // src/assets/engine/gutterpress-viewer.js
709
- var gutterpress_viewer_default = "./gutterpress-viewer-701vf4qp.js";
715
+ var gutterpress_viewer_default = "./gutterpress-viewer-mafsby5k.js";
710
716
 
711
717
  // src/assets/engine/gutterpress-agent.js
712
718
  var gutterpress_agent_default = "./gutterpress-agent-d29ry3ak.js";
713
719
 
714
720
  // src/assets/templates/book/manifest.yaml
715
- var manifest_default = "./manifest-n1gh3qw5.yaml";
721
+ var manifest_default = "./manifest-8afhrk30.yaml";
716
722
 
717
723
  // src/assets/templates/book/chapter-01.md
718
724
  var chapter_01_default = "./chapter-01-gsbjt584.md";
719
725
 
720
726
  // src/assets/templates/zine/manifest.yaml
721
- var manifest_default2 = "./manifest-n1gh3qw5.yaml";
727
+ var manifest_default2 = "./manifest-d4f9q79e.yaml";
722
728
 
723
729
  // src/assets/templates/zine/chapter-01.md
724
730
  var chapter_01_default2 = "./chapter-01-wgjfz4w6.md";
725
731
 
726
732
  // src/assets/templates/technical/manifest.yaml
727
- var manifest_default3 = "./manifest-n1gh3qw5.yaml";
733
+ var manifest_default3 = "./manifest-my7mdv8j.yaml";
728
734
 
729
735
  // src/assets/templates/technical/chapter-01.md
730
736
  var chapter_01_default3 = "./chapter-01-6fn9pvd0.md";
731
737
 
732
738
  // src/assets/templates/paper/manifest.yaml
733
- var manifest_default4 = "./manifest-eagfhba6.yaml";
739
+ var manifest_default4 = "./manifest-gf13sjp8.yaml";
734
740
 
735
741
  // src/assets/templates/paper/chapter-01.md
736
742
  var chapter_01_default4 = "./chapter-01-s71xrf5q.md";
@@ -757,13 +763,13 @@ var fixture_default = "./fixture-2qnyqgb5.md";
757
763
  var expected_default = "./expected-ycmacem8.html";
758
764
 
759
765
  // src/assets/extension-templates/plugin/test/plugin.test.js.tpl
760
- var plugin_test_js_default = "./plugin.test.js-xgxrd8hf.tpl";
766
+ var plugin_test_js_default = "./plugin.test.js-gxzqqfdh.tpl";
761
767
 
762
768
  // src/assets/extension-templates/look/package.json
763
- var package_default2 = "./package-aenwjew3.json";
769
+ var package_default2 = "./package-awwkt7sa.json";
764
770
 
765
771
  // src/assets/extension-templates/look/README.md
766
- var README_default2 = "./README-8ef336pp.md";
772
+ var README_default2 = "./README-8db7btxb.md";
767
773
 
768
774
  // src/assets/extension-templates/look/components.yaml
769
775
  var components_default = "./components-zzqdpt3m.yaml";
@@ -772,7 +778,7 @@ var components_default = "./components-zzqdpt3m.yaml";
772
778
  var callout_default = "./callout-hv56m16h.md";
773
779
 
774
780
  // src/assets/extension-templates/look/styles/tokens.css
775
- var tokens_default = "./tokens-7984461t.css";
781
+ var tokens_default = "./tokens-ye64p899.css";
776
782
 
777
783
  // src/assets/extension-templates/look/styles/base.css
778
784
  var base_default = "./base-ypqh9n7f.css";
@@ -784,7 +790,7 @@ var components_default2 = "./components-aam0fe2z.css";
784
790
  var page_templates_default = "./page-templates-tx9ryt19.css";
785
791
 
786
792
  // src/assets/extension-templates/look/styles/page-rules.css
787
- var page_rules_default = "./page-rules-nsj3aw42.css";
793
+ var page_rules_default = "./page-rules-fj09xct5.css";
788
794
 
789
795
  // src/assets/extension-templates/look/styles/book.css
790
796
  var book_default = "./book-ted3tzrp.css";
@@ -913,4 +919,4 @@ function marginBoxAlign(name) {
913
919
  return /right/.test(name) ? "end" : "start";
914
920
  }
915
921
 
916
- export { isRectoVersoBreak, wantsRecto, planRectoBlanks, lastPageMode, signaturePadding, parseWhich, stringValueAt, stringSymbols, cssQuote, counterStyleName, restartedPageValues, toFolioPage, leaderMarker, generatedContentCss, extract, splitTopLevel, parseSize, resolvePage, getAssetPath, MARGIN_BOX_IGNORED_PROPERTIES, isIgnoredMarginBoxProperty, marginBoxRectPt, marginBoxAlign };
922
+ export { isRectoVersoBreak, wantsRecto, planRectoBlanks, lastPageMode, signaturePadding, parseWhich, stringValueAt, stringSymbols, cssQuote, counterStyleName, restartedPageValues, toFolioPage, leaderMarker, generatedContentCss, extract, splitTopLevel, DEFAULT_PAGE_MARGIN_PT, resolvePage, getAssetPath, MARGIN_BOX_IGNORED_PROPERTIES, isIgnoredMarginBoxProperty, marginBoxRectPt, marginBoxAlign };
@@ -19,7 +19,7 @@ import {
19
19
  stringValueAt,
20
20
  toFolioPage,
21
21
  wantsRecto
22
- } from "./index-0skhjx3e.js";
22
+ } from "./index-nedd07bk.js";
23
23
  import {
24
24
  launchChromium
25
25
  } from "./index-bt0qws5c.js";