gutterpress 0.11.23-alpha.2 → 0.11.23-alpha.4

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 (82) hide show
  1. package/README.md +10 -13
  2. package/dist/{README-8ef336pp.md → README-syg2hn83.md} +13 -19
  3. package/dist/api/index.d.ts +1 -1
  4. package/dist/api/index.js +5 -5
  5. package/dist/{build-encgnv0c.js → build-c48eer6f.js} +8 -8
  6. package/dist/checks/asset/extensions.d.ts +1 -1
  7. package/dist/checks/asset/index.d.ts +0 -1
  8. package/dist/checks/policy.d.ts +5 -4
  9. package/dist/checks/source/config-file.d.ts +9 -6
  10. package/dist/checks/source/dangling-links.d.ts +1 -1
  11. package/dist/checks/types.d.ts +2 -2
  12. package/dist/{cli-pz4bn98t.js → cli-54xt7pjg.js} +19 -13
  13. package/dist/{index-2ppw6q9v.js → cli-5crpmz42.js} +80 -1
  14. package/dist/{cli-xq6djqbj.js → cli-93mkaw6v.js} +166 -308
  15. package/dist/{cli-evg8sbht.js → cli-d9mm3vvh.js} +7 -2
  16. package/dist/{cli-kh8v4vvw.js → cli-gnpea9dx.js} +1 -1
  17. package/dist/{cli-aqh6brew.js → cli-pspjxnc8.js} +1 -1
  18. package/dist/{cli-pwwfxdgb.js → cli-rqh295j9.js} +15 -21
  19. package/dist/{index-x3ema2w3.js → cli-y6d1arem.js} +321 -272
  20. package/dist/cli.js +12 -12
  21. package/dist/{doctor-5gtpgpd1.js → doctor-ptb346k8.js} +4 -3
  22. package/dist/engine/shared/gcpm-extract.d.ts +8 -0
  23. package/dist/engine/shared/print-area.d.ts +16 -4
  24. package/dist/{engine-mc5br8g8.js → engine-4rzdx6af.js} +1 -1
  25. package/dist/{engine-tn13gk0b.js → engine-6txhxmmv.js} +2 -2
  26. package/dist/{ext-wn2a5afq.js → ext-gy8szg3x.js} +8 -8
  27. package/dist/{extension-restore-s3x1618g.js → extension-restore-dymzcasz.js} +2 -2
  28. package/dist/{extension-restore-g8jnmmzq.js → extension-restore-m8tj43e7.js} +4 -4
  29. package/dist/{gutterpress-viewer-701vf4qp.js → gutterpress-viewer-mafsby5k.js} +9 -2
  30. package/dist/{cli-2ppw6q9v.js → index-5crpmz42.js} +80 -1
  31. package/dist/{index-0skhjx3e.js → index-5kh4c78h.js} +19 -13
  32. package/dist/{index-2bjcghze.js → index-8ywkd2sv.js} +15 -21
  33. package/dist/{index-j5z86r4a.js → index-ea94zbq4.js} +329 -488
  34. package/dist/{cli-sdmv4bba.js → index-kaks3mm2.js} +448 -156
  35. package/dist/{index-4x6y8krm.js → index-yc3xj266.js} +1 -1
  36. package/dist/index.js +6 -6
  37. package/dist/lib/build-preflight.d.ts +4 -10
  38. package/dist/lib/build-runner.d.ts +1 -1
  39. package/dist/lib/extension-manager.d.ts +8 -7
  40. package/dist/lib/extension-manifest.d.ts +1 -13
  41. package/dist/lib/ghostscript.d.ts +5 -2
  42. package/dist/lib/lint-rules.d.ts +5 -1
  43. package/dist/lib/manifest-config.d.ts +3 -2
  44. package/dist/lib/manifest-old-spellings.d.ts +64 -0
  45. package/dist/lib/manifest.d.ts +15 -1
  46. package/dist/lib/markdown/assemble.d.ts +4 -3
  47. package/dist/lib/markdown/chapter-id.d.ts +1 -1
  48. package/dist/lib/markdown/index.d.ts +1 -1
  49. package/dist/lib/markdown/table.d.ts +5 -3
  50. package/dist/lib/page-size.d.ts +45 -33
  51. package/dist/lib/pdf-inspect.d.ts +27 -0
  52. package/dist/lib/presets.d.ts +10 -8
  53. package/dist/lib/printsafe.d.ts +2 -1
  54. package/dist/lib/project-scaffold.d.ts +1 -1
  55. package/dist/lib/project-templates.d.ts +9 -0
  56. package/dist/lib/remote-auth/sync-messages.d.ts +2 -2
  57. package/dist/lib/targets.d.ts +4 -4
  58. package/dist/lib/validation-exec.d.ts +4 -4
  59. package/dist/manifest-2kc56wvw.yaml +22 -0
  60. package/dist/manifest-41ddzm13.yaml +18 -0
  61. package/dist/manifest-79zsgkpn.yaml +26 -0
  62. package/dist/manifest-sqzm4681.yaml +22 -0
  63. package/dist/{manifest.schema-t7nx2stg.json → manifest.schema-w86c1xw1.json} +30 -308
  64. package/dist/{new-mhs46pw3.js → new-t2t28ccb.js} +9 -15
  65. package/dist/{package-aenwjew3.json → package-awwkt7sa.json} +0 -1
  66. package/dist/{page-rules-nsj3aw42.css → page-rules-ytj9p04v.css} +12 -40
  67. package/dist/{pdf-inspect-wnw4za71.js → pdf-inspect-b3mf81ex.js} +3 -1
  68. package/dist/{plugin.test.js-xgxrd8hf.tpl → plugin.test.js-gxzqqfdh.tpl} +0 -1
  69. package/dist/{plugins-2cek4mz1.js → plugins-fec8t2bh.js} +1 -1
  70. package/dist/{plugins-1sxe0dkz.js → plugins-sqa4msdk.js} +3 -3
  71. package/dist/{preflight-3k2b1x8e.js → preflight-srq8fktp.js} +8 -8
  72. package/dist/preview/file-watcher.d.ts +1 -3
  73. package/dist/{preview-6p9v6rht.js → preview-zsp9hstd.js} +8 -8
  74. package/dist/{publish-qgsngy8s.js → publish-hhy31gr9.js} +8 -8
  75. package/dist/render.js +30 -562
  76. package/dist/schema/manifest.types.d.ts +60 -105
  77. package/dist/{tokens-7984461t.css → tokens-n82t4k9h.css} +12 -12
  78. package/dist/{validate-0v7xw6wa.js → validate-r9jdz85h.js} +8 -8
  79. package/package.json +1 -1
  80. package/dist/checks/asset/approved-fonts.d.ts +0 -3
  81. package/dist/manifest-eagfhba6.yaml +0 -19
  82. package/dist/manifest-n1gh3qw5.yaml +0 -9
