gutterpress 0.11.22-alpha.1 → 0.11.22-alpha.2
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.
- package/dist/api/index.js +6 -6
- package/dist/{build-se85j9ec.js → build-84retk4k.js} +9 -9
- package/dist/{cli-sth219v1.js → cli-2ppw6q9v.js} +26 -6
- package/dist/{cli-gc9av5hs.js → cli-3twpesca.js} +1 -1
- package/dist/{cli-9vy4b6ec.js → cli-5et23z83.js} +4 -4
- package/dist/{cli-yejbb9f8.js → cli-5qhjwne5.js} +1 -1
- package/dist/{cli-5553w972.js → cli-80t93x2r.js} +1 -1
- package/dist/{cli-fbwqv7p4.js → cli-885pcze8.js} +173 -61
- package/dist/{cli-8hccw62p.js → cli-9pk65fqf.js} +2 -2
- package/dist/{cli-gmm3bdeq.js → cli-hndkg7bn.js} +2 -2
- package/dist/{cli-pfrg1r9x.js → cli-pn3z0y9p.js} +1 -1
- package/dist/cli.js +12 -12
- package/dist/{doctor-bv2t82zd.js → doctor-fmzpg7ag.js} +3 -3
- package/dist/engine/shared/print-area.d.ts +77 -1
- package/dist/{engine-h4ehmrvf.js → engine-5p8tn9b4.js} +2 -2
- package/dist/{engine-qwkyhrej.js → engine-9710cd7x.js} +3 -3
- package/dist/{ext-a8ndp142.js → ext-hsdnad5c.js} +9 -9
- package/dist/{extension-restore-926mv2qk.js → extension-restore-05pae3cp.js} +3 -3
- package/dist/{extension-restore-q1f7njec.js → extension-restore-3r7phztr.js} +5 -5
- package/dist/{gutterpress-viewer-w7njnkj7.js → gutterpress-viewer-w9jzx6sb.js} +56 -52
- package/dist/{index-gmfh6n05.js → index-2d8j0enc.js} +2 -2
- package/dist/{index-sth219v1.js → index-2ppw6q9v.js} +26 -6
- package/dist/{index-tkjvs1gf.js → index-3wcr69ba.js} +162 -58
- package/dist/{index-5h9a38jn.js → index-apc8w9w8.js} +55 -55
- package/dist/{index-dm7hx46j.js → index-ew7cyk7c.js} +3 -3
- package/dist/{index-dhknsvfz.js → index-jsz0s3dy.js} +2 -2
- package/dist/{index-38e18a7j.js → index-kx03e4m4.js} +1 -1
- package/dist/index.js +7 -7
- package/dist/lib/markdown/assemble.d.ts +3 -2
- package/dist/lib/page-size.d.ts +3 -4
- package/dist/lib/pdf-inspect.d.ts +12 -0
- package/dist/lib/project-scaffold.d.ts +3 -3
- package/dist/{manifest.schema-n292sb77.json → manifest.schema-nvawq0xv.json} +2 -2
- package/dist/{new-nadp2hvb.js → new-fqtt022k.js} +9 -9
- package/dist/{pdf-inspect-zdmy7qca.js → pdf-inspect-wnw4za71.js} +1 -1
- package/dist/{plugins-yeh4shd7.js → plugins-gfvsgnxb.js} +1 -1
- package/dist/{plugins-gy4q9vaa.js → plugins-nfxr831f.js} +3 -3
- package/dist/{preflight-c6q25xqa.js → preflight-gr9mscjw.js} +9 -9
- package/dist/{preview-y8chv4cb.js → preview-52w9pdps.js} +9 -9
- package/dist/{publish-3qwvxsxa.js → publish-esmcyhpb.js} +9 -9
- package/dist/render.js +586 -0
- package/dist/schema/manifest.types.d.ts +8 -3
- package/dist/{validate-w108kk87.js → validate-vt1d7h6k.js} +9 -9
- package/package.json +1 -1
package/dist/api/index.js
CHANGED
|
@@ -101,7 +101,7 @@ import {
|
|
|
101
101
|
substituteVariables,
|
|
102
102
|
syncProject,
|
|
103
103
|
testRemoteAccess
|
|
104
|
-
} from "../index-
|
|
104
|
+
} from "../index-3wcr69ba.js";
|
|
105
105
|
import {
|
|
106
106
|
BUILT_IN_STYLE_SET_IDS,
|
|
107
107
|
BUNDLED_EXTENSIONS,
|
|
@@ -138,7 +138,7 @@ import {
|
|
|
138
138
|
setExtensionEnabled,
|
|
139
139
|
updateExtensions,
|
|
140
140
|
validateProjectExtensions
|
|
141
|
-
} from "../index-
|
|
141
|
+
} from "../index-ew7cyk7c.js";
|
|
142
142
|
import {
|
|
143
143
|
EXTENSION_MANIFEST_FILENAME,
|
|
144
144
|
assertExtensionContained,
|
|
@@ -148,13 +148,13 @@ import {
|
|
|
148
148
|
pathEscapesFolder,
|
|
149
149
|
readExtensionMeta,
|
|
150
150
|
resolveExtension
|
|
151
|
-
} from "../index-
|
|
151
|
+
} from "../index-kx03e4m4.js";
|
|
152
152
|
import"../index-ht1bcqdd.js";
|
|
153
|
-
import"../index-
|
|
153
|
+
import"../index-apc8w9w8.js";
|
|
154
154
|
import {
|
|
155
155
|
BuildError
|
|
156
|
-
} from "../index-
|
|
157
|
-
import"../index-
|
|
156
|
+
} from "../index-jsz0s3dy.js";
|
|
157
|
+
import"../index-2ppw6q9v.js";
|
|
158
158
|
import {
|
|
159
159
|
DEFAULT_PRINT_OPTS,
|
|
160
160
|
assertMilestone,
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runBuild,
|
|
3
3
|
splitOutPath
|
|
4
|
-
} from "./cli-
|
|
5
|
-
import"./cli-
|
|
4
|
+
} from "./cli-885pcze8.js";
|
|
5
|
+
import"./cli-5qhjwne5.js";
|
|
6
6
|
import"./cli-ht1bcqdd.js";
|
|
7
|
-
import"./cli-
|
|
8
|
-
import"./cli-
|
|
7
|
+
import"./cli-9pk65fqf.js";
|
|
8
|
+
import"./cli-2ppw6q9v.js";
|
|
9
9
|
import"./cli-eyyggect.js";
|
|
10
10
|
import"./cli-asap4t1z.js";
|
|
11
11
|
import"./cli-habkc5ng.js";
|
|
12
12
|
import"./cli-v5mp7a6q.js";
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
13
|
+
import"./cli-5et23z83.js";
|
|
14
|
+
import"./cli-pn3z0y9p.js";
|
|
15
15
|
import {
|
|
16
16
|
log
|
|
17
|
-
} from "./cli-
|
|
17
|
+
} from "./cli-80t93x2r.js";
|
|
18
18
|
import {
|
|
19
19
|
UsageError,
|
|
20
20
|
parseFormat,
|
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
rejectExtraPositionals,
|
|
23
23
|
rejectUnknownFlags
|
|
24
24
|
} from "./cli-d8xjns66.js";
|
|
25
|
-
import"./cli-
|
|
26
|
-
import"./cli-
|
|
25
|
+
import"./cli-3twpesca.js";
|
|
26
|
+
import"./cli-hndkg7bn.js";
|
|
27
27
|
import {
|
|
28
28
|
BuildError
|
|
29
29
|
} from "./cli-46ycxe6r.js";
|
|
@@ -168,6 +168,14 @@ function getTextPass(doc) {
|
|
|
168
168
|
return p;
|
|
169
169
|
}
|
|
170
170
|
var opCache = new WeakMap;
|
|
171
|
+
var opSet = (names) => new Set(names.map((name) => OPS[name]).filter((op) => op !== undefined));
|
|
172
|
+
var IMAGE_OPS = opSet([
|
|
173
|
+
"paintImageXObject",
|
|
174
|
+
"paintImageXObjectRepeat",
|
|
175
|
+
"paintInlineImageXObject",
|
|
176
|
+
"paintImageMaskXObject",
|
|
177
|
+
"paintJpegXObject"
|
|
178
|
+
]);
|
|
171
179
|
function multiply(m1, m2) {
|
|
172
180
|
return [
|
|
173
181
|
m1[0] * m2[0] + m1[2] * m2[1],
|
|
@@ -219,14 +227,27 @@ function getOpPass(doc) {
|
|
|
219
227
|
ctm = stack.pop() ?? ctm;
|
|
220
228
|
} else if (fn === OPS.transform) {
|
|
221
229
|
ctm = multiply(ctm, args);
|
|
222
|
-
} else if (fn === OPS.
|
|
230
|
+
} else if (fn === OPS.paintFormXObjectBegin) {
|
|
231
|
+
stack.push(ctm.slice());
|
|
232
|
+
const matrix = args[0];
|
|
233
|
+
if (Array.isArray(matrix))
|
|
234
|
+
ctm = multiply(ctm, matrix);
|
|
235
|
+
} else if (fn === OPS.paintFormXObjectEnd) {
|
|
236
|
+
ctm = stack.pop() ?? ctm;
|
|
237
|
+
} else if (IMAGE_OPS.has(fn)) {
|
|
223
238
|
const name = typeof args[0] === "string" ? args[0] : "(inline)";
|
|
239
|
+
const [a, b, c, d, e, f] = ctm;
|
|
240
|
+
const xs = [e, a + e, c + e, a + c + e];
|
|
241
|
+
const ys = [f, b + f, d + f, b + d + f];
|
|
242
|
+
const x0 = Math.min(...xs);
|
|
243
|
+
const y0 = Math.min(...ys);
|
|
224
244
|
pageImages.push({
|
|
225
245
|
name,
|
|
226
|
-
placedW: Math.hypot(
|
|
227
|
-
placedH: Math.hypot(
|
|
228
|
-
x:
|
|
229
|
-
y:
|
|
246
|
+
placedW: Math.hypot(a, b),
|
|
247
|
+
placedH: Math.hypot(c, d),
|
|
248
|
+
x: e,
|
|
249
|
+
y: f,
|
|
250
|
+
bounds: { x: x0, y: y0, w: Math.max(...xs) - x0, h: Math.max(...ys) - y0 },
|
|
230
251
|
page: i
|
|
231
252
|
});
|
|
232
253
|
} else if (fn === OPS.setFont) {
|
|
@@ -254,7 +275,6 @@ function getOpPass(doc) {
|
|
|
254
275
|
}
|
|
255
276
|
return p;
|
|
256
277
|
}
|
|
257
|
-
var opSet = (names) => new Set(names.map((name) => OPS[name]).filter((op) => op !== undefined));
|
|
258
278
|
var FILL_COLOR_OPS = opSet(["setFillGray", "setFillRGBColor", "setFillCMYKColor", "setFillColor"]);
|
|
259
279
|
var STROKE_COLOR_OPS = opSet(["setStrokeGray", "setStrokeRGBColor", "setStrokeCMYKColor", "setStrokeColor"]);
|
|
260
280
|
var SHOW_TEXT_OPS = opSet(["showText", "showSpacedText", "nextLineShowText", "nextLineSetSpacingShowText"]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "gutterpress",
|
|
4
|
-
version: "0.11.22-alpha.
|
|
4
|
+
version: "0.11.22-alpha.2",
|
|
5
5
|
description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
6
6
|
author: "itlackey",
|
|
7
7
|
license: "MPL-2.0",
|
|
@@ -7,16 +7,16 @@ import {
|
|
|
7
7
|
prettify,
|
|
8
8
|
readExtensionMeta,
|
|
9
9
|
slugify
|
|
10
|
-
} from "./cli-
|
|
10
|
+
} from "./cli-pn3z0y9p.js";
|
|
11
11
|
import {
|
|
12
12
|
log
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-80t93x2r.js";
|
|
14
14
|
import {
|
|
15
15
|
UsageError
|
|
16
16
|
} from "./cli-d8xjns66.js";
|
|
17
17
|
import {
|
|
18
18
|
getAssetsDir
|
|
19
|
-
} from "./cli-
|
|
19
|
+
} from "./cli-hndkg7bn.js";
|
|
20
20
|
import {
|
|
21
21
|
BuildError,
|
|
22
22
|
EXIT_CODES
|
|
@@ -159,7 +159,7 @@ var DTRPG_PRESET = {
|
|
|
159
159
|
bleed: 9,
|
|
160
160
|
safe: 36,
|
|
161
161
|
artSafe: 18,
|
|
162
|
-
gutter:
|
|
162
|
+
gutter: 36
|
|
163
163
|
},
|
|
164
164
|
ink: {
|
|
165
165
|
maxTac: 240,
|
|
@@ -8,14 +8,16 @@ import {
|
|
|
8
8
|
stampCreator,
|
|
9
9
|
stripAnnotations,
|
|
10
10
|
transparentPages
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-5qhjwne5.js";
|
|
12
12
|
import {
|
|
13
13
|
blackTextToGray
|
|
14
14
|
} from "./cli-ht1bcqdd.js";
|
|
15
15
|
import {
|
|
16
16
|
MARGIN_BOX_IGNORED_PROPERTIES,
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
extract,
|
|
18
|
+
lastPageMode,
|
|
19
|
+
resolvePage
|
|
20
|
+
} from "./cli-9pk65fqf.js";
|
|
19
21
|
import {
|
|
20
22
|
countLinkAnnotations,
|
|
21
23
|
getImageResolutions,
|
|
@@ -28,7 +30,7 @@ import {
|
|
|
28
30
|
loadPdf,
|
|
29
31
|
pageHasMarks,
|
|
30
32
|
retainPdfCache
|
|
31
|
-
} from "./cli-
|
|
33
|
+
} from "./cli-2ppw6q9v.js";
|
|
32
34
|
import {
|
|
33
35
|
INSTALL_HINTS,
|
|
34
36
|
execCapture,
|
|
@@ -68,7 +70,7 @@ import {
|
|
|
68
70
|
uniqueExtensionId,
|
|
69
71
|
withFetchTimeout,
|
|
70
72
|
writeManifestDoc
|
|
71
|
-
} from "./cli-
|
|
73
|
+
} from "./cli-5et23z83.js";
|
|
72
74
|
import {
|
|
73
75
|
EXTENSION_MANIFEST_FILENAME,
|
|
74
76
|
GUTTERPRESS_CSS,
|
|
@@ -89,7 +91,7 @@ import {
|
|
|
89
91
|
readExtensionMeta,
|
|
90
92
|
resolveDeclaredStyles,
|
|
91
93
|
slugify
|
|
92
|
-
} from "./cli-
|
|
94
|
+
} from "./cli-pn3z0y9p.js";
|
|
93
95
|
import {
|
|
94
96
|
PACKAGE_META,
|
|
95
97
|
PACKAGE_VERSION,
|
|
@@ -99,7 +101,7 @@ import {
|
|
|
99
101
|
log,
|
|
100
102
|
setLogLevel,
|
|
101
103
|
warn
|
|
102
|
-
} from "./cli-
|
|
104
|
+
} from "./cli-80t93x2r.js";
|
|
103
105
|
import {
|
|
104
106
|
DEBOUNCE,
|
|
105
107
|
UsageError,
|
|
@@ -107,7 +109,7 @@ import {
|
|
|
107
109
|
} from "./cli-d8xjns66.js";
|
|
108
110
|
import {
|
|
109
111
|
getAssetPath
|
|
110
|
-
} from "./cli-
|
|
112
|
+
} from "./cli-hndkg7bn.js";
|
|
111
113
|
import {
|
|
112
114
|
BuildError
|
|
113
115
|
} from "./cli-46ycxe6r.js";
|
|
@@ -281,36 +283,122 @@ var check2 = {
|
|
|
281
283
|
};
|
|
282
284
|
registerCheck(check2);
|
|
283
285
|
|
|
286
|
+
// src/engine/shared/print-area.ts
|
|
287
|
+
function isPositivePoints(value) {
|
|
288
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
289
|
+
}
|
|
290
|
+
var round3 = (n) => Math.round(n * 1000) / 1000;
|
|
291
|
+
function cssLength(pt) {
|
|
292
|
+
const inches = round3(pt / 72);
|
|
293
|
+
return Math.abs(inches * 72 - pt) < 0.000001 ? `${inches}in` : `${round3(pt)}pt`;
|
|
294
|
+
}
|
|
295
|
+
function formatPageSize(page) {
|
|
296
|
+
return `${cssLength(page.width)} ${cssLength(page.height)}`;
|
|
297
|
+
}
|
|
298
|
+
function printAreaMeta(page) {
|
|
299
|
+
const area = JSON.stringify({
|
|
300
|
+
width: page.width,
|
|
301
|
+
height: page.height,
|
|
302
|
+
bleed: page.bleed ?? 0,
|
|
303
|
+
safe: page.safe ?? 0,
|
|
304
|
+
artSafe: page.artSafe,
|
|
305
|
+
gutter: page.gutter,
|
|
306
|
+
preset: page.preset,
|
|
307
|
+
spec: page.spec
|
|
308
|
+
});
|
|
309
|
+
return `<meta name="gp-print-area" content='${area.replace(/&/g, "&").replace(/'/g, "'")}'>`;
|
|
310
|
+
}
|
|
311
|
+
function pageBoxes(area, side, scale = 1) {
|
|
312
|
+
const w = area.width * scale;
|
|
313
|
+
const h = area.height * scale;
|
|
314
|
+
const b = Math.max(0, area.bleed) * scale;
|
|
315
|
+
const s = Math.max(0, area.safe) * scale;
|
|
316
|
+
const a = Math.max(0, area.artSafe) * scale;
|
|
317
|
+
const g = Math.max(0, area.gutter) * scale;
|
|
318
|
+
const [textLeft, textRight] = side === "verso" ? [s, g] : [g, s];
|
|
319
|
+
const [artLeft, artRight] = side === "verso" ? [a, g] : [g, a];
|
|
320
|
+
const trim = { x: side === "verso" ? b : 0, y: b, w: Math.max(0, w - b), h: Math.max(0, h - 2 * b) };
|
|
321
|
+
return {
|
|
322
|
+
sheet: { x: 0, y: 0, w, h },
|
|
323
|
+
trim,
|
|
324
|
+
safe: {
|
|
325
|
+
x: trim.x + textLeft,
|
|
326
|
+
y: trim.y + s,
|
|
327
|
+
w: Math.max(0, trim.w - textLeft - textRight),
|
|
328
|
+
h: Math.max(0, trim.h - 2 * s)
|
|
329
|
+
},
|
|
330
|
+
safeArt: {
|
|
331
|
+
x: trim.x + artLeft,
|
|
332
|
+
y: trim.y + a,
|
|
333
|
+
w: Math.max(0, trim.w - artLeft - artRight),
|
|
334
|
+
h: Math.max(0, trim.h - 2 * a)
|
|
335
|
+
},
|
|
336
|
+
bleed: b
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
var SEVERITY = { inside: 0, unsafe: 1, bleed: 2, "off-page": 3 };
|
|
340
|
+
function judgeRect(r, boxes, rule, tol = 0) {
|
|
341
|
+
const { sheet, trim } = boxes;
|
|
342
|
+
const safe = rule === "art" ? boxes.safeArt : boxes.safe;
|
|
343
|
+
const sides = [
|
|
344
|
+
["left", -r.x, -safe.x, -trim.x, -sheet.x],
|
|
345
|
+
["right", r.x + r.w, safe.x + safe.w, trim.x + trim.w, sheet.x + sheet.w],
|
|
346
|
+
["top", -r.y, -safe.y, -trim.y, -sheet.y],
|
|
347
|
+
["bottom", r.y + r.h, safe.y + safe.h, trim.y + trim.h, sheet.y + sheet.h]
|
|
348
|
+
];
|
|
349
|
+
let worst = { kind: "inside", gap: 0, need: 0, edge: null };
|
|
350
|
+
let beyond = 0;
|
|
351
|
+
for (const [edge, ink, limit, trimEdge, sheetEdge] of sides) {
|
|
352
|
+
const past = ink - limit;
|
|
353
|
+
if (past <= tol || rule === "art" && ink >= sheetEdge - tol)
|
|
354
|
+
continue;
|
|
355
|
+
const kind = ink > sheetEdge + tol ? "off-page" : ink > trimEdge + tol ? "bleed" : "unsafe";
|
|
356
|
+
if (SEVERITY[kind] > SEVERITY[worst.kind] || kind === worst.kind && past > beyond) {
|
|
357
|
+
worst = { kind, gap: trimEdge - ink, need: trimEdge - limit, edge };
|
|
358
|
+
beyond = past;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return worst;
|
|
362
|
+
}
|
|
363
|
+
|
|
284
364
|
// src/checks/pdf/safe-margins.ts
|
|
285
365
|
var TOLERANCE_PT = 0.5;
|
|
286
366
|
var ABOVE_BASELINE = 0.8;
|
|
287
367
|
var BELOW_BASELINE = 0.2;
|
|
288
368
|
var inches = (pt) => `${+(pt / 72).toFixed(2)}in`;
|
|
369
|
+
var size = (r) => `${(r.w / 72).toFixed(1)} x ${(r.h / 72).toFixed(1)}in`;
|
|
370
|
+
var fromPdf = (x, y, w, h, sheetHeight) => ({
|
|
371
|
+
x,
|
|
372
|
+
y: sheetHeight - y - h,
|
|
373
|
+
w,
|
|
374
|
+
h
|
|
375
|
+
});
|
|
289
376
|
var check3 = {
|
|
290
377
|
id: "pdf.print.safe-margins",
|
|
291
378
|
name: "Safe margins",
|
|
292
|
-
description: "Fails when text sits closer to the trim than `page.safe` (DriveThruRPG: 0.5in on every edge)
|
|
379
|
+
description: "Fails when text sits closer to the trim than `page.safe` (DriveThruRPG: 0.5in on every edge) or an image that does not bleed closer than `page.artSafe` (DriveThruRPG: 0.25in on the top, bottom and outside edges), both held to `page.gutter` at the binding edge where one is set; and when an image crosses the trim without reaching the sheet's edge (it ends in the bleed band). Text and images: filled backgrounds and borders are judged in the preview's safe-area overlay, not here. Skipped when `page.safe` is not set",
|
|
293
380
|
category: "pdf",
|
|
294
381
|
phase: "post-build",
|
|
295
382
|
async run(ctx) {
|
|
296
|
-
const { width, height, bleed = 0, safe = 0, gutter = safe } = ctx.config.page;
|
|
383
|
+
const { width, height, bleed = 0, safe = 0, artSafe = safe, gutter = safe } = ctx.config.page;
|
|
297
384
|
if (!ctx.pdfPath || !safe)
|
|
298
385
|
return [];
|
|
299
386
|
const doc = await loadPdf(ctx.pdfPath);
|
|
300
387
|
if (!doc) {
|
|
301
|
-
return [inspectionFailed(check3.id, "Could not parse the PDF's text positions.", { file: ctx.pdfPath })];
|
|
388
|
+
return [inspectionFailed(check3.id, "Could not parse the PDF's text and image positions.", { file: ctx.pdfPath })];
|
|
302
389
|
}
|
|
390
|
+
const area = { width, height, bleed, safe, artSafe, gutter };
|
|
303
391
|
const rule = ctx.config.spec?.label ?? "page.safe";
|
|
392
|
+
const textRule = gutter === safe ? `${rule}: text must stay at least ${inches(safe)} inside the trim on every edge.` : `${rule}: text must stay at least ${inches(safe)} inside the trim, ${inches(gutter)} at the binding.`;
|
|
393
|
+
const artRule = gutter === artSafe ? `${rule}: art that does not bleed must stay at least ${inches(artSafe)} inside the trim on every edge.` : `${rule}: art that does not bleed must stay at least ${inches(artSafe)} inside the trim, ${inches(gutter)} at the binding.`;
|
|
304
394
|
const results = [];
|
|
305
395
|
try {
|
|
396
|
+
const { imagesByPage } = await getOpPass(doc);
|
|
306
397
|
for (let pageNum = 1;pageNum <= doc.numPages; pageNum++) {
|
|
307
|
-
const
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
bottom: bleed,
|
|
312
|
-
top: height - bleed
|
|
313
|
-
};
|
|
398
|
+
const side = pageNum % 2 === 1 ? "recto" : "verso";
|
|
399
|
+
const boxes = pageBoxes(area, side);
|
|
400
|
+
const binding = side === "recto" ? "left" : "right";
|
|
401
|
+
const edgeName = (edge) => edge === "top" || edge === "bottom" ? edge : edge === binding ? "binding" : "outside";
|
|
314
402
|
const { items } = await (await doc.getPage(pageNum)).getTextContent();
|
|
315
403
|
for (const item of items) {
|
|
316
404
|
if (!("str" in item) || !item.str.trim())
|
|
@@ -325,28 +413,55 @@ var check3 = {
|
|
|
325
413
|
ys.push(f + s * along * b + u * d);
|
|
326
414
|
}
|
|
327
415
|
}
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
];
|
|
334
|
-
const [edge, shortfall] = gaps.map(([name, gap]) => [name, (name === "binding" ? gutter : safe) - gap]).reduce((worst, g) => g[1] > worst[1] ? g : worst);
|
|
335
|
-
if (shortfall <= TOLERANCE_PT)
|
|
416
|
+
const x0 = Math.min(...xs);
|
|
417
|
+
const y0 = Math.min(...ys);
|
|
418
|
+
const box = fromPdf(x0, y0, Math.max(...xs) - x0, Math.max(...ys) - y0, height);
|
|
419
|
+
const { kind, edge, gap, need } = judgeRect(box, boxes, "text", TOLERANCE_PT);
|
|
420
|
+
if (kind === "inside")
|
|
336
421
|
continue;
|
|
422
|
+
const shortfall = need - gap;
|
|
337
423
|
const text = item.str.trim();
|
|
338
424
|
results.push(finding(check3.id, {
|
|
339
425
|
severity: "error",
|
|
340
|
-
message: `Page ${pageNum}: "${text.slice(0, 40)}${text.length > 40 ? "…" : ""}" is ${inches(shortfall)} too close to the ${edge} edge.`,
|
|
426
|
+
message: `Page ${pageNum}: "${text.slice(0, 40)}${text.length > 40 ? "…" : ""}" is ${inches(shortfall)} too close to the ${edgeName(edge)} edge.`,
|
|
341
427
|
file: ctx.pdfPath,
|
|
342
|
-
detail:
|
|
428
|
+
detail: textRule,
|
|
343
429
|
code: "text-outside-safe-margin",
|
|
344
|
-
data: { page: pageNum, edge, shortfallPt: +shortfall.toFixed(2) }
|
|
430
|
+
data: { page: pageNum, edge: edgeName(edge), shortfallPt: +shortfall.toFixed(2) }
|
|
431
|
+
}));
|
|
432
|
+
}
|
|
433
|
+
for (const image of imagesByPage.get(pageNum) ?? []) {
|
|
434
|
+
const { x, y, w, h } = image.bounds;
|
|
435
|
+
const box = fromPdf(x, y, w, h, height);
|
|
436
|
+
const { kind, edge, gap, need } = judgeRect(box, boxes, "art", TOLERANCE_PT);
|
|
437
|
+
if (kind === "inside")
|
|
438
|
+
continue;
|
|
439
|
+
const name = edgeName(edge);
|
|
440
|
+
if (kind === "bleed") {
|
|
441
|
+
const short = boxes.bleed + gap;
|
|
442
|
+
results.push(finding(check3.id, {
|
|
443
|
+
severity: "error",
|
|
444
|
+
message: `Page ${pageNum}: a ${size(box)} image ends in the bleed band on the ${name} edge, ${inches(short)} short of the sheet's edge.`,
|
|
445
|
+
file: ctx.pdfPath,
|
|
446
|
+
detail: `${rule}: art either stays ${inches(artSafe)} inside the trim or bleeds, running past it to the sheet's edge; art that stops between the two can leave a white sliver when the page is cut.`,
|
|
447
|
+
code: "art-ends-in-bleed-band",
|
|
448
|
+
data: { page: pageNum, edge: name, shortfallPt: +short.toFixed(2) }
|
|
449
|
+
}));
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
const shortfall = need - gap;
|
|
453
|
+
results.push(finding(check3.id, {
|
|
454
|
+
severity: "error",
|
|
455
|
+
message: `Page ${pageNum}: a ${size(box)} image is ${inches(shortfall)} too close to the ${name} edge.`,
|
|
456
|
+
file: ctx.pdfPath,
|
|
457
|
+
detail: artRule,
|
|
458
|
+
code: "art-outside-safe-margin",
|
|
459
|
+
data: { page: pageNum, edge: name, shortfallPt: +shortfall.toFixed(2) }
|
|
345
460
|
}));
|
|
346
461
|
}
|
|
347
462
|
}
|
|
348
463
|
} catch {
|
|
349
|
-
return [inspectionFailed(check3.id, "Could not read the PDF's text positions.", { file: ctx.pdfPath })];
|
|
464
|
+
return [inspectionFailed(check3.id, "Could not read the PDF's text and image positions.", { file: ctx.pdfPath })];
|
|
350
465
|
}
|
|
351
466
|
return results;
|
|
352
467
|
}
|
|
@@ -759,16 +874,16 @@ var check9 = {
|
|
|
759
874
|
if (!doc) {
|
|
760
875
|
return [inspectionFailed(check9.id, "Could not parse the PDF's page count.", { file: ctx.pdfPath })];
|
|
761
876
|
}
|
|
762
|
-
const
|
|
877
|
+
const size2 = ctx.config.print.signature;
|
|
763
878
|
const pages = doc.numPages;
|
|
764
|
-
if ((pages + 1) %
|
|
879
|
+
if ((pages + 1) % size2 === 0)
|
|
765
880
|
return [];
|
|
766
|
-
const data = { pages, signature:
|
|
767
|
-
if (pages %
|
|
881
|
+
const data = { pages, signature: size2 };
|
|
882
|
+
if (pages % size2 !== 0) {
|
|
768
883
|
return [
|
|
769
884
|
finding(check9.id, {
|
|
770
885
|
severity: "error",
|
|
771
|
-
message: `Page count ${pages} does not fit a signature of ${
|
|
886
|
+
message: `Page count ${pages} does not fit a signature of ${size2}: it must be a multiple of ${size2}, or one short of one.`,
|
|
772
887
|
file: ctx.pdfPath,
|
|
773
888
|
detail: "Set `print.signature` in the manifest and rebuild; the build pads the interior for you.",
|
|
774
889
|
code: "signature-page-count",
|
|
@@ -789,7 +904,7 @@ var check9 = {
|
|
|
789
904
|
severity: "error",
|
|
790
905
|
message: `The last page (${pages}) has content, but the printer needs it blank for its own information.`,
|
|
791
906
|
file: ctx.pdfPath,
|
|
792
|
-
detail: "The build adds that page for you (`print.lastPage: blank`, or `short-by-one` to stop a page short of a multiple " + `of ${
|
|
907
|
+
detail: "The build adds that page for you (`print.lastPage: blank`, or `short-by-one` to stop a page short of a multiple " + `of ${size2} and let the printer add it). Check that the interior was built with this manifest, and that nothing in it ` + "forces content onto the final page.",
|
|
793
908
|
code: "signature-last-page",
|
|
794
909
|
data
|
|
795
910
|
})
|
|
@@ -3884,22 +3999,18 @@ function canonicalChapterId(p) {
|
|
|
3884
3999
|
return s;
|
|
3885
4000
|
}
|
|
3886
4001
|
|
|
3887
|
-
// src/engine/shared/print-area.ts
|
|
3888
|
-
function printAreaMeta(page) {
|
|
3889
|
-
const area = JSON.stringify({
|
|
3890
|
-
width: page.width,
|
|
3891
|
-
height: page.height,
|
|
3892
|
-
bleed: page.bleed ?? 0,
|
|
3893
|
-
safe: page.safe ?? 0,
|
|
3894
|
-
artSafe: page.artSafe,
|
|
3895
|
-
gutter: page.gutter,
|
|
3896
|
-
preset: page.preset,
|
|
3897
|
-
spec: page.spec
|
|
3898
|
-
});
|
|
3899
|
-
return `<meta name="gp-print-area" content='${area.replace(/&/g, "&").replace(/'/g, "'")}'>`;
|
|
3900
|
-
}
|
|
3901
|
-
|
|
3902
4002
|
// src/lib/markdown/assemble.ts
|
|
4003
|
+
function defaultPageSizeCss(css, page) {
|
|
4004
|
+
if (!page || !isPositivePoints(page.width) || !isPositivePoints(page.height))
|
|
4005
|
+
return null;
|
|
4006
|
+
try {
|
|
4007
|
+
if (resolvePage(extract(css)).decls.size !== undefined)
|
|
4008
|
+
return null;
|
|
4009
|
+
} catch {
|
|
4010
|
+
return null;
|
|
4011
|
+
}
|
|
4012
|
+
return `@page { size: ${formatPageSize(page)}; }`;
|
|
4013
|
+
}
|
|
3903
4014
|
async function assembleBookHtml(opts) {
|
|
3904
4015
|
const title = opts.title ?? "Document";
|
|
3905
4016
|
const projectCss = opts.projectCss ?? "";
|
|
@@ -3937,6 +4048,8 @@ async function assembleBookHtml(opts) {
|
|
|
3937
4048
|
imageRefs.add(ref);
|
|
3938
4049
|
opts.onImageRefs([...imageRefs]);
|
|
3939
4050
|
}
|
|
4051
|
+
const pageSize = defaultPageSizeCss(`${pluginCss}
|
|
4052
|
+
${projectCss}`, opts.printArea);
|
|
3940
4053
|
const inlineCss = [
|
|
3941
4054
|
"@layer gp.marker, gp.vocab;",
|
|
3942
4055
|
`/* gutterpress markers */
|
|
@@ -3948,6 +4061,8 @@ ${TWO_VERSIONS_CSS.trim()}
|
|
|
3948
4061
|
@layer gp.vocab {
|
|
3949
4062
|
${GUTTERPRESS_CSS.trim()}
|
|
3950
4063
|
}`,
|
|
4064
|
+
pageSize ? `/* page size (manifest) */
|
|
4065
|
+
${pageSize}` : null,
|
|
3951
4066
|
pluginCss ? `/* extension css */
|
|
3952
4067
|
${pluginCss.trim()}` : null,
|
|
3953
4068
|
`/* column alignment */
|
|
@@ -5092,7 +5207,7 @@ class PdfOutput {
|
|
|
5092
5207
|
const rawPdf = pdfxMode ? path7.join(stage, "raw.pdf") : path7.resolve(pdfFile);
|
|
5093
5208
|
await fsp2.mkdir(path7.dirname(path7.resolve(pdfFile)), { recursive: true });
|
|
5094
5209
|
log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
|
|
5095
|
-
const { buildNativePdf } = await import("./engine-
|
|
5210
|
+
const { buildNativePdf } = await import("./engine-5p8tn9b4.js");
|
|
5096
5211
|
const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
|
|
5097
5212
|
title: config.title,
|
|
5098
5213
|
author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
|
|
@@ -5129,7 +5244,7 @@ class PdfOutput {
|
|
|
5129
5244
|
}
|
|
5130
5245
|
const flattenPages = config.pdfx.flattenPages;
|
|
5131
5246
|
if (transparent.length > 0 && config.pdfx.transparency === "preserve-text") {
|
|
5132
|
-
const { unsplittableTextReasons } = await import("./pdf-inspect-
|
|
5247
|
+
const { unsplittableTextReasons } = await import("./pdf-inspect-wnw4za71.js");
|
|
5133
5248
|
const reasons = await unsplittableTextReasons(rawBytes, transparent).catch((err) => {
|
|
5134
5249
|
log.warn(`pdfx.transparency: preserve-text could not inspect this PDF's text (${err instanceof Error ? err.message : String(err)}), so every page that uses transparency is flattened whole, as with flatten-page.`);
|
|
5135
5250
|
return null;
|
|
@@ -6388,9 +6503,6 @@ import path12 from "node:path";
|
|
|
6388
6503
|
// src/lib/page-size.ts
|
|
6389
6504
|
import postcss5 from "postcss";
|
|
6390
6505
|
import { isMap, Scalar } from "yaml";
|
|
6391
|
-
function isPositivePoints(value) {
|
|
6392
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
6393
|
-
}
|
|
6394
6506
|
function writePageBounds(doc, page) {
|
|
6395
6507
|
const tolerance = page.tolerance ?? numberAt(doc, ["page", "tolerance"]);
|
|
6396
6508
|
if (!isMap(doc.get("page", true)))
|
|
@@ -8906,7 +9018,7 @@ async function resolvePublishProvider(id, book) {
|
|
|
8906
9018
|
const ext = await bookExtensions(book);
|
|
8907
9019
|
const npmEntry = ext.extensions.some((c) => !c.path && c.name === id);
|
|
8908
9020
|
if (npmEntry) {
|
|
8909
|
-
const { restoreForCommand: restoreForCommand2 } = await import("./extension-restore-
|
|
9021
|
+
const { restoreForCommand: restoreForCommand2 } = await import("./extension-restore-3r7phztr.js");
|
|
8910
9022
|
await restoreForCommand2(book.projectDir, { manifestPath: book.manifestPath, failFast: true });
|
|
8911
9023
|
}
|
|
8912
9024
|
const publishers = await discover(ext);
|
|
@@ -8944,7 +9056,7 @@ function infoFor(p) {
|
|
|
8944
9056
|
}
|
|
8945
9057
|
function pluginProvider(p) {
|
|
8946
9058
|
let loading;
|
|
8947
|
-
const load = () => loading ??= import("./plugins-
|
|
9059
|
+
const load = () => loading ??= import("./plugins-nfxr831f.js").then((m) => m.loadPublishFunction(p));
|
|
8948
9060
|
return {
|
|
8949
9061
|
info: infoFor(p),
|
|
8950
9062
|
async authenticate() {
|
|
@@ -9236,10 +9348,10 @@ function isSmallBody(body) {
|
|
|
9236
9348
|
return false;
|
|
9237
9349
|
let total = 0;
|
|
9238
9350
|
for (const c of body) {
|
|
9239
|
-
const
|
|
9240
|
-
if (typeof
|
|
9351
|
+
const size2 = c?.byteLength;
|
|
9352
|
+
if (typeof size2 !== "number")
|
|
9241
9353
|
return false;
|
|
9242
|
-
total +=
|
|
9354
|
+
total += size2;
|
|
9243
9355
|
}
|
|
9244
9356
|
return total <= SMALL_BODY_MAX_BYTES;
|
|
9245
9357
|
}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./cli-eyyggect.js";
|
|
4
4
|
import {
|
|
5
5
|
getAssetPath
|
|
6
|
-
} from "./cli-
|
|
6
|
+
} from "./cli-hndkg7bn.js";
|
|
7
7
|
|
|
8
8
|
// src/engine/compiler/build.ts
|
|
9
9
|
import { readFile } from "node:fs/promises";
|
|
@@ -2503,4 +2503,4 @@ ${lines.length ? lines.join(`
|
|
|
2503
2503
|
`);
|
|
2504
2504
|
}
|
|
2505
2505
|
|
|
2506
|
-
export { lastPageMode, MARGIN_BOX_IGNORED_PROPERTIES, build };
|
|
2506
|
+
export { lastPageMode, extract, resolvePage, MARGIN_BOX_IGNORED_PROPERTIES, build };
|
|
@@ -9,7 +9,7 @@ import { fileURLToPath } from "node:url";
|
|
|
9
9
|
var favicon_default = "./favicon-272ga6y0.ico";
|
|
10
10
|
|
|
11
11
|
// src/assets/manifest.schema.json
|
|
12
|
-
var manifest_schema_default = "./manifest.schema-
|
|
12
|
+
var manifest_schema_default = "./manifest.schema-nvawq0xv.json";
|
|
13
13
|
|
|
14
14
|
// src/assets/preview/scripts/preview-interface.js
|
|
15
15
|
var preview_interface_default = "./preview-interface-nnmrxyqm.js";
|
|
@@ -24,7 +24,7 @@ var preview_shell_default = "./preview-shell-wk9k3gcd.js";
|
|
|
24
24
|
var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
|
|
25
25
|
|
|
26
26
|
// src/assets/engine/gutterpress-viewer.js
|
|
27
|
-
var gutterpress_viewer_default = "./gutterpress-viewer-
|
|
27
|
+
var gutterpress_viewer_default = "./gutterpress-viewer-w9jzx6sb.js";
|
|
28
28
|
|
|
29
29
|
// src/assets/engine/gutterpress-agent.js
|
|
30
30
|
var gutterpress_agent_default = "./gutterpress-agent-d29ry3ak.js";
|