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
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
uniqueExtensionId,
|
|
30
30
|
withFetchTimeout,
|
|
31
31
|
writeManifestDoc
|
|
32
|
-
} from "./index-
|
|
32
|
+
} from "./index-ew7cyk7c.js";
|
|
33
33
|
import {
|
|
34
34
|
EXTENSION_MANIFEST_FILENAME,
|
|
35
35
|
GUTTERPRESS_CSS,
|
|
@@ -64,19 +64,21 @@ import {
|
|
|
64
64
|
setLogLevel,
|
|
65
65
|
slugify,
|
|
66
66
|
warn
|
|
67
|
-
} from "./index-
|
|
67
|
+
} from "./index-kx03e4m4.js";
|
|
68
68
|
import {
|
|
69
69
|
blackTextToGray
|
|
70
70
|
} from "./index-ht1bcqdd.js";
|
|
71
71
|
import {
|
|
72
72
|
MARGIN_BOX_IGNORED_PROPERTIES,
|
|
73
|
+
extract,
|
|
73
74
|
lastPageMode,
|
|
74
|
-
parseSize
|
|
75
|
-
|
|
75
|
+
parseSize,
|
|
76
|
+
resolvePage
|
|
77
|
+
} from "./index-apc8w9w8.js";
|
|
76
78
|
import {
|
|
77
79
|
BuildError,
|
|
78
80
|
getAssetPath
|
|
79
|
-
} from "./index-
|
|
81
|
+
} from "./index-jsz0s3dy.js";
|
|
80
82
|
import {
|
|
81
83
|
countLinkAnnotations,
|
|
82
84
|
getImageResolutions,
|
|
@@ -89,7 +91,7 @@ import {
|
|
|
89
91
|
loadPdf,
|
|
90
92
|
pageHasMarks,
|
|
91
93
|
retainPdfCache
|
|
92
|
-
} from "./index-
|
|
94
|
+
} from "./index-2ppw6q9v.js";
|
|
93
95
|
import {
|
|
94
96
|
INSTALL_HINTS,
|
|
95
97
|
enhancedPath,
|
|
@@ -184,6 +186,17 @@ function canonicalChapterId(p) {
|
|
|
184
186
|
}
|
|
185
187
|
|
|
186
188
|
// src/engine/shared/print-area.ts
|
|
189
|
+
function isPositivePoints(value) {
|
|
190
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
191
|
+
}
|
|
192
|
+
var round3 = (n) => Math.round(n * 1000) / 1000;
|
|
193
|
+
function cssLength(pt) {
|
|
194
|
+
const inches = round3(pt / 72);
|
|
195
|
+
return Math.abs(inches * 72 - pt) < 0.000001 ? `${inches}in` : `${round3(pt)}pt`;
|
|
196
|
+
}
|
|
197
|
+
function formatPageSize(page) {
|
|
198
|
+
return `${cssLength(page.width)} ${cssLength(page.height)}`;
|
|
199
|
+
}
|
|
187
200
|
function printAreaMeta(page) {
|
|
188
201
|
const area = JSON.stringify({
|
|
189
202
|
width: page.width,
|
|
@@ -197,8 +210,71 @@ function printAreaMeta(page) {
|
|
|
197
210
|
});
|
|
198
211
|
return `<meta name="gp-print-area" content='${area.replace(/&/g, "&").replace(/'/g, "'")}'>`;
|
|
199
212
|
}
|
|
213
|
+
function pageBoxes(area, side, scale = 1) {
|
|
214
|
+
const w = area.width * scale;
|
|
215
|
+
const h = area.height * scale;
|
|
216
|
+
const b = Math.max(0, area.bleed) * scale;
|
|
217
|
+
const s = Math.max(0, area.safe) * scale;
|
|
218
|
+
const a = Math.max(0, area.artSafe) * scale;
|
|
219
|
+
const g = Math.max(0, area.gutter) * scale;
|
|
220
|
+
const [textLeft, textRight] = side === "verso" ? [s, g] : [g, s];
|
|
221
|
+
const [artLeft, artRight] = side === "verso" ? [a, g] : [g, a];
|
|
222
|
+
const trim = { x: side === "verso" ? b : 0, y: b, w: Math.max(0, w - b), h: Math.max(0, h - 2 * b) };
|
|
223
|
+
return {
|
|
224
|
+
sheet: { x: 0, y: 0, w, h },
|
|
225
|
+
trim,
|
|
226
|
+
safe: {
|
|
227
|
+
x: trim.x + textLeft,
|
|
228
|
+
y: trim.y + s,
|
|
229
|
+
w: Math.max(0, trim.w - textLeft - textRight),
|
|
230
|
+
h: Math.max(0, trim.h - 2 * s)
|
|
231
|
+
},
|
|
232
|
+
safeArt: {
|
|
233
|
+
x: trim.x + artLeft,
|
|
234
|
+
y: trim.y + a,
|
|
235
|
+
w: Math.max(0, trim.w - artLeft - artRight),
|
|
236
|
+
h: Math.max(0, trim.h - 2 * a)
|
|
237
|
+
},
|
|
238
|
+
bleed: b
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
var SEVERITY = { inside: 0, unsafe: 1, bleed: 2, "off-page": 3 };
|
|
242
|
+
function judgeRect(r, boxes, rule, tol = 0) {
|
|
243
|
+
const { sheet, trim } = boxes;
|
|
244
|
+
const safe = rule === "art" ? boxes.safeArt : boxes.safe;
|
|
245
|
+
const sides = [
|
|
246
|
+
["left", -r.x, -safe.x, -trim.x, -sheet.x],
|
|
247
|
+
["right", r.x + r.w, safe.x + safe.w, trim.x + trim.w, sheet.x + sheet.w],
|
|
248
|
+
["top", -r.y, -safe.y, -trim.y, -sheet.y],
|
|
249
|
+
["bottom", r.y + r.h, safe.y + safe.h, trim.y + trim.h, sheet.y + sheet.h]
|
|
250
|
+
];
|
|
251
|
+
let worst = { kind: "inside", gap: 0, need: 0, edge: null };
|
|
252
|
+
let beyond = 0;
|
|
253
|
+
for (const [edge, ink, limit, trimEdge, sheetEdge] of sides) {
|
|
254
|
+
const past = ink - limit;
|
|
255
|
+
if (past <= tol || rule === "art" && ink >= sheetEdge - tol)
|
|
256
|
+
continue;
|
|
257
|
+
const kind = ink > sheetEdge + tol ? "off-page" : ink > trimEdge + tol ? "bleed" : "unsafe";
|
|
258
|
+
if (SEVERITY[kind] > SEVERITY[worst.kind] || kind === worst.kind && past > beyond) {
|
|
259
|
+
worst = { kind, gap: trimEdge - ink, need: trimEdge - limit, edge };
|
|
260
|
+
beyond = past;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return worst;
|
|
264
|
+
}
|
|
200
265
|
|
|
201
266
|
// src/lib/markdown/assemble.ts
|
|
267
|
+
function defaultPageSizeCss(css, page) {
|
|
268
|
+
if (!page || !isPositivePoints(page.width) || !isPositivePoints(page.height))
|
|
269
|
+
return null;
|
|
270
|
+
try {
|
|
271
|
+
if (resolvePage(extract(css)).decls.size !== undefined)
|
|
272
|
+
return null;
|
|
273
|
+
} catch {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
return `@page { size: ${formatPageSize(page)}; }`;
|
|
277
|
+
}
|
|
202
278
|
async function assembleBookHtml(opts) {
|
|
203
279
|
const title = opts.title ?? "Document";
|
|
204
280
|
const projectCss = opts.projectCss ?? "";
|
|
@@ -236,6 +312,8 @@ async function assembleBookHtml(opts) {
|
|
|
236
312
|
imageRefs.add(ref);
|
|
237
313
|
opts.onImageRefs([...imageRefs]);
|
|
238
314
|
}
|
|
315
|
+
const pageSize = defaultPageSizeCss(`${pluginCss}
|
|
316
|
+
${projectCss}`, opts.printArea);
|
|
239
317
|
const inlineCss = [
|
|
240
318
|
"@layer gp.marker, gp.vocab;",
|
|
241
319
|
`/* gutterpress markers */
|
|
@@ -247,6 +325,8 @@ ${TWO_VERSIONS_CSS.trim()}
|
|
|
247
325
|
@layer gp.vocab {
|
|
248
326
|
${GUTTERPRESS_CSS.trim()}
|
|
249
327
|
}`,
|
|
328
|
+
pageSize ? `/* page size (manifest) */
|
|
329
|
+
${pageSize}` : null,
|
|
250
330
|
pluginCss ? `/* extension css */
|
|
251
331
|
${pluginCss.trim()}` : null,
|
|
252
332
|
`/* column alignment */
|
|
@@ -1827,31 +1907,39 @@ var TOLERANCE_PT = 0.5;
|
|
|
1827
1907
|
var ABOVE_BASELINE = 0.8;
|
|
1828
1908
|
var BELOW_BASELINE = 0.2;
|
|
1829
1909
|
var inches = (pt) => `${+(pt / 72).toFixed(2)}in`;
|
|
1910
|
+
var size = (r) => `${(r.w / 72).toFixed(1)} x ${(r.h / 72).toFixed(1)}in`;
|
|
1911
|
+
var fromPdf = (x, y, w, h, sheetHeight) => ({
|
|
1912
|
+
x,
|
|
1913
|
+
y: sheetHeight - y - h,
|
|
1914
|
+
w,
|
|
1915
|
+
h
|
|
1916
|
+
});
|
|
1830
1917
|
var check4 = {
|
|
1831
1918
|
id: "pdf.print.safe-margins",
|
|
1832
1919
|
name: "Safe margins",
|
|
1833
|
-
description: "Fails when text sits closer to the trim than `page.safe` (DriveThruRPG: 0.5in on every edge)
|
|
1920
|
+
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",
|
|
1834
1921
|
category: "pdf",
|
|
1835
1922
|
phase: "post-build",
|
|
1836
1923
|
async run(ctx) {
|
|
1837
|
-
const { width, height, bleed = 0, safe = 0, gutter = safe } = ctx.config.page;
|
|
1924
|
+
const { width, height, bleed = 0, safe = 0, artSafe = safe, gutter = safe } = ctx.config.page;
|
|
1838
1925
|
if (!ctx.pdfPath || !safe)
|
|
1839
1926
|
return [];
|
|
1840
1927
|
const doc = await loadPdf(ctx.pdfPath);
|
|
1841
1928
|
if (!doc) {
|
|
1842
|
-
return [inspectionFailed(check4.id, "Could not parse the PDF's text positions.", { file: ctx.pdfPath })];
|
|
1929
|
+
return [inspectionFailed(check4.id, "Could not parse the PDF's text and image positions.", { file: ctx.pdfPath })];
|
|
1843
1930
|
}
|
|
1931
|
+
const area = { width, height, bleed, safe, artSafe, gutter };
|
|
1844
1932
|
const rule = ctx.config.spec?.label ?? "page.safe";
|
|
1933
|
+
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.`;
|
|
1934
|
+
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.`;
|
|
1845
1935
|
const results = [];
|
|
1846
1936
|
try {
|
|
1937
|
+
const { imagesByPage } = await getOpPass(doc);
|
|
1847
1938
|
for (let pageNum = 1;pageNum <= doc.numPages; pageNum++) {
|
|
1848
|
-
const
|
|
1849
|
-
const
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
bottom: bleed,
|
|
1853
|
-
top: height - bleed
|
|
1854
|
-
};
|
|
1939
|
+
const side = pageNum % 2 === 1 ? "recto" : "verso";
|
|
1940
|
+
const boxes = pageBoxes(area, side);
|
|
1941
|
+
const binding = side === "recto" ? "left" : "right";
|
|
1942
|
+
const edgeName = (edge) => edge === "top" || edge === "bottom" ? edge : edge === binding ? "binding" : "outside";
|
|
1855
1943
|
const { items } = await (await doc.getPage(pageNum)).getTextContent();
|
|
1856
1944
|
for (const item of items) {
|
|
1857
1945
|
if (!("str" in item) || !item.str.trim())
|
|
@@ -1866,28 +1954,55 @@ var check4 = {
|
|
|
1866
1954
|
ys.push(f + s * along * b + u * d);
|
|
1867
1955
|
}
|
|
1868
1956
|
}
|
|
1869
|
-
const
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
];
|
|
1875
|
-
const [edge, shortfall] = gaps.map(([name, gap]) => [name, (name === "binding" ? gutter : safe) - gap]).reduce((worst, g) => g[1] > worst[1] ? g : worst);
|
|
1876
|
-
if (shortfall <= TOLERANCE_PT)
|
|
1957
|
+
const x0 = Math.min(...xs);
|
|
1958
|
+
const y0 = Math.min(...ys);
|
|
1959
|
+
const box = fromPdf(x0, y0, Math.max(...xs) - x0, Math.max(...ys) - y0, height);
|
|
1960
|
+
const { kind, edge, gap, need } = judgeRect(box, boxes, "text", TOLERANCE_PT);
|
|
1961
|
+
if (kind === "inside")
|
|
1877
1962
|
continue;
|
|
1963
|
+
const shortfall = need - gap;
|
|
1878
1964
|
const text = item.str.trim();
|
|
1879
1965
|
results.push(finding(check4.id, {
|
|
1880
1966
|
severity: "error",
|
|
1881
|
-
message: `Page ${pageNum}: "${text.slice(0, 40)}${text.length > 40 ? "…" : ""}" is ${inches(shortfall)} too close to the ${edge} edge.`,
|
|
1967
|
+
message: `Page ${pageNum}: "${text.slice(0, 40)}${text.length > 40 ? "…" : ""}" is ${inches(shortfall)} too close to the ${edgeName(edge)} edge.`,
|
|
1882
1968
|
file: ctx.pdfPath,
|
|
1883
|
-
detail:
|
|
1969
|
+
detail: textRule,
|
|
1884
1970
|
code: "text-outside-safe-margin",
|
|
1885
|
-
data: { page: pageNum, edge, shortfallPt: +shortfall.toFixed(2) }
|
|
1971
|
+
data: { page: pageNum, edge: edgeName(edge), shortfallPt: +shortfall.toFixed(2) }
|
|
1972
|
+
}));
|
|
1973
|
+
}
|
|
1974
|
+
for (const image of imagesByPage.get(pageNum) ?? []) {
|
|
1975
|
+
const { x, y, w, h } = image.bounds;
|
|
1976
|
+
const box = fromPdf(x, y, w, h, height);
|
|
1977
|
+
const { kind, edge, gap, need } = judgeRect(box, boxes, "art", TOLERANCE_PT);
|
|
1978
|
+
if (kind === "inside")
|
|
1979
|
+
continue;
|
|
1980
|
+
const name = edgeName(edge);
|
|
1981
|
+
if (kind === "bleed") {
|
|
1982
|
+
const short = boxes.bleed + gap;
|
|
1983
|
+
results.push(finding(check4.id, {
|
|
1984
|
+
severity: "error",
|
|
1985
|
+
message: `Page ${pageNum}: a ${size(box)} image ends in the bleed band on the ${name} edge, ${inches(short)} short of the sheet's edge.`,
|
|
1986
|
+
file: ctx.pdfPath,
|
|
1987
|
+
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.`,
|
|
1988
|
+
code: "art-ends-in-bleed-band",
|
|
1989
|
+
data: { page: pageNum, edge: name, shortfallPt: +short.toFixed(2) }
|
|
1990
|
+
}));
|
|
1991
|
+
continue;
|
|
1992
|
+
}
|
|
1993
|
+
const shortfall = need - gap;
|
|
1994
|
+
results.push(finding(check4.id, {
|
|
1995
|
+
severity: "error",
|
|
1996
|
+
message: `Page ${pageNum}: a ${size(box)} image is ${inches(shortfall)} too close to the ${name} edge.`,
|
|
1997
|
+
file: ctx.pdfPath,
|
|
1998
|
+
detail: artRule,
|
|
1999
|
+
code: "art-outside-safe-margin",
|
|
2000
|
+
data: { page: pageNum, edge: name, shortfallPt: +shortfall.toFixed(2) }
|
|
1886
2001
|
}));
|
|
1887
2002
|
}
|
|
1888
2003
|
}
|
|
1889
2004
|
} catch {
|
|
1890
|
-
return [inspectionFailed(check4.id, "Could not read the PDF's text positions.", { file: ctx.pdfPath })];
|
|
2005
|
+
return [inspectionFailed(check4.id, "Could not read the PDF's text and image positions.", { file: ctx.pdfPath })];
|
|
1891
2006
|
}
|
|
1892
2007
|
return results;
|
|
1893
2008
|
}
|
|
@@ -2300,16 +2415,16 @@ var check10 = {
|
|
|
2300
2415
|
if (!doc) {
|
|
2301
2416
|
return [inspectionFailed(check10.id, "Could not parse the PDF's page count.", { file: ctx.pdfPath })];
|
|
2302
2417
|
}
|
|
2303
|
-
const
|
|
2418
|
+
const size2 = ctx.config.print.signature;
|
|
2304
2419
|
const pages = doc.numPages;
|
|
2305
|
-
if ((pages + 1) %
|
|
2420
|
+
if ((pages + 1) % size2 === 0)
|
|
2306
2421
|
return [];
|
|
2307
|
-
const data = { pages, signature:
|
|
2308
|
-
if (pages %
|
|
2422
|
+
const data = { pages, signature: size2 };
|
|
2423
|
+
if (pages % size2 !== 0) {
|
|
2309
2424
|
return [
|
|
2310
2425
|
finding(check10.id, {
|
|
2311
2426
|
severity: "error",
|
|
2312
|
-
message: `Page count ${pages} does not fit a signature of ${
|
|
2427
|
+
message: `Page count ${pages} does not fit a signature of ${size2}: it must be a multiple of ${size2}, or one short of one.`,
|
|
2313
2428
|
file: ctx.pdfPath,
|
|
2314
2429
|
detail: "Set `print.signature` in the manifest and rebuild; the build pads the interior for you.",
|
|
2315
2430
|
code: "signature-page-count",
|
|
@@ -2330,7 +2445,7 @@ var check10 = {
|
|
|
2330
2445
|
severity: "error",
|
|
2331
2446
|
message: `The last page (${pages}) has content, but the printer needs it blank for its own information.`,
|
|
2332
2447
|
file: ctx.pdfPath,
|
|
2333
|
-
detail: "The build adds that page for you (`print.lastPage: blank`, or `short-by-one` to stop a page short of a multiple " + `of ${
|
|
2448
|
+
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.",
|
|
2334
2449
|
code: "signature-last-page",
|
|
2335
2450
|
data
|
|
2336
2451
|
})
|
|
@@ -5553,7 +5668,7 @@ class PdfOutput {
|
|
|
5553
5668
|
const rawPdf = pdfxMode ? path7.join(stage, "raw.pdf") : path7.resolve(pdfFile);
|
|
5554
5669
|
await fsp2.mkdir(path7.dirname(path7.resolve(pdfFile)), { recursive: true });
|
|
5555
5670
|
log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
|
|
5556
|
-
const { buildNativePdf } = await import("./engine-
|
|
5671
|
+
const { buildNativePdf } = await import("./engine-9710cd7x.js");
|
|
5557
5672
|
const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
|
|
5558
5673
|
title: config.title,
|
|
5559
5674
|
author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
|
|
@@ -5590,7 +5705,7 @@ class PdfOutput {
|
|
|
5590
5705
|
}
|
|
5591
5706
|
const flattenPages = config.pdfx.flattenPages;
|
|
5592
5707
|
if (transparent.length > 0 && config.pdfx.transparency === "preserve-text") {
|
|
5593
|
-
const { unsplittableTextReasons } = await import("./pdf-inspect-
|
|
5708
|
+
const { unsplittableTextReasons } = await import("./pdf-inspect-wnw4za71.js");
|
|
5594
5709
|
const reasons = await unsplittableTextReasons(rawBytes, transparent).catch((err) => {
|
|
5595
5710
|
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.`);
|
|
5596
5711
|
return null;
|
|
@@ -7099,9 +7214,6 @@ import { mkdir as mkdir5, readFile as readFile24, writeFile as writeFile7 } from
|
|
|
7099
7214
|
import path13 from "node:path";
|
|
7100
7215
|
import postcss5 from "postcss";
|
|
7101
7216
|
import { isMap, Scalar } from "yaml";
|
|
7102
|
-
function isPositivePoints(value) {
|
|
7103
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
7104
|
-
}
|
|
7105
7217
|
function writePageBounds(doc, page) {
|
|
7106
7218
|
const tolerance = page.tolerance ?? numberAt(doc, ["page", "tolerance"]);
|
|
7107
7219
|
if (!isMap(doc.get("page", true)))
|
|
@@ -7140,14 +7252,6 @@ function pageSizeForChoice(choice) {
|
|
|
7140
7252
|
const base = PRESETS[choice.preset].page;
|
|
7141
7253
|
return { width: base.width, height: base.height };
|
|
7142
7254
|
}
|
|
7143
|
-
var round3 = (n) => Math.round(n * 1000) / 1000;
|
|
7144
|
-
function cssLength(pt) {
|
|
7145
|
-
const inches2 = round3(pt / 72);
|
|
7146
|
-
return Math.abs(inches2 * 72 - pt) < 0.000001 ? `${inches2}in` : `${round3(pt)}pt`;
|
|
7147
|
-
}
|
|
7148
|
-
function formatPageSize(page) {
|
|
7149
|
-
return `${cssLength(page.width)} ${cssLength(page.height)}`;
|
|
7150
|
-
}
|
|
7151
7255
|
var SAME_SIZE_PT = 0.5;
|
|
7152
7256
|
function sameSize(a, b) {
|
|
7153
7257
|
return Math.abs(a.width - b.width) < SAME_SIZE_PT && Math.abs(a.height - b.height) < SAME_SIZE_PT;
|
|
@@ -7213,9 +7317,9 @@ var relDisplay2 = (projectDir, abs) => path13.relative(projectDir, abs).split(pa
|
|
|
7213
7317
|
async function findCssSize(projectDir, sheets) {
|
|
7214
7318
|
let found = null;
|
|
7215
7319
|
for (const file of sheets) {
|
|
7216
|
-
const
|
|
7217
|
-
if (
|
|
7218
|
-
found = { file, size };
|
|
7320
|
+
const size2 = readPageSizeFromCss(await readFile24(file, "utf8"));
|
|
7321
|
+
if (size2)
|
|
7322
|
+
found = { file, size: size2 };
|
|
7219
7323
|
}
|
|
7220
7324
|
return found;
|
|
7221
7325
|
}
|
|
@@ -7235,7 +7339,7 @@ async function readPageSetup(projectDir) {
|
|
|
7235
7339
|
};
|
|
7236
7340
|
}
|
|
7237
7341
|
async function setPageSetup(projectDir, choice) {
|
|
7238
|
-
const
|
|
7342
|
+
const size2 = pageSizeForChoice(choice);
|
|
7239
7343
|
const sheets = await ownStylesheets(projectDir);
|
|
7240
7344
|
const found = await findCssSize(projectDir, sheets);
|
|
7241
7345
|
const newSheet = path13.join(projectDir, "styles", "book.css");
|
|
@@ -7243,14 +7347,14 @@ async function setPageSetup(projectDir, choice) {
|
|
|
7243
7347
|
const before = existsSync8(target) ? await readFile24(target, "utf8") : "";
|
|
7244
7348
|
let after;
|
|
7245
7349
|
try {
|
|
7246
|
-
after = setPageSizeInCss(before,
|
|
7350
|
+
after = setPageSizeInCss(before, size2);
|
|
7247
7351
|
} catch (e) {
|
|
7248
7352
|
throw new UsageError(`Could not update the page size: ${relDisplay2(projectDir, target)} has a CSS error ` + `(${e instanceof Error ? e.message : String(e)}). Fix it, then try again.`);
|
|
7249
7353
|
}
|
|
7250
7354
|
const { doc, file } = await loadManifestDoc(projectDir);
|
|
7251
7355
|
doc.set("preset", choice.preset);
|
|
7252
7356
|
if (choice.preset === "custom")
|
|
7253
|
-
writePageBounds(doc,
|
|
7357
|
+
writePageBounds(doc, size2);
|
|
7254
7358
|
else
|
|
7255
7359
|
deletePageBounds(doc);
|
|
7256
7360
|
if (target === newSheet && !sheets.includes(newSheet)) {
|
|
@@ -8875,10 +8979,10 @@ function isSmallBody(body) {
|
|
|
8875
8979
|
return false;
|
|
8876
8980
|
let total = 0;
|
|
8877
8981
|
for (const c of body) {
|
|
8878
|
-
const
|
|
8879
|
-
if (typeof
|
|
8982
|
+
const size2 = c?.byteLength;
|
|
8983
|
+
if (typeof size2 !== "number")
|
|
8880
8984
|
return false;
|
|
8881
|
-
total +=
|
|
8985
|
+
total += size2;
|
|
8882
8986
|
}
|
|
8883
8987
|
return total <= SMALL_BODY_MAX_BYTES;
|
|
8884
8988
|
}
|
|
@@ -12520,7 +12624,7 @@ async function resolvePublishProvider(id, book) {
|
|
|
12520
12624
|
const ext = await bookExtensions(book);
|
|
12521
12625
|
const npmEntry = ext.extensions.some((c) => !c.path && c.name === id);
|
|
12522
12626
|
if (npmEntry) {
|
|
12523
|
-
const { restoreForCommand: restoreForCommand2 } = await import("./extension-restore-
|
|
12627
|
+
const { restoreForCommand: restoreForCommand2 } = await import("./extension-restore-05pae3cp.js");
|
|
12524
12628
|
await restoreForCommand2(book.projectDir, { manifestPath: book.manifestPath, failFast: true });
|
|
12525
12629
|
}
|
|
12526
12630
|
const publishers = await discover(ext);
|
|
@@ -12558,7 +12662,7 @@ function infoFor(p) {
|
|
|
12558
12662
|
}
|
|
12559
12663
|
function pluginProvider(p) {
|
|
12560
12664
|
let loading;
|
|
12561
|
-
const load = () => loading ??= import("./plugins-
|
|
12665
|
+
const load = () => loading ??= import("./plugins-gfvsgnxb.js").then((m) => m.loadPublishFunction(p));
|
|
12562
12666
|
return {
|
|
12563
12667
|
info: infoFor(p),
|
|
12564
12668
|
async authenticate() {
|
|
@@ -120,60 +120,6 @@ function generatedContentCss(selectors) {
|
|
|
120
120
|
`);
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
// src/engine/shared/margin-box-support.ts
|
|
124
|
-
var MARGIN_BOX_IGNORED_PROPERTIES = new Set([
|
|
125
|
-
"transform",
|
|
126
|
-
"rotate",
|
|
127
|
-
"translate",
|
|
128
|
-
"scale",
|
|
129
|
-
"perspective",
|
|
130
|
-
"box-shadow",
|
|
131
|
-
"opacity",
|
|
132
|
-
"outline",
|
|
133
|
-
"outline-color",
|
|
134
|
-
"outline-style",
|
|
135
|
-
"outline-width",
|
|
136
|
-
"outline-offset",
|
|
137
|
-
"filter",
|
|
138
|
-
"backdrop-filter",
|
|
139
|
-
"mix-blend-mode",
|
|
140
|
-
"clip-path"
|
|
141
|
-
]);
|
|
142
|
-
function isIgnoredMarginBoxProperty(property) {
|
|
143
|
-
return MARGIN_BOX_IGNORED_PROPERTIES.has(property.toLowerCase());
|
|
144
|
-
}
|
|
145
|
-
function marginBoxRectPt(name, g) {
|
|
146
|
-
const { top, right, bottom, left } = g.margin;
|
|
147
|
-
const cw = g.width - left - right;
|
|
148
|
-
const ch = g.height - top - bottom;
|
|
149
|
-
const third = (n) => n / 3;
|
|
150
|
-
const T = {
|
|
151
|
-
"top-left-corner": [0, 0, left, top],
|
|
152
|
-
"top-left": [left, 0, third(cw), top],
|
|
153
|
-
"top-center": [left + third(cw), 0, third(cw), top],
|
|
154
|
-
"top-right": [left + 2 * third(cw), 0, third(cw), top],
|
|
155
|
-
"top-right-corner": [g.width - right, 0, right, top],
|
|
156
|
-
"bottom-left-corner": [0, g.height - bottom, left, bottom],
|
|
157
|
-
"bottom-left": [left, g.height - bottom, third(cw), bottom],
|
|
158
|
-
"bottom-center": [left + third(cw), g.height - bottom, third(cw), bottom],
|
|
159
|
-
"bottom-right": [left + 2 * third(cw), g.height - bottom, third(cw), bottom],
|
|
160
|
-
"bottom-right-corner": [g.width - right, g.height - bottom, right, bottom],
|
|
161
|
-
"left-top": [0, top, left, third(ch)],
|
|
162
|
-
"left-middle": [0, top + third(ch), left, third(ch)],
|
|
163
|
-
"left-bottom": [0, top + 2 * third(ch), left, third(ch)],
|
|
164
|
-
"right-top": [g.width - right, top, right, third(ch)],
|
|
165
|
-
"right-middle": [g.width - right, top + third(ch), right, third(ch)],
|
|
166
|
-
"right-bottom": [g.width - right, top + 2 * third(ch), right, third(ch)]
|
|
167
|
-
};
|
|
168
|
-
const [x, y, w, h] = T[name] ?? [0, 0, 0, 0];
|
|
169
|
-
return { x, y, w, h };
|
|
170
|
-
}
|
|
171
|
-
function marginBoxAlign(name) {
|
|
172
|
-
if (name.includes("center") || name.includes("middle"))
|
|
173
|
-
return "center";
|
|
174
|
-
return /right/.test(name) ? "end" : "start";
|
|
175
|
-
}
|
|
176
|
-
|
|
177
123
|
// src/engine/shared/gcpm-extract.ts
|
|
178
124
|
var NESTED_AT_RULES = /^@(media|supports|layer|scope|container|document)\b/i;
|
|
179
125
|
function scanRules(css) {
|
|
@@ -734,4 +680,58 @@ function specificity(r) {
|
|
|
734
680
|
return (r.name ? 2 : 0) + r.pseudos.length;
|
|
735
681
|
}
|
|
736
682
|
|
|
737
|
-
|
|
683
|
+
// src/engine/shared/margin-box-support.ts
|
|
684
|
+
var MARGIN_BOX_IGNORED_PROPERTIES = new Set([
|
|
685
|
+
"transform",
|
|
686
|
+
"rotate",
|
|
687
|
+
"translate",
|
|
688
|
+
"scale",
|
|
689
|
+
"perspective",
|
|
690
|
+
"box-shadow",
|
|
691
|
+
"opacity",
|
|
692
|
+
"outline",
|
|
693
|
+
"outline-color",
|
|
694
|
+
"outline-style",
|
|
695
|
+
"outline-width",
|
|
696
|
+
"outline-offset",
|
|
697
|
+
"filter",
|
|
698
|
+
"backdrop-filter",
|
|
699
|
+
"mix-blend-mode",
|
|
700
|
+
"clip-path"
|
|
701
|
+
]);
|
|
702
|
+
function isIgnoredMarginBoxProperty(property) {
|
|
703
|
+
return MARGIN_BOX_IGNORED_PROPERTIES.has(property.toLowerCase());
|
|
704
|
+
}
|
|
705
|
+
function marginBoxRectPt(name, g) {
|
|
706
|
+
const { top, right, bottom, left } = g.margin;
|
|
707
|
+
const cw = g.width - left - right;
|
|
708
|
+
const ch = g.height - top - bottom;
|
|
709
|
+
const third = (n) => n / 3;
|
|
710
|
+
const T = {
|
|
711
|
+
"top-left-corner": [0, 0, left, top],
|
|
712
|
+
"top-left": [left, 0, third(cw), top],
|
|
713
|
+
"top-center": [left + third(cw), 0, third(cw), top],
|
|
714
|
+
"top-right": [left + 2 * third(cw), 0, third(cw), top],
|
|
715
|
+
"top-right-corner": [g.width - right, 0, right, top],
|
|
716
|
+
"bottom-left-corner": [0, g.height - bottom, left, bottom],
|
|
717
|
+
"bottom-left": [left, g.height - bottom, third(cw), bottom],
|
|
718
|
+
"bottom-center": [left + third(cw), g.height - bottom, third(cw), bottom],
|
|
719
|
+
"bottom-right": [left + 2 * third(cw), g.height - bottom, third(cw), bottom],
|
|
720
|
+
"bottom-right-corner": [g.width - right, g.height - bottom, right, bottom],
|
|
721
|
+
"left-top": [0, top, left, third(ch)],
|
|
722
|
+
"left-middle": [0, top + third(ch), left, third(ch)],
|
|
723
|
+
"left-bottom": [0, top + 2 * third(ch), left, third(ch)],
|
|
724
|
+
"right-top": [g.width - right, top, right, third(ch)],
|
|
725
|
+
"right-middle": [g.width - right, top + third(ch), right, third(ch)],
|
|
726
|
+
"right-bottom": [g.width - right, top + 2 * third(ch), right, third(ch)]
|
|
727
|
+
};
|
|
728
|
+
const [x, y, w, h] = T[name] ?? [0, 0, 0, 0];
|
|
729
|
+
return { x, y, w, h };
|
|
730
|
+
}
|
|
731
|
+
function marginBoxAlign(name) {
|
|
732
|
+
if (name.includes("center") || name.includes("middle"))
|
|
733
|
+
return "center";
|
|
734
|
+
return /right/.test(name) ? "end" : "start";
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
export { isRectoVersoBreak, wantsRecto, planRectoBlanks, lastPageMode, signaturePadding, parseWhich, stringValueAt, stringSymbols, cssQuote, counterStyleName, restartedPageValues, toFolioPage, leaderMarker, generatedContentCss, extract, splitTopLevel, parseSize, resolvePage, MARGIN_BOX_IGNORED_PROPERTIES, isIgnoredMarginBoxProperty, marginBoxRectPt, marginBoxAlign };
|
|
@@ -9,12 +9,12 @@ import {
|
|
|
9
9
|
readExtensionMeta,
|
|
10
10
|
resolveExtension,
|
|
11
11
|
slugify
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-kx03e4m4.js";
|
|
13
13
|
import {
|
|
14
14
|
BuildError,
|
|
15
15
|
EXIT_CODES,
|
|
16
16
|
getAssetsDir
|
|
17
|
-
} from "./index-
|
|
17
|
+
} from "./index-jsz0s3dy.js";
|
|
18
18
|
import {
|
|
19
19
|
PLUGINS_DIR,
|
|
20
20
|
VENDORED_NPM_DIR,
|
|
@@ -183,7 +183,7 @@ var DTRPG_PRESET = {
|
|
|
183
183
|
bleed: 9,
|
|
184
184
|
safe: 36,
|
|
185
185
|
artSafe: 18,
|
|
186
|
-
gutter:
|
|
186
|
+
gutter: 36
|
|
187
187
|
},
|
|
188
188
|
ink: {
|
|
189
189
|
maxTac: 240,
|
|
@@ -26,7 +26,7 @@ import { fileURLToPath } from "node:url";
|
|
|
26
26
|
var favicon_default = "./favicon-272ga6y0.ico";
|
|
27
27
|
|
|
28
28
|
// src/assets/manifest.schema.json
|
|
29
|
-
var manifest_schema_default = "./manifest.schema-
|
|
29
|
+
var manifest_schema_default = "./manifest.schema-nvawq0xv.json";
|
|
30
30
|
|
|
31
31
|
// src/assets/preview/scripts/preview-interface.js
|
|
32
32
|
var preview_interface_default = "./preview-interface-nnmrxyqm.js";
|
|
@@ -41,7 +41,7 @@ var preview_shell_default = "./preview-shell-wk9k3gcd.js";
|
|
|
41
41
|
var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
|
|
42
42
|
|
|
43
43
|
// src/assets/engine/gutterpress-viewer.js
|
|
44
|
-
var gutterpress_viewer_default = "./gutterpress-viewer-
|
|
44
|
+
var gutterpress_viewer_default = "./gutterpress-viewer-w9jzx6sb.js";
|
|
45
45
|
|
|
46
46
|
// src/assets/engine/gutterpress-agent.js
|
|
47
47
|
var gutterpress_agent_default = "./gutterpress-agent-d29ry3ak.js";
|
|
@@ -37,7 +37,7 @@ import { satisfies, validRange } from "semver";
|
|
|
37
37
|
// package.json
|
|
38
38
|
var package_default = {
|
|
39
39
|
name: "gutterpress",
|
|
40
|
-
version: "0.11.22-alpha.
|
|
40
|
+
version: "0.11.22-alpha.2",
|
|
41
41
|
description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
42
42
|
author: "itlackey",
|
|
43
43
|
license: "MPL-2.0",
|
package/dist/index.js
CHANGED
|
@@ -116,7 +116,7 @@ import {
|
|
|
116
116
|
substituteVariables,
|
|
117
117
|
syncProject,
|
|
118
118
|
testRemoteAccess
|
|
119
|
-
} from "./index-
|
|
119
|
+
} from "./index-3wcr69ba.js";
|
|
120
120
|
import {
|
|
121
121
|
BUILT_IN_STYLE_SET_IDS,
|
|
122
122
|
BUNDLED_EXTENSIONS,
|
|
@@ -154,7 +154,7 @@ import {
|
|
|
154
154
|
setExtensionEnabled,
|
|
155
155
|
updateExtensions,
|
|
156
156
|
validateProjectExtensions
|
|
157
|
-
} from "./index-
|
|
157
|
+
} from "./index-ew7cyk7c.js";
|
|
158
158
|
import {
|
|
159
159
|
EXTENSION_MANIFEST_FILENAME,
|
|
160
160
|
assertExtensionContained,
|
|
@@ -165,16 +165,16 @@ import {
|
|
|
165
165
|
pathEscapesFolder,
|
|
166
166
|
readExtensionMeta,
|
|
167
167
|
resolveExtension
|
|
168
|
-
} from "./index-
|
|
168
|
+
} from "./index-kx03e4m4.js";
|
|
169
169
|
import"./index-ht1bcqdd.js";
|
|
170
170
|
import {
|
|
171
171
|
BUILD_DIAGNOSTIC_CODES
|
|
172
|
-
} from "./index-
|
|
173
|
-
import"./index-
|
|
172
|
+
} from "./index-2d8j0enc.js";
|
|
173
|
+
import"./index-apc8w9w8.js";
|
|
174
174
|
import {
|
|
175
175
|
BuildError
|
|
176
|
-
} from "./index-
|
|
177
|
-
import"./index-
|
|
176
|
+
} from "./index-jsz0s3dy.js";
|
|
177
|
+
import"./index-2ppw6q9v.js";
|
|
178
178
|
import {
|
|
179
179
|
DEFAULT_PRINT_OPTS,
|
|
180
180
|
assertMilestone,
|
|
@@ -132,8 +132,9 @@ export interface AssembleBookHtmlOptions {
|
|
|
132
132
|
* preset id and printer spec — written as `<meta name="gp-print-area">`
|
|
133
133
|
* (engine/shared/print-area.ts) into EVERY assembled book, preview, build
|
|
134
134
|
* and publish alike: the preview's print overlays judge the ink against it,
|
|
135
|
-
* and both engines place pinned art on its art-safe line. Metadata only
|
|
136
|
-
*
|
|
135
|
+
* and both engines place pinned art on its art-safe line. Metadata only,
|
|
136
|
+
* with one exception: its `width` x `height` is also the page size the book
|
|
137
|
+
* prints at when no stylesheet sets one — see {@link defaultPageSizeCss}.
|
|
137
138
|
*/
|
|
138
139
|
printArea?: PrintAreaSource;
|
|
139
140
|
plugins?: LoadedPlugin[];
|
package/dist/lib/page-size.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Document } from "yaml";
|
|
2
2
|
import { type PresetId } from "./presets.ts";
|
|
3
|
+
import { formatPageSize, isPositivePoints } from "../engine/shared/print-area.ts";
|
|
4
|
+
export { formatPageSize, isPositivePoints };
|
|
3
5
|
/** Page bounds written to the manifest's `page:` block (points; 72pt = 1in). */
|
|
4
6
|
export interface CustomPageOptions {
|
|
5
7
|
/** Trim width in points (72pt = 1in). */
|
|
@@ -28,12 +30,11 @@ export interface PageSetup {
|
|
|
28
30
|
bounds: (PageSizePoints & {
|
|
29
31
|
tolerance: number;
|
|
30
32
|
}) | null;
|
|
31
|
-
/** What the book's stylesheets print at, or null when no plain `@page` sets a size. */
|
|
33
|
+
/** What the book's stylesheets print at, or null when no plain `@page` sets a size (the book then prints at `bounds`). */
|
|
32
34
|
css: (PageSizePoints & {
|
|
33
35
|
file: string;
|
|
34
36
|
}) | null;
|
|
35
37
|
}
|
|
36
|
-
export declare function isPositivePoints(value: unknown): value is number;
|
|
37
38
|
/**
|
|
38
39
|
* Write the manifest's `page:` bounds. `tolerance` defaults to whatever the
|
|
39
40
|
* block already carries, so re-sizing a book never silently resets a
|
|
@@ -43,8 +44,6 @@ export declare function isPositivePoints(value: unknown): value is number;
|
|
|
43
44
|
export declare function writePageBounds(doc: Document, page: CustomPageOptions): void;
|
|
44
45
|
/** The size (points) a choice means: `custom` brings its own, the others are the preset's. */
|
|
45
46
|
export declare function pageSizeForChoice(choice: PageSizeChoice): PageSizePoints;
|
|
46
|
-
/** The `size` value written for a page: `8.5in 11in`, `595pt 842pt`. */
|
|
47
|
-
export declare function formatPageSize(page: PageSizePoints): string;
|
|
48
47
|
/** The size the LAST plain `@page { size }` in the stylesheet sets (cascade: last wins), or null. */
|
|
49
48
|
export declare function readPageSizeFromCss(css: string): PageSizePoints | null;
|
|
50
49
|
/**
|