gutterpress 0.11.23-alpha.7 → 0.11.23-beta.1

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 (59) hide show
  1. package/README.md +2 -0
  2. package/dist/{README-syg2hn83.md → README-8rct3axy.md} +2 -2
  3. package/dist/api/index.d.ts +3 -3
  4. package/dist/api/index.js +7 -5
  5. package/dist/{build-w572wq10.js → build-dg8a566j.js} +8 -7
  6. package/dist/{cli-eatdqx3z.js → cli-1fy1pm9d.js} +1 -1
  7. package/dist/cli-65gy8ask.js +82 -0
  8. package/dist/{cli-3cvq3n1c.js → cli-989eg8jz.js} +186 -83
  9. package/dist/{cli-6pv84kf3.js → cli-e31jshz6.js} +6 -84
  10. package/dist/{cli-58fsk6d7.js → cli-k087gj0p.js} +66 -34
  11. package/dist/{cli-5ba6bm6z.js → cli-s1zt779w.js} +1 -1
  12. package/dist/{cli-wyg7qstd.js → cli-ttj95aex.js} +3 -3
  13. package/dist/{cli-mmgtqnmr.js → cli-vhav8g82.js} +1 -1
  14. package/dist/cli.js +12 -12
  15. package/dist/{doctor-2f3zqmza.js → doctor-g4a42tcz.js} +3 -3
  16. package/dist/engine/shared/page-vars.d.ts +32 -0
  17. package/dist/{engine-4rabsgwq.js → engine-jvkcahr1.js} +2 -1
  18. package/dist/{engine-wm4fggac.js → engine-wgkaqjsc.js} +3 -3
  19. package/dist/{ext-0cgky8n3.js → ext-w9d5ftcg.js} +8 -7
  20. package/dist/{extension-restore-vghc58vx.js → extension-restore-5x4mj79d.js} +3 -3
  21. package/dist/{extension-restore-e7je32pr.js → extension-restore-as0g38p1.js} +5 -4
  22. package/dist/{gutterpress-viewer-mafsby5k.js → gutterpress-viewer-ze691rrd.js} +52 -13
  23. package/dist/{index-2vxzxyyj.js → index-798jt0qc.js} +9 -9
  24. package/dist/{index-fp7xwvpr.js → index-a4j3xcfp.js} +3 -3
  25. package/dist/{index-nfysshcc.js → index-c6y0p7jy.js} +249 -139
  26. package/dist/{index-wm4x7xbf.js → index-fk2kpf2t.js} +58 -26
  27. package/dist/{index-hphcn7th.js → index-rj5vrhz6.js} +5 -85
  28. package/dist/index-tayzfr9c.js +99 -0
  29. package/dist/index.d.ts +2 -0
  30. package/dist/index.js +233 -6
  31. package/dist/lib/book-css.d.ts +56 -0
  32. package/dist/lib/markdown/assemble.d.ts +58 -0
  33. package/dist/lib/publish/google-drive.d.ts +12 -4
  34. package/dist/lib/publish/manifest-publish.d.ts +6 -0
  35. package/dist/lib/publish/providers/gdrive-folder.d.ts +30 -0
  36. package/dist/lib/publish/run-publish.d.ts +6 -1
  37. package/dist/lib/publish/types.d.ts +52 -5
  38. package/dist/lib/remote-auth/converge-merge.d.ts +3 -3
  39. package/dist/lib/remote-auth/sync-messages.d.ts +2 -2
  40. package/dist/lib/root-tokens.d.ts +76 -0
  41. package/dist/lib/version-changes.d.ts +12 -12
  42. package/dist/{manifest-79zsgkpn.yaml → manifest-0vwaskj2.yaml} +1 -1
  43. package/dist/{manifest-2kc56wvw.yaml → manifest-aya31jwt.yaml} +1 -1
  44. package/dist/{manifest-41ddzm13.yaml → manifest-mffah3hr.yaml} +1 -1
  45. package/dist/{manifest-sqzm4681.yaml → manifest-wbcv8cbp.yaml} +2 -2
  46. package/dist/{manifest.schema-93sd7zje.json → manifest.schema-0jgj0jt1.json} +1 -1
  47. package/dist/{new-88rkrv71.js → new-jtk028rf.js} +8 -7
  48. package/dist/{page-rules-ytj9p04v.css → page-rules-vnja6grt.css} +2 -2
  49. package/dist/{plugins-3aj0wc5h.js → plugins-bcbe7xs8.js} +1 -1
  50. package/dist/{plugins-sprxsz5d.js → plugins-zsm6wv79.js} +3 -3
  51. package/dist/{preflight-11dg1qkk.js → preflight-cs6mj1d6.js} +8 -7
  52. package/dist/{preview-nftp782j.js → preview-d1j1g4qf.js} +8 -7
  53. package/dist/{publish-6tgxfck9.js → publish-7yw4jyrt.js} +24 -8
  54. package/dist/render.js +65 -24
  55. package/dist/schema/manifest.types.d.ts +2 -1
  56. package/dist/{tokens-n82t4k9h.css → tokens-a7grv940.css} +4 -5
  57. package/dist/{validate-pktqrye5.js → validate-rkcdnzhw.js} +8 -7
  58. package/package.json +1 -1
  59. package/dist/index-46ycxe6r.js +0 -18