@@ -22,8 +22,8 @@ import { type VendorPreset } from "./presets";
22
22
  export type TargetOverlay = {
23
23
  pdfx?: Partial<ResolvedConfig["pdfx"]>;
24
24
  ink?: Partial<ResolvedConfig["ink"]>;
25
+ checks?: ResolvedConfig["checks"];
25
26
  validate?: {
26
- checks?: ResolvedConfig["validate"]["checks"];
27
27
  assets?: Partial<ResolvedConfig["validate"]["assets"]>;
28
28
  pdf?: Partial<ResolvedConfig["validate"]["pdf"]>;
29
29
  };
@@ -72,9 +72,9 @@ export declare function resolveTargets(requested: readonly string[] | undefined,
72
72
  export declare function overlayPreset(preset: VendorPreset, target: PublishTarget): VendorPreset;
73
73
  /**
74
74
  * The strict-PDF fill-ins applied to EVERY post-build PDF validation
75
- * regardless of preset/target: any of these left `undefined` by the config
76
- * becomes an error-severity check, without overwriting an author's explicit
77
- * choice (including an explicit disable).
75
+ * regardless of preset/target: any of these the config leaves unset reports
76
+ * at error severity, without overwriting an author's explicit level
77
+ * (including `off`).
78
78
  */
79
79
  export declare const DEFAULT_STRICT_PDF_CHECKS: readonly ["pdf.structure.qpdf", "pdf.print.pdfx-markers", "pdf.print.pdfx-metadata", "pdf.print.embedded-fonts"];
80
80
  export declare function applyDefaultPdfStrictChecks(config: ResolvedConfig): ResolvedConfig;
@@ -28,10 +28,10 @@ export interface ValidationExecutionArgs {
28
28
  pluginStylePaths?: string[];
29
29
  /**
30
30
  * Disable the `source.stylelint` check (CSS print-safety) for this run
31
- * only, without touching the manifest's `validate.source.stylelint`
32
- * setting on disk (#272 — one CSS gate, not two). Set by the build
33
- * pipeline's `runQualityGates` (build-runner.ts) from `--skip-lint` /
34
- * `config.lint.enabled: false`, so that flag disables just this one check.
31
+ * only, without touching the manifest's `checks:` on disk (#272 — one CSS
32
+ * gate, not two). Set by the build pipeline's `runQualityGates`
33
+ * (build-runner.ts) from `--skip-lint`, so that flag disables just this
34
+ * one check.
35
35
  * Every other caller (`gutterpress validate`/`preflight`, the desktop
36
36
  * Problems panel) leaves this unset and gets the manifest's own setting.
37
37
  */
@@ -0,0 +1,22 @@
1
+ title: "{{TITLE}}"
2
+ authors:
3
+ - "{{AUTHOR}}"
4
+ chapters:
5
+ - chapter-01.md
6
+ styles:
7
+ - styles/book.css
8
+ extensions:
9
+ - technical-doc
10
+ # Page size and margins in points (72 = 1 in): US Letter (8.5 x 11 in) with
11
+ # 0.9 in top and bottom and 1 in side margins; text stays 0.25 in (18) inside
12
+ # the trim. Change them under Setup > Book.
13
+ page:
14
+ width: 612
15
+ height: 792
16
+ safe: 18
17
+ margin:
18
+ top: 64.8
19
+ bottom: 64.8
20
+ inside: 72
21
+ outside: 72
22
+ preset: custom
@@ -0,0 +1,18 @@
1
+ title: "{{TITLE}}"
2
+ authors:
3
+ - "{{AUTHOR}}"
4
+ chapters:
5
+ - chapter-01.md
6
+ styles:
7
+ - styles/book.css
8
+ extensions:
9
+ - clean-book
10
+ # Page margins in points (72 = 1 in): top, bottom, inside (the binding edge)
11
+ # and outside. Change them, and the page size, under Setup > Book.
12
+ page:
13
+ margin:
14
+ top: 61.2
15
+ bottom: 61.2
16
+ inside: 54
17
+ outside: 54
18
+ preset: book
@@ -0,0 +1,26 @@
1
+ title: "{{TITLE}}"
2
+ authors:
3
+ - "{{AUTHOR}}"
4
+ language: en
5
+ chapters:
6
+ - chapter-01.md
7
+ styles:
8
+ - styles/book.css
9
+ # Page size and margins in points (72 = 1 in): US Letter with 1 in margins
10
+ # (A4 is width 595, height 842); text stays 0.25 in (18) inside the trim.
11
+ # Change them under Setup > Book.
12
+ page:
13
+ width: 612
14
+ height: 792
15
+ safe: 18
16
+ margin:
17
+ top: 72
18
+ bottom: 72
19
+ inside: 72
20
+ outside: 72
21
+ extensions:
22
+ - markdown-it-sup
23
+ - gutterpress-math
24
+ # The built-in academic look. Style over it from styles/book.css.
25
+ - academic
26
+ preset: custom
@@ -0,0 +1,22 @@
1
+ title: "{{TITLE}}"
2
+ authors:
3
+ - "{{AUTHOR}}"
4
+ chapters:
5
+ - chapter-01.md
6
+ styles:
7
+ - styles/book.css
8
+ extensions:
9
+ - zine
10
+ # Page size and margins in points (72 = 1 in): Digest (5.5 x 8.5 in) with
11
+ # 0.4 in margins; text stays 0.25 in (18) inside the trim. Change them under
12
+ # Setup > Book.
13
+ page:
14
+ width: 396
15
+ height: 612
16
+ safe: 18
17
+ margin:
18
+ top: 28.8
19
+ bottom: 28.8
20
+ inside: 28.8
21
+ outside: 28.8
22
+ preset: custom
@@ -116,24 +116,19 @@
116
116
  ]
117
117
  ]
118
118
  },
