gutterpress 0.11.23-alpha.1 → 0.11.23-alpha.3
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 +27 -29
- package/dist/{README-8ef336pp.md → README-8db7btxb.md} +13 -19
- package/dist/api/index.d.ts +5 -5
- package/dist/api/index.js +16 -22
- package/dist/{build-09cd1n7s.js → build-m78jcpf7.js} +9 -10
- package/dist/{cli-5hkmp2wy.js → cli-1h17ktsg.js} +125 -187
- package/dist/{cli-nr6j6300.js → cli-5jzyw06s.js} +1 -1
- package/dist/{cli-habkc5ng.js → cli-a35w7wzg.js} +5 -4
- package/dist/{cli-dd115fa8.js → cli-h4x81x97.js} +152 -124
- package/dist/{cli-ccp7sxz3.js → cli-n2tsxqpn.js} +1 -1
- package/dist/{cli-b0vyjvmt.js → cli-s6djx4ma.js} +1 -1
- package/dist/{cli-h17e3mtz.js → cli-t8be9yeb.js} +380 -16
- package/dist/{cli-dtckwda1.js → cli-xsrffqzt.js} +192 -10
- package/dist/{index-r7jcsk6h.js → cli-y28j019d.js} +19 -10
- package/dist/cli.js +12 -12
- package/dist/{doctor-nddspx4n.js → doctor-j71jqce3.js} +3 -3
- package/dist/engine/shared/gcpm-extract.d.ts +8 -0
- package/dist/engine/shared/print-area.d.ts +16 -4
- package/dist/{engine-yjzknt0g.js → engine-1r6q80tq.js} +3 -3
- package/dist/{engine-892swzzc.js → engine-m4y10shc.js} +1 -2
- package/dist/{ext-zjpen4yx.js → ext-fq2hg9va.js} +18 -33
- package/dist/{extension-restore-jvs60x9b.js → extension-restore-9dh7c4tp.js} +4 -4
- package/dist/{extension-restore-w8xt4kbq.js → extension-restore-tmxtzkm0.js} +5 -6
- package/dist/{gutterpress-viewer-701vf4qp.js → gutterpress-viewer-mafsby5k.js} +9 -2
- package/dist/{index-2jpk25en.js → index-0wee4408.js} +380 -16
- package/dist/index-46ycxe6r.js +18 -0
- package/dist/{cli-h3phdstf.js → index-5x42amh8.js} +19 -10
- package/dist/{index-m4hhzg3c.js → index-7pck1q9c.js} +174 -142
- package/dist/{index-93pqkvty.js → index-h6yk5tjx.js} +5 -4
- package/dist/{index-apc8w9w8.js → index-nedd07bk.js} +187 -2
- package/dist/{index-0w2azsk1.js → index-nvmf22rt.js} +2 -4
- package/dist/{index-zrhyb967.js → index-prqvz3xm.js} +510 -587
- package/dist/index.js +17 -23
- package/dist/lib/extension-manager.d.ts +24 -50
- package/dist/lib/extension-manifest.d.ts +1 -13
- package/dist/lib/extension-scaffold.d.ts +3 -3
- package/dist/lib/extension-specifier.d.ts +23 -6
- package/dist/lib/manifest.d.ts +15 -1
- package/dist/lib/markdown/assemble.d.ts +4 -3
- package/dist/lib/markdown/math.d.ts +1 -1
- package/dist/lib/npm-plugin-installer.d.ts +1 -1
- package/dist/lib/page-size.d.ts +34 -27
- package/dist/lib/plugin-vendor.d.ts +11 -3
- package/dist/lib/printsafe.d.ts +1 -0
- package/dist/lib/project-gitignore.d.ts +2 -2
- package/dist/lib/project-scaffold.d.ts +5 -7
- package/dist/lib/project-templates.d.ts +9 -3
- package/dist/lib/snippets.d.ts +2 -1
- package/dist/lib/style-resolver.d.ts +1 -2
- package/dist/manifest-8afhrk30.yaml +19 -0
- package/dist/manifest-d4f9q79e.yaml +23 -0
- package/dist/manifest-gf13sjp8.yaml +27 -0
- package/dist/manifest-my7mdv8j.yaml +23 -0
- package/dist/{manifest.schema-9aeaered.json → manifest.schema-650pe0d1.json} +17 -5
- package/dist/{new-xhq8wczn.js → new-s4zcaepg.js} +22 -21
- package/dist/{package-aenwjew3.json → package-awwkt7sa.json} +0 -1
- package/dist/{page-rules-nsj3aw42.css → page-rules-fj09xct5.css} +12 -40
- package/dist/{plugin.test.js-xgxrd8hf.tpl → plugin.test.js-gxzqqfdh.tpl} +0 -1
- package/dist/{plugins-9en8m9y0.js → plugins-4vaf27n9.js} +4 -4
- package/dist/{plugins-gf0gkjmv.js → plugins-80emnf31.js} +2 -2
- package/dist/{preflight-negnxg7b.js → preflight-c7w1xdn3.js} +9 -10
- package/dist/{preview-cep2s9cg.js → preview-mzytcwyk.js} +9 -10
- package/dist/{publish-xery6qc6.js → publish-fez14ad4.js} +9 -10
- package/dist/render.js +24 -561
- package/dist/schema/manifest.types.d.ts +22 -0
- package/dist/{source-provider-qbfknhyy.js → source-provider-98k5deda.js} +2 -2
- package/dist/{source-provider-2r74a7wp.js → source-provider-knmcam50.js} +2 -2
- package/dist/{tokens-7984461t.css → tokens-ye64p899.css} +5 -12
- package/dist/{validate-3d0sgf4g.js → validate-p2chr6hr.js} +9 -10
- package/package.json +1 -1
- package/dist/cli-fe43evmf.js +0 -212
- package/dist/index-dsvk7q6s.js +0 -229
- package/dist/manifest-8f10dr4f.yaml +0 -17
- package/dist/manifest-n1gh3qw5.yaml +0 -9
- package/dist/package-97gm31sg.json +0 -10
- package/dist/package-gag6ykwn.json +0 -10
- package/dist/package-nrhkwf2m.json +0 -10
- package/dist/package-zttkgydq.json +0 -10
- package/dist/theme-9c58td2d.css +0 -76
- package/dist/theme-h5recz6c.css +0 -61
- package/dist/theme-j2bagrfx.css +0 -59
- package/dist/theme-nn6d53zy.css +0 -71
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BUNDLED_EXTENSIONS,
|
|
2
3
|
EXTENSION_MANIFEST_FILENAME,
|
|
3
4
|
TWO_VERSIONS_OPEN,
|
|
5
|
+
bundledExtension,
|
|
4
6
|
extensionCarries,
|
|
5
7
|
extensionStyleList,
|
|
8
|
+
isPathSpecifier,
|
|
6
9
|
loadPlugin,
|
|
7
10
|
log,
|
|
11
|
+
parseExtensionSpecifier,
|
|
12
|
+
pinnedNpmSpecifier,
|
|
8
13
|
prettify,
|
|
9
14
|
readExtensionMeta,
|
|
10
15
|
resolveExtension,
|
|
11
16
|
slugify
|
|
12
|
-
} from "./index-
|
|
17
|
+
} from "./index-0wee4408.js";
|
|
13
18
|
import {
|
|
14
19
|
BuildError,
|
|
15
|
-
EXIT_CODES
|
|
16
|
-
|
|
17
|
-
} from "./index-dsvk7q6s.js";
|
|
20
|
+
EXIT_CODES
|
|
21
|
+
} from "./index-46ycxe6r.js";
|
|
18
22
|
import {
|
|
19
|
-
|
|
23
|
+
EXTENSIONS_DIR,
|
|
20
24
|
VENDORED_NPM_DIR,
|
|
21
25
|
assertWindowsSafeRelativePath,
|
|
22
26
|
isExactNpmVersion,
|
|
@@ -25,8 +29,9 @@ import {
|
|
|
25
29
|
resolveVendoredPluginInstallRoot,
|
|
26
30
|
vendoredNpmPluginPackageDir,
|
|
27
31
|
vendoredNpmPluginRoot,
|
|
32
|
+
vendoredNpmPluginRoots,
|
|
28
33
|
windowsPathKey
|
|
29
|
-
} from "./index-
|
|
34
|
+
} from "./index-5x42amh8.js";
|
|
30
35
|
import {
|
|
31
36
|
__require
|
|
32
37
|
} from "./index-37x76zdn.js";
|
|
@@ -68,7 +73,7 @@ async function withFetchTimeout(options, run) {
|
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
// src/lib/extension-manager.ts
|
|
71
|
-
import {
|
|
76
|
+
import { readdir, readFile as readFile5, rm as rm3, stat } from "node:fs/promises";
|
|
72
77
|
import { existsSync as existsSync3 } from "node:fs";
|
|
73
78
|
import path4 from "node:path";
|
|
74
79
|
import { isSeq as isSeq2, isMap, isScalar, YAMLMap, Scalar } from "yaml";
|
|
@@ -86,42 +91,85 @@ import { existsSync, statSync } from "node:fs";
|
|
|
86
91
|
import { resolve, dirname } from "node:path";
|
|
87
92
|
import { parse as parseYaml, YAMLParseError } from "yaml";
|
|
88
93
|
|
|
89
|
-
// src/
|
|
90
|
-
|
|
91
|
-
"
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
"
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
return
|
|
100
|
-
}
|
|
101
|
-
function
|
|
102
|
-
return
|
|
103
|
-
}
|
|
104
|
-
function
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
94
|
+
// src/engine/shared/print-area.ts
|
|
95
|
+
function isPositivePoints(value) {
|
|
96
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
97
|
+
}
|
|
98
|
+
function isNonNegativePoints(value) {
|
|
99
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
100
|
+
}
|
|
101
|
+
var round3 = (n) => Math.round(n * 1000) / 1000;
|
|
102
|
+
function cssLength(pt) {
|
|
103
|
+
const inches = round3(pt / 72);
|
|
104
|
+
return Math.abs(inches * 72 - pt) < 0.000001 ? `${inches}in` : `${round3(pt)}pt`;
|
|
105
|
+
}
|
|
106
|
+
function formatPageSize(page) {
|
|
107
|
+
return `${cssLength(page.width)} ${cssLength(page.height)}`;
|
|
108
|
+
}
|
|
109
|
+
function printAreaMeta(page) {
|
|
110
|
+
const area = JSON.stringify({
|
|
111
|
+
width: page.width,
|
|
112
|
+
height: page.height,
|
|
113
|
+
bleed: page.bleed ?? 0,
|
|
114
|
+
safe: page.safe ?? 0,
|
|
115
|
+
artSafe: page.artSafe,
|
|
116
|
+
gutter: page.gutter,
|
|
117
|
+
preset: page.preset,
|
|
118
|
+
spec: page.spec
|
|
119
|
+
});
|
|
120
|
+
return `<meta name="gp-print-area" content='${area.replace(/&/g, "&").replace(/'/g, "'")}'>`;
|
|
121
|
+
}
|
|
122
|
+
function pageBoxes(area, side, scale = 1) {
|
|
123
|
+
const w = area.width * scale;
|
|
124
|
+
const h = area.height * scale;
|
|
125
|
+
const b = Math.max(0, area.bleed) * scale;
|
|
126
|
+
const s = Math.max(0, area.safe) * scale;
|
|
127
|
+
const a = Math.max(0, area.artSafe) * scale;
|
|
128
|
+
const g = Math.max(0, area.gutter) * scale;
|
|
129
|
+
const [textLeft, textRight] = side === "verso" ? [s, g] : [g, s];
|
|
130
|
+
const [artLeft, artRight] = side === "verso" ? [a, g] : [g, a];
|
|
131
|
+
const trim = { x: side === "verso" ? b : 0, y: b, w: Math.max(0, w - b), h: Math.max(0, h - 2 * b) };
|
|
132
|
+
return {
|
|
133
|
+
sheet: { x: 0, y: 0, w, h },
|
|
134
|
+
trim,
|
|
135
|
+
safe: {
|
|
136
|
+
x: trim.x + textLeft,
|
|
137
|
+
y: trim.y + s,
|
|
138
|
+
w: Math.max(0, trim.w - textLeft - textRight),
|
|
139
|
+
h: Math.max(0, trim.h - 2 * s)
|
|
140
|
+
},
|
|
141
|
+
safeArt: {
|
|
142
|
+
x: trim.x + artLeft,
|
|
143
|
+
y: trim.y + a,
|
|
144
|
+
w: Math.max(0, trim.w - artLeft - artRight),
|
|
145
|
+
h: Math.max(0, trim.h - 2 * a)
|
|
146
|
+
},
|
|
147
|
+
bleed: b
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
var SEVERITY = { inside: 0, unsafe: 1, bleed: 2, "off-page": 3 };
|
|
151
|
+
function judgeRect(r, boxes, rule, tol = 0) {
|
|
152
|
+
const { sheet, trim } = boxes;
|
|
153
|
+
const safe = rule === "art" ? boxes.safeArt : boxes.safe;
|
|
154
|
+
const sides = [
|
|
155
|
+
["left", -r.x, -safe.x, -trim.x, -sheet.x],
|
|
156
|
+
["right", r.x + r.w, safe.x + safe.w, trim.x + trim.w, sheet.x + sheet.w],
|
|
157
|
+
["top", -r.y, -safe.y, -trim.y, -sheet.y],
|
|
158
|
+
["bottom", r.y + r.h, safe.y + safe.h, trim.y + trim.h, sheet.y + sheet.h]
|
|
159
|
+
];
|
|
160
|
+
let worst = { kind: "inside", gap: 0, need: 0, edge: null };
|
|
161
|
+
let beyond = 0;
|
|
162
|
+
for (const [edge, ink, limit, trimEdge, sheetEdge] of sides) {
|
|
163
|
+
const past = ink - limit;
|
|
164
|
+
if (past <= tol || rule === "art" && ink >= sheetEdge - tol)
|
|
165
|
+
continue;
|
|
166
|
+
const kind = ink > sheetEdge + tol ? "off-page" : ink > trimEdge + tol ? "bleed" : "unsafe";
|
|
167
|
+
if (SEVERITY[kind] > SEVERITY[worst.kind] || kind === worst.kind && past > beyond) {
|
|
168
|
+
worst = { kind, gap: trimEdge - ink, need: trimEdge - limit, edge };
|
|
169
|
+
beyond = past;
|
|
118
170
|
}
|
|
119
|
-
return { kind: "bundled", name: parsed.name };
|
|
120
171
|
}
|
|
121
|
-
return
|
|
122
|
-
}
|
|
123
|
-
function pinnedNpmSpecifier(name, version) {
|
|
124
|
-
return `${name}@${version}`;
|
|
172
|
+
return worst;
|
|
125
173
|
}
|
|
126
174
|
|
|
127
175
|
// src/constants.ts
|
|
@@ -184,7 +232,8 @@ var DTRPG_PRESET = {
|
|
|
184
232
|
bleed: 9,
|
|
185
233
|
safe: 36,
|
|
186
234
|
artSafe: 18,
|
|
187
|
-
gutter: 36
|
|
235
|
+
gutter: 36,
|
|
236
|
+
margin: undefined
|
|
188
237
|
},
|
|
189
238
|
ink: {
|
|
190
239
|
maxTac: 240,
|
|
@@ -270,7 +319,8 @@ var BOOK_PRESET = {
|
|
|
270
319
|
bleed: undefined,
|
|
271
320
|
safe: 18,
|
|
272
321
|
artSafe: undefined,
|
|
273
|
-
gutter: undefined
|
|
322
|
+
gutter: undefined,
|
|
323
|
+
margin: undefined
|
|
274
324
|
},
|
|
275
325
|
ink: {
|
|
276
326
|
maxTac: 400,
|
|
@@ -642,9 +692,28 @@ function resolveCustomPage(c, m) {
|
|
|
642
692
|
bleed: c.page?.bleed ?? m.page?.bleed,
|
|
643
693
|
safe: c.page?.safe ?? m.page?.safe,
|
|
644
694
|
artSafe: c.page?.artSafe ?? m.page?.artSafe,
|
|
645
|
-
gutter: c.page?.gutter ?? m.page?.gutter
|
|
695
|
+
gutter: c.page?.gutter ?? m.page?.gutter,
|
|
696
|
+
margin: c.page?.margin ?? m.page?.margin
|
|
646
697
|
};
|
|
647
698
|
}
|
|
699
|
+
var MARGIN_EDGES = ["top", "bottom", "inside", "outside"];
|
|
700
|
+
function validatePageMargin(margin, size) {
|
|
701
|
+
const edges = isPlainObject(margin) && Object.keys(margin).every((k) => MARGIN_EDGES.includes(k)) && MARGIN_EDGES.every((e) => isNonNegativePoints(margin[e]));
|
|
702
|
+
if (!edges) {
|
|
703
|
+
throw new UsageError("Manifest field `page.margin` must set all four edges in points (72pt = 1in), for example\n" + ` page:
|
|
704
|
+
margin:
|
|
705
|
+
top: 54
|
|
706
|
+
bottom: 54
|
|
707
|
+
inside: 54
|
|
708
|
+
outside: 54
|
|
709
|
+
` + `got ${JSON.stringify(margin)}.`);
|
|
710
|
+
}
|
|
711
|
+
const m = margin;
|
|
712
|
+
if (m.inside + m.outside >= size.width || m.top + m.bottom >= size.height) {
|
|
713
|
+
throw new UsageError(`Manifest field \`page.margin\` leaves no room for text on a ${size.width} x ${size.height}pt page ` + `(inside ${m.inside} + outside ${m.outside} across, top ${m.top} + bottom ${m.bottom} down).`);
|
|
714
|
+
}
|
|
715
|
+
return m;
|
|
716
|
+
}
|
|
648
717
|
function resolveWithPreset(cliOverrides, manifest, preset) {
|
|
649
718
|
const m = manifest;
|
|
650
719
|
const c = cliOverrides;
|
|
@@ -697,6 +766,9 @@ function resolveWithPreset(cliOverrides, manifest, preset) {
|
|
|
697
766
|
throw new UsageError("Manifest field `extensions` must be a list of specifiers.");
|
|
698
767
|
}
|
|
699
768
|
const extensions = rawExtensions.map((entry, index) => ({ entry, index })).filter(({ entry }) => typeof entry === "string" || entry?.enabled !== false).map(({ entry, index }) => normalizeExtensionEntry(entry, index));
|
|
769
|
+
const page = preset.page ? mergeShape(c.page, m.page, preset.page) : resolveCustomPage(c, m);
|
|
770
|
+
if (page.margin !== undefined && page.margin !== null)
|
|
771
|
+
validatePageMargin(page.margin, page);
|
|
700
772
|
return {
|
|
701
773
|
title: c.title ?? m.title ?? "Document",
|
|
702
774
|
authors: c.authors ?? m.authors ?? [],
|
|
@@ -709,7 +781,7 @@ function resolveWithPreset(cliOverrides, manifest, preset) {
|
|
|
709
781
|
source: mergeShape(c.source, m.source, preset.source),
|
|
710
782
|
pdfx: mergeShape(c.pdfx, m.pdfx, preset.pdfx),
|
|
711
783
|
print: mergeShape(c.print, m.print, preset.print),
|
|
712
|
-
page
|
|
784
|
+
page,
|
|
713
785
|
ink: mergeShape(c.ink, m.ink, preset.ink),
|
|
714
786
|
lint: {
|
|
715
787
|
...mergeShape(c.lint, m.lint, preset.lint),
|
|
@@ -1324,13 +1396,13 @@ async function removeEmptyDirs(dirs) {
|
|
|
1324
1396
|
}
|
|
1325
1397
|
}
|
|
1326
1398
|
async function prepareVendorParent(projectDir, name) {
|
|
1327
|
-
const
|
|
1328
|
-
const npm = path2.join(
|
|
1399
|
+
const extensions = path2.join(projectDir, EXTENSIONS_DIR);
|
|
1400
|
+
const npm = path2.join(extensions, VENDORED_NPM_DIR);
|
|
1329
1401
|
const packageParent = path2.dirname(vendoredNpmPluginRoot(projectDir, name, "0.0.0"));
|
|
1330
1402
|
await mkdir2(projectDir, { recursive: true });
|
|
1331
1403
|
const createdDirs = [];
|
|
1332
1404
|
try {
|
|
1333
|
-
for (const dir of [
|
|
1405
|
+
for (const dir of [extensions, npm, packageParent]) {
|
|
1334
1406
|
if (await ensureDirectory(dir))
|
|
1335
1407
|
createdDirs.push(dir);
|
|
1336
1408
|
}
|
|
@@ -1449,7 +1521,7 @@ function ignoreStatus(gitignore, entry) {
|
|
|
1449
1521
|
return "ignored";
|
|
1450
1522
|
return dir.unignored || file.unignored ? "negated" : "open";
|
|
1451
1523
|
}
|
|
1452
|
-
var PROJECT_GITIGNORE_ENTRIES = ["dist/", "
|
|
1524
|
+
var PROJECT_GITIGNORE_ENTRIES = ["dist/", "extensions/npm/"];
|
|
1453
1525
|
async function ensureProjectGitignore(projectDir) {
|
|
1454
1526
|
const gitignorePath = path3.join(projectDir, ".gitignore");
|
|
1455
1527
|
let existing = null;
|
|
@@ -1477,40 +1549,6 @@ async function ensureProjectGitignore(projectDir) {
|
|
|
1477
1549
|
}
|
|
1478
1550
|
|
|
1479
1551
|
// src/lib/extension-manager.ts
|
|
1480
|
-
var EXTENSIONS_DIR = "extensions";
|
|
1481
|
-
var RECOMMENDED_EXTENSIONS = [
|
|
1482
|
-
{
|
|
1483
|
-
use: "markdown-it-mark",
|
|
1484
|
-
label: "Highlight",
|
|
1485
|
-
description: "Highlight text by wrapping it in `==double equals==`."
|
|
1486
|
-
},
|
|
1487
|
-
{
|
|
1488
|
-
use: "markdown-it-sub",
|
|
1489
|
-
label: "Subscript",
|
|
1490
|
-
description: "Lower text below the line, like the 2 in `H~2~O`."
|
|
1491
|
-
},
|
|
1492
|
-
{
|
|
1493
|
-
use: "markdown-it-sup",
|
|
1494
|
-
label: "Superscript",
|
|
1495
|
-
description: "Raise text above the line, like the th in `29^th^`."
|
|
1496
|
-
},
|
|
1497
|
-
{
|
|
1498
|
-
use: "markdown-it-abbr",
|
|
1499
|
-
label: "Abbreviations",
|
|
1500
|
-
description: "Explain an abbreviation when readers hover over it. Define it once, like `*[GPS]: Global Positioning System`."
|
|
1501
|
-
},
|
|
1502
|
-
{
|
|
1503
|
-
use: "gutterpress-gfm-alerts",
|
|
1504
|
-
label: "Callouts",
|
|
1505
|
-
description: "Turn a quote into a boxed note: start it with `> [!NOTE]` (or `TIP`, `IMPORTANT`, `WARNING`, `CAUTION`)."
|
|
1506
|
-
},
|
|
1507
|
-
{
|
|
1508
|
-
use: "gutterpress-math",
|
|
1509
|
-
label: "Math",
|
|
1510
|
-
description: "Write LaTeX math between dollar signs: `$E = mc^2$` in a line, or `$$` … `$$` on lines of their own."
|
|
1511
|
-
}
|
|
1512
|
-
];
|
|
1513
|
-
var BUILT_IN_STYLE_SET_IDS = ["clean-book", "zine", "technical-doc", "academic"];
|
|
1514
1552
|
var mutationQueues = new Map;
|
|
1515
1553
|
function projectKey(projectDir) {
|
|
1516
1554
|
const resolved = path4.resolve(projectDir);
|
|
@@ -1602,7 +1640,6 @@ async function describeFolder(dir, base, fallbackLabel, labelFrom = prettify) {
|
|
|
1602
1640
|
...meta.description?.trim() ? { description: meta.description.trim() } : {},
|
|
1603
1641
|
...meta.author?.trim() ? { author: meta.author.trim() } : {},
|
|
1604
1642
|
...meta.preview !== undefined ? { preview: meta.preview } : {},
|
|
1605
|
-
...meta.tokensFile?.trim() ? { tokensFile: meta.tokensFile.trim() } : {},
|
|
1606
1643
|
...styles.length > 0 ? { styles } : {},
|
|
1607
1644
|
carries: extensionCarries(meta),
|
|
1608
1645
|
dir
|
|
@@ -1626,15 +1663,14 @@ async function describeEntry(projectDir, raw) {
|
|
|
1626
1663
|
return withWarnings({ ...common, kind: "npm", name: raw.use, label: raw.use, carries: NO_CARRIES });
|
|
1627
1664
|
}
|
|
1628
1665
|
if (parsed.kind === "bundled") {
|
|
1629
|
-
const
|
|
1630
|
-
const rec = RECOMMENDED_EXTENSIONS.find((r) => r.use === bundledName);
|
|
1666
|
+
const bundled = bundledExtension(parsed.name);
|
|
1631
1667
|
return withWarnings({
|
|
1632
1668
|
...common,
|
|
1633
1669
|
kind: "bundled",
|
|
1634
|
-
name:
|
|
1635
|
-
label:
|
|
1636
|
-
|
|
1637
|
-
carries: { ...NO_CARRIES, markdown: true }
|
|
1670
|
+
name: parsed.name,
|
|
1671
|
+
label: bundled.label,
|
|
1672
|
+
description: bundled.description,
|
|
1673
|
+
carries: { ...NO_CARRIES, ...bundled.css !== undefined ? { styles: true } : { markdown: true } }
|
|
1638
1674
|
});
|
|
1639
1675
|
}
|
|
1640
1676
|
if (parsed.kind === "path") {
|
|
@@ -1779,9 +1815,10 @@ async function removeExtension(projectDir, use) {
|
|
|
1779
1815
|
return;
|
|
1780
1816
|
}
|
|
1781
1817
|
if (parsed.kind === "npm" && parsed.version) {
|
|
1782
|
-
const root
|
|
1783
|
-
|
|
1784
|
-
|
|
1818
|
+
for (const root of vendoredNpmPluginRoots(projectDir, parsed.name, parsed.version)) {
|
|
1819
|
+
await rm3(root, { recursive: true, force: true });
|
|
1820
|
+
await removeEmptyDirs([path4.dirname(root)]);
|
|
1821
|
+
}
|
|
1785
1822
|
}
|
|
1786
1823
|
});
|
|
1787
1824
|
}
|
|
@@ -1899,8 +1936,8 @@ async function vendorNpmExtension(projectDir, input, exportName, options, commit
|
|
|
1899
1936
|
});
|
|
1900
1937
|
try {
|
|
1901
1938
|
const { negated } = await ensureProjectGitignore(projectDir);
|
|
1902
|
-
if (negated.includes("
|
|
1903
|
-
warnings.push("Your .gitignore re-includes
|
|
1939
|
+
if (negated.includes("extensions/npm/")) {
|
|
1940
|
+
warnings.push("Your .gitignore re-includes extensions/npm/, so downloaded extensions will be committed with " + "your book. They shouldn't be: the manifest pins each version and a build downloads a " + "missing copy again.");
|
|
1904
1941
|
}
|
|
1905
1942
|
} catch (error) {
|
|
1906
1943
|
warnings.push(`The extension was installed, but .gitignore could not be updated to keep it out of version history: ` + `${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -1926,24 +1963,32 @@ async function pinnedVersionsOf(projectDir, name) {
|
|
|
1926
1963
|
return versions;
|
|
1927
1964
|
}
|
|
1928
1965
|
async function pruneStaleVersions(projectDir, name, keep) {
|
|
1929
|
-
const
|
|
1966
|
+
const parents = vendoredNpmPluginRoots(projectDir, name, "0.0.0").map((root) => path4.dirname(root));
|
|
1930
1967
|
try {
|
|
1931
|
-
for (const
|
|
1932
|
-
|
|
1933
|
-
continue;
|
|
1934
|
-
let version;
|
|
1968
|
+
for (const parent of parents) {
|
|
1969
|
+
let entries;
|
|
1935
1970
|
try {
|
|
1936
|
-
|
|
1937
|
-
} catch {
|
|
1938
|
-
|
|
1971
|
+
entries = await readdir(parent, { withFileTypes: true });
|
|
1972
|
+
} catch (error) {
|
|
1973
|
+
if (error.code === "ENOENT")
|
|
1974
|
+
continue;
|
|
1975
|
+
throw error;
|
|
1976
|
+
}
|
|
1977
|
+
for (const entry of entries) {
|
|
1978
|
+
if (!entry.isDirectory())
|
|
1979
|
+
continue;
|
|
1980
|
+
let version;
|
|
1981
|
+
try {
|
|
1982
|
+
version = decodeURIComponent(entry.name);
|
|
1983
|
+
} catch {
|
|
1984
|
+
continue;
|
|
1985
|
+
}
|
|
1986
|
+
if (!isExactNpmVersion(version) || keep.includes(version))
|
|
1987
|
+
continue;
|
|
1988
|
+
await rm3(path4.join(parent, entry.name), { recursive: true, force: true });
|
|
1939
1989
|
}
|
|
1940
|
-
if (!isExactNpmVersion(version) || keep.includes(version))
|
|
1941
|
-
continue;
|
|
1942
|
-
await rm3(path4.join(parent, entry.name), { recursive: true, force: true });
|
|
1943
1990
|
}
|
|
1944
1991
|
} catch (error) {
|
|
1945
|
-
if (error.code === "ENOENT")
|
|
1946
|
-
return [];
|
|
1947
1992
|
return [
|
|
1948
1993
|
`The extension was installed, but a previous version's downloaded copy could not be removed: ` + `${error instanceof Error ? error.message : String(error)}`
|
|
1949
1994
|
];
|
|
@@ -2029,18 +2074,13 @@ async function updateExtensions(projectDir, options = {}) {
|
|
|
2029
2074
|
}
|
|
2030
2075
|
return updated;
|
|
2031
2076
|
}
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
name: prettify(meta.name?.trim() || id),
|
|
2040
|
-
description: meta.description?.trim() || ""
|
|
2041
|
-
});
|
|
2042
|
-
}
|
|
2043
|
-
return out;
|
|
2077
|
+
function listBundledExtensions() {
|
|
2078
|
+
return BUNDLED_EXTENSIONS.map((b) => ({
|
|
2079
|
+
use: b.name,
|
|
2080
|
+
label: b.label,
|
|
2081
|
+
description: b.description,
|
|
2082
|
+
look: b.css !== undefined
|
|
2083
|
+
}));
|
|
2044
2084
|
}
|
|
2045
2085
|
async function uniqueExtensionId(projectDir, base) {
|
|
2046
2086
|
const slug = slugify(base) || "extension";
|
|
@@ -2050,20 +2090,6 @@ async function uniqueExtensionId(projectDir, base) {
|
|
|
2050
2090
|
}
|
|
2051
2091
|
return candidate;
|
|
2052
2092
|
}
|
|
2053
|
-
async function addBuiltInStyleSet(projectDir, id) {
|
|
2054
|
-
if (!BUILT_IN_STYLE_SET_IDS.includes(id)) {
|
|
2055
|
-
throw new Error(`Unknown built-in look "${id}" (one of: ${BUILT_IN_STYLE_SET_IDS.join(", ")}).`);
|
|
2056
|
-
}
|
|
2057
|
-
return withMutationLock(projectDir, async () => {
|
|
2058
|
-
const dest = path4.join(projectDir, EXTENSIONS_DIR, id);
|
|
2059
|
-
if (!existsSync3(dest)) {
|
|
2060
|
-
const src = path4.join(await getAssetsDir(), "themes", id);
|
|
2061
|
-
await mkdir3(path4.dirname(dest), { recursive: true });
|
|
2062
|
-
await cp(src, dest, { recursive: true });
|
|
2063
|
-
}
|
|
2064
|
-
return addExtensionUnlocked(projectDir, `./${EXTENSIONS_DIR}/${id}`, {});
|
|
2065
|
-
});
|
|
2066
|
-
}
|
|
2067
2093
|
async function validateProjectExtensions(projectDir) {
|
|
2068
2094
|
const out = [];
|
|
2069
2095
|
for (const entry of await listProjectExtensions(projectDir)) {
|
|
@@ -2087,19 +2113,25 @@ async function validateProjectExtensions(projectDir) {
|
|
|
2087
2113
|
return out;
|
|
2088
2114
|
}
|
|
2089
2115
|
async function readExtensionCss(projectDir, use) {
|
|
2116
|
+
const direct = bundledExtension(use)?.css;
|
|
2117
|
+
if (direct !== undefined)
|
|
2118
|
+
return direct;
|
|
2090
2119
|
const entry = await describeExtension(projectDir, use);
|
|
2091
2120
|
if (!entry)
|
|
2092
2121
|
throw new Error(`Extension "${use}" is not in the manifest.`);
|
|
2122
|
+
return readEntryCss(entry);
|
|
2123
|
+
}
|
|
2124
|
+
async function readEntryCss(entry) {
|
|
2125
|
+
const direct = bundledExtension(entry.use)?.css;
|
|
2126
|
+
if (direct !== undefined)
|
|
2127
|
+
return direct;
|
|
2093
2128
|
if (!entry.dir)
|
|
2094
|
-
throw new Error(`Extension "${use}" has no stylesheets to preview.`);
|
|
2129
|
+
throw new Error(`Extension "${entry.use}" has no stylesheets to preview.`);
|
|
2095
2130
|
const meta = await readExtensionMeta(entry.dir);
|
|
2096
|
-
const sheets = resolveExtension(entry.dir, meta, `Extension "${use}"`).styles ?? [];
|
|
2131
|
+
const sheets = resolveExtension(entry.dir, meta, `Extension "${entry.use}"`).styles ?? [];
|
|
2097
2132
|
if (sheets.length === 0)
|
|
2098
|
-
throw new Error(`Extension "${use}" declares no stylesheets.`);
|
|
2099
|
-
|
|
2100
|
-
for (const sheet of sheets)
|
|
2101
|
-
parts.push(await readFile5(sheet, "utf8"));
|
|
2102
|
-
return parts.join(`
|
|
2133
|
+
throw new Error(`Extension "${entry.use}" declares no stylesheets.`);
|
|
2134
|
+
return (await Promise.all(sheets.map((sheet) => readFile5(sheet, "utf8")))).join(`
|
|
2103
2135
|
|
|
2104
2136
|
`);
|
|
2105
2137
|
}
|
|
@@ -2221,4 +2253,4 @@ async function restoreForCommand(dir, options) {
|
|
|
2221
2253
|
log.warn(problem);
|
|
2222
2254
|
}
|
|
2223
2255
|
|
|
2224
|
-
export {
|
|
2256
|
+
export { isPositivePoints, isNonNegativePoints, round3, cssLength, formatPageSize, printAreaMeta, pageBoxes, judgeRect, DEBOUNCE, UsageError, resolvePort, PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, resolveTargets, applyDefaultPdfStrictChecks, MANIFEST_FILENAMES, hasProjectManifest, loadManifest, loadManifestWithPath, resolveConfig, resolveConfigForTarget, MARGIN_EDGES, validatePageMargin, FriendlyHttpError, withFetchTimeout, loadManifestDoc, writeManifestDoc, scalarString, DEFAULT_NPM_REGISTRY, npmRegistryUrl, ensureProjectGitignore, sameExtension, listProjectExtensions, describeExtension, extensionConfigFor, setExtensionEnabled, reorderExtensions, removeExtension, addExtension, listNpmVersions, checkExtensionUpdates, updateExtensions, listBundledExtensions, uniqueExtensionId, validateProjectExtensions, readExtensionCss, readEntryCss, restorePinnedExtensions, restoreFailureMessage, restoreOfflineMessage, restoreForCommand };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
EXTENSIONS_DIR,
|
|
3
|
+
LEGACY_PLUGINS_DIR,
|
|
3
4
|
VENDORED_NPM_DIR
|
|
4
|
-
} from "./index-
|
|
5
|
+
} from "./index-5x42amh8.js";
|
|
5
6
|
import {
|
|
6
7
|
capabilitiesFor,
|
|
7
8
|
detectProjectSource,
|
|
@@ -562,10 +563,10 @@ async function countUnversionedChanges(projectDir) {
|
|
|
562
563
|
return null;
|
|
563
564
|
const dir = gitScopeFor(source);
|
|
564
565
|
const bookPrefix = source.subPath ? `${source.subPath.replace(/\/+$/, "")}/` : "";
|
|
565
|
-
const appWritten = `${bookPrefix}${
|
|
566
|
+
const appWritten = [EXTENSIONS_DIR, LEGACY_PLUGINS_DIR].map((d) => `${bookPrefix}${d}/${VENDORED_NPM_DIR}/`);
|
|
566
567
|
return withRepoLock(dir, async () => {
|
|
567
568
|
const { adds, removes } = await listWorkdirChanges(dir);
|
|
568
|
-
const mine = new Set([...adds, ...removes].filter((f) => f.startsWith(bookPrefix) && !f.startsWith(
|
|
569
|
+
const mine = new Set([...adds, ...removes].filter((f) => f.startsWith(bookPrefix) && !appWritten.some((p) => f.startsWith(p))));
|
|
569
570
|
return { changedFiles: mine.size, stale: gitFs.existsSync(snapshotStagingMarkerPath(dir)) };
|
|
570
571
|
});
|
|
571
572
|
}
|