@@ -0,0 +1,76 @@
1
+ /**
2
+ * A stylesheet's root-level custom properties — the design settings Book
3
+ * setup shows — read and written with postcss (#454).
4
+ *
5
+ * "Root-level" means a declaration in a `:root` rule that is not inside
6
+ * `@media`, `@supports` or any other conditional group (and, postcss being a
7
+ * parser, never one in a comment). A `:root` inside a cascade layer counts,
8
+ * tagged with its layer. Values are read as written, so a `;` inside
9
+ * `url("data:…")` is part of the value, and a write changes only the
10
+ * declarations it names: every other byte of the sheet is kept.
11
+ *
12
+ * Host-side only: postcss never reaches the desktop's SPA (architecture rules
13
+ * §8). The desktop reads these through its `style/book-css` route and writes
14
+ * through `style/edit-tokens` (`book-css.ts`).
15
+ *
16
+ * **Token annotations (issue #244).** Theme authors curate what the guided
17
+ * panel shows with a tiny comment grammar in the `:root` block — no new file
18
+ * format, no schema, and (since it's ordinary CSS comments) no risk to a
19
+ * plain browser or a build that never heard of Gutterpress. Three
20
+ * directives, each written in a block comment right before the declaration it
21
+ * describes:
22
+ *
23
+ * - `@group <name>` — show the token under a "<name>" heading instead of the
24
+ * Fonts/Colors/Sizes/Other bucket its kind would choose.
25
+ * - `@label <text>` — the label shown instead of the default one.
26
+ * - `@internal` — leave the token out of the panel. The CSS is untouched.
27
+ *
28
+ * Each directive applies to the NEXT custom-property declaration only and is
29
+ * consumed by it. A block has defaults too (#435): `@group` and `@internal`
30
+ * in the comments directly BEFORE the `:root` selector apply to every
31
+ * declaration in the block that carries no directive of its own; a
32
+ * declaration's own `@group`, `@label` or `@internal` still wins for that
33
+ * declaration (its own `@group` or `@label` shows it even inside an
34
+ * `@internal` block). Several directives can share one comment (`@label X
35
+ * @group Y`) or be spread across consecutive comments. A comment with none of
36
+ * them is prose and changes nothing.
37
+ */
38
+ /** One root-level custom property, as a stylesheet declares it. */
39
+ export interface RootToken {
40
+ /** The property name, e.g. `--color-accent`. */
41
+ name: string;
42
+ /**
43
+ * The value as written, comments and the space before its `;` included, so
44
+ * writing it back restores the declaration byte for byte (`!important` is
45
+ * not part of it, and stays on the declaration).
46
+ */
47
+ value: string;
48
+ /** An `@label` annotation's text. */
49
+ label?: string;
50
+ /** An `@group` annotation (the declaration's own, else its block's). */
51
+ group?: string;
52
+ /** The cascade layer the `:root` rule sits in, dotted (`ext.look.theme`); absent when unlayered. */
53
+ layer?: string;
54
+ }
55
+ /** One pending change: a token's new value, or null to remove the book's declaration of it. */
56
+ export interface TokenUpdate {
57
+ name: string;
58
+ value: string | null;
59
+ }
60
+ /**
61
+ * Every root-level custom property a stylesheet declares, in source order,
62
+ * with its annotations; an `@internal` one is left out. Throws postcss's
63
+ * `CssSyntaxError` for a sheet it cannot parse.
64
+ */
65
+ export declare function rootTokens(css: string): RootToken[];
66
+ /**
67
+ * Apply a batch of token updates to a book's stylesheets, in cascade order,
68
+ * folding each onto the result of the last so none is lost. A value is set
69
+ * where the book already declares the token — every root-level declaration
70
+ * of it in the LAST sheet that has one, the one that wins — and otherwise
71
+ * added to `sheets[target]`. A null value removes the token from every
72
+ * sheet, so what the looks set shows through. Returns the sheets' new text;
73
+ * a sheet nothing changed comes back as it was given. Throws postcss's
74
+ * `CssSyntaxError` for a sheet it cannot parse.
75
+ */
76
+ export declare function applyTokenUpdates(sheets: readonly string[], target: number, updates: readonly TokenUpdate[]): string[];
@@ -17,10 +17,8 @@ export interface VersionChanges {
17
17
  /** Changed files beyond the ones listed (the list is capped). */
18
18
  more: number;
19
19
  }
