gutterpress 0.11.23-alpha.1 → 0.11.23-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/README.md +21 -22
- package/dist/api/index.d.ts +4 -4
- package/dist/api/index.js +16 -22
- package/dist/{build-09cd1n7s.js → build-encgnv0c.js} +9 -10
- package/dist/{cli-habkc5ng.js → cli-a35w7wzg.js} +5 -4
- package/dist/{cli-b0vyjvmt.js → cli-aqh6brew.js} +1 -1
- package/dist/{cli-ccp7sxz3.js → cli-evg8sbht.js} +1 -1
- package/dist/{cli-nr6j6300.js → cli-kh8v4vvw.js} +1 -1
- package/dist/{cli-h17e3mtz.js → cli-pwwfxdgb.js} +385 -10
- package/dist/{cli-dtckwda1.js → cli-pz4bn98t.js} +185 -9
- package/dist/{cli-dd115fa8.js → cli-sdmv4bba.js} +47 -123
- package/dist/{cli-5hkmp2wy.js → cli-xq6djqbj.js} +55 -88
- package/dist/{index-r7jcsk6h.js → cli-y28j019d.js} +19 -10
- package/dist/cli.js +12 -12
- package/dist/{doctor-nddspx4n.js → doctor-5gtpgpd1.js} +3 -3
- package/dist/{engine-892swzzc.js → engine-mc5br8g8.js} +1 -2
- package/dist/{engine-yjzknt0g.js → engine-tn13gk0b.js} +3 -3
- package/dist/{ext-zjpen4yx.js → ext-wn2a5afq.js} +18 -33
- package/dist/{extension-restore-w8xt4kbq.js → extension-restore-g8jnmmzq.js} +5 -6
- package/dist/{extension-restore-jvs60x9b.js → extension-restore-s3x1618g.js} +4 -4
- package/dist/{index-apc8w9w8.js → index-0skhjx3e.js} +180 -1
- package/dist/{index-2jpk25en.js → index-2bjcghze.js} +385 -10
- package/dist/index-46ycxe6r.js +18 -0
- package/dist/{index-0w2azsk1.js → index-4x6y8krm.js} +2 -4
- package/dist/{cli-h3phdstf.js → index-5x42amh8.js} +19 -10
- package/dist/{index-93pqkvty.js → index-h6yk5tjx.js} +5 -4
- package/dist/{index-zrhyb967.js → index-j5z86r4a.js} +335 -349
- package/dist/{index-m4hhzg3c.js → index-x3ema2w3.js} +59 -134
- package/dist/index.js +17 -23
- package/dist/lib/extension-manager.d.ts +16 -43
- package/dist/lib/extension-scaffold.d.ts +3 -3
- package/dist/lib/extension-specifier.d.ts +23 -6
- package/dist/lib/markdown/math.d.ts +1 -1
- package/dist/lib/npm-plugin-installer.d.ts +1 -1
- package/dist/lib/plugin-vendor.d.ts +11 -3
- 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 +0 -3
- package/dist/lib/snippets.d.ts +2 -1
- package/dist/lib/style-resolver.d.ts +1 -2
- package/dist/{manifest-8f10dr4f.yaml → manifest-eagfhba6.yaml} +2 -0
- package/dist/{manifest.schema-9aeaered.json → manifest.schema-t7nx2stg.json} +5 -5
- package/dist/{new-xhq8wczn.js → new-mhs46pw3.js} +22 -21
- package/dist/{plugins-9en8m9y0.js → plugins-1sxe0dkz.js} +4 -4
- package/dist/{plugins-gf0gkjmv.js → plugins-2cek4mz1.js} +2 -2
- package/dist/{preflight-negnxg7b.js → preflight-3k2b1x8e.js} +9 -10
- package/dist/{preview-cep2s9cg.js → preview-6p9v6rht.js} +9 -10
- package/dist/{publish-xery6qc6.js → publish-qgsngy8s.js} +9 -10
- 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/{validate-3d0sgf4g.js → validate-0v7xw6wa.js} +9 -10
- package/package.json +1 -1
- package/dist/cli-fe43evmf.js +0 -212
- package/dist/index-dsvk7q6s.js +0 -229
- 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,28 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EXTENSION_MANIFEST_FILENAME,
|
|
3
3
|
TWO_VERSIONS_OPEN,
|
|
4
|
+
bundledExtension,
|
|
4
5
|
extensionCarries,
|
|
5
6
|
extensionStyleList,
|
|
7
|
+
isPathSpecifier,
|
|
6
8
|
loadPlugin,
|
|
9
|
+
parseExtensionSpecifier,
|
|
10
|
+
pinnedNpmSpecifier,
|
|
7
11
|
prettify,
|
|
8
12
|
readExtensionMeta,
|
|
9
13
|
slugify
|
|
10
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-pwwfxdgb.js";
|
|
11
15
|
import {
|
|
12
16
|
log
|
|
13
|
-
} from "./cli-
|
|
17
|
+
} from "./cli-aqh6brew.js";
|
|
14
18
|
import {
|
|
15
19
|
UsageError
|
|
16
20
|
} from "./cli-d8xjns66.js";
|
|
17
|
-
import {
|
|
18
|
-
getAssetsDir
|
|
19
|
-
} from "./cli-fe43evmf.js";
|
|
20
21
|
import {
|
|
21
22
|
BuildError,
|
|
22
23
|
EXIT_CODES
|
|
23
24
|
} from "./cli-46ycxe6r.js";
|
|
24
25
|
import {
|
|
25
|
-
|
|
26
|
+
EXTENSIONS_DIR,
|
|
26
27
|
VENDORED_NPM_DIR,
|
|
27
28
|
assertWindowsSafeRelativePath,
|
|
28
29
|
isExactNpmVersion,
|
|
@@ -31,8 +32,9 @@ import {
|
|
|
31
32
|
resolveVendoredPluginInstallRoot,
|
|
32
33
|
vendoredNpmPluginPackageDir,
|
|
33
34
|
vendoredNpmPluginRoot,
|
|
35
|
+
vendoredNpmPluginRoots,
|
|
34
36
|
windowsPathKey
|
|
35
|
-
} from "./cli-
|
|
37
|
+
} from "./cli-y28j019d.js";
|
|
36
38
|
import {
|
|
37
39
|
__require
|
|
38
40
|
} from "./cli-37x76zdn.js";
|
|
@@ -74,7 +76,7 @@ async function withFetchTimeout(options, run) {
|
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
// src/lib/extension-manager.ts
|
|
77
|
-
import {
|
|
79
|
+
import { readdir, readFile as readFile5, rm as rm3, stat } from "node:fs/promises";
|
|
78
80
|
import { existsSync as existsSync3 } from "node:fs";
|
|
79
81
|
import path4 from "node:path";
|
|
80
82
|
import { isSeq as isSeq2, isMap, isScalar, YAMLMap, Scalar } from "yaml";
|
|
@@ -92,44 +94,6 @@ import { existsSync, statSync } from "node:fs";
|
|
|
92
94
|
import { resolve, dirname } from "node:path";
|
|
93
95
|
import { parse as parseYaml, YAMLParseError } from "yaml";
|
|
94
96
|
|
|
95
|
-
// src/lib/extension-specifier.ts
|
|
96
|
-
var BUNDLED_EXTENSIONS = [
|
|
97
|
-
"markdown-it-mark",
|
|
98
|
-
"markdown-it-sub",
|
|
99
|
-
"markdown-it-sup",
|
|
100
|
-
"markdown-it-abbr",
|
|
101
|
-
"gutterpress-gfm-alerts",
|
|
102
|
-
"gutterpress-math"
|
|
103
|
-
];
|
|
104
|
-
function isBundledExtension(name) {
|
|
105
|
-
return BUNDLED_EXTENSIONS.includes(name);
|
|
106
|
-
}
|
|
107
|
-
function isPathSpecifier(use) {
|
|
108
|
-
return use.startsWith("./") || use.startsWith("../") || use.startsWith("/") || /^[a-zA-Z]:[\\/]/.test(use);
|
|
109
|
-
}
|
|
110
|
-
function parseExtensionSpecifier(use) {
|
|
111
|
-
const spec = use.trim();
|
|
112
|
-
if (!spec) {
|
|
113
|
-
throw new Error("An extension specifier is required — an npm package name, or a ./ path.");
|
|
114
|
-
}
|
|
115
|
-
if (isPathSpecifier(spec))
|
|
116
|
-
return { kind: "path", path: spec };
|
|
117
|
-
if (/\.(m?js|cjs)$/i.test(spec) || !spec.startsWith("@") && spec.includes("/")) {
|
|
118
|
-
throw new Error(`"${spec}" looks like a path; write it as "./${spec}". A specifier that does not ` + "start with ./, ../ or / is an npm package name.");
|
|
119
|
-
}
|
|
120
|
-
const parsed = parseNpmPluginSpec(spec);
|
|
121
|
-
if (isBundledExtension(parsed.name)) {
|
|
122
|
-
if (parsed.selector !== undefined) {
|
|
123
|
-
throw new Error(`"${parsed.name}" is bundled with Gutterpress and always resolves to the bundled copy — ` + `drop "@${parsed.selector}".`);
|
|
124
|
-
}
|
|
125
|
-
return { kind: "bundled", name: parsed.name };
|
|
126
|
-
}
|
|
127
|
-
return parsed.selector === undefined ? { kind: "npm", name: parsed.name } : { kind: "npm", name: parsed.name, version: parsed.selector };
|
|
128
|
-
}
|
|
129
|
-
function pinnedNpmSpecifier(name, version) {
|
|
130
|
-
return `${name}@${version}`;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
97
|
// src/lib/presets.ts
|
|
134
98
|
var PRESET_IDS = ["dtrpg", "book", "custom"];
|
|
135
99
|
var DTRPG_PRESET = {
|
|
@@ -1283,13 +1247,13 @@ async function removeEmptyDirs(dirs) {
|
|
|
1283
1247
|
}
|
|
1284
1248
|
}
|
|
1285
1249
|
async function prepareVendorParent(projectDir, name) {
|
|
1286
|
-
const
|
|
1287
|
-
const npm = path2.join(
|
|
1250
|
+
const extensions = path2.join(projectDir, EXTENSIONS_DIR);
|
|
1251
|
+
const npm = path2.join(extensions, VENDORED_NPM_DIR);
|
|
1288
1252
|
const packageParent = path2.dirname(vendoredNpmPluginRoot(projectDir, name, "0.0.0"));
|
|
1289
1253
|
await mkdir2(projectDir, { recursive: true });
|
|
1290
1254
|
const createdDirs = [];
|
|
1291
1255
|
try {
|
|
1292
|
-
for (const dir of [
|
|
1256
|
+
for (const dir of [extensions, npm, packageParent]) {
|
|
1293
1257
|
if (await ensureDirectory(dir))
|
|
1294
1258
|
createdDirs.push(dir);
|
|
1295
1259
|
}
|
|
@@ -1408,7 +1372,7 @@ function ignoreStatus(gitignore, entry) {
|
|
|
1408
1372
|
return "ignored";
|
|
1409
1373
|
return dir.unignored || file.unignored ? "negated" : "open";
|
|
1410
1374
|
}
|
|
1411
|
-
var PROJECT_GITIGNORE_ENTRIES = ["dist/", "
|
|
1375
|
+
var PROJECT_GITIGNORE_ENTRIES = ["dist/", "extensions/npm/"];
|
|
1412
1376
|
async function ensureProjectGitignore(projectDir) {
|
|
1413
1377
|
const gitignorePath = path3.join(projectDir, ".gitignore");
|
|
1414
1378
|
let existing = null;
|
|
@@ -1436,40 +1400,6 @@ async function ensureProjectGitignore(projectDir) {
|
|
|
1436
1400
|
}
|
|
1437
1401
|
|
|
1438
1402
|
// src/lib/extension-manager.ts
|
|
1439
|
-
var EXTENSIONS_DIR = "extensions";
|
|
1440
|
-
var RECOMMENDED_EXTENSIONS = [
|
|
1441
|
-
{
|
|
1442
|
-
use: "markdown-it-mark",
|
|
1443
|
-
label: "Highlight",
|
|
1444
|
-
description: "Highlight text by wrapping it in `==double equals==`."
|
|
1445
|
-
},
|
|
1446
|
-
{
|
|
1447
|
-
use: "markdown-it-sub",
|
|
1448
|
-
label: "Subscript",
|
|
1449
|
-
description: "Lower text below the line, like the 2 in `H~2~O`."
|
|
1450
|
-
},
|
|
1451
|
-
{
|
|
1452
|
-
use: "markdown-it-sup",
|
|
1453
|
-
label: "Superscript",
|
|
1454
|
-
description: "Raise text above the line, like the th in `29^th^`."
|
|
1455
|
-
},
|
|
1456
|
-
{
|
|
1457
|
-
use: "markdown-it-abbr",
|
|
1458
|
-
label: "Abbreviations",
|
|
1459
|
-
description: "Explain an abbreviation when readers hover over it. Define it once, like `*[GPS]: Global Positioning System`."
|
|
1460
|
-
},
|
|
1461
|
-
{
|
|
1462
|
-
use: "gutterpress-gfm-alerts",
|
|
1463
|
-
label: "Callouts",
|
|
1464
|
-
description: "Turn a quote into a boxed note: start it with `> [!NOTE]` (or `TIP`, `IMPORTANT`, `WARNING`, `CAUTION`)."
|
|
1465
|
-
},
|
|
1466
|
-
{
|
|
1467
|
-
use: "gutterpress-math",
|
|
1468
|
-
label: "Math",
|
|
1469
|
-
description: "Write LaTeX math between dollar signs: `$E = mc^2$` in a line, or `$$` … `$$` on lines of their own."
|
|
1470
|
-
}
|
|
1471
|
-
];
|
|
1472
|
-
var BUILT_IN_STYLE_SET_IDS = ["clean-book", "zine", "technical-doc", "academic"];
|
|
1473
1403
|
var mutationQueues = new Map;
|
|
1474
1404
|
function projectKey(projectDir) {
|
|
1475
1405
|
const resolved = path4.resolve(projectDir);
|
|
@@ -1585,15 +1515,14 @@ async function describeEntry(projectDir, raw) {
|
|
|
1585
1515
|
return withWarnings({ ...common, kind: "npm", name: raw.use, label: raw.use, carries: NO_CARRIES });
|
|
1586
1516
|
}
|
|
1587
1517
|
if (parsed.kind === "bundled") {
|
|
1588
|
-
const
|
|
1589
|
-
const rec = RECOMMENDED_EXTENSIONS.find((r) => r.use === bundledName);
|
|
1518
|
+
const bundled = bundledExtension(parsed.name);
|
|
1590
1519
|
return withWarnings({
|
|
1591
1520
|
...common,
|
|
1592
1521
|
kind: "bundled",
|
|
1593
|
-
name:
|
|
1594
|
-
label:
|
|
1595
|
-
|
|
1596
|
-
carries: { ...NO_CARRIES, markdown: true }
|
|
1522
|
+
name: parsed.name,
|
|
1523
|
+
label: bundled.label,
|
|
1524
|
+
description: bundled.description,
|
|
1525
|
+
carries: { ...NO_CARRIES, ...bundled.css !== undefined ? { styles: true } : { markdown: true } }
|
|
1597
1526
|
});
|
|
1598
1527
|
}
|
|
1599
1528
|
if (parsed.kind === "path") {
|
|
@@ -1715,9 +1644,10 @@ async function removeExtension(projectDir, use) {
|
|
|
1715
1644
|
return;
|
|
1716
1645
|
}
|
|
1717
1646
|
if (parsed.kind === "npm" && parsed.version) {
|
|
1718
|
-
const root
|
|
1719
|
-
|
|
1720
|
-
|
|
1647
|
+
for (const root of vendoredNpmPluginRoots(projectDir, parsed.name, parsed.version)) {
|
|
1648
|
+
await rm3(root, { recursive: true, force: true });
|
|
1649
|
+
await removeEmptyDirs([path4.dirname(root)]);
|
|
1650
|
+
}
|
|
1721
1651
|
}
|
|
1722
1652
|
});
|
|
1723
1653
|
}
|
|
@@ -1835,8 +1765,8 @@ async function vendorNpmExtension(projectDir, input, exportName, options, commit
|
|
|
1835
1765
|
});
|
|
1836
1766
|
try {
|
|
1837
1767
|
const { negated } = await ensureProjectGitignore(projectDir);
|
|
1838
|
-
if (negated.includes("
|
|
1839
|
-
warnings.push("Your .gitignore re-includes
|
|
1768
|
+
if (negated.includes("extensions/npm/")) {
|
|
1769
|
+
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.");
|
|
1840
1770
|
}
|
|
1841
1771
|
} catch (error) {
|
|
1842
1772
|
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)}`);
|
|
@@ -1862,24 +1792,32 @@ async function pinnedVersionsOf(projectDir, name) {
|
|
|
1862
1792
|
return versions;
|
|
1863
1793
|
}
|
|
1864
1794
|
async function pruneStaleVersions(projectDir, name, keep) {
|
|
1865
|
-
const
|
|
1795
|
+
const parents = vendoredNpmPluginRoots(projectDir, name, "0.0.0").map((root) => path4.dirname(root));
|
|
1866
1796
|
try {
|
|
1867
|
-
for (const
|
|
1868
|
-
|
|
1869
|
-
continue;
|
|
1870
|
-
let version;
|
|
1797
|
+
for (const parent of parents) {
|
|
1798
|
+
let entries;
|
|
1871
1799
|
try {
|
|
1872
|
-
|
|
1873
|
-
} catch {
|
|
1874
|
-
|
|
1800
|
+
entries = await readdir(parent, { withFileTypes: true });
|
|
1801
|
+
} catch (error) {
|
|
1802
|
+
if (error.code === "ENOENT")
|
|
1803
|
+
continue;
|
|
1804
|
+
throw error;
|
|
1805
|
+
}
|
|
1806
|
+
for (const entry of entries) {
|
|
1807
|
+
if (!entry.isDirectory())
|
|
1808
|
+
continue;
|
|
1809
|
+
let version;
|
|
1810
|
+
try {
|
|
1811
|
+
version = decodeURIComponent(entry.name);
|
|
1812
|
+
} catch {
|
|
1813
|
+
continue;
|
|
1814
|
+
}
|
|
1815
|
+
if (!isExactNpmVersion(version) || keep.includes(version))
|
|
1816
|
+
continue;
|
|
1817
|
+
await rm3(path4.join(parent, entry.name), { recursive: true, force: true });
|
|
1875
1818
|
}
|
|
1876
|
-
if (!isExactNpmVersion(version) || keep.includes(version))
|
|
1877
|
-
continue;
|
|
1878
|
-
await rm3(path4.join(parent, entry.name), { recursive: true, force: true });
|
|
1879
1819
|
}
|
|
1880
1820
|
} catch (error) {
|
|
1881
|
-
if (error.code === "ENOENT")
|
|
1882
|
-
return [];
|
|
1883
1821
|
return [
|
|
1884
1822
|
`The extension was installed, but a previous version's downloaded copy could not be removed: ` + `${error instanceof Error ? error.message : String(error)}`
|
|
1885
1823
|
];
|
|
@@ -1970,20 +1908,6 @@ async function uniqueExtensionId(projectDir, base) {
|
|
|
1970
1908
|
}
|
|
1971
1909
|
return candidate;
|
|
1972
1910
|
}
|
|
1973
|
-
async function addBuiltInStyleSet(projectDir, id) {
|
|
1974
|
-
if (!BUILT_IN_STYLE_SET_IDS.includes(id)) {
|
|
1975
|
-
throw new Error(`Unknown built-in look "${id}" (one of: ${BUILT_IN_STYLE_SET_IDS.join(", ")}).`);
|
|
1976
|
-
}
|
|
1977
|
-
return withMutationLock(projectDir, async () => {
|
|
1978
|
-
const dest = path4.join(projectDir, EXTENSIONS_DIR, id);
|
|
1979
|
-
if (!existsSync3(dest)) {
|
|
1980
|
-
const src = path4.join(await getAssetsDir(), "themes", id);
|
|
1981
|
-
await mkdir3(path4.dirname(dest), { recursive: true });
|
|
1982
|
-
await cp(src, dest, { recursive: true });
|
|
1983
|
-
}
|
|
1984
|
-
return addExtensionUnlocked(projectDir, `./${EXTENSIONS_DIR}/${id}`, {});
|
|
1985
|
-
});
|
|
1986
|
-
}
|
|
1987
1911
|
|
|
1988
1912
|
// src/lib/extension-restore.ts
|
|
1989
1913
|
var OFFLINE_REASON = "you appear to be offline (npm can't be reached)";
|
|
@@ -2102,4 +2026,4 @@ async function restoreForCommand(dir, options) {
|
|
|
2102
2026
|
log.warn(problem);
|
|
2103
2027
|
}
|
|
2104
2028
|
|
|
2105
|
-
export {
|
|
2029
|
+
export { PRESET_IDS, PRESETS, TARGETS, TARGET_IDS, publishTargetFor, resolveTargets, applyDefaultPdfStrictChecks, MANIFEST_FILENAMES, loadManifest, loadManifestWithPath, resolveConfig, resolveConfigForTarget, FriendlyHttpError, withFetchTimeout, loadManifestDoc, writeManifestDoc, npmRegistryUrl, ensureProjectGitignore, listProjectExtensions, setExtensionEnabled, removeExtension, addExtension, checkExtensionUpdates, updateExtensions, uniqueExtensionId, restorePinnedExtensions, restoreFailureMessage, restoreOfflineMessage, restoreForCommand };
|
|
@@ -8,16 +8,17 @@ import {
|
|
|
8
8
|
stampCreator,
|
|
9
9
|
stripAnnotations,
|
|
10
10
|
transparentPages
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-evg8sbht.js";
|
|
12
12
|
import {
|
|
13
13
|
blackTextToGray
|
|
14
14
|
} from "./cli-ht1bcqdd.js";
|
|
15
15
|
import {
|
|
16
16
|
MARGIN_BOX_IGNORED_PROPERTIES,
|
|
17
17
|
extract,
|
|
18
|
+
getAssetPath,
|
|
18
19
|
lastPageMode,
|
|
19
20
|
resolvePage
|
|
20
|
-
} from "./cli-
|
|
21
|
+
} from "./cli-pz4bn98t.js";
|
|
21
22
|
import {
|
|
22
23
|
countLinkAnnotations,
|
|
23
24
|
getImageResolutions,
|
|
@@ -42,20 +43,18 @@ import {
|
|
|
42
43
|
import {
|
|
43
44
|
hasUncommittedChanges,
|
|
44
45
|
listWorkdirChanges
|
|
45
|
-
} from "./cli-
|
|
46
|
+
} from "./cli-a35w7wzg.js";
|
|
46
47
|
import {
|
|
47
48
|
detectProjectSource,
|
|
48
49
|
repoSubPath
|
|
49
50
|
} from "./cli-v5mp7a6q.js";
|
|
50
51
|
import {
|
|
51
|
-
EXTENSIONS_DIR,
|
|
52
52
|
FriendlyHttpError,
|
|
53
53
|
MANIFEST_FILENAMES,
|
|
54
54
|
PRESETS,
|
|
55
55
|
PRESET_IDS,
|
|
56
56
|
TARGETS,
|
|
57
57
|
TARGET_IDS,
|
|
58
|
-
addBuiltInStyleSet,
|
|
59
58
|
addExtension,
|
|
60
59
|
applyDefaultPdfStrictChecks,
|
|
61
60
|
ensureProjectGitignore,
|
|
@@ -71,7 +70,7 @@ import {
|
|
|
71
70
|
uniqueExtensionId,
|
|
72
71
|
withFetchTimeout,
|
|
73
72
|
writeManifestDoc
|
|
74
|
-
} from "./cli-
|
|
73
|
+
} from "./cli-sdmv4bba.js";
|
|
75
74
|
import {
|
|
76
75
|
EXTENSION_MANIFEST_FILENAME,
|
|
77
76
|
GUTTERPRESS_CSS,
|
|
@@ -92,7 +91,7 @@ import {
|
|
|
92
91
|
readExtensionMeta,
|
|
93
92
|
resolveDeclaredStyles,
|
|
94
93
|
slugify
|
|
95
|
-
} from "./cli-
|
|
94
|
+
} from "./cli-pwwfxdgb.js";
|
|
96
95
|
import {
|
|
97
96
|
PACKAGE_META,
|
|
98
97
|
PACKAGE_VERSION,
|
|
@@ -102,22 +101,20 @@ import {
|
|
|
102
101
|
log,
|
|
103
102
|
setLogLevel,
|
|
104
103
|
warn
|
|
105
|
-
} from "./cli-
|
|
104
|
+
} from "./cli-aqh6brew.js";
|
|
106
105
|
import {
|
|
107
106
|
DEBOUNCE,
|
|
108
107
|
UsageError,
|
|
109
108
|
resolvePort
|
|
110
109
|
} from "./cli-d8xjns66.js";
|
|
111
|
-
import {
|
|
112
|
-
getAssetPath
|
|
113
|
-
} from "./cli-fe43evmf.js";
|
|
114
110
|
import {
|
|
115
111
|
BuildError
|
|
116
112
|
} from "./cli-46ycxe6r.js";
|
|
117
113
|
import {
|
|
114
|
+
EXTENSIONS_DIR,
|
|
118
115
|
resolveVendoredPluginInstallRoot,
|
|
119
116
|
vendoredNpmPluginPackageDir
|
|
120
|
-
} from "./cli-
|
|
117
|
+
} from "./cli-y28j019d.js";
|
|
121
118
|
import {
|
|
122
119
|
__require
|
|
123
120
|
} from "./cli-37x76zdn.js";
|
|
@@ -1818,13 +1815,7 @@ import { existsSync as existsSync3 } from "node:fs";
|
|
|
1818
1815
|
import { readdir } from "node:fs/promises";
|
|
1819
1816
|
import path from "node:path";
|
|
1820
1817
|
var STYLES_SUBDIR = "styles";
|
|
1821
|
-
var
|
|
1822
|
-
"styles/book.css",
|
|
1823
|
-
"css/print.css",
|
|
1824
|
-
"css/index.css",
|
|
1825
|
-
"css/style.css",
|
|
1826
|
-
"css/main.css"
|
|
1827
|
-
];
|
|
1818
|
+
var DEFAULT_STYLESHEET = "styles/book.css";
|
|
1828
1819
|
function relDisplay(projectDir, absPath) {
|
|
1829
1820
|
return path.relative(projectDir, absPath).split(path.sep).join("/");
|
|
1830
1821
|
}
|
|
@@ -1862,10 +1853,8 @@ async function resolveActiveStyles(projectDir, manifestStyles) {
|
|
|
1862
1853
|
const manifest = configured.filter((s) => typeof s === "string" && s.trim().length > 0);
|
|
1863
1854
|
if (manifest.length > 0)
|
|
1864
1855
|
return manifest;
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
return [rel];
|
|
1868
|
-
}
|
|
1856
|
+
if (existsSync3(path.join(projectDir, DEFAULT_STYLESHEET)))
|
|
1857
|
+
return [DEFAULT_STYLESHEET];
|
|
1869
1858
|
const discovered = await discoverCssFiles(projectDir);
|
|
1870
1859
|
if (discovered.length > 0) {
|
|
1871
1860
|
const first = discovered.map((abs) => relDisplay(projectDir, abs)).sort((a, b) => a.localeCompare(b))[0];
|
|
@@ -5217,7 +5206,7 @@ class PdfOutput {
|
|
|
5217
5206
|
const rawPdf = pdfxMode ? path7.join(stage, "raw.pdf") : path7.resolve(pdfFile);
|
|
5218
5207
|
await fsp2.mkdir(path7.dirname(path7.resolve(pdfFile)), { recursive: true });
|
|
5219
5208
|
log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
|
|
5220
|
-
const { buildNativePdf } = await import("./engine-
|
|
5209
|
+
const { buildNativePdf } = await import("./engine-mc5br8g8.js");
|
|
5221
5210
|
const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
|
|
5222
5211
|
title: config.title,
|
|
5223
5212
|
author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
|
|
@@ -5597,7 +5586,7 @@ function isGeneratedProjectPath(relative) {
|
|
|
5597
5586
|
const segment = segments[i];
|
|
5598
5587
|
if (segment === "dist" || segment === "node_modules")
|
|
5599
5588
|
return true;
|
|
5600
|
-
if (segment === "plugins" && segments[i + 1] === "npm")
|
|
5589
|
+
if ((segment === "extensions" || segment === "plugins") && segments[i + 1] === "npm")
|
|
5601
5590
|
return true;
|
|
5602
5591
|
}
|
|
5603
5592
|
return false;
|
|
@@ -6506,43 +6495,6 @@ async function startPreviewServer(options) {
|
|
|
6506
6495
|
};
|
|
6507
6496
|
}
|
|
6508
6497
|
|
|
6509
|
-
// src/lib/project-templates.ts
|
|
6510
|
-
import { isMap, isScalar, isSeq, parseDocument } from "yaml";
|
|
6511
|
-
var BUILT_IN_TEMPLATE_IDS = [
|
|
6512
|
-
"book",
|
|
6513
|
-
"zine",
|
|
6514
|
-
"technical",
|
|
6515
|
-
"paper"
|
|
6516
|
-
];
|
|
6517
|
-
var BUILT_IN_META = {
|
|
6518
|
-
book: {
|
|
6519
|
-
label: "Book",
|
|
6520
|
-
description: "A clean starting point for a novel, memoir, or any long-form book."
|
|
6521
|
-
},
|
|
6522
|
-
zine: {
|
|
6523
|
-
label: "Zine",
|
|
6524
|
-
description: "A short, personal zine made to be printed, folded, and shared."
|
|
6525
|
-
},
|
|
6526
|
-
technical: {
|
|
6527
|
-
label: "Technical document",
|
|
6528
|
-
description: "A manual or guide with steps, reference tables, and code examples."
|
|
6529
|
-
},
|
|
6530
|
-
paper: {
|
|
6531
|
-
label: "Academic paper",
|
|
6532
|
-
description: "A journal-style article with LaTeX math, numbered equations, figures, tables, notes and references.",
|
|
6533
|
-
look: "academic"
|
|
6534
|
-
}
|
|
6535
|
-
};
|
|
6536
|
-
var SKIP_ENTRIES = new Set([
|
|
6537
|
-
".git",
|
|
6538
|
-
"node_modules",
|
|
6539
|
-
"out",
|
|
6540
|
-
"dist",
|
|
6541
|
-
"build",
|
|
6542
|
-
".gutterpress",
|
|
6543
|
-
".DS_Store"
|
|
6544
|
-
]);
|
|
6545
|
-
|
|
6546
6498
|
// src/lib/project-scaffold.ts
|
|
6547
6499
|
import { access, copyFile, cp, mkdir as mkdir4, readdir as readdir5, readFile as readFile22, stat as stat4, writeFile as writeFile5 } from "node:fs/promises";
|
|
6548
6500
|
import { constants as FS, existsSync as existsSync7 } from "node:fs";
|
|
@@ -6550,10 +6502,10 @@ import path12 from "node:path";
|
|
|
6550
6502
|
|
|
6551
6503
|
// src/lib/page-size.ts
|
|
6552
6504
|
import postcss5 from "postcss";
|
|
6553
|
-
import { isMap
|
|
6505
|
+
import { isMap, Scalar } from "yaml";
|
|
6554
6506
|
function writePageBounds(doc, page) {
|
|
6555
6507
|
const tolerance = page.tolerance ?? numberAt(doc, ["page", "tolerance"]);
|
|
6556
|
-
if (!
|
|
6508
|
+
if (!isMap(doc.get("page", true)))
|
|
6557
6509
|
doc.set("page", doc.createNode({}));
|
|
6558
6510
|
doc.setIn(["page", "width"], page.width);
|
|
6559
6511
|
doc.setIn(["page", "height"], page.height);
|
|
@@ -6571,11 +6523,10 @@ function starterOverridesCss() {
|
|
|
6571
6523
|
* Your book's own styles.
|
|
6572
6524
|
*
|
|
6573
6525
|
* This file loads AFTER every extension, so any rule you add here overrides
|
|
6574
|
-
* a look's defaults. A new book has no look until
|
|
6575
|
-
*
|
|
6576
|
-
* gutterpress ext add
|
|
6577
|
-
* gutterpress ext add <package> <book>
|
|
6578
|
-
* A book has one look at a time; adding another turns the current one off.
|
|
6526
|
+
* a look's defaults. A new book has no look until its template or you add
|
|
6527
|
+
* one:
|
|
6528
|
+
* gutterpress ext add academic <book> (a built-in look)
|
|
6529
|
+
* gutterpress ext add <package> <book> (a look from npm)
|
|
6579
6530
|
*/
|
|
6580
6531
|
`;
|
|
6581
6532
|
}
|
|
@@ -6596,9 +6547,8 @@ function escapeYamlScalar(value) {
|
|
|
6596
6547
|
}
|
|
6597
6548
|
var DEFAULT_AUTHOR = "Anonymous";
|
|
6598
6549
|
function requirePreset(preset, customPage) {
|
|
6599
|
-
if (!
|
|
6600
|
-
|
|
6601
|
-
throw new CreateProjectErrorImpl("preset-required", `A preset is required to create a book${got}. Choose one of: ${PRESET_IDS.join(", ")}.`);
|
|
6550
|
+
if (!PRESET_IDS.includes(preset)) {
|
|
6551
|
+
throw new CreateProjectErrorImpl("preset-required", `Unknown preset "${preset}". Choose one of: ${PRESET_IDS.join(", ")}.`);
|
|
6602
6552
|
}
|
|
6603
6553
|
if (preset === "custom") {
|
|
6604
6554
|
const missing = [];
|
|
@@ -6656,7 +6606,7 @@ async function scaffoldProject(options) {
|
|
|
6656
6606
|
}
|
|
6657
6607
|
const template = options.template ?? "book";
|
|
6658
6608
|
const customTemplateDir = options.templateDir;
|
|
6659
|
-
const preset =
|
|
6609
|
+
const preset = options.preset === undefined ? undefined : requirePreset(options.preset, options.customPage);
|
|
6660
6610
|
const targets = preset ? resolveScaffoldTargets(options.targets, preset) : undefined;
|
|
6661
6611
|
try {
|
|
6662
6612
|
await mkdir4(projectDir, { recursive: true });
|
|
@@ -6694,13 +6644,12 @@ async function scaffoldProject(options) {
|
|
|
6694
6644
|
let openFile = path12.join(projectDir, "chapter-01.md");
|
|
6695
6645
|
try {
|
|
6696
6646
|
await fillTemplateFile(manifestPath, substitutions);
|
|
6697
|
-
|
|
6698
|
-
if (look)
|
|
6699
|
-
await addBuiltInStyleSet(projectDir, look);
|
|
6700
|
-
if (preset) {
|
|
6647
|
+
if (preset || options.customPage) {
|
|
6701
6648
|
const { doc, file } = await loadManifestDoc(projectDir);
|
|
6702
|
-
|
|
6703
|
-
|
|
6649
|
+
if (preset) {
|
|
6650
|
+
doc.set("preset", preset);
|
|
6651
|
+
doc.set("targets", doc.createNode(targets ?? []));
|
|
6652
|
+
}
|
|
6704
6653
|
if (options.customPage)
|
|
6705
6654
|
writePageBounds(doc, options.customPage);
|
|
6706
6655
|
await writeManifestDoc(file, doc);
|
|
@@ -6717,7 +6666,7 @@ async function scaffoldProject(options) {
|
|
|
6717
6666
|
let versionHistoryError;
|
|
6718
6667
|
if (requested === "local-git") {
|
|
6719
6668
|
try {
|
|
6720
|
-
const { providerFor } = await import("./source-provider-
|
|
6669
|
+
const { providerFor } = await import("./source-provider-knmcam50.js");
|
|
6721
6670
|
const provider = providerFor({ type: "local-folder", path: projectDir });
|
|
6722
6671
|
await provider.initVersionHistory({
|
|
6723
6672
|
projectDir,
|
|
@@ -6769,7 +6718,7 @@ async function fillTemplateFile(filePath, substitutions) {
|
|
|
6769
6718
|
import { access as access2, mkdir as mkdir5, readFile as readFile23, writeFile as writeFile6 } from "node:fs/promises";
|
|
6770
6719
|
import { constants as FS2 } from "node:fs";
|
|
6771
6720
|
import path13 from "node:path";
|
|
6772
|
-
var EXTENSION_KINDS = ["plugin", "
|
|
6721
|
+
var EXTENSION_KINDS = ["plugin", "look"];
|
|
6773
6722
|
var RESERVED_PREFIX = "gp-";
|
|
6774
6723
|
var TEMPLATE_FILES = {
|
|
6775
6724
|
plugin: [
|
|
@@ -6782,7 +6731,7 @@ var TEMPLATE_FILES = {
|
|
|
6782
6731
|
["test/expected.html", "test/expected.html"],
|
|
6783
6732
|
["test/plugin.test.js.tpl", "test/plugin.test.js"]
|
|
6784
6733
|
],
|
|
6785
|
-
|
|
6734
|
+
look: [
|
|
6786
6735
|
["package.json", "package.json"],
|
|
6787
6736
|
["README.md", "README.md"],
|
|
6788
6737
|
["components.yaml", "components.yaml"],
|
|
@@ -6797,11 +6746,11 @@ var TEMPLATE_FILES = {
|
|
|
6797
6746
|
};
|
|
6798
6747
|
var OPEN_FILE = {
|
|
6799
6748
|
plugin: "plugin.js",
|
|
6800
|
-
|
|
6749
|
+
look: "styles/tokens.css"
|
|
6801
6750
|
};
|
|
6802
6751
|
var DEFAULT_DESCRIPTION = {
|
|
6803
6752
|
plugin: "A Gutterpress plugin.",
|
|
6804
|
-
|
|
6753
|
+
look: "A Gutterpress look."
|
|
6805
6754
|
};
|
|
6806
6755
|
var DEFAULT_AUTHOR2 = "Anonymous";
|
|
6807
6756
|
|
|
@@ -6833,7 +6782,7 @@ function escapeJsonScalar(value) {
|
|
|
6833
6782
|
}
|
|
6834
6783
|
async function scaffoldExtension(options) {
|
|
6835
6784
|
const kind = options.kind;
|
|
6836
|
-
if (kind !== "plugin" && kind !== "
|
|
6785
|
+
if (kind !== "plugin" && kind !== "look") {
|
|
6837
6786
|
throw new ExtensionScaffoldError("invalid-name", `Unknown extension kind "${String(kind)}". Choose one of: ${EXTENSION_KINDS.join(", ")}.`);
|
|
6838
6787
|
}
|
|
6839
6788
|
const name = (options.name ?? "").trim();
|
|
@@ -6909,6 +6858,24 @@ function substitute(text, table) {
|
|
|
6909
6858
|
return out;
|
|
6910
6859
|
}
|
|
6911
6860
|
|
|
6861
|
+
// src/lib/project-templates.ts
|
|
6862
|
+
import { isMap as isMap2, isScalar, isSeq, parseDocument } from "yaml";
|
|
6863
|
+
var BUILT_IN_TEMPLATE_IDS = [
|
|
6864
|
+
"book",
|
|
6865
|
+
"zine",
|
|
6866
|
+
"technical",
|
|
6867
|
+
"paper"
|
|
6868
|
+
];
|
|
6869
|
+
var SKIP_ENTRIES = new Set([
|
|
6870
|
+
".git",
|
|
6871
|
+
"node_modules",
|
|
6872
|
+
"out",
|
|
6873
|
+
"dist",
|
|
6874
|
+
"build",
|
|
6875
|
+
".gutterpress",
|
|
6876
|
+
".DS_Store"
|
|
6877
|
+
]);
|
|
6878
|
+
|
|
6912
6879
|
// src/lib/extension-import.ts
|
|
6913
6880
|
import { existsSync as existsSync8 } from "node:fs";
|
|
6914
6881
|
import { cp as cp2, mkdir as mkdir6, mkdtemp, readFile as readFile24, rm, writeFile as writeFile7 } from "node:fs/promises";
|
|
@@ -9053,7 +9020,7 @@ async function resolvePublishProvider(id, book) {
|
|
|
9053
9020
|
const ext = await bookExtensions(book);
|
|
9054
9021
|
const npmEntry = ext.extensions.some((c) => !c.path && c.name === id);
|
|
9055
9022
|
if (npmEntry) {
|
|
9056
|
-
const { restoreForCommand: restoreForCommand2 } = await import("./extension-restore-
|
|
9023
|
+
const { restoreForCommand: restoreForCommand2 } = await import("./extension-restore-g8jnmmzq.js");
|
|
9057
9024
|
await restoreForCommand2(book.projectDir, { manifestPath: book.manifestPath, failFast: true });
|
|
9058
9025
|
}
|
|
9059
9026
|
const publishers = await discover(ext);
|
|
@@ -9091,7 +9058,7 @@ function infoFor(p) {
|
|
|
9091
9058
|
}
|
|
9092
9059
|
function pluginProvider(p) {
|
|
9093
9060
|
let loading;
|
|
9094
|
-
const load = () => loading ??= import("./plugins-
|
|
9061
|
+
const load = () => loading ??= import("./plugins-1sxe0dkz.js").then((m) => m.loadPublishFunction(p));
|
|
9095
9062
|
return {
|
|
9096
9063
|
info: infoFor(p),
|
|
9097
9064
|
async authenticate() {
|
|
@@ -9578,4 +9545,4 @@ function normalizeProjectKey(projectDir) {
|
|
|
9578
9545
|
}
|
|
9579
9546
|
// src/lib/publish/manifest-publish.ts
|
|
9580
9547
|
import { isMap as isMap4 } from "yaml";
|
|
9581
|
-
export { reportMissingTools, executeValidation, executeAndReport, splitOutPath, runBuild, openPath, startPreviewServer,
|
|
9548
|
+
export { reportMissingTools, executeValidation, executeAndReport, splitOutPath, runBuild, openPath, startPreviewServer, scaffoldProject, EXTENSION_KINDS, scaffoldExtension, BUILT_IN_TEMPLATE_IDS, importExtensionFromFile, importExtensionFromUrl, searchNpmExtensions, publishCredentialKey, publishConnectionStatus, listPublishAccounts, connectGoogleDrive, listBookPublishProviders, resolvePublishProvider, resolvePublishFormat, runPublish, connectPublishProvider, disconnectPublishCredential };
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { lstat, readFile, realpath } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { exports as resolveExports } from "resolve.exports";
|
|
5
|
-
var
|
|
5
|
+
var EXTENSIONS_DIR = "extensions";
|
|
6
|
+
var LEGACY_PLUGINS_DIR = "plugins";
|
|
6
7
|
var VENDORED_NPM_DIR = "npm";
|
|
7
8
|
var NPM_SEGMENT = /^[a-z0-9][a-z0-9._~-]*$/;
|
|
8
9
|
var EXACT_VERSION = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
@@ -51,7 +52,10 @@ function encodePathPart(value) {
|
|
|
51
52
|
return encodeURIComponent(value).replace(/[!'()*]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
52
53
|
}
|
|
53
54
|
function vendoredNpmPluginRoot(projectDir, name, version) {
|
|
54
|
-
return path.join(projectDir,
|
|
55
|
+
return path.join(projectDir, EXTENSIONS_DIR, VENDORED_NPM_DIR, encodePathPart(name), encodePathPart(version));
|
|
56
|
+
}
|
|
57
|
+
function vendoredNpmPluginRoots(projectDir, name, version) {
|
|
58
|
+
return [EXTENSIONS_DIR, LEGACY_PLUGINS_DIR].map((parent) => path.join(projectDir, parent, VENDORED_NPM_DIR, encodePathPart(name), encodePathPart(version)));
|
|
55
59
|
}
|
|
56
60
|
function vendoredNpmPluginPackageDir(installRoot, name) {
|
|
57
61
|
return path.join(installRoot, "node_modules", ...name.split("/"));
|
|
@@ -175,15 +179,20 @@ async function resolvePackageEntry(packageDir, packageJson) {
|
|
|
175
179
|
}
|
|
176
180
|
async function resolveVendoredPluginInstallRoot(projectDir, expectedName, expectedVersion) {
|
|
177
181
|
const requestedProjectRoot = path.resolve(projectDir);
|
|
178
|
-
|
|
182
|
+
let requestedInstallRoot = "";
|
|
179
183
|
let installInfo;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
184
|
+
for (const candidate of vendoredNpmPluginRoots(requestedProjectRoot, expectedName, expectedVersion)) {
|
|
185
|
+
requestedInstallRoot = candidate;
|
|
186
|
+
try {
|
|
187
|
+
installInfo = await lstat(requestedInstallRoot);
|
|
188
|
+
break;
|
|
189
|
+
} catch (error) {
|
|
190
|
+
if (error.code !== "ENOENT")
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
186
193
|
}
|
|
194
|
+
if (!installInfo)
|
|
195
|
+
return null;
|
|
187
196
|
if (!installInfo.isDirectory() || installInfo.isSymbolicLink()) {
|
|
188
197
|
throw new Error("Vendor install root is not a normal directory.");
|
|
189
198
|
}
|
|
@@ -197,4 +206,4 @@ async function resolveVendoredPluginInstallRoot(projectDir, expectedName, expect
|
|
|
197
206
|
return installRoot;
|
|
198
207
|
}
|
|
199
208
|
|
|
200
|
-
export {
|
|
209
|
+
export { EXTENSIONS_DIR, LEGACY_PLUGINS_DIR, VENDORED_NPM_DIR, isValidNpmPackageName, parseNpmPluginSpec, isExactNpmVersion, vendoredNpmPluginRoot, vendoredNpmPluginRoots, vendoredNpmPluginPackageDir, assertWindowsSafeRelativePath, windowsPathKey, packageResolutionTargets, safePackageTarget, resolvePackageEntry, resolveVendoredPluginInstallRoot };
|