119
- "source": {
119
+ "chapters": {
120
+ "type": ["array", "null"],
121
+ "description": "The book's markdown files, in reading order, relative to the manifest directory. Omit it (or set it to null) to use every top-level .md file in natural order. Book setup > Details in the app edits it. Assets are not listed anywhere: the build copies exactly what the book references.",
122
+ "items": { "type": "string" },
123
+ "examples": [["chapter-01.md", "chapter-02.md"]]
124
+ },
125
+ "checks": {
120
126
  "type": "object",
121
- "description": "Where the book's content comes from. There is no `assets` list: the build discovers every file the book actually references (image src, CSS url()/@font-face, …) and copies exactly those — see lib/asset-inline.ts. An author-maintained asset directory list could drift from what the book uses; this can't.",
122
- "properties": {
123
- "files": {
124
- "type": ["array", "null"],
125
- "description": "Explicit, ordered list of markdown files to concatenate, relative to the manifest directory. Omit or set to null to include every .md file in the directory in alphabetical order.",
126
- "default": null,
127
- "items": {
128
- "type": "string",
129
- "minLength": 1
130
- },
131
- "examples": [
132
- ["chapter-01.md", "chapter-02.md"],
133
- ["frontmatter/title.md", "chapters/intro.md", "appendix.md"]
134
- ]
135
- }
136
- }
127
+ "description": "Per-check and per-rule levels, keyed by a check id (pdf.print.image-resolution, source.markdownlint, …) or a lint rule id (printsafe/no-risky-print-effects). `off` switches it off; `on` switches on a check the preset leaves off, at its own severity; `info`, `warn` and `error` set the severity its findings are reported at. The numbers the checks measure against come from the preset and the publish targets. Linter config files (.markdownlint.yaml, .htmlhintrc, .gutterpress/css-contract.yaml) are found by name in the book's folder or a folder above it, up to the repository.",
128
+ "additionalProperties": {
129
+ "enum": ["off", "on", "info", "warn", "warning", "error", true, false]
130
+ },
131
+ "examples": [{ "pdf.structure.qpdf": "off", "heuristic.whitespace.text-density": "info", "pdf.nav.bookmarks": "warn" }]
137
132
  },
138
133
  "pdfx": {
139
134
  "type": "object",
@@ -164,7 +159,7 @@
164
159
  },
165
160
  "transparency": {
166
161
  "type": "string",
167
- "description": "What a PDF/X build does with a page that uses transparency (an alpha-channel image, a soft `rgba()` shadow, CSS `opacity` or `mix-blend-mode`), which PDF/X (PDF 1.3) cannot represent. `flatten-page` leaves the page to Ghostscript, which rasterizes the WHOLE page: it looks right but loses the page's text and fonts. `preserve-text` flattens only the artwork to a picture (300 DPI, or `rasterDpi`) and draws the text live on top, so the page stays searchable. Text is then always the top layer (text another element covers shows through). A page whose text is translucent or blended, set in a Type 3 font (e.g. a synthetic bold or a text stroke), filled with a pattern or used as a clip, or that has a repeating or conic gradient, falls back to `flatten-page`, and so does any page listed in `flattenPages`. Set `validate.assets.allowAlpha: true` to use alpha-channel images. Same for every preset: `flatten-page`.",
162
+ "description": "What a PDF/X build does with a page that uses transparency (an alpha-channel image, a soft `rgba()` shadow, CSS `opacity` or `mix-blend-mode`), which PDF/X (PDF 1.3) cannot represent. `flatten-page` leaves the page to Ghostscript, which rasterizes the WHOLE page: it looks right but loses the page's text and fonts. `preserve-text` flattens only the artwork to a picture (300 DPI, or `rasterDpi`) and draws the text live on top, so the page stays searchable. Text is then always the top layer (text another element covers shows through). A page whose text is translucent or blended, set in a Type 3 font (e.g. a synthetic bold or a text stroke), filled with a pattern or used as a clip, or that has a repeating or conic gradient, falls back to `flatten-page`, and so does any page listed in `flattenPages`. Set `checks: { asset.image.alpha-channel: off }` to use alpha-channel images. Same for every preset: `flatten-page`.",
168
163
  "enum": ["flatten-page", "preserve-text"],
169
164
  "default": "flatten-page"
170
165
  },
@@ -207,26 +202,20 @@
207
202
  },