20
- /** A history entry with what it changed and where it is kept. */
20
+ /** A history entry and where it is kept. */
21
21
  export interface VersionEntry extends SnapshotEntry {
22
- changes: VersionFileChange[];
23
- moreChanges: number;
24
22
  /** True = online too; false = on this computer only; null = no online copy to compare with. */
25
23
  backedUp: boolean | null;
26
24
  }
@@ -29,18 +27,20 @@ export declare const VERSION_CHANGES_SHOWN = 8;
29
27
  /** The size hint for a text file that changed between two versions. */
30
28
  export declare function changeHint(filepath: string, before: string, after: string): string;
31
29
  /**
32
- * The files `oid` changed against its first parent (every file, for a
33
- * version with no parent), sorted by path and capped to
30
+ * The files version `oid` of the book changed against its first parent
31
+ * (every file, for a version with no parent), sorted by path and capped to
34
32
  * {@link VERSION_CHANGES_SHOWN}.
35
33
  */
36
- export declare function listVersionChanges(dir: string, oid: string, options?: {
37
- cache?: object;
38
- }): Promise<VersionChanges>;
34
+ export declare function listVersionChanges(projectDir: string, oid: string): Promise<VersionChanges>;
39
35
  /**
40
- * A history page with each version's changes and whether it is backed up.
41
- * Versions come newest-first, and everything older than the first backed-up
42
- * one is backed up too, so the ancestry walk runs only over the versions
43
- * that are on this computer only.
36
+ * A history page with whether each version is backed up: whether it is the
37
+ * online tip or one of its earlier versions. Versions come newest-first, and
38
+ * everything older than the first backed-up one is backed up too. The rest
39
+ * share ONE breadth-first walk back from the tip, step for step the walk
40
+ * `git.isDescendent` makes (a shallow commit's parents are not followed; a
41
+ * missing object ends the walk, and a version not reached by then is not
42
+ * backed up): asking `isDescendent` once per version walked the whole history
43
+ * again for every version on this computer only.
44
44
  */
45
45
  export declare function describeVersions(projectDir: string, entries: SnapshotEntry[]): Promise<VersionEntry[]>;
