gutterpress 0.9.0-alpha.2 → 0.10.0-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 (138) hide show
  1. package/README.md +18 -4
  2. package/dist/api/index.d.ts +11 -5
  3. package/dist/api/index.js +20 -15
  4. package/dist/assets/preview/scripts/preview-bridge.d.ts +1 -0
  5. package/dist/assets/preview/scripts/preview-interface.d.ts +1 -0
  6. package/dist/{audit-nhn2pjz3.js → audit-xxegv0t0.js} +10 -7
  7. package/dist/{build-san7fv2z.js → build-w0vb6mgq.js} +14 -8
  8. package/dist/checks/source/index.d.ts +1 -0
  9. package/dist/checks/source/layout-markers.d.ts +3 -0
  10. package/dist/checks/source/local-ref-parser.d.ts +28 -0
  11. package/dist/cli-46ycxe6r.js +18 -0
  12. package/dist/{cli-k4bd06sd.js → cli-5czby0dd.js} +4986 -5889
  13. package/dist/cli-c41yr7he.js +241 -0
  14. package/dist/{cli-e5zhb0xs.js → cli-f4rcbt2t.js} +17 -24
  15. package/dist/{cli-najycadg.js → cli-gk3wsdpb.js} +69 -253
  16. package/dist/{index-yzrh708h.js → cli-k1065rkg.js} +2 -5
  17. package/dist/{cli-506tg37g.js → cli-revgt4pr.js} +2 -1
  18. package/dist/{cli-wchtvxvw.js → cli-v5mp7a6q.js} +14 -1
  19. package/dist/cli-yp3p0sf2.js +2343 -0
  20. package/dist/cli.js +20 -18
  21. package/dist/{doctor-hrk0kxxz.js → doctor-ctgn1dnt.js} +4 -2
  22. package/dist/engine/compiler/build.d.ts +139 -0
  23. package/dist/engine/compiler/postprocess.d.ts +23 -0
  24. package/dist/engine/compiler/tier2.d.ts +78 -0
  25. package/dist/engine/shared/cdp.d.ts +104 -0
  26. package/dist/engine/shared/content-value.d.ts +64 -0
  27. package/dist/engine/shared/gcpm-extract.d.ts +119 -0
  28. package/dist/engine/shared/margin-box-support.d.ts +12 -0
  29. package/dist/engine/shared/pdf-inspect.d.ts +24 -0
  30. package/dist/engine/shared/synthesis.d.ts +155 -0
  31. package/dist/engine-eng4xh2q.js +41 -0
  32. package/dist/engine-q5skhgms.js +40 -0
  33. package/dist/gutterpress-agent-1ctgfz92.js +576 -0
  34. package/dist/gutterpress-viewer-cem7dmr5.js +2349 -0
  35. package/dist/index-a4kr77td.js +1907 -0
  36. package/dist/{cli-yzrh708h.js → index-mdefp0y5.js} +1 -1
  37. package/dist/index-mvehxh0e.js +708 -0
  38. package/dist/{index-bynn850m.js → index-s416qpdv.js} +3049 -4015
  39. package/dist/{index-wchtvxvw.js → index-v5mp7a6q.js} +14 -1
  40. package/dist/index.d.ts +3 -1
  41. package/dist/index.js +24 -17
  42. package/dist/lib/asset-inline.d.ts +36 -0
  43. package/dist/lib/browser-pool.d.ts +18 -0
  44. package/dist/lib/build-error.d.ts +1 -1
  45. package/dist/lib/build-preflight.d.ts +35 -2
  46. package/dist/lib/build-runner.d.ts +45 -17
  47. package/dist/lib/build-staging.d.ts +9 -55
  48. package/dist/lib/cli-args.d.ts +8 -0
  49. package/dist/lib/desktop.d.ts +2 -2
  50. package/dist/lib/embedded-assets.d.ts +1 -1
  51. package/dist/lib/engine.d.ts +33 -0
  52. package/dist/lib/ghostscript.d.ts +46 -1
  53. package/dist/lib/markdown/assemble.d.ts +18 -10
  54. package/dist/lib/markdown/gp-pin-scope.d.ts +1 -0
  55. package/dist/lib/markdown/gutterpress-css.d.ts +125 -0
  56. package/dist/lib/markdown/images.d.ts +26 -0
  57. package/dist/lib/markdown/index.d.ts +4 -2
  58. package/dist/lib/markdown/inline-source.d.ts +10 -0
  59. package/dist/lib/markdown/markers.d.ts +32 -0
  60. package/dist/lib/markdown/renderer.d.ts +8 -3
  61. package/dist/lib/markdown/source-range.d.ts +61 -0
  62. package/dist/lib/missing-asset-placeholder.d.ts +52 -0
  63. package/dist/lib/presets.d.ts +1 -1
  64. package/dist/lib/printsafe.d.ts +2 -3
  65. package/dist/lib/remote-auth/converge-merge.d.ts +48 -0
  66. package/dist/lib/remote-auth/image-clash.d.ts +17 -0
  67. package/dist/lib/remote-auth/recovery/classify.d.ts +55 -67
  68. package/dist/lib/remote-auth/recovery/inspect.d.ts +14 -13
  69. package/dist/lib/remote-auth/recovery/locks.d.ts +20 -0
  70. package/dist/lib/remote-auth/recovery/repair.d.ts +29 -0
  71. package/dist/lib/remote-auth/recovery/types.d.ts +8 -204
  72. package/dist/lib/remote-auth/sync-messages.d.ts +2 -3
  73. package/dist/lib/remote-auth/sync-types.d.ts +35 -63
  74. package/dist/lib/remote-auth/sync.d.ts +11 -18
  75. package/dist/lib/remote-auth/transport.d.ts +14 -7
  76. package/dist/lib/theme-import.d.ts +4 -5
  77. package/dist/{lint-96j9hrj4.js → lint-gsh6qwrq.js} +10 -7
  78. package/dist/{manifest.schema-z61rzw44.json → manifest.schema-zxgxnbg7.json} +21 -0
  79. package/dist/{new-8p38wavc.js → new-nkhycqy4.js} +12 -8
  80. package/dist/{plugin-ees6nhkc.js → plugin-129wcs93.js} +10 -7
  81. package/dist/{preflight-1q6c2edh.js → preflight-41hcejg9.js} +10 -7
  82. package/dist/preview/file-watcher.d.ts +13 -17
  83. package/dist/preview/lifecycle.d.ts +1 -1
  84. package/dist/{pagedjs-bridge-vn4hk9fx.js → preview-bridge-fz7vpk8m.js} +8 -0
  85. package/dist/preview-interface-fnqb2y4v.js +1015 -0
  86. package/dist/{preview-y5a2zen1.js → preview-pftsvr9z.js} +16 -9
  87. package/dist/preview-shell-c5mfa3q0.js +346 -0
  88. package/dist/{project-source-p0gn1wd5.js → project-source-ekcyp63q.js} +1 -1
  89. package/dist/{publish-rm9yb3wh.js → publish-dnjvb4jg.js} +10 -7
  90. package/dist/render.d.ts +3 -4
  91. package/dist/render.js +728 -64
  92. package/dist/{repair-zgq7q2g6.js → repair-a3enjttn.js} +45 -79
  93. package/dist/schema/manifest.types.d.ts +38 -0
  94. package/dist/{source-provider-c1rjm2c0.js → source-provider-3tcj6qg2.js} +2 -2
  95. package/dist/source-provider-vanafrt9.js +40 -0
  96. package/dist/{theme-zz2ktzqs.css → theme-h5recz6c.css} +8 -7
  97. package/dist/{theme-570zmh2t.css → theme-j2bagrfx.css} +8 -7
  98. package/dist/{theme-nya4nqh6.css → theme-nn6d53zy.css} +8 -7
  99. package/dist/types.d.ts +7 -0
  100. package/dist/{validate-nr0xa6sa.js → validate-ph1xffqy.js} +10 -7
  101. package/package.json +6 -6
  102. package/dist/cli-yja077f6.js +0 -92
  103. package/dist/git-http-yrb4ag6z.js +0 -17
  104. package/dist/index-yja077f6.js +0 -92
  105. package/dist/lib/markdown/markdown-it-paged.d.ts +0 -30
  106. package/dist/lib/pagedjs-marker.d.ts +0 -42
  107. package/dist/lib/pagedjs.d.ts +0 -26
  108. package/dist/lib/pagination.d.ts +0 -149
  109. package/dist/lib/remote-auth/conflict-resolution.d.ts +0 -29
  110. package/dist/lib/remote-auth/recovery/abort-interrupted-operation.d.ts +0 -103
  111. package/dist/lib/remote-auth/recovery/backup.d.ts +0 -113
  112. package/dist/lib/remote-auth/recovery/context.d.ts +0 -47
  113. package/dist/lib/remote-auth/recovery/dispatch.d.ts +0 -28
  114. package/dist/lib/remote-auth/recovery/failsafe.d.ts +0 -33
  115. package/dist/lib/remote-auth/recovery/manual-guidance.d.ts +0 -28
  116. package/dist/lib/remote-auth/recovery/outcome-mapping.d.ts +0 -59
  117. package/dist/lib/remote-auth/recovery/policy.d.ts +0 -47
  118. package/dist/lib/remote-auth/recovery/recover-auth.d.ts +0 -42
  119. package/dist/lib/remote-auth/recovery/recover-binary-conflict.d.ts +0 -37
  120. package/dist/lib/remote-auth/recovery/recover-corrupt-index.d.ts +0 -40
  121. package/dist/lib/remote-auth/recovery/recover-detached-head.d.ts +0 -70
  122. package/dist/lib/remote-auth/recovery/recover-interrupted-cherry-pick.d.ts +0 -23
  123. package/dist/lib/remote-auth/recovery/recover-interrupted-merge.d.ts +0 -28
  124. package/dist/lib/remote-auth/recovery/recover-interrupted-rebase.d.ts +0 -39
  125. package/dist/lib/remote-auth/recovery/recover-merge-conflict.d.ts +0 -34
  126. package/dist/lib/remote-auth/recovery/recover-missing-git-dir.d.ts +0 -37
  127. package/dist/lib/remote-auth/recovery/recover-missing-objects.d.ts +0 -56
  128. package/dist/lib/remote-auth/recovery/recover-network.d.ts +0 -34
  129. package/dist/lib/remote-auth/recovery/recover-non-fast-forward.d.ts +0 -27
  130. package/dist/lib/remote-auth/recovery/recover-stale-lock.d.ts +0 -68
  131. package/dist/lib/remote-auth/recovery/recover-unrelated-histories.d.ts +0 -44
  132. package/dist/lib/remote-auth/recovery/recover-wrong-remote.d.ts +0 -35
  133. package/dist/lib/remote-auth/resolution-plan.d.ts +0 -64
  134. package/dist/paged.polyfill-n95pbxfn.js +0 -33288
  135. package/dist/pagedjs-interface-qxvzgwd7.js +0 -557
  136. package/dist/preview-shell-6dqexx1m.js +0 -581
  137. /package/dist/assets/{preview/scripts/pagedjs-bridge.d.ts → engine/gutterpress-agent.d.ts} +0 -0
  138. /package/dist/assets/{preview/scripts/pagedjs-interface.d.ts → engine/gutterpress-viewer.d.ts} +0 -0
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Shared synthesis policy — the single implementation both renderers consume.
3
+ *
4
+ * The compiler and the viewer must produce the same book from the same CSS, so
5
+ * every rule that DECIDES something (where blank pages go, which string value a
6
+ * page shows) lives here as a pure function. The renderers differ only in how
7
+ * they measure (client rects vs the PDF's /Dests) and how they apply (DOM
8
+ * spacers vs DOM spacers via the agent) — never in policy. This is what keeps
9
+ * "every compiler-side synthesis needs a viewer-side twin" from rotting: there
10
+ * is no twin, there is one function.
11
+ */
12
+ /** `break-before` values Chromium treats as a plain page break but shouldn't. */
13
+ export declare const RECTO_VERSO_VALUES: RegExp;
14
+ export declare function isRectoVersoBreak(decl: {
15
+ prop: string;
16
+ value: string;
17
+ }): boolean;
18
+ export declare function wantsRecto(value: string): boolean;
19
+ export interface RectoSite {
20
+ /** 1-based page the element landed on in a clean (spacer-free) layout */
21
+ page: number;
22
+ /** true = must start on a right-hand page; false = left-hand */
23
+ wantsRecto: boolean;
24
+ }
25
+ /**
26
+ * Which sites need a blank page inserted before them.
27
+ *
28
+ * Pure and analytic: a blank page shifts every later page by exactly one and
29
+ * changes no content, so the whole set follows from one clean measurement —
30
+ * walk the sites in document order carrying the count of blanks inserted so
31
+ * far. (Toggling spacers one measure-pass at a time oscillates instead: the
32
+ * spacer fixes the parity, the next pass sees it fixed and removes it.)
33
+ *
34
+ * Page 1 is a recto; recto pages are odd.
35
+ */
36
+ export declare function planRectoBlanks(sites: RectoSite[]): boolean[];
37
+ export type StringWhich = "first" | "start" | "last" | "first-except";
38
+ export interface StringEntry {
39
+ /** 1-based page the assignment lands on */
40
+ page: number;
41
+ value: string;
42
+ }
43
+ export declare function parseWhich(raw: string | undefined): StringWhich;
44
+ /**
45
+ * The value `string(name, which)` shows on `page`, per CSS GCPM §2.4:
46
+ *
47
+ * - `first` — the value of the first assignment on the page; if none, the
48
+ * entry value (what was in effect at the top of the page).
49
+ * - `start` — the entry value: the value in effect at the START of the page
50
+ * (assignments on the page itself don't count).
51
+ * - `last` — the value of the last assignment on the page; if none, the entry
52
+ * value.
53
+ * - `first-except` — empty on pages where an assignment happens (the chapter
54
+ * opener), the entry value elsewhere. The classic "no running head on the
55
+ * opener" behaviour.
56
+ *
57
+ * `entries` must be sorted by page; multiple entries on one page keep document
58
+ * order.
59
+ */
60
+ export declare function stringValueAt(entries: StringEntry[], page: number, which?: StringWhich): string;
61
+ /**
62
+ * One symbol per page for a `@counter-style { system: fixed }` map — the
63
+ * compiler's whole running-heads mechanism is `stringValueAt` sampled at every
64
+ * page (verified in s3).
65
+ */
66
+ export declare function stringSymbols(entries: StringEntry[], pageCount: number, which?: StringWhich): string[];
67
+ /** CSS-escape a string for use inside a double-quoted `symbols:` list. */
68
+ export declare function cssQuote(s: string): string;
69
+ /** Stable generated counter-style name for a (string name, which) pair. */
70
+ export declare function counterStyleName(name: string, which: StringWhich): string;
71
+ export interface PageCounterReset {
72
+ /** 1-based page (after recto/verso blank insertion) the reset takes effect on */
73
+ page: number;
74
+ /** the value `counter-reset: page N` sets */
75
+ start: number;
76
+ }
77
+ /**
78
+ * One numeric `counter(page)` value per page, honoring `counter-reset: page N`
79
+ * restarts the author declared in content flow.
80
+ *
81
+ * Native Chromium print ignores this restart entirely (ENGINE.md §8: the
82
+ * element sits on page 3, the margin box still reads 3) — front-matter (roman)
83
+ * → body (arabic from 1) is therefore not expressible in the author's content,
84
+ * so the compiler replays the restart as a fixed per-page value list, the same
85
+ * trick `stringSymbols` uses for `string()`. Formatting (`lower-roman` front
86
+ * matter vs decimal body) is a separate, per-`@page`-context concern the
87
+ * caller applies with `formatCounter` — this function only fixes the NUMBER,
88
+ * so one map serves every context regardless of which style each requests.
89
+ *
90
+ * Pure and analytic, like `planRectoBlanks`: one pass, no fixpoint. A blank
91
+ * page inserted before a restart site shifts `page` by exactly one, which is
92
+ * why `page` must be the FINAL (post-blank) page number — the caller resolves
93
+ * that the same way it resolves every other measured page (`ENGINE.md` §6).
94
+ *
95
+ * Multiple resets on the same page keep the LAST one in `resets` order,
96
+ * matching `counter-reset`'s own last-write-wins cascade. `resets` need not be
97
+ * pre-sorted.
98
+ */
99
+ export declare function pageCounterValues(resets: PageCounterReset[], pageCount: number): number[];
100
+ /**
101
+ * `resetSites` (id + declared start) -> `pageCounterValues`'s input shape,
102
+ * resolved against a measured id->page map. Both the compiler's folio-CSS
103
+ * synthesis (`counterStyleCss`) and its `target-counter()` resolution
104
+ * (`applySynthesis`) need this same resets->values step — one function, so
105
+ * a page's own folio and a cross-reference TO that page can never disagree
106
+ * (F2/F3). Returns `null` when the document declares no restart, so a
107
+ * caller can fall back to the raw physical page number.
108
+ */
109
+ export declare function restartedPageValues(resetSites: Array<{
110
+ id: string;
111
+ start: number;
112
+ }>, pageMap: Record<string, number>, pageCount: number): number[] | null;
113
+ /**
114
+ * A 1-based PHYSICAL page number -> the folio it actually prints, honoring a
115
+ * `counter-reset: page N` restart (F3: `target-counter(attr(href), page)`
116
+ * must resolve to the SAME folio the target page's own margin box prints,
117
+ * not the raw physical page). `pageValues` is the array `pageCounterValues`
118
+ * (or `restartedPageValues`) produced; `null` means no restart is in play.
119
+ */
120
+ export declare function toFolioPage(physicalPage: number, pageValues: number[] | null): number;
121
+ /**
122
+ * Marker pair wrapping a pending leader inside generated content. Private-use
123
+ * codepoints so author text can never collide; the glue string sits between
124
+ * them. Both renderers replace the marker with a measured run of glue.
125
+ */
126
+ export declare const LEADER_START = "\uE000";
127
+ export declare const LEADER_END = "\uE001";
128
+ export declare function leaderMarker(glue: string): string;
129
+ export declare const LEADER_RE: RegExp;
130
+ /**
131
+ * How many glue repetitions fill `gapPx`. One short of the exact quotient so
132
+ * the line can never overflow by a rounding error — measured on print output:
133
+ * numbers land 1–2 glue-widths from the content edge, nothing wraps.
134
+ */
135
+ export declare function leaderFillCount(gapPx: number, gluePx: number): number;
136
+ /**
137
+ * CSS that makes Gutterpress's computed text win over the author's own rule.
138
+ *
139
+ * Gutterpress resolves `target-counter()` / `target-text()` / `leader()` into a
140
+ * `data-gp-after|before` attribute and renders it with `content: attr(…)`.
141
+ *
142
+ * The pinned engine PARSES `target-counter()` (and `CSS.supports()` reports it
143
+ * as supported) but computes the whole `content` value to `none` — nothing
144
+ * renders. So the author's declaration SURVIVES the cascade, and
145
+ * `a.xref::after` (0,1,1) outranks a bare `[data-gp-after]::after` (0,1,0):
146
+ * a lower-specificity override loses to the author's empty value and the
147
+ * cross-reference silently disappears.
148
+ *
149
+ * The fix is to out-specify the author on their own terms: reuse their selector
150
+ * and add Gutterpress's attribute to it, so the override is strictly more specific
151
+ * than the rule it must beat, whatever that rule looks like. The bare rules are
152
+ * kept as a fallback for content Gutterpress generates on elements no author selector
153
+ * mentions.
154
+ */
155
+ export declare function generatedContentCss(selectors: Iterable<string>): string;
@@ -0,0 +1,41 @@
1
+ import {
2
+ RENDER_TIMEOUT_MS,
3
+ assertMilestone,
4
+ build,
5
+ connectChromium,
6
+ getBrowser
7
+ } from "./cli-yp3p0sf2.js";
8
+ import"./cli-c41yr7he.js";
9
+ import {
10
+ BuildError
11
+ } from "./cli-46ycxe6r.js";
12
+ import"./cli-37x76zdn.js";
13
+
14
+ // src/lib/engine.ts
15
+ import { writeFile } from "node:fs/promises";
16
+ async function buildNativePdf(htmlFile, outPdf, options = {}, getEngineBrowser) {
17
+ let result;
18
+ try {
19
+ const engineBrowser = getEngineBrowser ? await getEngineBrowser() : await connectChromium((await getBrowser(RENDER_TIMEOUT_MS)).wsEndpoint());
20
+ if (getEngineBrowser) {
21
+ try {
22
+ assertMilestone(engineBrowser.version, "(host-supplied browser)");
23
+ } catch (e) {
24
+ await engineBrowser.close();
25
+ throw e;
26
+ }
27
+ }
28
+ try {
29
+ result = await build({ input: htmlFile, browser: engineBrowser, ...options });
30
+ } finally {
31
+ await engineBrowser.close();
32
+ }
33
+ } catch (err) {
34
+ throw new BuildError(`--engine native failed: ${err instanceof Error ? err.message : String(err)}`);
35
+ }
36
+ await writeFile(outPdf, result.bytes);
37
+ return result.diagnostics;
38
+ }
39
+ export {
40
+ buildNativePdf
41
+ };
@@ -0,0 +1,40 @@
1
+ import {
2
+ build
3
+ } from "./index-a4kr77td.js";
4
+ import {
5
+ BuildError,
6
+ RENDER_TIMEOUT_MS,
7
+ assertMilestone,
8
+ connectChromium,
9
+ getBrowser
10
+ } from "./index-mvehxh0e.js";
11
+ import"./index-37x76zdn.js";
12
+
13
+ // src/lib/engine.ts
14
+ import { writeFile } from "node:fs/promises";
15
+ async function buildNativePdf(htmlFile, outPdf, options = {}, getEngineBrowser) {
16
+ let result;
17
+ try {
18
+ const engineBrowser = getEngineBrowser ? await getEngineBrowser() : await connectChromium((await getBrowser(RENDER_TIMEOUT_MS)).wsEndpoint());
19
+ if (getEngineBrowser) {
20
+ try {
21
+ assertMilestone(engineBrowser.version, "(host-supplied browser)");
22
+ } catch (e) {
23
+ await engineBrowser.close();
24
+ throw e;
25
+ }
26
+ }
27
+ try {
28
+ result = await build({ input: htmlFile, browser: engineBrowser, ...options });
29
+ } finally {
30
+ await engineBrowser.close();
31
+ }
32
+ } catch (err) {
33
+ throw new BuildError(`--engine native failed: ${err instanceof Error ? err.message : String(err)}`);
34
+ }
35
+ await writeFile(outPdf, result.bytes);
36
+ return result.diagnostics;
37
+ }
38
+ export {
39
+ buildNativePdf
40
+ };