gutterpress 0.10.0-alpha.3 → 0.10.0-beta.1
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 +2 -0
- package/dist/api/index.js +2 -2
- package/dist/{audit-xxegv0t0.js → audit-85zn35v8.js} +4 -4
- package/dist/{build-w0vb6mgq.js → build-1faqmp0y.js} +6 -4
- package/dist/{cli-5czby0dd.js → cli-5tffrg48.js} +90 -23
- package/dist/{cli-f4rcbt2t.js → cli-7e79d7se.js} +1 -1
- package/dist/{cli-yp3p0sf2.js → cli-afm8pa0h.js} +327 -24
- package/dist/{cli-gk3wsdpb.js → cli-v935c2ws.js} +1 -1
- package/dist/{cli-revgt4pr.js → cli-yzf38679.js} +1 -0
- package/dist/cli.js +16 -16
- package/dist/{doctor-ctgn1dnt.js → doctor-69v5c9wy.js} +2 -2
- package/dist/engine/compiler/build.d.ts +1 -1
- package/dist/engine/shared/flush.d.ts +59 -0
- package/dist/engine/shared/margin-box-support.d.ts +24 -0
- package/dist/{engine-eng4xh2q.js → engine-hrtn0b28.js} +1 -1
- package/dist/{engine-q5skhgms.js → engine-nbfdy0pp.js} +2 -2
- package/dist/{gutterpress-agent-1ctgfz92.js → gutterpress-agent-cazqstr1.js} +49 -1
- package/dist/{gutterpress-viewer-cem7dmr5.js → gutterpress-viewer-fb6fhwsy.js} +137 -51
- package/dist/{index-s416qpdv.js → index-052x5fef.js} +89 -22
- package/dist/{index-mvehxh0e.js → index-c2b6gyeg.js} +47 -4
- package/dist/{index-a4kr77td.js → index-wsydvp08.js} +287 -23
- package/dist/index.js +3 -3
- package/dist/lib/build-runner.d.ts +7 -0
- package/dist/lib/engine.d.ts +9 -0
- package/dist/lib/markdown/gutterpress-css.d.ts +9 -1
- package/dist/lib/markdown/markers.d.ts +51 -1
- package/dist/{lint-gsh6qwrq.js → lint-17404bsx.js} +4 -4
- package/dist/{new-nkhycqy4.js → new-vsgpxzek.js} +4 -4
- package/dist/{plugin-129wcs93.js → plugin-s4yfpx6p.js} +4 -4
- package/dist/{preflight-41hcejg9.js → preflight-1h3apvqh.js} +4 -4
- package/dist/{preview-pftsvr9z.js → preview-cqf383g4.js} +6 -5
- package/dist/{preview-interface-fnqb2y4v.js → preview-interface-hg5eqv88.js} +193 -4
- package/dist/{publish-dnjvb4jg.js → publish-arvycera.js} +4 -4
- package/dist/render.js +83 -7
- package/dist/{repair-a3enjttn.js → repair-vmwh2bhe.js} +4 -4
- package/dist/{validate-ph1xffqy.js → validate-ztzq7p35.js} +4 -4
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
BuildError,
|
|
3
3
|
EXIT_CODES,
|
|
4
4
|
INSTALL_HINTS,
|
|
5
|
+
MARGIN_BOX_IGNORED_PROPERTIES,
|
|
5
6
|
RENDER_TIMEOUT_MS,
|
|
6
7
|
REQUIRED_MILESTONE,
|
|
7
8
|
closeBrowser,
|
|
@@ -16,7 +17,7 @@ import {
|
|
|
16
17
|
resolveChromiumExecutable,
|
|
17
18
|
run,
|
|
18
19
|
spawnCapture
|
|
19
|
-
} from "./index-
|
|
20
|
+
} from "./index-c2b6gyeg.js";
|
|
20
21
|
import {
|
|
21
22
|
gitDirFor,
|
|
22
23
|
gitScopeFor,
|
|
@@ -731,6 +732,9 @@ function warn(env, line, type, message, marker) {
|
|
|
731
732
|
env.layoutWarnings = [];
|
|
732
733
|
env.layoutWarnings.push({ line, type, message, marker });
|
|
733
734
|
}
|
|
735
|
+
function proseEscapeHint(kind) {
|
|
736
|
+
return ` If this line is prose that happens to begin with "@${kind}" — a wrapped sentence, for` + ` instance — escape it as \\@${kind} or write it as \`@${kind}\` in backticks, and it stays text.`;
|
|
737
|
+
}
|
|
734
738
|
function addClasses(token, baseClass, extraClass) {
|
|
735
739
|
const cls = [];
|
|
736
740
|
if (baseClass)
|
|
@@ -792,14 +796,14 @@ function plugin(md, pluginOptions = {}) {
|
|
|
792
796
|
const unknown = parsed.__unknownTokens;
|
|
793
797
|
delete parsed.__unknownTokens;
|
|
794
798
|
for (const t of unknown) {
|
|
795
|
-
warn(state.env, startLine + 1, "unrecognized_marker_token", `@${parsed.kind}: "${t}" is not something a marker understands, so it was kept verbatim as a class name. Write a class as .my-class (or {.my-class}), an id as #my-id, and anything else as key=value
|
|
799
|
+
warn(state.env, startLine + 1, "unrecognized_marker_token", `@${parsed.kind}: "${t}" is not something a marker understands, so it was kept verbatim as a class name. Write a class as .my-class (or {.my-class}), an id as #my-id, and anything else as key=value.` + proseEscapeHint(parsed.kind), parsed);
|
|
796
800
|
}
|
|
797
801
|
}
|
|
798
802
|
if (parsed.__extraBareTokens) {
|
|
799
803
|
const { tokens, named } = parsed.__extraBareTokens;
|
|
800
804
|
delete parsed.__extraBareTokens;
|
|
801
805
|
const list = tokens.map((t) => `"${t}"`).join(", ");
|
|
802
|
-
warn(state.env, startLine + 1, "extra_bare_marker_token", named ? `@${parsed.kind}: only the first plain word (${list.split(", ")[0]}) is used as the name; the rest (${tokens.slice(1).map((t) => `"${t}"`).join(", ")}) became class names instead. Quote a name that contains spaces ("${tokens.join(" ")}"), or write classes as .${tokens.slice(1).join(" .")}.` : `@${parsed.kind}: ${list} are several plain words, but a marker has only one name slot — so NONE of them was used as the name and they all became class names instead. Quote a name that contains spaces ("${tokens.join(" ")}"), or write classes as .${tokens.join(" .")}
|
|
806
|
+
warn(state.env, startLine + 1, "extra_bare_marker_token", named ? `@${parsed.kind}: only the first plain word (${list.split(", ")[0]}) is used as the name; the rest (${tokens.slice(1).map((t) => `"${t}"`).join(", ")}) became class names instead. Quote a name that contains spaces ("${tokens.join(" ")}"), or write classes as .${tokens.slice(1).join(" .")}.` : `@${parsed.kind}: ${list} are several plain words, but a marker has only one name slot — so NONE of them was used as the name and they all became class names instead. Quote a name that contains spaces ("${tokens.join(" ")}"), or write classes as .${tokens.join(" .")}.` + proseEscapeHint(parsed.kind), parsed);
|
|
803
807
|
}
|
|
804
808
|
state.line = startLine + 1;
|
|
805
809
|
return true;
|
|
@@ -891,7 +895,12 @@ function plugin(md, pluginOptions = {}) {
|
|
|
891
895
|
t.meta = { line: meta.__line };
|
|
892
896
|
addClasses(t, "spread", meta.attrs && meta.attrs.class ? meta.attrs.class : "");
|
|
893
897
|
attachDataAttrs(t, "spread", meta.name, meta.attrs || {});
|
|
894
|
-
stack.open({
|
|
898
|
+
stack.open({
|
|
899
|
+
kind: "spread",
|
|
900
|
+
classes: meta.attrs && meta.attrs.class || "",
|
|
901
|
+
noPagesYet: true,
|
|
902
|
+
sawAnyPage: false
|
|
903
|
+
}, t);
|
|
895
904
|
}
|
|
896
905
|
function openPage(meta) {
|
|
897
906
|
const chapter = stack.get("chapter");
|
|
@@ -906,7 +915,7 @@ function plugin(md, pluginOptions = {}) {
|
|
|
906
915
|
const label = chapter ? chapter.label : "";
|
|
907
916
|
if (label)
|
|
908
917
|
t.attrSet("data-chapter-label", label);
|
|
909
|
-
stack.open({ kind: "page" }, t);
|
|
918
|
+
stack.open({ kind: "page", classes: explicit }, t);
|
|
910
919
|
if (label && !chapter.openerEmitted) {
|
|
911
920
|
const opener = new state.Token("html_block", "", 0);
|
|
912
921
|
opener.content = `<div class="chapter-opener" data-chapter-label="${escapeAttr(label)}">${escapeHtml(label)}</div>
|
|
@@ -929,13 +938,51 @@ function plugin(md, pluginOptions = {}) {
|
|
|
929
938
|
t.meta = { hasColumnBreak: false, line: meta.__line };
|
|
930
939
|
stack.open({
|
|
931
940
|
kind: "section",
|
|
941
|
+
classes: meta.attrs && meta.attrs.class || "",
|
|
942
|
+
sawContent: false,
|
|
932
943
|
meta: { name: meta.name || null, attrs: { ...meta.attrs || {} } },
|
|
933
944
|
openToken: t
|
|
934
945
|
}, t);
|
|
935
946
|
}
|
|
947
|
+
function breakHost() {
|
|
948
|
+
return stack.get("section") || stack.get("page") || stack.get("spread");
|
|
949
|
+
}
|
|
950
|
+
function gridClassOf(frame) {
|
|
951
|
+
if (!frame || !frame.classes)
|
|
952
|
+
return null;
|
|
953
|
+
return frame.classes.split(/\s+/).find((c) => c.startsWith("gp-grid-")) || null;
|
|
954
|
+
}
|
|
955
|
+
function warnBreakInsideGrid(kind, line, meta) {
|
|
956
|
+
const host = breakHost();
|
|
957
|
+
const gridClass = gridClassOf(host);
|
|
958
|
+
if (!gridClass)
|
|
959
|
+
return;
|
|
960
|
+
warn(state.env, line, "break_inside_grid", `@${kind} inside a grid container: the enclosing @${host.kind} carries .${gridClass}, so this break's <div> becomes a grid ITEM — it takes a cell of its own, corrupts the grid's placement, and print and the live preview then disagree about which page the content after it lands on. Move the break outside the grid @${host.kind}, or remove it — grid rows already flow and fragment across pages on their own.`, meta);
|
|
961
|
+
}
|
|
962
|
+
function warnIfEmptyDecoratedSection(closingKind, closingLine) {
|
|
963
|
+
const sec = stack.get("section");
|
|
964
|
+
if (!sec || sec.sawContent)
|
|
965
|
+
return;
|
|
966
|
+
const attrs = sec.meta && sec.meta.attrs || {};
|
|
967
|
+
const decorations = [];
|
|
968
|
+
for (const c of (attrs.class || "").split(/\s+/).filter(Boolean))
|
|
969
|
+
decorations.push(`.${c}`);
|
|
970
|
+
for (const [k, v] of Object.entries(attrs)) {
|
|
971
|
+
if (k === "class")
|
|
972
|
+
continue;
|
|
973
|
+
decorations.push(k === "id" ? `#${v}` : `${k}=${v}`);
|
|
974
|
+
}
|
|
975
|
+
if (!decorations.length)
|
|
976
|
+
return;
|
|
977
|
+
const openLine = sec.openToken && sec.openToken.meta && Number.isFinite(sec.openToken.meta.line) ? sec.openToken.meta.line : closingLine;
|
|
978
|
+
warn(state.env, openLine, "empty_section", `This @section (${decorations.join(" ")}) was closed by the @${closingKind} on line ${closingLine} with no content between the two markers, so its styling applies to an empty element and nothing prints the layout it asked for. Delete one of the two markers, or move the content that belongs inside the section between them.`, null);
|
|
979
|
+
}
|
|
936
980
|
for (let i = 0;i < state.tokens.length; i++) {
|
|
937
981
|
const tok = state.tokens[i];
|
|
938
982
|
if (tok.type !== "layout_marker") {
|
|
983
|
+
const openSectionFrame = stack.get("section");
|
|
984
|
+
if (openSectionFrame)
|
|
985
|
+
openSectionFrame.sawContent = true;
|
|
939
986
|
out.push(tok);
|
|
940
987
|
continue;
|
|
941
988
|
}
|
|
@@ -961,6 +1008,7 @@ function plugin(md, pluginOptions = {}) {
|
|
|
961
1008
|
continue;
|
|
962
1009
|
}
|
|
963
1010
|
if (kind === "section") {
|
|
1011
|
+
warnIfEmptyDecoratedSection("section", line);
|
|
964
1012
|
stack.close("section");
|
|
965
1013
|
const spread = stack.get("spread");
|
|
966
1014
|
if (spread && spread.noPagesYet) {
|
|
@@ -989,6 +1037,7 @@ function plugin(md, pluginOptions = {}) {
|
|
|
989
1037
|
continue;
|
|
990
1038
|
}
|
|
991
1039
|
if (kind === "page-break") {
|
|
1040
|
+
warnBreakInsideGrid("page-break", line, meta);
|
|
992
1041
|
const t = new state.Token("layout_page_break", "div", 0);
|
|
993
1042
|
t.meta = { line };
|
|
994
1043
|
t.attrSet("class", "gp-page-break");
|
|
@@ -997,6 +1046,7 @@ function plugin(md, pluginOptions = {}) {
|
|
|
997
1046
|
continue;
|
|
998
1047
|
}
|
|
999
1048
|
if (kind === "column-break") {
|
|
1049
|
+
warnBreakInsideGrid("column-break", line, meta);
|
|
1000
1050
|
const openSectionFrame = stack.get("section");
|
|
1001
1051
|
if (openSectionFrame && openSectionFrame.openToken && !openSectionFrame.openToken.meta.hasColumnBreak) {
|
|
1002
1052
|
const sectionCls = openSectionFrame.openToken.attrGet("class") || "";
|
|
@@ -1012,6 +1062,7 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1012
1062
|
continue;
|
|
1013
1063
|
}
|
|
1014
1064
|
if (kind === "end-section") {
|
|
1065
|
+
warnIfEmptyDecoratedSection("end-section", line);
|
|
1015
1066
|
stack.close("section");
|
|
1016
1067
|
continue;
|
|
1017
1068
|
}
|
|
@@ -1099,7 +1150,7 @@ body { margin: 0; }
|
|
|
1099
1150
|
.gp-page-break { break-before: page; }
|
|
1100
1151
|
.page { break-before: page; }
|
|
1101
1152
|
.spread { break-before: page; }
|
|
1102
|
-
:where(.page, .spread) { position: relative; }
|
|
1153
|
+
:where(.page, .spread) { position: relative; display: flow-root; box-sizing: border-box; min-height: calc(var(--gp-content-h, 1px) - 1px); }
|
|
1103
1154
|
.gp-column-break { break-after: column; height: 0; font-size: 0; line-height: 0; visibility: hidden; }
|
|
1104
1155
|
|
|
1105
1156
|
:where(h1,h2,h3,h4,h5,h6) { break-after: avoid; }
|
|
@@ -1183,6 +1234,26 @@ var GUTTERPRESS_CSS = `
|
|
|
1183
1234
|
.gp-columns-2 { columns: 2; column-gap: var(--gp-column-gap, 1.5em); }
|
|
1184
1235
|
.gp-columns-3 { columns: 3; column-gap: var(--gp-column-gap, 1.5em); }
|
|
1185
1236
|
|
|
1237
|
+
/* grid runs — the SLOTTED counterpart to the column runs above. Grid places
|
|
1238
|
+
each child into the next cell, across then down (deterministic slots: card
|
|
1239
|
+
layouts, stat blocks, image-plus-caption pairs); columns FLOW one text run
|
|
1240
|
+
down then across. Same neutral-primitive rationale as .gp-columns-*, and
|
|
1241
|
+
permanent vocabulary for the same reason: standard CSS Grid verbatim, no
|
|
1242
|
+
spec gap to remove later. MEASURED (Chromium 151, gp-grid evidence pack):
|
|
1243
|
+
grid rows fragment across sheets with EXACT print/viewer parity — 2- and
|
|
1244
|
+
3-col, unequal item heights, mid-row cuts, multi-sheet overflow,
|
|
1245
|
+
break-inside:avoid, gap geometry — so a grid taller than the page is safe,
|
|
1246
|
+
no fit-one-page constraint. Two things to know, not fix:
|
|
1247
|
+
- on a min-height page root (MARKER_CSS), default align-content
|
|
1248
|
+
stretches rows apart to fill the page — identically in both engines.
|
|
1249
|
+
Authors wanting packed rows set align-content: start.
|
|
1250
|
+
- a @page-break / @column-break marker DIRECTLY inside a grid container
|
|
1251
|
+
becomes a grid item and corrupts placement (the one measured parity
|
|
1252
|
+
break); markers.js diagnoses it (break_inside_grid).
|
|
1253
|
+
--gp-grid-gap is author-settable. */
|
|
1254
|
+
.gp-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--gp-grid-gap, 1.5em); }
|
|
1255
|
+
.gp-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gp-grid-gap, 1.5em); }
|
|
1256
|
+
|
|
1186
1257
|
/* shape wrap — text follows the image's alpha silhouette instead of its
|
|
1187
1258
|
rectangular box. shape-outside only applies to floats, so this is inert
|
|
1188
1259
|
without .gp-left/.gp-right (and under .gp-pin, which un-floats). The
|
|
@@ -1245,8 +1316,14 @@ img.gp-shape {
|
|
|
1245
1316
|
opacity, filter, transform on it traps the negative layer inside).
|
|
1246
1317
|
Core keeps .page/.spread at 'position: relative; z-index: auto'
|
|
1247
1318
|
precisely so they are not stacking contexts.
|
|
1248
|
-
- a clipping ancestor (overflow other than visible)
|
|
1249
|
-
|
|
1319
|
+
- a clipping ancestor (overflow other than visible) — but only where
|
|
1320
|
+
the art actually overhangs that ancestor's clip box on a clipped
|
|
1321
|
+
axis: the overhang is cut off, the same mechanism that clips a
|
|
1322
|
+
.gp-bleed plate back to the wrapper's width. Clipping never reorders
|
|
1323
|
+
layers — within-bounds art under a clipping .page prints whole and
|
|
1324
|
+
still behind (measured; see the build audit's comment in
|
|
1325
|
+
engine/compiler/build.ts), and a static wrapper's overflow never
|
|
1326
|
+
binds an abspos .gp-pin at all.
|
|
1250
1327
|
The build-time engine.layer.trapped audit reports both against the live
|
|
1251
1328
|
ancestor chain. printsafe/page-containment is only an early source hint for
|
|
1252
1329
|
declarations written directly on .page/.spread. */
|
|
@@ -3873,7 +3950,7 @@ import git from "isomorphic-git";
|
|
|
3873
3950
|
// package.json
|
|
3874
3951
|
var package_default = {
|
|
3875
3952
|
name: "gutterpress",
|
|
3876
|
-
version: "0.10.0-
|
|
3953
|
+
version: "0.10.0-beta.1",
|
|
3877
3954
|
description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
3878
3955
|
author: "itlackey",
|
|
3879
3956
|
license: "MPL-2.0",
|
|
@@ -4325,17 +4402,6 @@ import { readFile as readFile8 } from "node:fs/promises";
|
|
|
4325
4402
|
|
|
4326
4403
|
// src/lib/printsafe.ts
|
|
4327
4404
|
import postcss2 from "postcss";
|
|
4328
|
-
|
|
4329
|
-
// src/engine/shared/margin-box-support.ts
|
|
4330
|
-
var MARGIN_BOX_IGNORED_PROPERTIES = new Set([
|
|
4331
|
-
"transform",
|
|
4332
|
-
"rotate",
|
|
4333
|
-
"translate",
|
|
4334
|
-
"scale",
|
|
4335
|
-
"box-shadow"
|
|
4336
|
-
]);
|
|
4337
|
-
|
|
4338
|
-
// src/lib/printsafe.ts
|
|
4339
4405
|
var ruleRemoteUrls = "printsafe/no-remote-urls";
|
|
4340
4406
|
var ruleRiskyProps = "printsafe/no-risky-print-effects";
|
|
4341
4407
|
var ruleSyntax = "printsafe/syntax-error";
|
|
@@ -7827,11 +7893,12 @@ class PdfOutput {
|
|
|
7827
7893
|
const rawPdf = pdfxMode ? path7.join(stage, "raw.pdf") : path7.resolve(pdfFile);
|
|
7828
7894
|
await fsp2.mkdir(path7.dirname(path7.resolve(pdfFile)), { recursive: true });
|
|
7829
7895
|
log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
|
|
7830
|
-
const { buildNativePdf } = await import("./engine-
|
|
7896
|
+
const { buildNativePdf } = await import("./engine-nbfdy0pp.js");
|
|
7831
7897
|
const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
|
|
7832
7898
|
title: config.title,
|
|
7833
7899
|
author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
|
|
7834
|
-
signature: config.print.signature
|
|
7900
|
+
signature: config.print.signature,
|
|
7901
|
+
allowShrink: opts.allowShrink
|
|
7835
7902
|
}, opts.engineBrowser);
|
|
7836
7903
|
for (const d of engineDiagnostics)
|
|
7837
7904
|
log.warn(d.message);
|
|
@@ -596,7 +596,7 @@ var favicon_default = "./favicon-wkbm9cjn.ico";
|
|
|
596
596
|
var manifest_schema_default = "./manifest.schema-zxgxnbg7.json";
|
|
597
597
|
|
|
598
598
|
// src/assets/preview/scripts/preview-interface.js
|
|
599
|
-
var preview_interface_default = "./preview-interface-
|
|
599
|
+
var preview_interface_default = "./preview-interface-hg5eqv88.js";
|
|
600
600
|
|
|
601
601
|
// src/assets/preview/scripts/preview-bridge.js
|
|
602
602
|
var preview_bridge_default = "./preview-bridge-fz7vpk8m.js";
|
|
@@ -608,10 +608,10 @@ var preview_shell_default = "./preview-shell-c5mfa3q0.js";
|
|
|
608
608
|
var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
|
|
609
609
|
|
|
610
610
|
// src/assets/engine/gutterpress-viewer.js
|
|
611
|
-
var gutterpress_viewer_default = "./gutterpress-viewer-
|
|
611
|
+
var gutterpress_viewer_default = "./gutterpress-viewer-fb6fhwsy.js";
|
|
612
612
|
|
|
613
613
|
// src/assets/engine/gutterpress-agent.js
|
|
614
|
-
var gutterpress_agent_default = "./gutterpress-agent-
|
|
614
|
+
var gutterpress_agent_default = "./gutterpress-agent-cazqstr1.js";
|
|
615
615
|
|
|
616
616
|
// src/assets/templates/book/manifest.yaml
|
|
617
617
|
var manifest_default = "./manifest-n1gh3qw5.yaml";
|
|
@@ -705,4 +705,47 @@ async function getAssetPath(relPath) {
|
|
|
705
705
|
return join3(root, relPath);
|
|
706
706
|
}
|
|
707
707
|
|
|
708
|
-
|
|
708
|
+
// src/engine/shared/margin-box-support.ts
|
|
709
|
+
var MARGIN_BOX_IGNORED_PROPERTIES = new Set([
|
|
710
|
+
"transform",
|
|
711
|
+
"rotate",
|
|
712
|
+
"translate",
|
|
713
|
+
"scale",
|
|
714
|
+
"box-shadow"
|
|
715
|
+
]);
|
|
716
|
+
function isIgnoredMarginBoxProperty(property) {
|
|
717
|
+
return MARGIN_BOX_IGNORED_PROPERTIES.has(property.toLowerCase());
|
|
718
|
+
}
|
|
719
|
+
function marginBoxRectPt(name, g) {
|
|
720
|
+
const { top, right, bottom, left } = g.margin;
|
|
721
|
+
const cw = g.width - left - right;
|
|
722
|
+
const ch = g.height - top - bottom;
|
|
723
|
+
const third = (n) => n / 3;
|
|
724
|
+
const T = {
|
|
725
|
+
"top-left-corner": [0, 0, left, top],
|
|
726
|
+
"top-left": [left, 0, third(cw), top],
|
|
727
|
+
"top-center": [left + third(cw), 0, third(cw), top],
|
|
728
|
+
"top-right": [left + 2 * third(cw), 0, third(cw), top],
|
|
729
|
+
"top-right-corner": [g.width - right, 0, right, top],
|
|
730
|
+
"bottom-left-corner": [0, g.height - bottom, left, bottom],
|
|
731
|
+
"bottom-left": [left, g.height - bottom, third(cw), bottom],
|
|
732
|
+
"bottom-center": [left + third(cw), g.height - bottom, third(cw), bottom],
|
|
733
|
+
"bottom-right": [left + 2 * third(cw), g.height - bottom, third(cw), bottom],
|
|
734
|
+
"bottom-right-corner": [g.width - right, g.height - bottom, right, bottom],
|
|
735
|
+
"left-top": [0, top, left, third(ch)],
|
|
736
|
+
"left-middle": [0, top + third(ch), left, third(ch)],
|
|
737
|
+
"left-bottom": [0, top + 2 * third(ch), left, third(ch)],
|
|
738
|
+
"right-top": [g.width - right, top, right, third(ch)],
|
|
739
|
+
"right-middle": [g.width - right, top + third(ch), right, third(ch)],
|
|
740
|
+
"right-bottom": [g.width - right, top + 2 * third(ch), right, third(ch)]
|
|
741
|
+
};
|
|
742
|
+
const [x, y, w, h] = T[name] ?? [0, 0, 0, 0];
|
|
743
|
+
return { x, y, w, h };
|
|
744
|
+
}
|
|
745
|
+
function marginBoxAlign(name) {
|
|
746
|
+
if (name.includes("center") || name.includes("middle"))
|
|
747
|
+
return "center";
|
|
748
|
+
return /right/.test(name) ? "end" : "start";
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
export { EXIT_CODES, BuildError, run, spawnCapture, execCapture, isToolAvailable, findTool, INSTALL_HINTS, fullInstallHint, resolveChromiumExecutable, requireChromiumExecutable, RENDER_TIMEOUT_MS, prewarmBrowser, getBrowser, closeBrowser, getAssetPath, MARGIN_BOX_IGNORED_PROPERTIES, isIgnoredMarginBoxProperty, marginBoxRectPt, marginBoxAlign, REQUIRED_MILESTONE, assertMilestone, readyProbeExpr, DEFAULT_PRINT_OPTS, launchChromium, connectChromium };
|