46
46
  /**
@@ -8,7 +8,7 @@ styles:
8
8
  - styles/book.css
9
9
  # Page size and margins in points (72 = 1 in): US Letter with 1 in margins
10
10
  # (A4 is width 595, height 842); text stays 0.25 in (18) inside the trim.
11
- # Change them under Setup > Book.
11
+ # Change them in Book setup.
12
12
  page:
13
13
  width: 612
14
14
  height: 792
@@ -9,7 +9,7 @@ extensions:
9
9
  - technical-doc
10
10
  # Page size and margins in points (72 = 1 in): US Letter (8.5 x 11 in) with
11
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.
12
+ # the trim. Change them in Book setup.
13
13
  page:
14
14
  width: 612
15
15
  height: 792
@@ -8,7 +8,7 @@ styles:
8
8
  extensions:
9
9
  - clean-book
10
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.
11
+ # and outside. Change them, and the page size, in Book setup.
12
12
  page:
13
13
  margin:
14
14
  top: 61.2
@@ -8,8 +8,8 @@ styles:
8
8
  extensions:
9
9
  - zine
10
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.
11
+ # 0.4 in margins; text stays 0.25 in (18) inside the trim. Change them in
12
+ # Book setup.
13
13
  page:
14
14
  width: 396
15
15
  height: 612
@@ -242,7 +242,7 @@
242
242
  },
243
243
  "margin": {
244
244
  "type": "object",
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.",
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, except where a named page sets its own (`@page full { margin: 0 }`); 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.",
246
246
  "properties": {
247
247
  "top": { "type": "number", "description": "Top margin in points.", "minimum": 0, "examples": [61.2, 72] },
248
248
  "bottom": { "type": "number", "description": "Bottom margin in points.", "minimum": 0, "examples": [61.2, 72] },
@@ -3,12 +3,12 @@ import {
3
3
  EXTENSION_KINDS,
4
4
  scaffoldExtension,
5
5
  scaffoldProject
6
- } from "./cli-3cvq3n1c.js";
6
+ } from "./cli-989eg8jz.js";
7
7
  import {
8
8
  resolveGhostscript
9
- } from "./cli-mmgtqnmr.js";
9
+ } from "./cli-vhav8g82.js";
10
10
  import"./cli-ht1bcqdd.js";
11
- import"./cli-58fsk6d7.js";
11
+ import"./cli-k087gj0p.js";
12
12
  import"./cli-5crpmz42.js";
13
13
  import"./cli-eyyggect.js";
14
14
  import {
@@ -22,15 +22,16 @@ import {
22
22
  TARGET_IDS,
23
23
  loadManifest,
24
24
  resolveConfig
25
- } from "./cli-6pv84kf3.js";
26
- import"./cli-wyg7qstd.js";
27
- import"./cli-eatdqx3z.js";
25
+ } from "./cli-e31jshz6.js";
26
+ import"./cli-ttj95aex.js";
27
+ import"./cli-1fy1pm9d.js";
28
28
  import {
29
29
  UsageError,
30
30
  rejectExtraPositionals,
31
31
  rejectUnknownFlags
32
32
  } from "./cli-d8xjns66.js";
33
- import"./cli-5ba6bm6z.js";
33
+ import"./cli-s1zt779w.js";
34
+ import"./cli-65gy8ask.js";
34
35
  import {
35
36
  EXIT_CODES
36
37
  } from "./cli-46ycxe6r.js";
@@ -7,8 +7,8 @@
7
7
  * to a CSS `@page name`.
8
8
  *
9
9
  * NOT the page geometry. The trim size and the margins are the BOOK's,
10
- * recorded in its manifest (`preset:`, `page:` — Setup > Book in the
11
- * app) and written by the build after every stylesheet, so a `size` here
10
+ * recorded in its manifest (`preset:`, `page:` — set in Book setup) and
11
+ * written by the build after every stylesheet, so a `size` here
12
12
  * would be ignored (and reported) and a `margin` here would hold only
13
13
  * until the author sets margins in the app. Design the furniture below to
14
14
  * sit in whatever margin the book gives it.
@@ -8,7 +8,7 @@ import {
8
8
  loadPlugins,
9
9
  loadPluginsWithCss,
10
10
  loadPublishFunction
11
- } from "./index-fp7xwvpr.js";
11
+ } from "./index-a4j3xcfp.js";
12
12
  import"./index-5x42amh8.js";
13
13
  import"./index-37x76zdn.js";
14
14
  export {
@@ -8,9 +8,9 @@ import {
8
8
  loadPlugins,
9
9
  loadPluginsWithCss,
10
10
  loadPublishFunction
11
- } from "./cli-wyg7qstd.js";
12
- import"./cli-eatdqx3z.js";
13
- import"./cli-5ba6bm6z.js";
11
+ } from "./cli-ttj95aex.js";
12
+ import"./cli-1fy1pm9d.js";
13
+ import"./cli-s1zt779w.js";
14
14
  import"./cli-y28j019d.js";
15
15
  import"./cli-37x76zdn.js";
16
16
  export {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  executeValidation,
3
3
  reportMissingTools
4
- } from "./cli-3cvq3n1c.js";
5
- import"./cli-mmgtqnmr.js";
4
+ } from "./cli-989eg8jz.js";
5
+ import"./cli-vhav8g82.js";
6
6
  import"./cli-ht1bcqdd.js";
7
- import"./cli-58fsk6d7.js";
7
+ import"./cli-k087gj0p.js";
8
8
  import"./cli-5crpmz42.js";
9
9
  import"./cli-eyyggect.js";
10
10
  import"./cli-asap4t1z.js";
@@ -12,17 +12,18 @@ import"./cli-31anr0r9.js";
12
12
  import"./cli-v5mp7a6q.js";
13
13
  import {
14
14
  publishTargetFor
15
- } from "./cli-6pv84kf3.js";
16
- import"./cli-wyg7qstd.js";
15
+ } from "./cli-e31jshz6.js";
16
+ import"./cli-ttj95aex.js";
17
17
  import {
18
18
  log
19
- } from "./cli-eatdqx3z.js";
19
+ } from "./cli-1fy1pm9d.js";
20
20
  import {
21
21
  UsageError,
22
22
  rejectExtraPositionals,
23
23
  rejectUnknownFlags
24
24
  } from "./cli-d8xjns66.js";
25
- import"./cli-5ba6bm6z.js";
25
+ import"./cli-s1zt779w.js";
26
+ import"./cli-65gy8ask.js";
26
27
  import {
27
28
  BuildError,
28
29
  EXIT_CODES
@@ -3,23 +3,23 @@ import {
3
3
  runBuild,
4
4
  splitOutPath,
5
5
  startPreviewServer
6
- } from "./cli-3cvq3n1c.js";
7
- import"./cli-mmgtqnmr.js";
6
+ } from "./cli-989eg8jz.js";
7
+ import"./cli-vhav8g82.js";
8
8
  import {
9
9
  previewArgs
10
10
  } from "./cli-75qkn0k5.js";
11
11
  import"./cli-ht1bcqdd.js";
12
- import"./cli-58fsk6d7.js";
12
+ import"./cli-k087gj0p.js";
13
13
  import"./cli-5crpmz42.js";
14
14
  import"./cli-eyyggect.js";
15
15
  import"./cli-asap4t1z.js";
16
16
  import"./cli-31anr0r9.js";
17
17
  import"./cli-v5mp7a6q.js";
18
- import"./cli-6pv84kf3.js";
19
- import"./cli-wyg7qstd.js";
18
+ import"./cli-e31jshz6.js";
19
+ import"./cli-ttj95aex.js";
20
20
  import {
21
21
  log
22
- } from "./cli-eatdqx3z.js";
22
+ } from "./cli-1fy1pm9d.js";
23
23
  import {
24
24
  UsageError,
25
25
  parseFormat,
@@ -28,7 +28,8 @@ import {
28
28
  rejectUnknownFlags,
29
29
  resolvePort
30
30
  } from "./cli-d8xjns66.js";
31
- import"./cli-5ba6bm6z.js";
31
+ import"./cli-s1zt779w.js";
32
+ import"./cli-65gy8ask.js";
32
33
  import {
33
34
  BuildError
34
35
  } from "./cli-46ycxe6r.js";
@@ -10,12 +10,12 @@ import {
10
10
  resolvePublishFormat,
11
11
  resolvePublishProvider,
12
12
  runPublish
13
- } from "./cli-3cvq3n1c.js";
13
+ } from "./cli-989eg8jz.js";
14
14
  import {
15
15
  FileTokenStore
16
- } from "./cli-mmgtqnmr.js";
16
+ } from "./cli-vhav8g82.js";
17
17
  import"./cli-ht1bcqdd.js";
18
- import"./cli-58fsk6d7.js";
18
+ import"./cli-k087gj0p.js";
19
19
  import"./cli-5crpmz42.js";
20
20
  import"./cli-eyyggect.js";
21
21
  import"./cli-asap4t1z.js";
@@ -23,17 +23,18 @@ import"./cli-31anr0r9.js";
23
23
  import"./cli-v5mp7a6q.js";
24
24
  import {
25
25
  loadManifestWithPath
26
- } from "./cli-6pv84kf3.js";
27
- import"./cli-wyg7qstd.js";
26
+ } from "./cli-e31jshz6.js";
27
+ import"./cli-ttj95aex.js";
28
28
  import {
29
29
  log
30
- } from "./cli-eatdqx3z.js";
30
+ } from "./cli-1fy1pm9d.js";
31
31
  import {
32
32
  UsageError,
33
33
  rejectExtraPositionals,
34
34
  rejectUnknownFlags
35
35
  } from "./cli-d8xjns66.js";
36
- import"./cli-5ba6bm6z.js";
36
+ import"./cli-s1zt779w.js";
37
+ import"./cli-65gy8ask.js";
37
38
  import {
38
39
  BuildError,
39
40
  EXIT_CODES
@@ -128,6 +129,14 @@ var commandArgs = {
128
129
  type: "string",
129
130
  description: "Artifact to publish (PDF path, or HTML export dir). Default: the manifest's output location"
130
131
  },
132
+ "folder-id": {
133
+ type: "string",
134
+ description: "Google Drive: publish to this folder id for this run only (the manifest is not changed)"
135
+ },
136
+ folder: {
137
+ type: "string",
138
+ description: "Google Drive: publish to the folder with this name in your own Drive, found or created, for this run only (the manifest is not changed)"
139
+ },
131
140
  manifest: { type: "string", description: "Path to manifest.yaml" },
132
141
  "dry-run": { type: "boolean", description: "Preflight only; don't contact the platform" },
133
142
  json: { type: "boolean", description: "Machine-readable JSON output (CI)" },
@@ -274,6 +283,12 @@ Create one at: ${provider.info.credential.tokenUrl}` : ""));
274
283
  log.success(`Connected ${provider.info.label}${account ? ` (${account})` : ""}. The key is stored in your user config, not the book.`);
275
284
  return;
276
285
  }
286
+ const folderId = typeof args["folder-id"] === "string" ? args["folder-id"].trim() : "";
287
+ const folder = typeof args.folder === "string" ? args.folder.trim() : "";
288
+ if ((folderId || folder) && provider.info.id !== "gdrive") {
289
+ log.error("--folder-id and --folder are for --provider gdrive.");
290
+ process.exit(EXIT_CODES.USAGE);
291
+ }
277
292
  let result;
278
293
  try {
279
294
  result = await runPublish({
@@ -282,7 +297,8 @@ Create one at: ${provider.info.credential.tokenUrl}` : ""));
282
297
  provider,
283
298
  manifestPath: typeof args.manifest === "string" ? args.manifest : undefined,
284
299
  artifactPath: typeof args.file === "string" ? args.file : undefined,
285
- dryRun: !!args["dry-run"]
300
+ dryRun: !!args["dry-run"],
301
+ ...folderId || folder ? { settings: { folderId, folder } } : {}
286
302
  }, deps);
287
303
  } catch (e) {
288
304
  if (e instanceof UsageError) {
package/dist/render.js CHANGED
@@ -3008,6 +3008,7 @@ var UNITS_PER_PT = {
3008
3008
  var DEFAULT_PAGE_MARGIN_PT = 72;
3009
3009
 
3010
3010
  // src/lib/markdown/assemble.ts
3011
+ import postcss from "postcss";
3011
3012
  function pageGeometryCss(page) {
3012
3013
  if (!page || !isPositivePoints(page.width) || !isPositivePoints(page.height))
3013
3014
  return null;
@@ -3028,6 +3029,65 @@ function defaultPageMarginCss(page) {
3028
3029
  @page { margin: ${cssLength(DEFAULT_PAGE_MARGIN_PT)}; }
3029
3030
  }`;
3030
3031
  }
3032
+ function liftPageRules(css) {
3033
+ if (!/@page\b/i.test(css))
3034
+ return { layered: css, pages: "" };
3035
+ let root;
3036
+ try {
3037
+ root = postcss.parse(css);
3038
+ } catch {
3039
+ return { layered: css, pages: "" };
3040
+ }
3041
+ const found = [];
3042
+ root.walkAtRules(/^page$/i, (rule) => {
3043
+ found.push(rule);
3044
+ });
3045
+ const pages = found.map((rule) => {
3046
+ let lifted = rule.clone();
3047
+ for (let p = rule.parent;p instanceof postcss.AtRule || p instanceof postcss.Rule; p = p.parent) {
3048
+ if (p instanceof postcss.AtRule && p.name.toLowerCase() === "layer")
3049
+ continue;
3050
+ lifted = p.clone({ nodes: [] }).append(lifted);
3051
+ }
3052
+ rule.remove();
3053
+ return lifted.toString();
3054
+ });
3055
+ return { layered: root.toString(), pages: pages.join(`
3056
+ `) };
3057
+ }
3058
+ var CORE_MARKERS = liftPageRules(`${MARKER_CSS.trim()}
3059
+ ${TWO_VERSIONS_CSS.trim()}`);
3060
+ var CORE_VOCAB = liftPageRules(GUTTERPRESS_CSS.trim());
3061
+ function assembleCssChunks(opts) {
3062
+ const core = (css) => css ? [{ origin: { kind: "core" }, css }] : [];
3063
+ const headed = (title, chunks = []) => chunks.map((chunk, i) => i === 0 ? { ...chunk, css: `/* ${title} */
3064
+ ${chunk.css.trim()}` } : chunk);
3065
+ const pageGeometry = pageGeometryCss(opts.printArea);
3066
+ const defaultMargin = defaultPageMarginCss(opts.printArea);
3067
+ return [
3068
+ ...core("@layer gp.marker, gp.vocab;"),
3069
+ ...core(`/* gutterpress markers */
3070
+ @layer gp.marker {
3071
+ ${CORE_MARKERS.layered.trim()}
3072
+ }`),
3073
+ ...core(CORE_MARKERS.pages && `/* gutterpress markers: page rules */
3074
+ ${CORE_MARKERS.pages}`),
3075
+ ...core(`/* gutterpress */
3076
+ @layer gp.vocab {
3077
+ ${CORE_VOCAB.layered.trim()}
3078
+ }`),
3079
+ ...core(CORE_VOCAB.pages && `/* gutterpress: page rules */
3080
+ ${CORE_VOCAB.pages}`),
3081
+ ...core(defaultMargin && `/* page margins (default) */
3082
+ ${defaultMargin}`),
3083
+ ...headed("extension css", opts.extensions),
3084
+ ...core(`/* column alignment */
3085
+ ${TABLE_ALIGN_CSS.trim()}`),
3086
+ ...headed("project css", opts.book),
3087
+ ...core(pageGeometry && `/* page geometry (manifest) */
3088
+ ${pageGeometry}`)
3089
+ ];
3090
+ }
3031
3091
  async function assembleBookHtml(opts) {
3032
3092
  const title = opts.title ?? "Document";
3033
3093
  const projectCss = opts.projectCss ?? "";
@@ -3066,30 +3126,11 @@ async function assembleBookHtml(opts) {
3066
3126
  imageRefs.add(ref);
3067
3127
  opts.onImageRefs([...imageRefs]);
3068
3128
  }
3069
- const pageGeometry = pageGeometryCss(opts.printArea);
3070
- const defaultMargin = defaultPageMarginCss(opts.printArea);
3071
- const inlineCss = [
3072
- "@layer gp.marker, gp.vocab;",
3073
- `/* gutterpress markers */
3074
- @layer gp.marker {
3075
- ${MARKER_CSS.trim()}
3076
- ${TWO_VERSIONS_CSS.trim()}
3077
- }`,
3078
- `/* gutterpress */
3079
- @layer gp.vocab {
3080
- ${GUTTERPRESS_CSS.trim()}
3081
- }`,
3082
- defaultMargin ? `/* page margins (default) */
3083
- ${defaultMargin}` : null,
3084
- pluginCss ? `/* extension css */
3085
- ${pluginCss.trim()}` : null,
3086
- `/* column alignment */
3087
- ${TABLE_ALIGN_CSS.trim()}`,
3088
- projectCss ? `/* project css */
3089
- ${projectCss.trim()}` : null,
3090
- pageGeometry ? `/* page geometry (manifest) */
3091
- ${pageGeometry}` : null
3092
- ].filter(Boolean).join(`
3129
+ const inlineCss = assembleCssChunks({
3130
+ printArea: opts.printArea,
3131
+ extensions: pluginCss ? [{ origin: { kind: "extension" }, css: pluginCss }] : [],
3132
+ book: projectCss ? [{ origin: { kind: "book" }, css: projectCss }] : []
3133
+ }).map((chunk) => chunk.css).join(`
3093
3134
 
3094
3135
  `);
