gutterpress 0.0.0

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 (230) hide show
  1. package/README.md +422 -0
  2. package/dist/CGATS21_CRPC1-g0e3k7kr.icc +0 -0
  3. package/dist/api/index.d.ts +76 -0
  4. package/dist/api/index.js +272 -0
  5. package/dist/assets/preview/scripts/pagedjs-bridge.d.ts +1 -0
  6. package/dist/assets/preview/scripts/pagedjs-interface.d.ts +1 -0
  7. package/dist/assets/preview/scripts/preview-shell.d.ts +1 -0
  8. package/dist/audit-1jrwwacz.js +66 -0
  9. package/dist/build-5s92kgpc.js +77 -0
  10. package/dist/chapter-01-6fn9pvd0.md +31 -0
  11. package/dist/chapter-01-7jwqg1ct.md +20 -0
  12. package/dist/chapter-01-jj8ftn4c.md +29 -0
  13. package/dist/chapter-01-rkpyvjna.md +26 -0
  14. package/dist/checks/asset/approved-fonts.d.ts +3 -0
  15. package/dist/checks/asset/extensions.d.ts +41 -0
  16. package/dist/checks/asset/font-license.d.ts +3 -0
  17. package/dist/checks/asset/image-alpha.d.ts +3 -0
  18. package/dist/checks/asset/image-color-space.d.ts +3 -0
  19. package/dist/checks/asset/image-file-size.d.ts +3 -0
  20. package/dist/checks/asset/image-resolution.d.ts +3 -0
  21. package/dist/checks/asset/image-tac.d.ts +3 -0
  22. package/dist/checks/asset/index.d.ts +7 -0
  23. package/dist/checks/formatter.d.ts +3 -0
  24. package/dist/checks/heuristic/index.d.ts +4 -0
  25. package/dist/checks/heuristic/layer-count.d.ts +3 -0
  26. package/dist/checks/heuristic/placement-variance.d.ts +3 -0
  27. package/dist/checks/heuristic/section-density.d.ts +3 -0
  28. package/dist/checks/heuristic/text-density.d.ts +3 -0
  29. package/dist/checks/pdf/bleed.d.ts +3 -0
  30. package/dist/checks/pdf/bookmarks.d.ts +3 -0
  31. package/dist/checks/pdf/color-spaces.d.ts +3 -0
  32. package/dist/checks/pdf/cross-refs.d.ts +3 -0
  33. package/dist/checks/pdf/embedded-fonts.d.ts +3 -0
  34. package/dist/checks/pdf/image-resolution.d.ts +3 -0
  35. package/dist/checks/pdf/index.d.ts +15 -0
  36. package/dist/checks/pdf/ink-coverage.d.ts +3 -0
  37. package/dist/checks/pdf/page-labels.d.ts +3 -0
  38. package/dist/checks/pdf/page-size.d.ts +3 -0
  39. package/dist/checks/pdf/pdfx-markers.d.ts +3 -0
  40. package/dist/checks/pdf/pdfx-metadata.d.ts +3 -0
  41. package/dist/checks/pdf/pdfx-structure.d.ts +6 -0
  42. package/dist/checks/pdf/qpdf-structure.d.ts +3 -0
  43. package/dist/checks/pdf/rasterized-pages.d.ts +3 -0
  44. package/dist/checks/pdf/toc-links.d.ts +3 -0
  45. package/dist/checks/pdf/transparency.d.ts +3 -0
  46. package/dist/checks/policy.d.ts +61 -0
  47. package/dist/checks/register-builtins.d.ts +17 -0
  48. package/dist/checks/registry.d.ts +40 -0
  49. package/dist/checks/runner.d.ts +25 -0
  50. package/dist/checks/source/accessibility-alt-text.d.ts +3 -0
  51. package/dist/checks/source/accessibility-heading-order.d.ts +3 -0
  52. package/dist/checks/source/config-file.d.ts +8 -0
  53. package/dist/checks/source/htmlhint.d.ts +3 -0
  54. package/dist/checks/source/index.d.ts +6 -0
  55. package/dist/checks/source/local-refs.d.ts +3 -0
  56. package/dist/checks/source/markdownlint.d.ts +3 -0
  57. package/dist/checks/source/stylelint.d.ts +3 -0
  58. package/dist/checks/tool-check.d.ts +23 -0
  59. package/dist/checks/types.d.ts +52 -0
  60. package/dist/cli-1tyj4bk3.js +124 -0
  61. package/dist/cli-37x76zdn.js +4 -0
  62. package/dist/cli-506tg37g.js +26 -0
  63. package/dist/cli-5bxx0c4y.js +464 -0
  64. package/dist/cli-7ykx7pp0.js +12378 -0
  65. package/dist/cli-h7phg3ka.js +746 -0
  66. package/dist/cli-hvqjs342.js +284 -0
  67. package/dist/cli-yja077f6.js +92 -0
  68. package/dist/cli.js +157 -0
  69. package/dist/constants.d.ts +17 -0
  70. package/dist/doctor-25zjt8dz.js +57 -0
  71. package/dist/favicon-wkbm9cjn.ico +0 -0
  72. package/dist/git-http-yrb4ag6z.js +17 -0
  73. package/dist/index-1tyj4bk3.js +124 -0
  74. package/dist/index-37x76zdn.js +4 -0
  75. package/dist/index-3h3fef7r.js +15218 -0
  76. package/dist/index-5bxx0c4y.js +464 -0
  77. package/dist/index-yja077f6.js +92 -0
  78. package/dist/index.d.ts +32 -0
  79. package/dist/index.js +310 -0
  80. package/dist/lib/app-heartbeat.d.ts +102 -0
  81. package/dist/lib/asset-inline.d.ts +73 -0
  82. package/dist/lib/browser-pool.d.ts +17 -0
  83. package/dist/lib/build-error.d.ts +52 -0
  84. package/dist/lib/build-fingerprint.d.ts +15 -0
  85. package/dist/lib/build-preflight.d.ts +43 -0
  86. package/dist/lib/build-runner.d.ts +161 -0
  87. package/dist/lib/build-staging.d.ts +64 -0
  88. package/dist/lib/chromium.d.ts +20 -0
  89. package/dist/lib/cli-args.d.ts +45 -0
  90. package/dist/lib/desktop.d.ts +14 -0
  91. package/dist/lib/diagnostics.d.ts +64 -0
  92. package/dist/lib/embedded-assets.d.ts +29 -0
  93. package/dist/lib/exec.d.ts +84 -0
  94. package/dist/lib/fetch-timeout.d.ts +41 -0
  95. package/dist/lib/ghostscript.d.ts +48 -0
  96. package/dist/lib/host-policy.d.ts +75 -0
  97. package/dist/lib/image-inspect.d.ts +32 -0
  98. package/dist/lib/install-hints.d.ts +21 -0
  99. package/dist/lib/lint-runner.d.ts +10 -0
  100. package/dist/lib/manifest-config.d.ts +31 -0
  101. package/dist/lib/manifest-doc.d.ts +25 -0
  102. package/dist/lib/manifest.d.ts +41 -0
  103. package/dist/lib/markdown/assemble.d.ts +78 -0
  104. package/dist/lib/markdown/chapter-id.d.ts +24 -0
  105. package/dist/lib/markdown/images.d.ts +34 -0
  106. package/dist/lib/markdown/index.d.ts +78 -0
  107. package/dist/lib/markdown/markdown-it-paged.d.ts +30 -0
  108. package/dist/lib/markdown/plugins.d.ts +69 -0
  109. package/dist/lib/markdown/renderer.d.ts +111 -0
  110. package/dist/lib/npm-plugin-installer.d.ts +33 -0
  111. package/dist/lib/open-path.d.ts +5 -0
  112. package/dist/lib/output-paths.d.ts +23 -0
  113. package/dist/lib/pagedjs-marker.d.ts +42 -0
  114. package/dist/lib/pagedjs.d.ts +26 -0
  115. package/dist/lib/pagination.d.ts +169 -0
  116. package/dist/lib/pdf-inspect.d.ts +123 -0
  117. package/dist/lib/pdf-parse.d.ts +57 -0
  118. package/dist/lib/plugin-manager.d.ts +108 -0
  119. package/dist/lib/plugin-vendor.d.ts +107 -0
  120. package/dist/lib/presets.d.ts +45 -0
  121. package/dist/lib/printsafe.d.ts +17 -0
  122. package/dist/lib/project-scaffold.d.ts +116 -0
  123. package/dist/lib/project-source.d.ts +140 -0
  124. package/dist/lib/project-templates.d.ts +49 -0
  125. package/dist/lib/publish/butler.d.ts +10 -0
  126. package/dist/lib/publish/command-runner.d.ts +18 -0
  127. package/dist/lib/publish/connect.d.ts +23 -0
  128. package/dist/lib/publish/manifest-publish.d.ts +9 -0
  129. package/dist/lib/publish/providers/azure-swa.d.ts +3 -0
  130. package/dist/lib/publish/providers/drivethrurpg.d.ts +10 -0
  131. package/dist/lib/publish/providers/guided.d.ts +3 -0
  132. package/dist/lib/publish/providers/itch.d.ts +5 -0
  133. package/dist/lib/publish/providers/kdp.d.ts +9 -0
  134. package/dist/lib/publish/providers/shopify.d.ts +5 -0
  135. package/dist/lib/publish/registry.d.ts +5 -0
  136. package/dist/lib/publish/run-publish.d.ts +30 -0
  137. package/dist/lib/publish/selections.d.ts +25 -0
  138. package/dist/lib/publish/types.d.ts +258 -0
  139. package/dist/lib/remote-auth/clone.d.ts +87 -0
  140. package/dist/lib/remote-auth/conflict-resolution.d.ts +29 -0
  141. package/dist/lib/remote-auth/diagnose.d.ts +77 -0
  142. package/dist/lib/remote-auth/generic-auth.d.ts +97 -0
  143. package/dist/lib/remote-auth/git-http.d.ts +85 -0
  144. package/dist/lib/remote-auth/github-auth.d.ts +69 -0
  145. package/dist/lib/remote-auth/github-repos.d.ts +64 -0
  146. package/dist/lib/remote-auth/operation-log.d.ts +66 -0
  147. package/dist/lib/remote-auth/recovery/abort-interrupted-operation.d.ts +103 -0
  148. package/dist/lib/remote-auth/recovery/backup.d.ts +113 -0
  149. package/dist/lib/remote-auth/recovery/classify.d.ts +109 -0
  150. package/dist/lib/remote-auth/recovery/context.d.ts +47 -0
  151. package/dist/lib/remote-auth/recovery/dispatch.d.ts +33 -0
  152. package/dist/lib/remote-auth/recovery/failsafe.d.ts +33 -0
  153. package/dist/lib/remote-auth/recovery/inspect.d.ts +74 -0
  154. package/dist/lib/remote-auth/recovery/manual-guidance.d.ts +28 -0
  155. package/dist/lib/remote-auth/recovery/outcome-mapping.d.ts +58 -0
  156. package/dist/lib/remote-auth/recovery/policy.d.ts +47 -0
  157. package/dist/lib/remote-auth/recovery/recover-auth.d.ts +42 -0
  158. package/dist/lib/remote-auth/recovery/recover-binary-conflict.d.ts +37 -0
  159. package/dist/lib/remote-auth/recovery/recover-corrupt-index.d.ts +40 -0
  160. package/dist/lib/remote-auth/recovery/recover-detached-head.d.ts +70 -0
  161. package/dist/lib/remote-auth/recovery/recover-interrupted-cherry-pick.d.ts +23 -0
  162. package/dist/lib/remote-auth/recovery/recover-interrupted-merge.d.ts +28 -0
  163. package/dist/lib/remote-auth/recovery/recover-interrupted-rebase.d.ts +39 -0
  164. package/dist/lib/remote-auth/recovery/recover-merge-conflict.d.ts +34 -0
  165. package/dist/lib/remote-auth/recovery/recover-missing-git-dir.d.ts +37 -0
  166. package/dist/lib/remote-auth/recovery/recover-missing-objects.d.ts +56 -0
  167. package/dist/lib/remote-auth/recovery/recover-network.d.ts +34 -0
  168. package/dist/lib/remote-auth/recovery/recover-non-fast-forward.d.ts +27 -0
  169. package/dist/lib/remote-auth/recovery/recover-stale-lock.d.ts +76 -0
  170. package/dist/lib/remote-auth/recovery/recover-unrelated-histories.d.ts +44 -0
  171. package/dist/lib/remote-auth/recovery/recover-wrong-remote.d.ts +35 -0
  172. package/dist/lib/remote-auth/recovery/types.d.ts +235 -0
  173. package/dist/lib/remote-auth/resolution-plan.d.ts +64 -0
  174. package/dist/lib/remote-auth/sync-messages.d.ts +26 -0
  175. package/dist/lib/remote-auth/sync-types.d.ts +225 -0
  176. package/dist/lib/remote-auth/sync.d.ts +45 -0
  177. package/dist/lib/remote-auth/test-access.d.ts +47 -0
  178. package/dist/lib/remote-auth/test-support/git-http-server.d.ts +71 -0
  179. package/dist/lib/remote-auth/token-store.d.ts +95 -0
  180. package/dist/lib/remote-auth/transport.d.ts +105 -0
  181. package/dist/lib/slug.d.ts +28 -0
  182. package/dist/lib/snippets.d.ts +39 -0
  183. package/dist/lib/source-provider.d.ts +244 -0
  184. package/dist/lib/static-serve.d.ts +54 -0
  185. package/dist/lib/style-resolver.d.ts +30 -0
  186. package/dist/lib/theme-import.d.ts +70 -0
  187. package/dist/lib/theme-manager.d.ts +128 -0
  188. package/dist/lib/tool-probe.d.ts +37 -0
  189. package/dist/lib/validation-exec.d.ts +47 -0
  190. package/dist/lib/validation-profile.d.ts +18 -0
  191. package/dist/lib/version.d.ts +9 -0
  192. package/dist/lint-f63nxjfj.js +65 -0
  193. package/dist/manifest-n1gh3qw5.yaml +9 -0
  194. package/dist/manifest-ryyg71nf.yaml +9 -0
  195. package/dist/manifest.schema-rn1dpdpn.json +564 -0
  196. package/dist/new-7b08a42h.js +105 -0
  197. package/dist/paged.polyfill-n95pbxfn.js +33288 -0
  198. package/dist/pagedjs-bridge-vn4hk9fx.js +111 -0
  199. package/dist/pagedjs-interface-80g3xa8p.js +498 -0
  200. package/dist/platform.d.ts +100 -0
  201. package/dist/plugin-wf2cbmwc.js +129 -0
  202. package/dist/preflight-tg4mpz1h.js +222 -0
  203. package/dist/preview/file-watcher.d.ts +174 -0
  204. package/dist/preview/http-server.d.ts +45 -0
  205. package/dist/preview/lifecycle.d.ts +67 -0
  206. package/dist/preview/server-context.d.ts +36 -0
  207. package/dist/preview-h2bwbb2x.js +102 -0
  208. package/dist/preview-shell-rghtfmc8.js +155 -0
  209. package/dist/project-source-0tg0r6vm.js +17 -0
  210. package/dist/publish-ztaet53r.js +233 -0
  211. package/dist/render.d.ts +20 -0
  212. package/dist/render.js +682 -0
  213. package/dist/repair-jkp4n3j8.js +171 -0
  214. package/dist/schema/manifest.types.d.ts +218 -0
  215. package/dist/server.d.ts +34 -0
  216. package/dist/source-provider-hp96b5jf.js +46 -0
  217. package/dist/test-helpers/testkit.d.ts +91 -0
  218. package/dist/theme-0yzvthe8.css +65 -0
  219. package/dist/theme-570zmh2t.css +58 -0
  220. package/dist/theme-6a2fngc8.json +6 -0
  221. package/dist/theme-cd6efzjw.json +6 -0
  222. package/dist/theme-nya4nqh6.css +70 -0
  223. package/dist/theme-tqfypc1w.json +6 -0
  224. package/dist/theme-xt0hjb1b.json +6 -0
  225. package/dist/theme-zz2ktzqs.css +60 -0
  226. package/dist/types.d.ts +31 -0
  227. package/dist/utils/file-utils.d.ts +53 -0
  228. package/dist/utils/logger.d.ts +59 -0
  229. package/dist/validate-k2drs19j.js +99 -0
  230. package/package.json +102 -0