208
203
  "page": {
209
204
  "type": "object",
210
- "description": "Page geometry, in POINTS (1in = 72pt): the trim size the book prints at. The build writes it as the default `@page { size }` unless a stylesheet's own plain `@page` rule sets a size, in which case that rule wins, and the `pdf.print.page-size` check compares the produced PDF against these numbers either way. A bleed-inclusive @page size legitimately differs from the trim recorded here.",
205
+ "description": "Page geometry, in POINTS (1in = 72pt): the trim size the book prints at and, with `margin`, the margins. The build writes them as the `@page` rule after every stylesheet, so a `size` in a stylesheet's own `@page` is overridden (the print-safety check reports it); the `pdf.print.page-size` check compares the produced PDF against these numbers. A bleed-inclusive page size legitimately differs from the trim recorded here.",
211
206
  "properties": {
212
207
  "width": {
213
208
  "type": "number",
214
- "description": "Page width in points (1in = 72pt): the trim the book prints at unless a stylesheet's plain @page rule sets its own, and what validation compares against. Preset defaults: dtrpg 621, book 432 (6in).",
209
+ "description": "Page width in points (1in = 72pt): the trim the book prints at and what validation compares against. Preset defaults: dtrpg 621, book 432 (6in).",
215
210
  "exclusiveMinimum": 0,
216
211
  "examples": [612, 621, 432]
217
212
  },
218
213
  "height": {
219
214
  "type": "number",
220
- "description": "Page height in points (1in = 72pt): the trim the book prints at unless a stylesheet's plain @page rule sets its own, and what validation compares against. Preset defaults: dtrpg 810, book 648 (9in).",
215
+ "description": "Page height in points (1in = 72pt): the trim the book prints at and what validation compares against. Preset defaults: dtrpg 810, book 648 (9in).",
221
216
  "exclusiveMinimum": 0,
222
217
  "examples": [792, 810, 648]
223
218
  },
224
- "tolerance": {
225
- "type": "number",
226
- "description": "Allowed deviation, in points, between the expected and the actual page size.",
227
- "default": 0.5,
228
- "minimum": 0
229
- },
230
219
  "bleed": {
231
220
  "type": "number",
232
221
  "description": "A bleed, in points, that the page width x height ALREADY CONTAINS on the top, bottom and OUTER edges (none on the binding edge) — how DriveThruRPG's interior file is cut (8.625 x 11.25in for an 8.5 x 11in book). It tells the preview's safe area & bleed overlay, the `pdf.print.safe-margins` check and pinned art where the trim is, and by itself changes nothing in the PDF. Preset default: dtrpg 9 (0.125in); book and custom none.",
@@ -250,254 +239,18 @@
250
239
  "description": "The binding allowance, in points: how far content stays from the spine, measured from the trim at the binding edge (the left edge of a right-hand page, the right edge of a left-hand one). It stands in for `safe` there, for text and for art alike: the preview's overlay draws and judges that edge against it, the `pdf.print.safe-margins` check fails text or an image closer to the spine than it, and an image pinned to the binding edge (`.gp-pin`) sits on it. The other edges keep `safe` and `artSafe`. Use it when your book keeps its text further from the spine than the printer's minimum, for example 54 (0.75in) where DriveThruRPG asks for 0.5in. Absent = the same as `safe`. Preset default: dtrpg 36 (0.5in, DriveThruRPG's rule for text and non-bleeding art at the binding — the same as its `safe`, declared so a book inherits it visibly); book and custom none.",
251
240
  "minimum": 0,
252
241
  "examples": [54]
253
- }
254
- }
255
- },
256
- "ink": {
257
- "type": "object",
258
- "description": "Ink coverage limits used by the `pdf.print.ink-coverage` check.",
259
- "properties": {
260
- "maxTac": {
261
- "type": "number",
262
- "description": "Maximum total area coverage (TAC), as a percentage summed across C+M+Y+K. 400 is the physical ceiling (100% of each plate), so it effectively disables the cap. Preset defaults: dtrpg 240 (DriveThruRPG's limit), book 400.",
263
- "minimum": 0,
264
- "examples": [240, 300, 400]
265
- },
266
- "tacTolerance": {
267
- "type": "number",
268
- "description": "Allowed percentage of sampled pixels that may exceed `maxTac` before the check fails.",
269
- "default": 0.5,
270
- "minimum": 0
271
- }
272
- }
273
- },
274
- "lint": {
275
- "type": "object",
276
- "description": "Lint settings: whether the pre-build lint runs, the markdownlint config, and per-rule level overrides.",
277
- "properties": {
278
- "enabled": {
279
- "type": "boolean",
280
- "description": "Whether linting runs.",
281
- "default": true
282
- },
283
- "configPath": {
284
- "type": ["string", "null"],
285
- "description": "Path to a markdownlint config file, relative to the manifest directory. null uses the built-in defaults.",
286
- "default": null
287
- },
288
- "rules": {
289
- "type": "object",
290
- "description": "Per-rule level overrides, keyed by rule id: a printsafe rule (printsafe/no-risky-print-effects, printsafe/page-containment, printsafe/preview-cannot-follow, printsafe/no-remote-urls) or a check id such as source.accessibility.heading-order. \"off\" silences the rule; \"warn\" / \"error\" set its severity. An id that matches no rule is ignored. To silence one site instead, put a `gutterpress-disable-next-line <rule-id> -- reason` comment (CSS `/* */` or markdown `<!-- -->`) on the line above it.",
291
- "additionalProperties": { "enum": ["off", "warn", "error"] },
292
- "examples": [{ "printsafe/no-risky-print-effects": "off" }]
293
- }
294
- }
295
- },
296
- "validate": {
297
- "type": "object",
298
- "description": "Preflight/validation configuration. Individual checks are addressed by id (see `checks`); the sections below supply the thresholds those checks read.",
299
- "properties": {
300
- "enabled": {
301
- "type": "boolean",
302
- "description": "Whether validation runs.",
303
- "default": true
304
- },
305
- "checks": {
306
- "type": "object",
307
- "description": "Per-check overrides, keyed by check id. This is an OPEN dictionary — any registered check id may appear, including ids contributed by plugins. Built-in ids are namespaced source.*, asset.*, pdf.* and heuristic.* (e.g. pdf.structure.qpdf, pdf.print.embedded-fonts, pdf.print.pdfx-markers, pdf.print.page-size, asset.image.file-size, source.markdownlint, heuristic.whitespace.text-density). A boolean value is shorthand for enabled/disabled.",
308
- "propertyNames": {
309
- "description": "A registered check id, e.g. \"pdf.print.embedded-fonts\"."
310
- },
311
- "additionalProperties": {
312
- "oneOf": [
313
- {
314
- "type": "boolean",
315
- "description": "Shorthand for { enabled: <value> }."
316
- },
317
- {
318
- "type": "object",
319
- "properties": {
320
- "enabled": {
321
- "type": "boolean",
322
- "description": "Whether this check runs.",
323
- "default": true
324
- },
325
- "severity": {
326
- "type": "string",
327
- "description": "How a failure of this check is reported.",
328
- "enum": ["error", "warning", "info"]
329
- },
330
- "options": {
331
- "type": "object",
332
- "description": "Check-specific options.",
333
- "additionalProperties": true
334
- }
335
- }
336
- }
337
- ]
338
- },
339
- "examples": [
340
- {
341
- "pdf.structure.qpdf": { "enabled": true, "severity": "error" },
342
- "pdf.print.pdfx-markers": false
343
- }
344
- ]
345
242
  },
346
- "source": {
243
+ "margin": {
347
244
  "type": "object",
348
- "description": "Source-linting checks (markdown, generated HTML, CSS). Each entry is a path to that linter's config file, or false to disable the check.",
245
+ "description": "Page margins, in points (1in = 72pt): the space between the trim and the text on each edge. `inside` is the binding edge (the left of a right-hand page, the right of a left-hand one), `outside` the other. When set, the book prints with these margins and any `@page` margin in a stylesheet is overridden; when left out, the stylesheets' `@page` margins apply (a look's design), else 1in. Setup > Book in the app edits it. All four edges are required together.",
349
246
  "properties": {
350
- "markdownlint": {
351
- "description": "Path to a markdownlint config, or false to disable the source.markdownlint check.",
352
- "default": null,
353
- "oneOf": [
354
- { "type": "string", "minLength": 1 },
355
- { "type": "boolean", "const": false }
356
- ]
357
- },
358
- "htmlhint": {
359
- "description": "Path to an htmlhint config, or false to disable the source.htmlhint check.",
360
- "default": null,
361
- "oneOf": [
362
- { "type": "string", "minLength": 1 },
363
- { "type": "boolean", "const": false }
364
- ]
365
- },
366
- "stylelint": {
367
- "description": "Path to a stylelint config, or false to disable the source.stylelint check.",
368
- "default": null,
369
- "oneOf": [
370
- { "type": "string", "minLength": 1 },
371
- { "type": "boolean", "const": false }
372
- ]
373
- },
374
- "cssOwnership": {
375
- "description": "Path to a CSS ownership contract (default discovery: .gutterpress/css-contract.yaml), or false to disable the source.css-ownership check. Optional — absent means no contract, so the check reports nothing.",
376
- "default": null,
377
- "oneOf": [
378
- { "type": "string", "minLength": 1 },
379
- { "type": "boolean", "const": false }
380
- ]
381
- },
382
- "allowedCallouts": {
383
- "type": "array",
384
- "deprecated": true,
385
- "description": "DEPRECATED and IGNORED (no-op). The `:::name` container syntax this gated was removed 2026-05-17, along with the callout-validation check it configured. Kept only so older manifests still parse; setting it logs a deprecation warning. See docs/migrations/2026-05-removing-container-syntax.md.",
386
- "items": { "type": "string" }
387
- }
388
- }
389
- },
390
- "assets": {
391
- "type": "object",
392
- "description": "Thresholds for the asset.* checks (images and fonts on disk).",
393
- "properties": {
394
- "maxImageSize": {
395
- "type": "integer",
396
- "description": "Maximum image file size in bytes (asset.image.file-size).",
397
- "default": 10000000,
398
- "minimum": 0
399
- },
400
- "minImageDpi": {
401
- "type": "integer",
402
- "deprecated": true,
403
- "description": "DEPRECATED and IGNORED (no-op). The source-image check it configured read DPI metadata, which says nothing about the printed size. The build warns about each image placed below 300 DPI, and `validate.pdf.minImageResolution` checks the built PDF. Kept only so older manifests still parse.",
404
- "minimum": 0
405
- },
406
- "allowedColorSpaces": {
407
- "type": "array",
408
- "deprecated": true,
409
- "description": "DEPRECATED and IGNORED (no-op). The source-image colour-space check it configured was removed: a PDF/X build converts every image to the output intent, and `pdf.print.color-spaces` checks the result. Kept only so older manifests still parse.",
410
- "items": { "type": "string" }
411
- },
412
- "allowAlpha": {
413
- "type": "boolean",
414
- "description": "Whether images may carry an alpha channel (asset.image.alpha-channel). Preset defaults: dtrpg false (PDF/X forbids transparency), book true."
415
- },
416
- "approvedFontFiles": {
417
- "type": "array",
418
- "description": "Allow-list of font files (asset.font.approved-files). Empty means no restriction.",
419
- "default": [],
420
- "items": { "type": "string" }
421
- },
422
- "requireFontLicense": {
423
- "type": "boolean",
424
- "description": "Require a license record for each embedded font (asset.font.license).",
425
- "default": false
426
- }
427
- }
428
- },
429
- "pdf": {
430
- "type": "object",
431
- "description": "Thresholds for the pdf.* checks (run against the produced PDF).",
432
- "properties": {
433
- "requireBookmarks": {
434
- "type": "boolean",
435
- "description": "Require a PDF outline/bookmark tree (pdf.nav.bookmarks).",
436
- "default": false
437
- },
438
- "requireTocLinks": {
439
- "type": "boolean",
440
- "description": "Require the table of contents to use real internal links (pdf.nav.toc-links).",
441
- "default": false
442
- },
443
- "minImageResolution": {
444
- "type": "integer",
445
- "description": "Minimum placed-image resolution in DPI (pdf.print.image-resolution).",
446
- "default": 300,
447
- "minimum": 0
448
- },
449
- "forbidTransparency": {
450
- "type": "boolean",
451
- "description": "Fail on transparency in the PDF (pdf.print.transparency). Preset defaults: dtrpg true (required by PDF/X), book false."
452
- },
453
- "requireBleed": {
454
- "type": "boolean",
455
- "description": "Require a bleed box on every page (pdf.print.bleed).",
456
- "default": false
457
- },
458
- "bleedSize": {
459
- "type": "number",
460
- "description": "Expected bleed, in points (9pt = 0.125in).",
461
- "default": 9,
462
- "minimum": 0
463
- }
464
- }
465
- },
466
- "heuristics": {
467
- "type": "object",
468
- "description": "Thresholds for the heuristic.* layout-quality checks. These are advisory design heuristics, not hard print requirements.",
469
- "properties": {
470
- "maxDecorativeLayers": {
471
- "type": "integer",
472
- "description": "Maximum stacked decorative layers per page (heuristic.decoration.layer-count).",
473
- "default": 5,
474
- "minimum": 0
475
- },
476
- "textDensityRange": {
477
- "type": "object",
478
- "description": "Acceptable characters-per-page range (heuristic.whitespace.text-density).",
479
- "properties": {
480
- "min": {
481
- "type": "number",
482
- "description": "Minimum characters per page.",
483
- "default": 200,
484
- "minimum": 0
485
- },
486
- "max": {
487
- "type": "number",
488
- "description": "Maximum characters per page.",
489
- "default": 5000,
490
- "minimum": 0
491
- }
492
- }
493
- },
494
- "maxParagraphsPerSection": {
495
- "type": "integer",
496
- "description": "Maximum paragraphs in one section before it is flagged as under-chunked (heuristic.chunking.section-density).",
497
- "default": 10,
498
- "minimum": 0
499
- }
500
- }
247
+ "top": { "type": "number", "description": "Top margin in points.", "minimum": 0, "examples": [61.2, 72] },
248
+ "bottom": { "type": "number", "description": "Bottom margin in points.", "minimum": 0, "examples": [61.2, 72] },
249
+ "inside": { "type": "number", "description": "Binding-edge margin in points: the left of a right-hand page, the right of a left-hand one.", "minimum": 0, "examples": [54, 72] },
250
+ "outside": { "type": "number", "description": "Outer-edge margin in points.", "minimum": 0, "examples": [54, 72] }
251
+ },
252
+ "required": ["top", "bottom", "inside", "outside"],
253
+ "additionalProperties": false
501
254
  }
502
255
  }
503
256
  },