3095
3136
  const preloadTags = (opts.preloadImages ?? []).map((href) => `
@@ -266,7 +266,8 @@ export interface GutterpressManifest {
266
266
  * Page margins (pt), the space between the trim and the text on each
267
267
  * edge — `inside` is the binding edge, `outside` the other. Setup >
268
268
  * Details in the app writes it. When set, the book prints with these
269
- * margins and any `@page` margin in a stylesheet is overridden; left
269
+ * margins and any `@page` margin in a stylesheet is overridden, except
270
+ * where a named page sets its own (`@page full { margin: 0 }`); left
270
271
  * out, the stylesheets' `@page` margins apply (a look's design), else
271
272
  * 1in. All four edges are required together.
272
273
  */
@@ -4,9 +4,8 @@
4
4
  * OWNS
5
5
  * `:root` custom properties, and nothing else. The palette, the type scale,
6
6
  * the spacing scale, the measure. This is the file to edit to rebrand the
7
- * look. The desktop app's Book setup lists these tokens (the six shared
8
- * ones under Look, every one under Advanced) and saves a book's changes
9
- * to that book's own stylesheet, never to this file.
7
+ * look. The desktop app's Book setup lists these tokens and saves a
8
+ * book's changes to that book's own stylesheet, never to this file.
10
9
  *
11
10
  * MUST NOT CONTAIN
12
11
  * - Any selector other than `:root`. The moment a rule here targets `h1`,
@@ -18,12 +17,12 @@
18
17
  * waiting to happen.
19
18
  * - Anything a specific book needs. Book-specific values go in book.css.
20
19
  *
21
- * WHAT THE DESIGN TAB SHOWS is curated with comments. Right above one
20
+ * WHAT BOOK SETUP SHOWS is curated with comments. Right above one
22
21
  * declaration: `@label Accent color` (its plain-words name), `@group Paper`
23
22
  * (its heading), `@internal` (not shown). Right above a `:root` selector:
24
23
  * `@group` or `@internal` for the whole block, which a declaration's own
25
24
  * comment overrides. One `@internal` line above a block of component
26
- * defaults keeps them off the tab.
25
+ * defaults keeps them out of Book setup.
27
26
  *
28
27
  * LOADS FIRST, and therefore declares the layer order for the whole stack.
29
28
  * ======================================================================== */
@@ -1,25 +1,26 @@
1
1
  import {
2
2
  executeAndReport
3
- } from "./cli-3cvq3n1c.js";
4
- import"./cli-mmgtqnmr.js";
3
+ } from "./cli-989eg8jz.js";
4
+ import"./cli-vhav8g82.js";
5
5
  import"./cli-ht1bcqdd.js";
6
- import"./cli-58fsk6d7.js";
6
+ import"./cli-k087gj0p.js";
7
7
  import"./cli-5crpmz42.js";
8
8
  import"./cli-eyyggect.js";
9
9
  import"./cli-asap4t1z.js";
10
10
  import"./cli-31anr0r9.js";
11
11
  import"./cli-v5mp7a6q.js";
12
- import"./cli-6pv84kf3.js";
13
- import"./cli-wyg7qstd.js";
12
+ import"./cli-e31jshz6.js";
13
+ import"./cli-ttj95aex.js";
14
14
  import {
15
15
  log
16
- } from "./cli-eatdqx3z.js";
16
+ } from "./cli-1fy1pm9d.js";
17
17
  import {
18
18
  UsageError,
19
19
  rejectExtraPositionals,
20
20
  rejectUnknownFlags
21
21
  } from "./cli-d8xjns66.js";
22
- import"./cli-5ba6bm6z.js";
22
+ import"./cli-s1zt779w.js";
23
+ import"./cli-65gy8ask.js";
23
24
  import {
24
25
  BuildError,
25
26
  EXIT_CODES
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gutterpress",
3
- "version": "0.11.23-alpha.7",
3
+ "version": "0.11.23-beta.1",
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,18 +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
- export { EXIT_CODES, BuildError };