package/dist/render.js ADDED
@@ -0,0 +1,682 @@
1
+ // src/lib/markdown/markdown-it-paged.js
2
+ function isBareToken(token) {
3
+ return token && !token.includes("=") && !token.startsWith(".") && !token.startsWith("#");
4
+ }
5
+ function escapeHtml(s) {
6
+ return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
7
+ }
8
+ function escapeAttr(s) {
9
+ return String(s).replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
10
+ }
11
+ function parseMarkerLine(line) {
12
+ const trimmed = line.trim();
13
+ if (!trimmed.startsWith("@"))
14
+ return null;
15
+ const tokens = [];
16
+ let buf = "";
17
+ let quote = null;
18
+ for (let i = 0;i < trimmed.length; i++) {
19
+ const ch = trimmed[i];
20
+ if (quote) {
21
+ if (ch === quote)
22
+ quote = null;
23
+ else
24
+ buf += ch;
25
+ continue;
26
+ }
27
+ if (ch === '"' || ch === "'") {
28
+ quote = ch;
29
+ continue;
30
+ }
31
+ if (/\s/.test(ch)) {
32
+ if (buf)
33
+ tokens.push(buf);
34
+ buf = "";
35
+ continue;
36
+ }
37
+ buf += ch;
38
+ }
39
+ if (buf)
40
+ tokens.push(buf);
41
+ const head = tokens[0];
42
+ const kind = head.slice(1);
43
+ if (!["chapter", "spread", "page", "section", "continue", "page-break", "column-break", "end-section"].includes(kind))
44
+ return null;
45
+ if (kind === "page-break" || kind === "column-break" || kind === "end-section" || kind === "continue") {
46
+ return { kind, name: null, attrs: {} };
47
+ }
48
+ const body = tokens.slice(1);
49
+ const hasExplicitAttrsOrShorthand = body.some((token) => token.includes("=") || token.startsWith(".") || token.startsWith("#"));
50
+ const bareTokens = body.filter(isBareToken);
51
+ let name = null;
52
+ let nameIndex = -1;
53
+ const firstBareTokenIndex = body.findIndex((token) => isBareToken(token));
54
+ if (hasExplicitAttrsOrShorthand && bareTokens.length) {
55
+ name = bareTokens[0];
56
+ nameIndex = firstBareTokenIndex;
57
+ } else if (bareTokens.length === 1) {
58
+ name = bareTokens[0];
59
+ nameIndex = firstBareTokenIndex;
60
+ }
61
+ const attrs = {};
62
+ const classes = [];
63
+ let sawExplicitAttr = false;
64
+ let hasAmbiguousBareToken = false;
65
+ for (let idx = 0;idx < body.length; idx++) {
66
+ if (idx === nameIndex) {
67
+ if (sawExplicitAttr && isBareToken(body[idx]))
68
+ hasAmbiguousBareToken = true;
69
+ continue;
70
+ }
71
+ const t = body[idx];
72
+ if (t.startsWith(".")) {
73
+ const c = t.slice(1).trim();
74
+ if (c)
75
+ classes.push(c);
76
+ continue;
77
+ }
78
+ if (t.startsWith("#")) {
79
+ const id = t.slice(1).trim();
80
+ if (id)
81
+ attrs.id = id;
82
+ continue;
83
+ }
84
+ const eq = t.indexOf("=");
85
+ if (eq > 0) {
86
+ sawExplicitAttr = true;
87
+ const key = t.slice(0, eq).trim();
88
+ const val = t.slice(eq + 1).trim();
89
+ if (!key)
90
+ continue;
91
+ if (key === "class") {
92
+ val.split(/[,\s]+/).filter(Boolean).forEach((c) => classes.push(c));
93
+ } else {
94
+ attrs[key] = val;
95
+ }
96
+ continue;
97
+ }
98
+ if (sawExplicitAttr && isBareToken(t))
99
+ hasAmbiguousBareToken = true;
100
+ classes.push(t);
101
+ }
102
+ if (classes.length)
103
+ attrs.class = classes.join(" ");
104
+ const marker = { kind, name, attrs };
105
+ if (hasAmbiguousBareToken)
106
+ marker.__ambiguousBareToken = true;
107
+ return marker;
108
+ }
109
+ function warn(env, line, type, message, marker) {
110
+ if (!env.layoutWarnings)
111
+ env.layoutWarnings = [];
112
+ env.layoutWarnings.push({ line, type, message, marker });
113
+ }
114
+ function addClasses(token, baseClass, extraClass) {
115
+ const cls = [];
116
+ if (baseClass)
117
+ cls.push(baseClass);
118
+ if (extraClass)
119
+ cls.push(extraClass);
120
+ const merged = cls.join(" ").trim();
121
+ if (merged)
122
+ token.attrSet("class", merged);
123
+ }
124
+ function attachDataAttrs(token, kind, name, attrs) {
125
+ if (name) {
126
+ if (kind === "chapter")
127
+ token.attrSet("data-chapter-label", name);
128
+ if (kind === "spread")
129
+ token.attrSet("data-spread", name);
130
+ if (kind === "page")
131
+ token.attrSet("data-page", name);
132
+ if (kind === "section")
133
+ token.attrSet("data-section", name);
134
+ }
135
+ if (attrs.template)
136
+ token.attrSet("data-template", attrs.template);
137
+ if (attrs.region)
138
+ token.attrSet("data-region", attrs.region);
139
+ if (attrs.id)
140
+ token.attrSet("id", attrs.id);
141
+ for (const [k, v] of Object.entries(attrs)) {
142
+ if (!v)
143
+ continue;
144
+ if (k === "class" || k === "id" || k === "template" || k === "region")
145
+ continue;
146
+ token.attrSet(`data-${k}`, v);
147
+ }
148
+ }
149
+ function plugin(md, pluginOptions = {}) {
150
+ const options = {
151
+ implicitPage: false,
152
+ preferPagesInSpreads: false,
153
+ ...pluginOptions
154
+ };
155
+ function markerBlock(state, startLine, endLine, silent) {
156
+ const pos = state.bMarks[startLine] + state.tShift[startLine];
157
+ const max = state.eMarks[startLine];
158
+ const line = state.src.slice(pos, max);
159
+ const parsed = parseMarkerLine(line);
160
+ if (!parsed)
161
+ return false;
162
+ if (silent)
163
+ return true;
164
+ state.env.__layoutMarkersUsed = true;
165
+ const token = state.push("layout_marker", "", 0);
166
+ token.meta = parsed;
167
+ token.meta.__line = startLine + 1;
168
+ if (parsed.__ambiguousBareToken) {
169
+ delete parsed.__ambiguousBareToken;
170
+ warn(state.env, startLine + 1, "ambiguous_marker_token", "A bare marker token after a key=value attribute is being interpreted as the marker name (or an extra class). Use comma-separated classes (class=a,b) or .class shorthand instead.", parsed);
171
+ }
172
+ state.line = startLine + 1;
173
+ return true;
174
+ }
175
+ md.block.ruler.before("paragraph", "layout_marker", markerBlock, {
176
+ alt: ["paragraph", "reference", "blockquote", "list"]
177
+ });
178
+ const SCOPE_CLOSE_ORDER = ["section", "page", "spread", "chapter"];
179
+ md.core.ruler.after("block", "layout_transform", function(state) {
180
+ if (!state.env.__layoutMarkersUsed)
181
+ return;
182
+ const out = [];
183
+ setDepth(state.env, 0);
184
+ const stack = {
185
+ frames: [],
186
+ get(kind) {
187
+ return this.frames.find((f) => f.kind === kind) || null;
188
+ },
189
+ has(kind) {
190
+ return this.frames.some((f) => f.kind === kind);
191
+ },
192
+ open(frame, openToken) {
193
+ out.push(openToken);
194
+ this.frames.push(frame);
195
+ },
196
+ _pop(kind) {
197
+ const at = this.frames.findIndex((f) => f.kind === kind);
198
+ if (at === -1)
199
+ return;
200
+ this.frames.splice(at, 1);
201
+ out.push(new state.Token(`layout_${kind}_close`, "div", -1));
202
+ },
203
+ close(kind) {
204
+ if (!this.has(kind))
205
+ return;
206
+ for (const inner of SCOPE_CLOSE_ORDER) {
207
+ if (inner === kind)
208
+ break;
209
+ this._pop(inner);
210
+ }
211
+ this._pop(kind);
212
+ },
213
+ closeAll() {
214
+ for (const kind of SCOPE_CLOSE_ORDER)
215
+ this._pop(kind);
216
+ }
217
+ };
218
+ function openChapter(meta) {
219
+ const t = new state.Token("layout_chapter_open", "div", 1);
220
+ const classes = meta.attrs?.class || "";
221
+ addClasses(t, "chapter", classes);
222
+ attachDataAttrs(t, "chapter", meta.name, meta.attrs || {});
223
+ const explicit = (classes.match(/(?:^|\s)(chapter-\d+)(?=\s|$)/) || [])[1] || "";
224
+ const fromAttr = meta.attrs?.ch ? `chapter-${meta.attrs.ch}` : "";
225
+ stack.open({
226
+ kind: "chapter",
227
+ label: meta.name || "",
228
+ counterClass: explicit || fromAttr,
229
+ openerEmitted: false
230
+ }, t);
231
+ }
232
+ function openSpread(meta) {
233
+ const t = new state.Token("layout_spread_open", "div", 1);
234
+ addClasses(t, "spread", meta.attrs && meta.attrs.class ? meta.attrs.class : "");
235
+ attachDataAttrs(t, "spread", meta.name, meta.attrs || {});
236
+ stack.open({ kind: "spread", noPagesYet: true, sawAnyPage: false }, t);
237
+ }
238
+ function openPage(meta) {
239
+ const chapter = stack.get("chapter");
240
+ const t = new state.Token("layout_page_open", "div", 1);
241
+ const explicit = meta.attrs && meta.attrs.class ? meta.attrs.class : "";
242
+ const counterClass = chapter ? chapter.counterClass : "";
243
+ const tokens = explicit ? explicit.split(/\s+/) : [];
244
+ const merged = counterClass && !tokens.includes(counterClass) ? explicit ? `${explicit} ${counterClass}` : counterClass : explicit;
245
+ addClasses(t, "page", merged);
246
+ attachDataAttrs(t, "page", meta.name, meta.attrs || {});
247
+ const label = chapter ? chapter.label : "";
248
+ if (label)
249
+ t.attrSet("data-chapter-label", label);
250
+ stack.open({ kind: "page" }, t);
251
+ if (label && !chapter.openerEmitted) {
252
+ const opener = new state.Token("html_block", "", 0);
253
+ opener.content = `<div class="chapter-opener" data-chapter-label="${escapeAttr(label)}">${escapeHtml(label)}</div>
254
+ `;
255
+ out.push(opener);
256
+ chapter.openerEmitted = true;
257
+ }
258
+ const spread = stack.get("spread");
259
+ if (spread) {
260
+ spread.sawAnyPage = true;
261
+ spread.noPagesYet = false;
262
+ } else if (options.preferPagesInSpreads) {
263
+ warn(state.env, meta.__line || 0, "page_outside_spread", "@page used outside of a spread; allowed, but spreads are recommended for deliberate grouping.", meta);
264
+ }
265
+ }
266
+ function openSection(meta) {
267
+ const t = new state.Token("layout_section_open", "div", 1);
268
+ addClasses(t, "section", meta.attrs && meta.attrs.class ? meta.attrs.class : "");
269
+ attachDataAttrs(t, "section", meta.name, meta.attrs || {});
270
+ t.meta = { hasColumnBreak: false };
271
+ stack.open({
272
+ kind: "section",
273
+ meta: { name: meta.name || null, attrs: { ...meta.attrs || {} } },
274
+ openToken: t
275
+ }, t);
276
+ }
277
+ for (let i = 0;i < state.tokens.length; i++) {
278
+ const tok = state.tokens[i];
279
+ if (tok.type !== "layout_marker") {
280
+ out.push(tok);
281
+ continue;
282
+ }
283
+ const meta = tok.meta || {};
284
+ const kind = meta.kind;
285
+ const line = meta.__line || 0;
286
+ if (kind === "chapter") {
287
+ stack.close("chapter");
288
+ openChapter(meta);
289
+ continue;
290
+ }
291
+ if (kind === "spread") {
292
+ if (stack.has("spread")) {
293
+ warn(state.env, line, "nested_spread", "@spread encountered while another spread is open; closing the previous spread automatically.", meta);
294
+ }
295
+ stack.close("spread");
296
+ openSpread(meta);
297
+ continue;
298
+ }
299
+ if (kind === "page") {
300
+ stack.close("page");
301
+ openPage(meta);
302
+ continue;
303
+ }
304
+ if (kind === "section") {
305
+ stack.close("section");
306
+ if (!stack.has("page")) {
307
+ if (options.implicitPage) {
308
+ warn(state.env, line, "implicit_page", '@section used without an open @page; creating an implicit page wrapper (data-page="auto").', meta);
309
+ openPage({ name: "auto", attrs: {}, __line: line });
310
+ } else {
311
+ warn(state.env, line, "section_without_page", "@section used without an open @page; region will render but will not be wrapped in a page.", meta);
312
+ }
313
+ }
314
+ const spread = stack.get("spread");
315
+ if (spread && spread.noPagesYet) {
316
+ warn(state.env, line, "spread_without_pages", "@section inside a spread without an explicit @page. Allowed (adhoc spread), but explicit @page markers give stronger control.", meta);
317
+ }
318
+ openSection(meta);
319
+ continue;
320
+ }
321
+ if (kind === "continue") {
322
+ const section = stack.get("section");
323
+ if (!section || !section.meta) {
324
+ warn(state.env, line, "continue_without_section", "@continue used without an open @section; ignoring marker.", meta);
325
+ continue;
326
+ }
327
+ const contMeta = {
328
+ name: section.meta.name,
329
+ attrs: { ...section.meta.attrs || {} }
330
+ };
331
+ const cls = (contMeta.attrs.class || "").split(/\s+/).filter(Boolean);
332
+ if (!cls.includes("gutterpress-continued"))
333
+ cls.push("gutterpress-continued");
334
+ contMeta.attrs.class = cls.join(" ");
335
+ stack.close("section");
336
+ openSection(contMeta);
337
+ continue;
338
+ }
339
+ if (kind === "page-break") {
340
+ const t = new state.Token("layout_page_break", "div", 0);
341
+ t.attrSet("class", "md-page-break");
342
+ t.attrSet("aria-hidden", "true");
343
+ out.push(t);
344
+ continue;
345
+ }
346
+ if (kind === "column-break") {
347
+ const openSectionFrame = stack.get("section");
348
+ if (openSectionFrame && openSectionFrame.openToken && !openSectionFrame.openToken.meta.hasColumnBreak) {
349
+ const sectionCls = openSectionFrame.openToken.attrGet("class") || "";
350
+ if (sectionCls.includes("col-split")) {
351
+ openSectionFrame.openToken.meta.hasColumnBreak = true;
352
+ }
353
+ }
354
+ const t = new state.Token("layout_column_break", "div", 0);
355
+ t.attrSet("class", "md-column-break");
356
+ t.attrSet("aria-hidden", "true");
357
+ out.push(t);
358
+ continue;
359
+ }
360
+ if (kind === "end-section") {
361
+ stack.close("section");
362
+ continue;
363
+ }
364
+ }
365
+ const eofSpread = stack.get("spread");
366
+ if (eofSpread && !eofSpread.sawAnyPage) {
367
+ warn(state.env, 0, "spread_eof_close", "An open @spread reached end-of-document; closing it automatically.", null);
368
+ }
369
+ stack.closeAll();
370
+ state.tokens = out;
371
+ });
372
+ function getDepth(env) {
373
+ return env && env.__colSplitDepth || 0;
374
+ }
375
+ function setDepth(env, n) {
376
+ if (env)
377
+ env.__colSplitDepth = n;
378
+ }
379
+ md.renderer.rules.layout_chapter_open = (tokens, idx, opts, env, self) => {
380
+ setDepth(env, 0);
381
+ return self.renderToken(tokens, idx, opts);
382
+ };
383
+ md.renderer.rules.layout_page_open = (tokens, idx, opts, env, self) => {
384
+ setDepth(env, 0);
385
+ return self.renderToken(tokens, idx, opts);
386
+ };
387
+ md.renderer.rules.layout_section_open = (tokens, idx, opts, env, self) => {
388
+ const token = tokens[idx];
389
+ const cls = token.attrGet("class") || "";
390
+ if (cls.includes("col-split") && token.meta && token.meta.hasColumnBreak) {
391
+ setDepth(env, getDepth(env) + 1);
392
+ return `<div class="${escapeAttr(cls)}"><div class="col">
393
+ `;
394
+ }
395
+ return self.renderToken(tokens, idx, opts);
396
+ };
397
+ md.renderer.rules.layout_section_close = (tokens, idx, opts, env, self) => {
398
+ if (getDepth(env) > 0) {
399
+ setDepth(env, getDepth(env) - 1);
400
+ return `</div></div>
401
+ `;
402
+ }
403
+ return self.renderToken(tokens, idx, opts);
404
+ };
405
+ md.renderer.rules.layout_page_break = (tokens, idx) => {
406
+ const cls = tokens[idx].attrGet("class") || "md-page-break";
407
+ return `<div class="${escapeAttr(cls)}" aria-hidden="true"></div>
408
+ `;
409
+ };
410
+ md.renderer.rules.layout_column_break = (tokens, idx, opts, env) => {
411
+ if (getDepth(env) > 0) {
412
+ return `</div><div class="col">
413
+ `;
414
+ }
415
+ const cls = tokens[idx].attrGet("class") || "md-column-break";
416
+ return `<div class="${escapeAttr(cls)}" aria-hidden="true"></div>
417
+ `;
418
+ };
419
+ md.renderer.rules.layout_marker = () => "";
420
+ }
421
+ var PAGED_CSS = `
422
+ .md-page-break { break-before: page; }
423
+ .page { break-before: page; }
424
+ .spread { break-before: page; }
425
+ .section { break-inside: avoid; }
426
+ .section.col-split { break-inside: auto; }
427
+ .md-column-break { break-after: column; height: 0; font-size: 0; line-height: 0; visibility: hidden; }
428
+
429
+ .center { display: block; margin-left: auto; margin-right: auto; max-width: 100%; }
430
+ .float-left { float: left; margin: 0 1em 1em 0; max-width: 50%; }
431
+ .float-right { float: right; margin: 0 0 1em 1em; max-width: 50%; }
432
+ .full-width { display: block; width: 100%; max-width: 100%; }
433
+ .full-bleed {
434
+ display: block;
435
+ break-before: page;
436
+ max-width: none;
437
+ width: calc(100% + var(--pagedjs-margin-left, 0px) + var(--pagedjs-margin-right, 0px));
438
+ margin-left: calc(-1 * var(--pagedjs-margin-left, 0px));
439
+ margin-right: calc(-1 * var(--pagedjs-margin-right, 0px));
440
+ }
441
+ `;
442
+
443
+ // src/lib/markdown/chapter-id.ts
444
+ function canonicalChapterId(p) {
445
+ let s = String(p).replace(/\\/g, "/");
446
+ s = s.replace(/\/{2,}/g, "/");
447
+ while (s.startsWith("./"))
448
+ s = s.slice(2);
449
+ return s;
450
+ }
451
+
452
+ // src/lib/markdown/renderer.ts
453
+ import MarkdownIt from "markdown-it";
454
+
455
+ // src/utils/logger.ts
456
+ var currentLevel = "INFO";
457
+ var LEVELS = {
458
+ DEBUG: 0,
459
+ INFO: 1,
460
+ WARN: 2,
461
+ ERROR: 3
462
+ };
463
+ function emit(level, message, ...args) {
464
+ if (LEVELS[level] < LEVELS[currentLevel])
465
+ return;
466
+ const colors = {
467
+ DEBUG: "\x1B[36m",
468
+ INFO: "\x1B[32m",
469
+ WARN: "\x1B[33m",
470
+ ERROR: "\x1B[31m"
471
+ };
472
+ const reset = "\x1B[0m";
473
+ const timestamp = new Date().toISOString().slice(11, 19);
474
+ const prefix = `${colors[level]}[${timestamp}] ${level}${reset}:`;
475
+ if (level === "ERROR") {
476
+ console.error(prefix, message, ...args);
477
+ } else {
478
+ console.log(prefix, message, ...args);
479
+ }
480
+ }
481
+ function debug(message, ...args) {
482
+ emit("DEBUG", message, ...args);
483
+ }
484
+
485
+ // src/lib/markdown/renderer.ts
486
+ import markdownItAttrs from "markdown-it-attrs";
487
+ import markdownItFootnote from "markdown-it-footnote";
488
+ import markdownItSourceMap from "markdown-it-source-map";
489
+ import markdownItDeflist from "markdown-it-deflist";
490
+ import markdownItMark from "markdown-it-mark";
491
+ import markdownItSub from "markdown-it-sub";
492
+ import markdownItSup from "markdown-it-sup";
493
+ import markdownItAbbr from "markdown-it-abbr";
494
+
495
+ // src/lib/markdown/images.ts
496
+ function registerImageRule(md) {
497
+ const defaultRender = md.renderer.rules.image ?? ((tokens, idx, options, _env, self) => self.renderToken(tokens, idx, options));
498
+ md.renderer.rules.image = (tokens, idx, options, env, self) => {
499
+ const token = tokens[idx];
500
+ const srcIdx = token.attrIndex("src");
501
+ if (srcIdx >= 0 && token.attrs) {
502
+ const src = token.attrs[srcIdx][1];
503
+ if (src) {
504
+ const bucket = env ?? {};
505
+ (bucket.imageRefs ??= []).push(src);
506
+ }
507
+ }
508
+ return defaultRender(tokens, idx, options, env, self);
509
+ };
510
+ }
511
+ function collectHtmlImageRefs(html) {
512
+ const refs = [];
513
+ const srcRe = /<img\b[^>]*?\bsrc\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/gi;
514
+ let m;
515
+ while (m = srcRe.exec(html)) {
516
+ const src = m[1] ?? m[2] ?? m[3];
517
+ if (src)
518
+ refs.push(src);
519
+ }
520
+ const srcsetRe = /<(?:img|source)\b[^>]*?\bsrcset\s*=\s*(?:"([^"]*)"|'([^']*)')/gi;
521
+ while (m = srcsetRe.exec(html)) {
522
+ const list = m[1] ?? m[2] ?? "";
523
+ for (const candidate of list.split(",")) {
524
+ const url = candidate.trim().split(/\s+/)[0];
525
+ if (url)
526
+ refs.push(url);
527
+ }
528
+ }
529
+ return refs;
530
+ }
531
+
532
+ // src/lib/markdown/renderer.ts
533
+ function hasDefaultExport(plugin2) {
534
+ return !!plugin2 && typeof plugin2 === "object" && "default" in plugin2;
535
+ }
536
+ function unwrapPlugin(plugin2) {
537
+ return hasDefaultExport(plugin2) ? plugin2.default : plugin2;
538
+ }
539
+ var BUILTIN_OPTIONAL_PLUGINS = {
540
+ "markdown-it-mark": unwrapPlugin(markdownItMark),
541
+ "markdown-it-sub": unwrapPlugin(markdownItSub),
542
+ "markdown-it-sup": unwrapPlugin(markdownItSup),
543
+ "markdown-it-abbr": unwrapPlugin(markdownItAbbr)
544
+ };
545
+ function createMarkdownRenderer(customPlugins) {
546
+ const md = new MarkdownIt({
547
+ html: true,
548
+ linkify: true,
549
+ typographer: true
550
+ });
551
+ md.use(unwrapPlugin(markdownItAttrs));
552
+ md.use(unwrapPlugin(markdownItFootnote));
553
+ md.use(unwrapPlugin(markdownItDeflist));
554
+ md.use(unwrapPlugin(markdownItSourceMap));
555
+ md.use(plugin);
556
+ registerImageRule(md);
557
+ if (customPlugins && customPlugins.length > 0) {
558
+ applyPlugins(md, customPlugins);
559
+ }
560
+ return md;
561
+ }
562
+ function applyPlugins(md, plugins) {
563
+ for (const { name, plugin: plugin2, options, metadata } of plugins) {
564
+ try {
565
+ md.use(plugin2, options);
566
+ } catch (error) {
567
+ const errorMsg = error instanceof Error ? error.message : String(error);
568
+ throw new Error(`Failed to apply plugin "${name}": ${errorMsg}`);
569
+ }
570
+ if (metadata?.name) {
571
+ debug(`Loaded plugin: ${metadata.name} v${metadata.version ?? "?"}`);
572
+ } else {
573
+ debug(`Loaded plugin: ${name}`);
574
+ }
575
+ }
576
+ }
577
+ function collectPluginCss(plugins) {
578
+ return plugins.map((p) => p.css).filter((css) => typeof css === "string" && css.length > 0).join(`
579
+
580
+ `);
581
+ }
582
+
583
+ // src/lib/pagedjs-marker.ts
584
+ var PAGEDJS_VERSION = "0.4.3";
585
+ var PAGEDJS_POLYFILL_MARKER = "data-pagedjs-polyfill";
586
+ function pagedjsPolyfillTag(version = PAGEDJS_VERSION) {
587
+ return `<script ${PAGEDJS_POLYFILL_MARKER}="${version}"></script>`;
588
+ }
589
+ function pagedjsPolyfillTagRegex() {
590
+ return /<script\b[^>]*(?:\bdata-pagedjs-polyfill\b|\bsrc=["'][^"']*paged\.polyfill[^"']*["'])[^>]*>\s*<\/script>/gi;
591
+ }
592
+
593
+ // src/lib/markdown/assemble.ts
594
+ async function assembleBookHtml(opts) {
595
+ const title = opts.title ?? "Document";
596
+ const projectCss = opts.projectCss ?? "";
597
+ const pluginCss = opts.pluginCss ?? "";
598
+ const files = opts.files;
599
+ if (files.length === 0) {
600
+ throw new Error("No markdown files to render");
601
+ }
602
+ const md = createMarkdownRenderer(opts.plugins);
603
+ let sourceChapter = null;
604
+ if (opts.wrapChapters) {
605
+ const renderToken = md.renderer.renderToken.bind(md.renderer);
606
+ md.renderer.renderToken = (tokens, idx, options) => {
607
+ const token = tokens[idx];
608
+ if (sourceChapter !== null && token.level === 0 && token.map !== null && token.type.endsWith("_open")) {
609
+ token.attrSet("data-chapter-src", sourceChapter);
610
+ }
611
+ return renderToken(tokens, idx, options);
612
+ };
613
+ }
614
+ let bodyContent = "";
615
+ const imageRefs = new Set;
616
+ for (const file of files) {
617
+ const chapterId = canonicalChapterId(file);
618
+ let content;
619
+ try {
620
+ content = await opts.readText(chapterId);
621
+ } catch (err) {
622
+ const errorMsg = err instanceof Error ? err.message : String(err);
623
+ throw new Error(`Failed to read file ${file}: ${errorMsg}`);
624
+ }
625
+ const env = {};
626
+ sourceChapter = opts.wrapChapters ? chapterId : null;
627
+ let rendered;
628
+ try {
629
+ rendered = md.render(content, env);
630
+ } finally {
631
+ sourceChapter = null;
632
+ }
633
+ if (env.layoutWarnings && env.layoutWarnings.length > 0) {
634
+ opts.onChapterWarnings?.(chapterId, env.layoutWarnings);
635
+ }
636
+ for (const ref of env.imageRefs ?? [])
637
+ imageRefs.add(ref);
638
+ bodyContent += rendered + `
639
+ `;
640
+ }
641
+ if (opts.onImageRefs) {
642
+ for (const ref of collectHtmlImageRefs(bodyContent))
643
+ imageRefs.add(ref);
644
+ opts.onImageRefs([...imageRefs]);
645
+ }
646
+ const inlineCss = [
647
+ `/* markdown-it-paged */
648
+ ${PAGED_CSS.trim()}`,
649
+ pluginCss ? `/* user plugin css */
650
+ ${pluginCss.trim()}` : null,
651
+ projectCss ? `/* project css */
652
+ ${projectCss.trim()}` : null
653
+ ].filter(Boolean).join(`
654
+
655
+ `);
656
+ return `<!DOCTYPE html>
657
+ <html lang="en">
658
+ <head>
659
+ <meta charset="UTF-8">
660
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
661
+ <title>${title}</title>
662
+ <style data-project-css>
663
+ ${inlineCss}
664
+ </style>
665
+ ${pagedjsPolyfillTag()}
666
+ </head>
667
+ <body>
668
+ ${bodyContent}
669
+ </body>
670
+ </html>`;
671
+ }
672
+ export {
673
+ pagedjsPolyfillTagRegex,
674
+ pagedjsPolyfillTag,
675
+ createMarkdownRenderer,
676
+ collectPluginCss,
677
+ assembleBookHtml,
678
+ applyPlugins,
679
+ PAGED_CSS,
680
+ PAGEDJS_VERSION,
681
+ PAGEDJS_POLYFILL_MARKER
682
+ };