@@ -622,53 +375,22 @@
622
375
  "authors": ["Author Name"],
623
376
  "preset": "book",
624
377
  "styles": ["styles/book.css"],
625
- "source": {
626
- "files": ["chapter-01.md", "chapter-02.md"]
627
- }
378
+ "chapters": ["chapter-01.md", "chapter-02.md"]
628
379
  },
629
380
  {
630
381
  "title": "Print-Ready Supplement",
631
382
  "authors": ["Author Name"],
632
383
  "preset": "dtrpg",
633
- "plugins": [
634
- {
635
- "path": "plugins/my-plugin.js",
636
- "priority": 100
637
- }
638
- ],
639
- "styles": ["css/index.css"],
640
- "source": {
641
- "files": ["chapter-00.md", "chapter-01.md"]
642
- },
643
- "page": {
644
- "width": 621,
645
- "height": 810,
646
- "tolerance": 0.5
647
- },
648
- "pdfx": {
649
- "flavor": "x1a",
650
- "icc": ".gutterpress/profiles/CGATS21_CRPC1.icc"
651
- },
652
- "ink": {
653
- "maxTac": 240
654
- }
384
+ "extensions": ["clean-book"],
385
+ "chapters": ["chapter-00.md", "chapter-01.md"],
386
+ "pdfx": { "flavor": "x1a" }
655
387
  },
