gutterpress 0.11.23-beta.1 → 0.11.23-beta.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/README.md +1 -1
- package/dist/api/index.js +5 -5
- package/dist/{build-dg8a566j.js → build-3e18wnqj.js} +8 -8
- package/dist/{cli-vhav8g82.js → cli-0ep11b0q.js} +1 -1
- package/dist/{cli-e31jshz6.js → cli-88arpdke.js} +2 -2
- package/dist/{cli-1fy1pm9d.js → cli-9n9kg58f.js} +1 -1
- package/dist/{cli-k087gj0p.js → cli-pd2cje5b.js} +122 -11
- package/dist/{cli-989eg8jz.js → cli-pnrararp.js} +11 -10
- package/dist/{cli-ttj95aex.js → cli-tgnyvra3.js} +13 -3
- package/dist/{cli-31anr0r9.js → cli-v0evdpdf.js} +68 -28
- package/dist/{cli-s1zt779w.js → cli-x7gcdg6w.js} +1 -1
- package/dist/cli.js +12 -12
- package/dist/{doctor-g4a42tcz.js → doctor-2f4s9dyn.js} +3 -3
- package/dist/engine/compiler/postprocess.d.ts +3 -0
- package/dist/engine/shared/pdf-inspect.d.ts +33 -0
- package/dist/{engine-jvkcahr1.js → engine-c4pxz79g.js} +1 -1
- package/dist/{engine-wgkaqjsc.js → engine-cs5g2ez0.js} +2 -2
- package/dist/{ext-w9d5ftcg.js → ext-70gv86v5.js} +8 -8
- package/dist/{extension-restore-5x4mj79d.js → extension-restore-chj5nx3t.js} +2 -2
- package/dist/{extension-restore-as0g38p1.js → extension-restore-pd87p8r2.js} +4 -4
- package/dist/{gutterpress-agent-d29ry3ak.js → gutterpress-agent-wyryqehx.js} +13 -4
- package/dist/{gutterpress-viewer-ze691rrd.js → gutterpress-viewer-ywkf49q5.js} +38 -153
- package/dist/{index-c6y0p7jy.js → index-0k43evt0.js} +66 -22
- package/dist/{index-fk2kpf2t.js → index-2t1gdma7.js} +121 -10
- package/dist/{index-cw03e9p4.js → index-7j3hkwya.js} +68 -28
- package/dist/{index-a4j3xcfp.js → index-80vg3ed6.js} +13 -3
- package/dist/{index-798jt0qc.js → index-swfdgn2n.js} +2 -2
- package/dist/{index-rj5vrhz6.js → index-ytjkvwy5.js} +1 -1
- package/dist/index.js +6 -6
- package/dist/lib/markdown/gutterpress-css.d.ts +1 -1
- package/dist/lib/source-provider.d.ts +27 -0
- package/dist/lib/version-changes.d.ts +14 -4
- package/dist/{new-jtk028rf.js → new-d61n5cn0.js} +8 -8
- package/dist/{plugins-bcbe7xs8.js → plugins-0hhw6s17.js} +1 -1
- package/dist/{plugins-zsm6wv79.js → plugins-e0n46s6m.js} +3 -3
- package/dist/{preflight-cs6mj1d6.js → preflight-fjayhjr5.js} +8 -8
- package/dist/{preview-d1j1g4qf.js → preview-h815jrfb.js} +8 -8
- package/dist/{publish-7yw4jyrt.js → publish-ft39zgma.js} +8 -8
- package/dist/render.js +12 -2
- package/dist/{source-provider-n7vehh6t.js → source-provider-j1w7byeq.js} +5 -1
- package/dist/{source-provider-tgzet3j5.js → source-provider-tjaf303m.js} +5 -1
- package/dist/test-helpers/vocabulary.d.ts +12 -0
- package/dist/{validate-rkcdnzhw.js → validate-b201dbrb.js} +8 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -221,7 +221,7 @@ gutterpress build [input-dir] [options]
|
|
|
221
221
|
--skip-lint Skip the CSS print-safety check (default: it runs for pdf/pdfx)
|
|
222
222
|
--skip-pre-validate Skip pre-build validation
|
|
223
223
|
--skip-post-validate Skip post-build PDF/X validation
|
|
224
|
-
--allow-shrink Build anyway when content is wider than the page content box. Chromium then scales the WHOLE book down to fit it — the build reports
|
|
224
|
+
--allow-shrink Build anyway when content is wider than the page content box. Chromium then scales the WHOLE book down to fit it — the build reports the scale the PDF printed at (e.g. "printed at 72.0000% of its declared size") plus every offender, as warnings.
|
|
225
225
|
```
|
|
226
226
|
|
|
227
227
|
A `--out <dir>` is shared between formats safely: each build delivers only
|
package/dist/api/index.js
CHANGED
|
@@ -105,7 +105,7 @@ import {
|
|
|
105
105
|
substituteVariables,
|
|
106
106
|
syncProject,
|
|
107
107
|
testRemoteAccess
|
|
108
|
-
} from "../index-
|
|
108
|
+
} from "../index-0k43evt0.js";
|
|
109
109
|
import {
|
|
110
110
|
DEFAULT_NPM_REGISTRY,
|
|
111
111
|
MANIFEST_FILENAMES,
|
|
@@ -134,7 +134,7 @@ import {
|
|
|
134
134
|
setExtensionEnabled,
|
|
135
135
|
updateExtensions,
|
|
136
136
|
validateProjectExtensions
|
|
137
|
-
} from "../index-
|
|
137
|
+
} from "../index-ytjkvwy5.js";
|
|
138
138
|
import {
|
|
139
139
|
BUNDLED_EXTENSIONS,
|
|
140
140
|
EXTENSION_MANIFEST_FILENAME,
|
|
@@ -149,9 +149,9 @@ import {
|
|
|
149
149
|
pathEscapesFolder,
|
|
150
150
|
readExtensionMeta,
|
|
151
151
|
resolveExtension
|
|
152
|
-
} from "../index-
|
|
152
|
+
} from "../index-80vg3ed6.js";
|
|
153
153
|
import"../index-ht1bcqdd.js";
|
|
154
|
-
import"../index-
|
|
154
|
+
import"../index-swfdgn2n.js";
|
|
155
155
|
import {
|
|
156
156
|
BuildError
|
|
157
157
|
} from "../index-tayzfr9c.js";
|
|
@@ -176,7 +176,7 @@ import {
|
|
|
176
176
|
revisionNameFrom,
|
|
177
177
|
switchBranch,
|
|
178
178
|
whenGitIdle
|
|
179
|
-
} from "../index-
|
|
179
|
+
} from "../index-7j3hkwya.js";
|
|
180
180
|
import {
|
|
181
181
|
EXTENSIONS_DIR
|
|
182
182
|
} from "../index-5x42amh8.js";
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runBuild,
|
|
3
3
|
splitOutPath
|
|
4
|
-
} from "./cli-
|
|
5
|
-
import"./cli-
|
|
4
|
+
} from "./cli-pnrararp.js";
|
|
5
|
+
import"./cli-0ep11b0q.js";
|
|
6
6
|
import"./cli-ht1bcqdd.js";
|
|
7
|
-
import"./cli-
|
|
7
|
+
import"./cli-pd2cje5b.js";
|
|
8
8
|
import"./cli-5crpmz42.js";
|
|
9
9
|
import"./cli-eyyggect.js";
|
|
10
10
|
import"./cli-asap4t1z.js";
|
|
11
|
-
import"./cli-
|
|
11
|
+
import"./cli-v0evdpdf.js";
|
|
12
12
|
import"./cli-v5mp7a6q.js";
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
13
|
+
import"./cli-88arpdke.js";
|
|
14
|
+
import"./cli-tgnyvra3.js";
|
|
15
15
|
import {
|
|
16
16
|
log
|
|
17
|
-
} from "./cli-
|
|
17
|
+
} from "./cli-9n9kg58f.js";
|
|
18
18
|
import {
|
|
19
19
|
UsageError,
|
|
20
20
|
parseFormat,
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
rejectExtraPositionals,
|
|
23
23
|
rejectUnknownFlags
|
|
24
24
|
} from "./cli-d8xjns66.js";
|
|
25
|
-
import"./cli-
|
|
25
|
+
import"./cli-x7gcdg6w.js";
|
|
26
26
|
import"./cli-65gy8ask.js";
|
|
27
27
|
import {
|
|
28
28
|
BuildError
|
|
@@ -11,10 +11,10 @@ import {
|
|
|
11
11
|
prettify,
|
|
12
12
|
readExtensionMeta,
|
|
13
13
|
slugify
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-tgnyvra3.js";
|
|
15
15
|
import {
|
|
16
16
|
log
|
|
17
|
-
} from "./cli-
|
|
17
|
+
} from "./cli-9n9kg58f.js";
|
|
18
18
|
import {
|
|
19
19
|
UsageError
|
|
20
20
|
} from "./cli-d8xjns66.js";
|
|
@@ -1032,12 +1032,14 @@ function needsMeasurement(value) {
|
|
|
1032
1032
|
|
|
1033
1033
|
// src/engine/shared/pdf-inspect.ts
|
|
1034
1034
|
import {
|
|
1035
|
+
decodePDFRawStream,
|
|
1035
1036
|
PDFArray,
|
|
1036
1037
|
PDFDict,
|
|
1037
1038
|
PDFDocument,
|
|
1038
1039
|
PDFHexString,
|
|
1039
1040
|
PDFName,
|
|
1040
1041
|
PDFNumber,
|
|
1042
|
+
PDFRawStream,
|
|
1041
1043
|
PDFRef,
|
|
1042
1044
|
PDFString
|
|
1043
1045
|
} from "pdf-lib";
|
|
@@ -1158,6 +1160,52 @@ async function inspectPdf(bytes) {
|
|
|
1158
1160
|
walkOutline(outlines);
|
|
1159
1161
|
return { pageCount: pages.length, boxes, linkTargets, namedDests, outline };
|
|
1160
1162
|
}
|
|
1163
|
+
var PROLOGUE = /^\s*(\d*\.?\d+) 0 0 -\d*\.?\d+ -?\d*\.?\d+ -?\d*\.?\d+ cm/;
|
|
1164
|
+
var CLIP = /(-?\d*\.?\d+) (-?\d*\.?\d+) (\d*\.?\d+) (\d*\.?\d+) re\s+W\*? n\b/g;
|
|
1165
|
+
var UNIFORM = /\bq\s+(\d*\.?\d+) 0 0 \1 (-?\d*\.?\d+) -?\d*\.?\d+ cm/g;
|
|
1166
|
+
var UNSCALED_EPSILON = 0.000001;
|
|
1167
|
+
function printScale(doc) {
|
|
1168
|
+
const readings = new Map;
|
|
1169
|
+
for (const page of doc.getPages()) {
|
|
1170
|
+
const contents = page.node.Contents();
|
|
1171
|
+
const streams = contents instanceof PDFArray ? contents.asArray().map((ref) => doc.context.lookup(ref)) : [contents];
|
|
1172
|
+
let text = "";
|
|
1173
|
+
for (const stream of streams) {
|
|
1174
|
+
if (!(stream instanceof PDFRawStream))
|
|
1175
|
+
continue;
|
|
1176
|
+
try {
|
|
1177
|
+
text += Buffer.from(decodePDFRawStream(stream).decode()).toString("latin1") + `
|
|
1178
|
+
`;
|
|
1179
|
+
} catch {}
|
|
1180
|
+
}
|
|
1181
|
+
const prologue = PROLOGUE.exec(text);
|
|
1182
|
+
if (!prologue)
|
|
1183
|
+
continue;
|
|
1184
|
+
let area;
|
|
1185
|
+
for (const m of text.matchAll(CLIP)) {
|
|
1186
|
+
const size = Number(m[3]) * Number(m[4]);
|
|
1187
|
+
if (!area || size > area.size)
|
|
1188
|
+
area = { x: Number(m[1]), size, end: m.index + m[0].length };
|
|
1189
|
+
}
|
|
1190
|
+
if (!area)
|
|
1191
|
+
continue;
|
|
1192
|
+
UNIFORM.lastIndex = area.end;
|
|
1193
|
+
for (let m;m = UNIFORM.exec(text); ) {
|
|
1194
|
+
if (Math.abs(Number(m[2]) - area.x) > 0.5)
|
|
1195
|
+
continue;
|
|
1196
|
+
const scale = Number(m[1]) * Number(prologue[1]) * 96 / 72;
|
|
1197
|
+
readings.set(scale, (readings.get(scale) ?? 0) + 1);
|
|
1198
|
+
break;
|
|
1199
|
+
}
|
|
1200
|
+
if ([...readings.values()].some((n) => n >= 3))
|
|
1201
|
+
break;
|
|
1202
|
+
}
|
|
1203
|
+
let best = null;
|
|
1204
|
+
for (const [scale, n] of readings)
|
|
1205
|
+
if (best === null || n > readings.get(best))
|
|
1206
|
+
best = scale;
|
|
1207
|
+
return best === null ? null : Math.abs(1 - best) < UNSCALED_EPSILON ? 1 : best;
|
|
1208
|
+
}
|
|
1161
1209
|
|
|
1162
1210
|
// src/lib/embedded-assets.ts
|
|
1163
1211
|
import { existsSync } from "node:fs";
|
|
@@ -1185,10 +1233,10 @@ var preview_shell_default = "./preview-shell-wk9k3gcd.js";
|
|
|
1185
1233
|
var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
|
|
1186
1234
|
|
|
1187
1235
|
// src/assets/engine/gutterpress-viewer.js
|
|
1188
|
-
var gutterpress_viewer_default = "./gutterpress-viewer-
|
|
1236
|
+
var gutterpress_viewer_default = "./gutterpress-viewer-ywkf49q5.js";
|
|
1189
1237
|
|
|
1190
1238
|
// src/assets/engine/gutterpress-agent.js
|
|
1191
|
-
var gutterpress_agent_default = "./gutterpress-agent-
|
|
1239
|
+
var gutterpress_agent_default = "./gutterpress-agent-wyryqehx.js";
|
|
1192
1240
|
|
|
1193
1241
|
// src/assets/templates/book/manifest.yaml
|
|
1194
1242
|
var manifest_default = "./manifest-mffah3hr.yaml";
|
|
@@ -1483,6 +1531,7 @@ function round(n) {
|
|
|
1483
1531
|
import { PDFDocument as PDFDocument2, PDFName as PDFName2, PDFNumber as PDFNumber2, rgb } from "pdf-lib";
|
|
1484
1532
|
async function postprocess(input, opts) {
|
|
1485
1533
|
const doc = await PDFDocument2.load(input, { updateMetadata: false });
|
|
1534
|
+
const scale = printScale(doc);
|
|
1486
1535
|
const g = opts.geometry;
|
|
1487
1536
|
const inset = g.bleed + g.slug;
|
|
1488
1537
|
const media = [0, 0, g.media.width, g.media.height];
|
|
@@ -1529,7 +1578,8 @@ async function postprocess(input, opts) {
|
|
|
1529
1578
|
bytes,
|
|
1530
1579
|
pageCount: doc.getPageCount(),
|
|
1531
1580
|
padded,
|
|
1532
|
-
boxes: { media, bleed: bleedBox, trim: trimBox }
|
|
1581
|
+
boxes: { media, bleed: bleedBox, trim: trimBox },
|
|
1582
|
+
scale
|
|
1533
1583
|
};
|
|
1534
1584
|
}
|
|
1535
1585
|
function drawCropMarks(page, g) {
|
|
@@ -1820,8 +1870,6 @@ ${pinCss}`);
|
|
|
1820
1870
|
const msg = `${headline}:
|
|
1821
1871
|
${describe(widthOffenders.boxes)}`;
|
|
1822
1872
|
if (opts.allowShrink) {
|
|
1823
|
-
if (scale !== null)
|
|
1824
|
-
diagnose("engine.width.overflow", `${headline}.`);
|
|
1825
1873
|
for (const o of widthOffenders.boxes)
|
|
1826
1874
|
diagnose("engine.width.overflow", `${o.desc} is ${Math.round(o.px)}px wide, past the ${Math.round(widthOffenders.limitPx)}px page content box. ${o.left < -1 ? "Keep it inside the page content box." : "Give it an explicit width that fits."}`);
|
|
1827
1875
|
log(`WARNING: ${msg}`);
|
|
@@ -1837,6 +1885,54 @@ ${describe(widthOffenders.intrinsics)}`;
|
|
|
1837
1885
|
diagnose("engine.width.intrinsic", `${o.desc} has no width set and is naturally wider than the page — if the printed output comes out smaller than your CSS says, give it an explicit width (e.g. width: 100%).`);
|
|
1838
1886
|
log(`WARNING: ${msg}`);
|
|
1839
1887
|
}
|
|
1888
|
+
let unclipped = null;
|
|
1889
|
+
if (!widthOffenders.boxes.length) {
|
|
1890
|
+
const g = tier2.geometry;
|
|
1891
|
+
const ext = g.bleed + g.slug;
|
|
1892
|
+
const contentPx = (name, pseudos) => {
|
|
1893
|
+
const { width, margin } = resolvePage(model, { name: name || undefined, pseudos }).geometry;
|
|
1894
|
+
return (width + 2 * ext - bleedMargin(margin.left, g) - bleedMargin(margin.right, g)) * 96 / 72;
|
|
1895
|
+
};
|
|
1896
|
+
const pages = await page.evaluate(`(() => {
|
|
1897
|
+
const body = document.body;
|
|
1898
|
+
const named = (el) => { const p = getComputedStyle(el).page; return p && p !== "auto" ? p : ""; };
|
|
1899
|
+
if (!body) return { first: "", used: [], reason: "there is no body" };
|
|
1900
|
+
const bs = getComputedStyle(body);
|
|
1901
|
+
const r = body.getBoundingClientRect();
|
|
1902
|
+
if (
|
|
1903
|
+
Math.abs(r.left + parseFloat(bs.borderLeftWidth)) > 0.01 ||
|
|
1904
|
+
Math.abs(r.right - parseFloat(bs.borderRightWidth) - window.innerWidth) > 0.01
|
|
1905
|
+
) return { first: "", used: [], reason: "the body does not span the page content box" };
|
|
1906
|
+
// The first page's name: the root's, overridden down the chain of
|
|
1907
|
+
// first in-flow children (CSS Paged Media's start page value).
|
|
1908
|
+
let first = named(document.documentElement) || named(body);
|
|
1909
|
+
for (let el = body; el; ) {
|
|
1910
|
+
el = [...el.children].find((c) => {
|
|
1911
|
+
const cs = getComputedStyle(c);
|
|
1912
|
+
return cs.display !== "none" && cs.position !== "absolute" && cs.position !== "fixed";
|
|
1913
|
+
});
|
|
1914
|
+
if (el && named(el)) first = named(el);
|
|
1915
|
+
}
|
|
1916
|
+
const used = new Set([""]);
|
|
1917
|
+
for (const el of document.querySelectorAll("*")) used.add(named(el));
|
|
1918
|
+
return { first, used: [...used], reason: "" };
|
|
1919
|
+
})()`);
|
|
1920
|
+
const firstPx = contentPx(pages.first, ["first", "right", "recto"]);
|
|
1921
|
+
const wider = pages.used.find((name) => pseudoContexts.some((pseudos) => contentPx(name, pseudos) > firstPx + 0.01));
|
|
1922
|
+
unclipped = pages.reason || (wider !== undefined ? `${wider ? `the page "${wider}"` : "the unnamed page"} is wider than the first page` : await page.evaluate(`(() => {
|
|
1923
|
+
const hs = getComputedStyle(document.documentElement);
|
|
1924
|
+
const bs = getComputedStyle(document.body);
|
|
1925
|
+
let css;
|
|
1926
|
+
if (hs.overflowX === "visible" && hs.overflowY === "visible")
|
|
1927
|
+
css = "html { overflow-x: clip !important; } " +
|
|
1928
|
+
"body { overflow-x: clip !important; overflow-y: visible !important; }";
|
|
1929
|
+
else if (bs.overflowX === "visible") css = "body { overflow-x: clip !important; }";
|
|
1930
|
+
else return "the body clips its own overflow";
|
|
1931
|
+
window.__gp.addCss("gp-root-clip", css);
|
|
1932
|
+
return "";
|
|
1933
|
+
})()`)) || null;
|
|
1934
|
+
log(`body overflow ${unclipped ? `left as authored: ${unclipped}` : "held to the page content box"}`);
|
|
1935
|
+
}
|
|
1840
1936
|
const rectoDecls = model.breaks.filter(isRectoVersoBreak);
|
|
1841
1937
|
const needsMeasure = tier3Reasons.length > 0 || consumedStrings(model).size > 0 || rectoDecls.length > 0 || model.counterResets.length > 0 || furnitureRoots.length > 0 || sideRoots.length > 0;
|
|
1842
1938
|
let tier = tier2.geometry.bleed > 0 || tier2.geometry.slug > 0 ? 2 : 1;
|
|
@@ -2358,6 +2454,20 @@ ${mapCss}`;
|
|
|
2358
2454
|
author: opts.author
|
|
2359
2455
|
});
|
|
2360
2456
|
log(`postprocess: ${post.pageCount} pages` + (post.padded ? ` (+${post.padded} blank${opts.lastPage ? `; last page: ${opts.lastPage}` : ""})` : ""));
|
|
2457
|
+
{
|
|
2458
|
+
const scale = post.scale;
|
|
2459
|
+
if (scale !== null && scale < 1) {
|
|
2460
|
+
const pct = (scale * 100).toPrecision(6);
|
|
2461
|
+
const overPx = widthOffenders.defaultLimitPx * (1 / scale - 1);
|
|
2462
|
+
diagnose("engine.width.overflow", `This book printed at ${pct}% of its declared size: content reaches about ` + `${overPx < 0.1 ? overPx.toFixed(3) : overPx.toFixed(2)}px past the ` + `${Math.round(widthOffenders.defaultLimitPx)}px page content box, and Chromium shrinks ` + `the WHOLE print to fit it. The preview is not shrunk, so its lines and page ` + `breaks can differ from the PDF's.` + (unclipped ? ` Gutterpress could not hold it at the page content box: ${unclipped}.` : ""));
|
|
2463
|
+
if (!widthOffenders.boxes.length) {
|
|
2464
|
+
const named = await findWidthOffenders(page, model, 2 * (tier2.geometry.bleed + tier2.geometry.slug), sheetViewport, 0);
|
|
2465
|
+
for (const o of named.boxes)
|
|
2466
|
+
diagnose("engine.width.overflow", `${o.desc} reaches ${Math.max(o.px + Math.min(0, o.left) - (o.limit ?? named.limitPx), -o.left).toFixed(2)}px ` + `past the ${Math.round(o.limit ?? named.limitPx)}px page content box. Keep it ` + `inside the page content box.`);
|
|
2467
|
+
}
|
|
2468
|
+
log(`audit: printed at ${pct}% (shrink-to-fit)`);
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2361
2471
|
return {
|
|
2362
2472
|
bytes: post.bytes,
|
|
2363
2473
|
tier,
|
|
@@ -2392,7 +2502,7 @@ function shrinkScale(boxes, limitPx) {
|
|
|
2392
2502
|
return null;
|
|
2393
2503
|
return Math.max(1 / MAX_SHRINK, limitPx / maxRight);
|
|
2394
2504
|
}
|
|
2395
|
-
async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreViewport) {
|
|
2505
|
+
async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreViewport, tolerancePx = 1) {
|
|
2396
2506
|
const contexts = [
|
|
2397
2507
|
resolvePage(model),
|
|
2398
2508
|
...model.pageNames.filter((n) => !n.startsWith("gp-") || n.startsWith("gp--pin-")).map((n) => resolvePage(model, { name: n }))
|
|
@@ -2418,7 +2528,8 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
|
|
|
2418
2528
|
mobile: false
|
|
2419
2529
|
});
|
|
2420
2530
|
boxes.push(...JSON.parse(await page.evaluate(`(() => {
|
|
2421
|
-
const
|
|
2531
|
+
const TOL = ${tolerancePx};
|
|
2532
|
+
const LIMIT = Math.max(${widthPx} + TOL, ${Math.ceil(widthPx)});
|
|
2422
2533
|
const NAMED = ${JSON.stringify(namedLimits)};
|
|
2423
2534
|
const DEFAULT_LIMIT = ${defaultLimitPx};
|
|
2424
2535
|
// The page an element lands on: the nearest ancestor with a non-auto
|
|
@@ -2458,10 +2569,10 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
|
|
|
2458
2569
|
// pulls) AND left-edge protrusion (negative left with an ordinary
|
|
2459
2570
|
// width) — both trigger the same whole-document shrink-to-fit,
|
|
2460
2571
|
// measured: a left bleed alone cost 16%.
|
|
2461
|
-
if (right <= LIMIT && r.width <= LIMIT && r.left >= -
|
|
2572
|
+
if (right <= LIMIT && r.width <= LIMIT && r.left >= -TOL) continue;
|
|
2462
2573
|
// ...but only where it actually escapes its clipping ancestors.
|
|
2463
2574
|
const clip = clipEdges(el).edges;
|
|
2464
|
-
if (Math.min(right, clip.right) <= LIMIT && Math.max(r.left, clip.left) >= -
|
|
2575
|
+
if (Math.min(right, clip.right) <= LIMIT && Math.max(r.left, clip.left) >= -TOL) continue;
|
|
2465
2576
|
let deepest = true;
|
|
2466
2577
|
for (const c of el.children) {
|
|
2467
2578
|
if (c.getBoundingClientRect().width >= r.width - 1) { deepest = false; break; }
|
|
@@ -2498,7 +2609,7 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
|
|
|
2498
2609
|
const over = el.scrollWidth - el.clientWidth;
|
|
2499
2610
|
// clientWidth is 0 on inline/replaced boxes, where scrollWidth
|
|
2500
2611
|
// carries no overflow information -- skip rather than guess.
|
|
2501
|
-
if (el.clientWidth <= 0 || over <=
|
|
2612
|
+
if (el.clientWidth <= 0 || over <= TOL) continue;
|
|
2502
2613
|
// A descendant assigned to a DIFFERENT page is not overflowing this
|
|
2503
2614
|
// element's page -- it is laid out against its own, wider one. The
|
|
2504
2615
|
// full-bleed art plate is the standard case: it is legitimately
|
|
@@ -2552,7 +2663,7 @@ async function findWidthOffenders(page, model, bleedSlugExtensionPt, restoreView
|
|
|
2552
2663
|
}
|
|
2553
2664
|
return JSON.stringify(out);
|
|
2554
2665
|
})()`));
|
|
2555
|
-
return { limitPx, boxes, intrinsics: replaced };
|
|
2666
|
+
return { limitPx, defaultLimitPx, boxes, intrinsics: replaced };
|
|
2556
2667
|
} finally {
|
|
2557
2668
|
await page.send("Emulation.setDeviceMetricsOverride", restoreViewport);
|
|
2558
2669
|
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
stampCreator,
|
|
9
9
|
stripAnnotations,
|
|
10
10
|
transparentPages
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-0ep11b0q.js";
|
|
12
12
|
import {
|
|
13
13
|
blackTextToGray
|
|
14
14
|
} from "./cli-ht1bcqdd.js";
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
MARGIN_BOX_IGNORED_PROPERTIES,
|
|
18
18
|
getAssetPath,
|
|
19
19
|
lastPageMode
|
|
20
|
-
} from "./cli-
|
|
20
|
+
} from "./cli-pd2cje5b.js";
|
|
21
21
|
import {
|
|
22
22
|
countLinkAnnotations,
|
|
23
23
|
getImageResolutions,
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
import {
|
|
43
43
|
hasUncommittedChanges,
|
|
44
44
|
listWorkdirChanges
|
|
45
|
-
} from "./cli-
|
|
45
|
+
} from "./cli-v0evdpdf.js";
|
|
46
46
|
import {
|
|
47
47
|
detectProjectSource,
|
|
48
48
|
repoSubPath
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
uniqueExtensionId,
|
|
70
70
|
withFetchTimeout,
|
|
71
71
|
writeManifestDoc
|
|
72
|
-
} from "./cli-
|
|
72
|
+
} from "./cli-88arpdke.js";
|
|
73
73
|
import {
|
|
74
74
|
EXTENSION_MANIFEST_FILENAME,
|
|
75
75
|
GUTTERPRESS_CSS,
|
|
@@ -90,7 +90,7 @@ import {
|
|
|
90
90
|
readExtensionMeta,
|
|
91
91
|
resolveDeclaredStyles,
|
|
92
92
|
slugify
|
|
93
|
-
} from "./cli-
|
|
93
|
+
} from "./cli-tgnyvra3.js";
|
|
94
94
|
import {
|
|
95
95
|
PACKAGE_META,
|
|
96
96
|
PACKAGE_VERSION,
|
|
@@ -100,7 +100,7 @@ import {
|
|
|
100
100
|
log,
|
|
101
101
|
setLogLevel,
|
|
102
102
|
warn
|
|
103
|
-
} from "./cli-
|
|
103
|
+
} from "./cli-9n9kg58f.js";
|
|
104
104
|
import {
|
|
105
105
|
DEBOUNCE,
|
|
106
106
|
UsageError,
|
|
@@ -5103,7 +5103,7 @@ class PdfOutput {
|
|
|
5103
5103
|
const rawPdf = pdfxMode ? path7.join(stage, "raw.pdf") : path7.resolve(pdfFile);
|
|
5104
5104
|
await fsp2.mkdir(path7.dirname(path7.resolve(pdfFile)), { recursive: true });
|
|
5105
5105
|
log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
|
|
5106
|
-
const { buildNativePdf } = await import("./engine-
|
|
5106
|
+
const { buildNativePdf } = await import("./engine-c4pxz79g.js");
|
|
5107
5107
|
const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
|
|
5108
5108
|
title: config.title,
|
|
5109
5109
|
author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
|
|
@@ -6571,7 +6571,7 @@ async function scaffoldProject(options) {
|
|
|
6571
6571
|
let versionHistoryError;
|
|
6572
6572
|
if (requested === "local-git") {
|
|
6573
6573
|
try {
|
|
6574
|
-
const { providerFor } = await import("./source-provider-
|
|
6574
|
+
const { providerFor } = await import("./source-provider-j1w7byeq.js");
|
|
6575
6575
|
const provider = providerFor({ type: "local-folder", path: projectDir });
|
|
6576
6576
|
await provider.initVersionHistory({
|
|
6577
6577
|
projectDir,
|
|
@@ -8978,7 +8978,7 @@ async function resolvePublishProvider(id, book) {
|
|
|
8978
8978
|
const ext = await bookExtensions(book);
|
|
8979
8979
|
const npmEntry = ext.extensions.some((c) => !c.path && c.name === id);
|
|
8980
8980
|
if (npmEntry) {
|
|
8981
|
-
const { restoreForCommand: restoreForCommand2 } = await import("./extension-restore-
|
|
8981
|
+
const { restoreForCommand: restoreForCommand2 } = await import("./extension-restore-pd87p8r2.js");
|
|
8982
8982
|
await restoreForCommand2(book.projectDir, { manifestPath: book.manifestPath, failFast: true });
|
|
8983
8983
|
}
|
|
8984
8984
|
const publishers = await discover(ext);
|
|
@@ -9016,7 +9016,7 @@ function infoFor(p) {
|
|
|
9016
9016
|
}
|
|
9017
9017
|
function pluginProvider(p) {
|
|
9018
9018
|
let loading;
|
|
9019
|
-
const load = () => loading ??= import("./plugins-
|
|
9019
|
+
const load = () => loading ??= import("./plugins-e0n46s6m.js").then((m) => m.loadPublishFunction(p));
|
|
9020
9020
|
return {
|
|
9021
9021
|
info: infoFor(p),
|
|
9022
9022
|
async authenticate() {
|
|
@@ -9404,6 +9404,7 @@ var defaultGitHttp = withIdleTimeout(httpNode);
|
|
|
9404
9404
|
|
|
9405
9405
|
// src/lib/version-changes.ts
|
|
9406
9406
|
var decoder = new TextDecoder;
|
|
9407
|
+
var CLOCK_SKEW_SECONDS = 10 * 60;
|
|
9407
9408
|
// src/lib/host-policy.ts
|
|
9408
9409
|
var AUTO_SYNC_MAX_MINUTES = 24 * 60;
|
|
9409
9410
|
// src/lib/remote-auth/github-repos.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PACKAGE_VERSION,
|
|
3
3
|
debug
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-9n9kg58f.js";
|
|
5
5
|
import {
|
|
6
6
|
isExactNpmVersion,
|
|
7
7
|
isValidNpmPackageName,
|
|
@@ -1950,8 +1950,9 @@ img.gp-shape {
|
|
|
1950
1950
|
|
|
1951
1951
|
/* Math (the bundled gutterpress-math feature, math.ts): MathJax's own rules
|
|
1952
1952
|
for the <mjx-container> SVG output it emits, from its SVG output jax's
|
|
1953
|
-
stylesheet, less the ones for its interactive menu and tooltips
|
|
1954
|
-
|
|
1953
|
+
stylesheet, less the ones for its interactive menu and tooltips, plus one
|
|
1954
|
+
bound of ours on the hidden MathML copy (#469, below). Inert in a book
|
|
1955
|
+
without formulas. */
|
|
1955
1956
|
mjx-container[jax="SVG"] { direction: ltr; }
|
|
1956
1957
|
mjx-container[jax="SVG"] > svg { overflow: visible; min-height: 1px; min-width: 1px; }
|
|
1957
1958
|
mjx-container[jax="SVG"] > svg a { fill: blue; stroke: blue; }
|
|
@@ -1968,6 +1969,15 @@ mjx-assistive-mml {
|
|
|
1968
1969
|
border: 0px !important;
|
|
1969
1970
|
display: block !important;
|
|
1970
1971
|
width: auto !important;
|
|
1972
|
+
/* Ours (#469). The browser lays the copy out in whatever math font it has,
|
|
1973
|
+
so it can be wider than the formula's SVG; ending a line, it crossed the
|
|
1974
|
+
column edge and Chromium shrank the whole print to fit. MathJax makes the
|
|
1975
|
+
container position: relative with the copy at its top left, so 100% is
|
|
1976
|
+
the formula's width. Clip and overflow still hide the copy and its MathML
|
|
1977
|
+
still reaches screen readers; only its box changes. Not the 1px
|
|
1978
|
+
visually-hidden box MathJax 2 used: its docs note VoiceOver on iOS could
|
|
1979
|
+
not reach a formula by touch in it. */
|
|
1980
|
+
max-width: 100% !important;
|
|
1971
1981
|
overflow: hidden !important;
|
|
1972
1982
|
user-select: none;
|
|
1973
1983
|
}
|
|
@@ -372,6 +372,40 @@ class LocalFolderSourceProvider {
|
|
|
372
372
|
return Promise.reject(new Error(NO_VERSION_HISTORY));
|
|
373
373
|
}
|
|
374
374
|
}
|
|
375
|
+
var lastHistoryWalk = null;
|
|
376
|
+
async function startHistoryWalk(dir, cache, heads) {
|
|
377
|
+
const shallow = await gitFs.promises.readFile(path2.join(gitDirFor(dir), "shallow"), "utf8").catch(() => "");
|
|
378
|
+
const tips = await Promise.all(heads.map((oid) => git.readCommit({ fs: gitFs, dir, cache, oid })));
|
|
379
|
+
tips.sort((a, b) => a.commit.committer.timestamp - b.commit.committer.timestamp);
|
|
380
|
+
return {
|
|
381
|
+
tips,
|
|
382
|
+
queued: new Set(heads),
|
|
383
|
+
shallow: new Set(shallow.split(`
|
|
384
|
+
`)),
|
|
385
|
+
readAhead: new Map
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
async function nextInHistory(dir, walk, cache, needed) {
|
|
389
|
+
const commit = walk.tips.pop();
|
|
390
|
+
if (!commit || walk.shallow.has(commit.oid))
|
|
391
|
+
return commit;
|
|
392
|
+
for (const oid of commit.commit.parent) {
|
|
393
|
+
if (walk.queued.has(oid))
|
|
394
|
+
continue;
|
|
395
|
+
const oneLine = walk.tips.length === 0 && commit.commit.parent.length === 1;
|
|
396
|
+
if (needed > 1 && oneLine && !walk.readAhead.has(oid)) {
|
|
397
|
+
for (const c of await git.log({ fs: gitFs, dir, cache, ref: oid, depth: needed })) {
|
|
398
|
+
if (!walk.queued.has(c.oid))
|
|
399
|
+
walk.readAhead.set(c.oid, c);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
walk.queued.add(oid);
|
|
403
|
+
walk.tips.push(walk.readAhead.get(oid) ?? await git.readCommit({ fs: gitFs, dir, cache, oid }));
|
|
404
|
+
walk.readAhead.delete(oid);
|
|
405
|
+
}
|
|
406
|
+
walk.tips.sort((a, b) => a.commit.committer.timestamp - b.commit.committer.timestamp);
|
|
407
|
+
return commit;
|
|
408
|
+
}
|
|
375
409
|
|
|
376
410
|
class LocalGitSourceProvider {
|
|
377
411
|
source;
|
|
@@ -409,40 +443,46 @@ class LocalGitSourceProvider {
|
|
|
409
443
|
const dir = this.dir;
|
|
410
444
|
const limit = Math.min(500, Math.max(1, options.limit ?? HISTORY_PAGE_LIMIT));
|
|
411
445
|
const before = options.before;
|
|
412
|
-
|
|
446
|
+
const cache = {};
|
|
413
447
|
try {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
}
|
|
448
|
+
const head = await git.resolveRef({ fs: gitFs, dir, ref: "HEAD" });
|
|
449
|
+
let walk;
|
|
450
|
+
const saved = lastHistoryWalk;
|
|
451
|
+
if (before && saved?.dir === dir && saved.head === head && saved.last === before) {
|
|
452
|
+
walk = saved.walk;
|
|
453
|
+
lastHistoryWalk = null;
|
|
454
|
+
} else {
|
|
455
|
+
walk = await startHistoryWalk(dir, cache, [head]);
|
|
456
|
+
if (before) {
|
|
457
|
+
let c;
|
|
458
|
+
do {
|
|
459
|
+
c = await nextInHistory(dir, walk, cache, limit);
|
|
460
|
+
} while (c && c.oid !== before);
|
|
461
|
+
if (!c)
|
|
462
|
+
return { entries: [], hasMore: false };
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
const entries = [];
|
|
466
|
+
while (entries.length < limit) {
|
|
467
|
+
const c = await nextInHistory(dir, walk, cache, limit - entries.length);
|
|
468
|
+
if (!c)
|
|
469
|
+
break;
|
|
470
|
+
entries.push({
|
|
471
|
+
id: c.oid,
|
|
472
|
+
message: c.commit.message.trim(),
|
|
473
|
+
timestamp: c.commit.author.timestamp * 1000,
|
|
474
|
+
author: c.commit.author.name
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
const hasMore = walk.tips.length > 0;
|
|
478
|
+
lastHistoryWalk = hasMore ? { dir, head, last: entries.at(-1).id, walk } : null;
|
|
479
|
+
return { entries, hasMore };
|
|
421
480
|
} catch (e) {
|
|
422
481
|
if (before && e?.code === "NotFoundError") {
|
|
423
482
|
return { entries: [], hasMore: false };
|
|
424
483
|
}
|
|
425
484
|
throw e;
|
|
426
485
|
}
|
|
427
|
-
const seen = new Set;
|
|
428
|
-
let filtered = commits.filter((c) => {
|
|
429
|
-
if (c.oid === before || seen.has(c.oid))
|
|
430
|
-
return false;
|
|
431
|
-
seen.add(c.oid);
|
|
432
|
-
return true;
|
|
433
|
-
});
|
|
434
|
-
const hasMore = filtered.length > limit;
|
|
435
|
-
if (hasMore)
|
|
436
|
-
filtered = filtered.slice(0, limit);
|
|
437
|
-
return {
|
|
438
|
-
entries: filtered.map((c) => ({
|
|
439
|
-
id: c.oid,
|
|
440
|
-
message: c.commit.message.trim(),
|
|
441
|
-
timestamp: c.commit.author.timestamp * 1000,
|
|
442
|
-
author: c.commit.author.name
|
|
443
|
-
})),
|
|
444
|
-
hasMore
|
|
445
|
-
};
|
|
446
486
|
}
|
|
447
487
|
restore(options) {
|
|
448
488
|
return withRepoLock(this.dir, () => this.restoreUnlocked(options));
|
|
@@ -742,4 +782,4 @@ async function switchBranch(options) {
|
|
|
742
782
|
});
|
|
743
783
|
}
|
|
744
784
|
|
|
745
|
-
export { gitScopeFor, HISTORY_PAGE_LIMIT, NO_VERSION_HISTORY, withRepoLock, whenGitIdle, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, snapshotWorkingTreeUnlocked, isNoChangesError, countUnversionedChanges, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup, SWITCH_BRANCH_SNAPSHOT_MESSAGE, readRevisionRefs, isContained, listRevisions, revisionNameFrom, assertFreeRevisionName, createRevision, switchBranch };
|
|
785
|
+
export { gitScopeFor, HISTORY_PAGE_LIMIT, NO_VERSION_HISTORY, withRepoLock, whenGitIdle, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, startHistoryWalk, nextInHistory, snapshotWorkingTreeUnlocked, isNoChangesError, countUnversionedChanges, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup, SWITCH_BRANCH_SNAPSHOT_MESSAGE, readRevisionRefs, isContained, listRevisions, revisionNameFrom, assertFreeRevisionName, createRevision, switchBranch };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "gutterpress",
|
|
4
|
-
version: "0.11.23-beta.
|
|
4
|
+
version: "0.11.23-beta.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",
|