656
388
  {
657
389
  "title": "Technical Documentation",
658
390
  "authors": ["Tech Team"],
659
391
  "preset": "book",
660
392
  "styles": ["styles/book.css"],
661
- "validate": {
662
- "enabled": true,
663
- "checks": {
664
- "pdf.nav.bookmarks": { "enabled": true, "severity": "warning" },
665
- "pdf.print.pdfx-markers": false
666
- },
667
- "pdf": {
668
- "requireBookmarks": true,
669
- "requireTocLinks": true
670
- }
671
- }
393
+ "checks": { "pdf.nav.bookmarks": "warn", "pdf.nav.toc-links": "warn" }
672
394
  }
673
395
  ]
674
396
  }
@@ -3,13 +3,13 @@ import {
3
3
  EXTENSION_KINDS,
4
4
  scaffoldExtension,
5
5
  scaffoldProject
6
- } from "./cli-xq6djqbj.js";
6
+ } from "./cli-93mkaw6v.js";
7
7
  import {
8
8
  resolveGhostscript
9
- } from "./cli-evg8sbht.js";
9
+ } from "./cli-d9mm3vvh.js";
10
10
  import"./cli-ht1bcqdd.js";
11
- import"./cli-pz4bn98t.js";
12
- import"./cli-2ppw6q9v.js";
11
+ import"./cli-54xt7pjg.js";
12
+ import"./cli-5crpmz42.js";
13
13
  import"./cli-eyyggect.js";
14
14
  import {
15
15
  isToolAvailable
@@ -22,15 +22,15 @@ import {
22
22
  TARGET_IDS,
23
23
  loadManifest,
24
24
  resolveConfig
25
- } from "./cli-sdmv4bba.js";
26
- import"./cli-pwwfxdgb.js";
27
- import"./cli-aqh6brew.js";
25
+ } from "./cli-y6d1arem.js";
26
+ import"./cli-rqh295j9.js";
27
+ import"./cli-pspjxnc8.js";
28
28
  import {
29
29
  UsageError,
30
30
  rejectExtraPositionals,
31
31
  rejectUnknownFlags
32
32
  } from "./cli-d8xjns66.js";
33
- import"./cli-kh8v4vvw.js";
33
+ import"./cli-gnpea9dx.js";
34
34
  import {
35
35
  EXIT_CODES
36
36
  } from "./cli-46ycxe6r.js";
@@ -90,10 +90,6 @@ var newArgs = {
90
90
  type: "string",
91
91
  description: "Trim height in points, 72pt = 1in (required with --preset custom; optional override otherwise)"
92
92
  },
93
- "page-tolerance": {
94
- type: "string",
95
- description: "Allowed trim deviation in points when validating a built PDF (default: 0.5)"
96
- },
97
93
  git: {
98
94
  type: "boolean",
99
95
  description: "Initialise local version history (default: true; use --no-git to skip)",
@@ -122,7 +118,6 @@ var BOOK_ONLY_FLAGS = [
122
118
  "template",
123
119
  "page-width",
124
120
  "page-height",
125
- "page-tolerance",
126
121
  "git"
127
122
  ];
128
123
  var EXTENSION_ONLY_FLAGS = ["prefix", "description"];
@@ -243,8 +238,7 @@ var new_default = defineCommand({
243
238
  }
244
239
  const pageWidth = parsePoints(args["page-width"], "--page-width");
245
240
  const pageHeight = parsePoints(args["page-height"], "--page-height");
246
- const pageTolerance = parsePoints(args["page-tolerance"], "--page-tolerance");
247
- const customPage = pageWidth !== undefined && pageHeight !== undefined ? { width: pageWidth, height: pageHeight, ...pageTolerance !== undefined ? { tolerance: pageTolerance } : {} } : undefined;
241
+ const customPage = pageWidth !== undefined && pageHeight !== undefined ? { width: pageWidth, height: pageHeight } : undefined;
248
242
  if (preset === "custom" && !customPage) {
249
243
  console.error("The custom preset needs a trim size: --page-width and --page-height in points (72pt = 1in — e.g. US Letter is 612 x 792).");
250
244
  process.exit(EXIT_CODES.USAGE);
@@ -20,7 +20,6 @@
20
20
  "styles/page-rules.css",
21
21
  "styles/book.css"
22
22
  ],
23
- "tokensFile": "styles/tokens.css",
24
23
  "components": "components.yaml",
25
24
  "snippets": "snippets",
26
25
  "preview": null