gutterpress 0.11.23-beta.1 → 0.11.23-beta.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 +13 -3
- package/dist/api/index.d.ts +5 -5
- package/dist/api/index.js +19 -7
- package/dist/{build-dg8a566j.js → build-fq3mexhy.js} +9 -9
- package/dist/checks/asset/approved-fonts.d.ts +8 -0
- package/dist/checks/asset/extensions.d.ts +1 -1
- package/dist/checks/asset/index.d.ts +1 -0
- package/dist/{cli-e31jshz6.js → cli-5zbdb6mt.js} +296 -65
- package/dist/{cli-ttj95aex.js → cli-7mt0dftw.js} +47 -18
- package/dist/{cli-989eg8jz.js → cli-ah93yyzb.js} +163 -55
- package/dist/{cli-31anr0r9.js → cli-eymdsefg.js} +69 -29
- package/dist/{cli-1fy1pm9d.js → cli-fh685nqs.js} +1 -1
- package/dist/{cli-k087gj0p.js → cli-fsjre61x.js} +123 -12
- package/dist/{cli-s1zt779w.js → cli-q7t04gjt.js} +1 -1
- package/dist/{cli-vhav8g82.js → cli-rybz2dfs.js} +1 -1
- package/dist/cli.js +12 -12
- package/dist/{doctor-g4a42tcz.js → doctor-tg9ht1n3.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-17v87vq5.js} +1 -1
- package/dist/{engine-wgkaqjsc.js → engine-y9fnarfa.js} +2 -2
- package/dist/{ext-w9d5ftcg.js → ext-esz03jz4.js} +27 -10
- package/dist/{extension-restore-5x4mj79d.js → extension-restore-91gy1e28.js} +3 -3
- package/dist/{extension-restore-as0g38p1.js → extension-restore-q70wqah5.js} +5 -5
- 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-a4j3xcfp.js → index-67g8f7r4.js} +47 -18
- package/dist/{index-798jt0qc.js → index-d9w3r89w.js} +3 -3
- package/dist/{index-rj5vrhz6.js → index-fntpr44x.js} +321 -66
- package/dist/{index-5x42amh8.js → index-g3te5ey1.js} +2 -1
- package/dist/{index-cw03e9p4.js → index-kw4tbthz.js} +69 -29
- package/dist/{index-fk2kpf2t.js → index-santcs4q.js} +121 -10
- package/dist/{index-c6y0p7jy.js → index-z6vzj3s5.js} +243 -73
- package/dist/index.js +35 -8
- package/dist/lib/check-options.d.ts +70 -0
- package/dist/lib/extension-manager.d.ts +16 -1
- package/dist/lib/extension-scaffold.d.ts +15 -2
- package/dist/lib/extension-specifier.d.ts +8 -1
- package/dist/lib/manifest-config.d.ts +3 -1
- package/dist/lib/manifest-old-spellings.d.ts +32 -9
- package/dist/lib/markdown/gutterpress-css.d.ts +1 -1
- package/dist/lib/markdown/math.d.ts +1 -1
- package/dist/lib/markdown/typography.d.ts +1 -0
- package/dist/lib/page-size.d.ts +12 -4
- package/dist/lib/plugin-vendor.d.ts +6 -0
- package/dist/lib/presets.d.ts +2 -2
- package/dist/lib/root-tokens.d.ts +2 -1
- package/dist/lib/source-provider.d.ts +27 -0
- package/dist/lib/style-resolver.d.ts +2 -1
- package/dist/lib/version-changes.d.ts +22 -6
- package/dist/{manifest.schema-0jgj0jt1.json → manifest.schema-5cm13vr3.json} +215 -5
- package/dist/{new-jtk028rf.js → new-rmfyb7va.js} +22 -15
- package/dist/{plugins-bcbe7xs8.js → plugins-gs21xz5s.js} +2 -2
- package/dist/{plugins-zsm6wv79.js → plugins-tqv1s16f.js} +4 -4
- package/dist/{preflight-cs6mj1d6.js → preflight-bjyeeq0d.js} +9 -9
- package/dist/{preview-d1j1g4qf.js → preview-ke03fk5d.js} +9 -9
- package/dist/{publish-7yw4jyrt.js → publish-wpnz0qng.js} +9 -9
- package/dist/render.js +55 -13
- package/dist/schema/manifest.types.d.ts +45 -7
- package/dist/{source-provider-n7vehh6t.js → source-provider-3g3yrn1f.js} +6 -2
- package/dist/{source-provider-tgzet3j5.js → source-provider-azg9ywhb.js} +6 -2
- package/dist/test-helpers/vocabulary.d.ts +12 -0
- package/dist/{validate-rkcdnzhw.js → validate-zcwykb43.js} +9 -9
- package/package.json +1 -1
- /package/dist/{cli-y28j019d.js → cli-1dha1nxk.js} +0 -0
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
stampCreator,
|
|
9
9
|
stripAnnotations,
|
|
10
10
|
transparentPages
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-rybz2dfs.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-fsjre61x.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-eymdsefg.js";
|
|
46
46
|
import {
|
|
47
47
|
detectProjectSource,
|
|
48
48
|
repoSubPath
|
|
@@ -66,10 +66,11 @@ import {
|
|
|
66
66
|
resolveConfigForTarget,
|
|
67
67
|
resolveTargets,
|
|
68
68
|
restoreForCommand,
|
|
69
|
+
setCheckOption,
|
|
69
70
|
uniqueExtensionId,
|
|
70
71
|
withFetchTimeout,
|
|
71
72
|
writeManifestDoc
|
|
72
|
-
} from "./cli-
|
|
73
|
+
} from "./cli-5zbdb6mt.js";
|
|
73
74
|
import {
|
|
74
75
|
EXTENSION_MANIFEST_FILENAME,
|
|
75
76
|
GUTTERPRESS_CSS,
|
|
@@ -90,7 +91,7 @@ import {
|
|
|
90
91
|
readExtensionMeta,
|
|
91
92
|
resolveDeclaredStyles,
|
|
92
93
|
slugify
|
|
93
|
-
} from "./cli-
|
|
94
|
+
} from "./cli-7mt0dftw.js";
|
|
94
95
|
import {
|
|
95
96
|
PACKAGE_META,
|
|
96
97
|
PACKAGE_VERSION,
|
|
@@ -100,7 +101,7 @@ import {
|
|
|
100
101
|
log,
|
|
101
102
|
setLogLevel,
|
|
102
103
|
warn
|
|
103
|
-
} from "./cli-
|
|
104
|
+
} from "./cli-fh685nqs.js";
|
|
104
105
|
import {
|
|
105
106
|
DEBOUNCE,
|
|
106
107
|
UsageError,
|
|
@@ -121,7 +122,7 @@ import {
|
|
|
121
122
|
EXTENSIONS_DIR,
|
|
122
123
|
resolveVendoredPluginInstallRoot,
|
|
123
124
|
vendoredNpmPluginPackageDir
|
|
124
|
-
} from "./cli-
|
|
125
|
+
} from "./cli-1dha1nxk.js";
|
|
125
126
|
import {
|
|
126
127
|
__require
|
|
127
128
|
} from "./cli-37x76zdn.js";
|
|
@@ -1740,7 +1741,13 @@ import { existsSync as existsSync3 } from "node:fs";
|
|
|
1740
1741
|
import { readdir } from "node:fs/promises";
|
|
1741
1742
|
import path from "node:path";
|
|
1742
1743
|
var STYLES_SUBDIR = "styles";
|
|
1743
|
-
var
|
|
1744
|
+
var FALLBACK_PRIORITY = [
|
|
1745
|
+
"styles/book.css",
|
|
1746
|
+
"css/print.css",
|
|
1747
|
+
"css/index.css",
|
|
1748
|
+
"css/style.css",
|
|
1749
|
+
"css/main.css"
|
|
1750
|
+
];
|
|
1744
1751
|
function relDisplay(projectDir, absPath) {
|
|
1745
1752
|
return path.relative(projectDir, absPath).split(path.sep).join("/");
|
|
1746
1753
|
}
|
|
@@ -1778,8 +1785,10 @@ async function resolveActiveStyles(projectDir, manifestStyles) {
|
|
|
1778
1785
|
const manifest = configured.filter((s) => typeof s === "string" && s.trim().length > 0);
|
|
1779
1786
|
if (manifest.length > 0)
|
|
1780
1787
|
return manifest;
|
|
1781
|
-
|
|
1782
|
-
|
|
1788
|
+
for (const rel of FALLBACK_PRIORITY) {
|
|
1789
|
+
if (existsSync3(path.join(projectDir, rel)))
|
|
1790
|
+
return [rel];
|
|
1791
|
+
}
|
|
1783
1792
|
const discovered = await discoverCssFiles(projectDir);
|
|
1784
1793
|
if (discovered.length > 0) {
|
|
1785
1794
|
const first = discovered.map((abs) => relDisplay(projectDir, abs)).sort((a, b) => a.localeCompare(b))[0];
|
|
@@ -3532,6 +3541,58 @@ var check30 = {
|
|
|
3532
3541
|
};
|
|
3533
3542
|
registerCheck(check30);
|
|
3534
3543
|
|
|
3544
|
+
// src/checks/asset/approved-fonts.ts
|
|
3545
|
+
var check31 = {
|
|
3546
|
+
id: "asset.font.approved-files",
|
|
3547
|
+
name: "Approved Font Files",
|
|
3548
|
+
description: "Checks font files against the approved file patterns",
|
|
3549
|
+
category: "asset",
|
|
3550
|
+
phase: "pre-build",
|
|
3551
|
+
async run(ctx) {
|
|
3552
|
+
const patterns = ctx.config.validate.assets.approvedFontFiles;
|
|
3553
|
+
if (!patterns || patterns.length === 0)
|
|
3554
|
+
return [];
|
|
3555
|
+
const { glob } = await import("glob");
|
|
3556
|
+
const dirs = ctx.assetDirs ?? [ctx.inputDir];
|
|
3557
|
+
const allFonts = [];
|
|
3558
|
+
for (const dir of dirs) {
|
|
3559
|
+
const matches = await glob(`**/*.{${FONT_EXTS2.join(",")}}`, {
|
|
3560
|
+
cwd: dir,
|
|
3561
|
+
absolute: true,
|
|
3562
|
+
ignore: [...ASSET_SCAN_IGNORE_GLOBS]
|
|
3563
|
+
});
|
|
3564
|
+
allFonts.push(...matches);
|
|
3565
|
+
}
|
|
3566
|
+
if (allFonts.length === 0)
|
|
3567
|
+
return [];
|
|
3568
|
+
const approvedFonts = new Set;
|
|
3569
|
+
for (const dir of dirs) {
|
|
3570
|
+
for (const pattern of patterns) {
|
|
3571
|
+
const matches = await glob(pattern, {
|
|
3572
|
+
cwd: dir,
|
|
3573
|
+
absolute: true,
|
|
3574
|
+
ignore: [...ASSET_SCAN_IGNORE_GLOBS]
|
|
3575
|
+
});
|
|
3576
|
+
for (const m of matches)
|
|
3577
|
+
approvedFonts.add(m);
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3580
|
+
const results = [];
|
|
3581
|
+
for (const font of allFonts) {
|
|
3582
|
+
if (!approvedFonts.has(font)) {
|
|
3583
|
+
results.push({
|
|
3584
|
+
checkId: check31.id,
|
|
3585
|
+
severity: "warning",
|
|
3586
|
+
message: "Font file not in approved list",
|
|
3587
|
+
file: font
|
|
3588
|
+
});
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
return results;
|
|
3592
|
+
}
|
|
3593
|
+
};
|
|
3594
|
+
registerCheck(check31);
|
|
3595
|
+
|
|
3535
3596
|
// src/checks/asset/font-license.ts
|
|
3536
3597
|
import { existsSync as existsSync5 } from "node:fs";
|
|
3537
3598
|
import { resolve as resolve3 } from "node:path";
|
|
@@ -3545,7 +3606,7 @@ var LICENSE_NAMES = [
|
|
|
3545
3606
|
"OFL-1.1.txt",
|
|
3546
3607
|
"COPYING"
|
|
3547
3608
|
];
|
|
3548
|
-
var
|
|
3609
|
+
var check32 = {
|
|
3549
3610
|
id: "asset.font.license",
|
|
3550
3611
|
name: "Font License",
|
|
3551
3612
|
description: "Checks for license files in font directories",
|
|
@@ -3570,7 +3631,7 @@ var check31 = {
|
|
|
3570
3631
|
const hasLicense = LICENSE_NAMES.some((name) => existsSync5(resolve3(fontDir, name)));
|
|
3571
3632
|
if (!hasLicense) {
|
|
3572
3633
|
results.push({
|
|
3573
|
-
checkId:
|
|
3634
|
+
checkId: check32.id,
|
|
3574
3635
|
severity: "warning",
|
|
3575
3636
|
message: `No font license file found in directory`,
|
|
3576
3637
|
file: fontDir
|
|
@@ -3580,10 +3641,10 @@ var check31 = {
|
|
|
3580
3641
|
return results;
|
|
3581
3642
|
}
|
|
3582
3643
|
};
|
|
3583
|
-
registerCheck(
|
|
3644
|
+
registerCheck(check32);
|
|
3584
3645
|
|
|
3585
3646
|
// src/checks/heuristic/text-density.ts
|
|
3586
|
-
var
|
|
3647
|
+
var check33 = {
|
|
3587
3648
|
id: "heuristic.whitespace.text-density",
|
|
3588
3649
|
name: "Text Density",
|
|
3589
3650
|
description: "Checks characters-per-page ratio",
|
|
@@ -3612,7 +3673,7 @@ var check32 = {
|
|
|
3612
3673
|
});
|
|
3613
3674
|
if (lowPages.length > 0) {
|
|
3614
3675
|
results.push({
|
|
3615
|
-
checkId:
|
|
3676
|
+
checkId: check33.id,
|
|
3616
3677
|
severity: "info",
|
|
3617
3678
|
message: `Low text density on pages: ${lowPages.join(", ")} (below ${range.min} chars)`,
|
|
3618
3679
|
file: ctx.pdfPath
|
|
@@ -3620,7 +3681,7 @@ var check32 = {
|
|
|
3620
3681
|
}
|
|
3621
3682
|
if (highPages.length > 0) {
|
|
3622
3683
|
results.push({
|
|
3623
|
-
checkId:
|
|
3684
|
+
checkId: check33.id,
|
|
3624
3685
|
severity: "info",
|
|
3625
3686
|
message: `High text density on pages: ${highPages.join(", ")} (above ${range.max} chars)`,
|
|
3626
3687
|
file: ctx.pdfPath
|
|
@@ -3629,11 +3690,11 @@ var check32 = {
|
|
|
3629
3690
|
return results;
|
|
3630
3691
|
}
|
|
3631
3692
|
};
|
|
3632
|
-
registerCheck(
|
|
3693
|
+
registerCheck(check33);
|
|
3633
3694
|
|
|
3634
3695
|
// src/checks/heuristic/section-density.ts
|
|
3635
3696
|
import { readFile as readFile15 } from "node:fs/promises";
|
|
3636
|
-
var
|
|
3697
|
+
var check34 = {
|
|
3637
3698
|
id: "heuristic.chunking.section-density",
|
|
3638
3699
|
name: "Section Density",
|
|
3639
3700
|
description: "Checks heading/paragraph/callout density from source Markdown",
|
|
@@ -3659,7 +3720,7 @@ var check33 = {
|
|
|
3659
3720
|
const line = lines[i];
|
|
3660
3721
|
if (/^#{1,6}\s/.test(line)) {
|
|
3661
3722
|
if (paragraphCount > maxParas) {
|
|
3662
|
-
results.push(finding(
|
|
3723
|
+
results.push(finding(check34.id, {
|
|
3663
3724
|
severity: "info",
|
|
3664
3725
|
message: `Section has ${paragraphCount} paragraphs (max recommended: ${maxParas})`,
|
|
3665
3726
|
file,
|
|
@@ -3679,7 +3740,7 @@ var check33 = {
|
|
|
3679
3740
|
}
|
|
3680
3741
|
}
|
|
3681
3742
|
if (paragraphCount > maxParas) {
|
|
3682
|
-
results.push(finding(
|
|
3743
|
+
results.push(finding(check34.id, {
|
|
3683
3744
|
severity: "info",
|
|
3684
3745
|
message: `Section has ${paragraphCount} paragraphs (max recommended: ${maxParas})`,
|
|
3685
3746
|
file,
|
|
@@ -3687,7 +3748,7 @@ var check33 = {
|
|
|
3687
3748
|
}));
|
|
3688
3749
|
}
|
|
3689
3750
|
} catch {
|
|
3690
|
-
results.push(inspectionFailed(
|
|
3751
|
+
results.push(inspectionFailed(check34.id, `Could not read source file: ${file}`, {
|
|
3691
3752
|
file
|
|
3692
3753
|
}));
|
|
3693
3754
|
}
|
|
@@ -3695,10 +3756,10 @@ var check33 = {
|
|
|
3695
3756
|
return results;
|
|
3696
3757
|
}
|
|
3697
3758
|
};
|
|
3698
|
-
registerCheck(
|
|
3759
|
+
registerCheck(check34);
|
|
3699
3760
|
|
|
3700
3761
|
// src/checks/heuristic/layer-count.ts
|
|
3701
|
-
var
|
|
3762
|
+
var check35 = {
|
|
3702
3763
|
id: "heuristic.decoration.layer-count",
|
|
3703
3764
|
name: "Layer Count",
|
|
3704
3765
|
description: "Counts image objects per page",
|
|
@@ -3723,7 +3784,7 @@ var check34 = {
|
|
|
3723
3784
|
heavyPages.sort((a, b) => a - b);
|
|
3724
3785
|
return [
|
|
3725
3786
|
{
|
|
3726
|
-
checkId:
|
|
3787
|
+
checkId: check35.id,
|
|
3727
3788
|
severity: "info",
|
|
3728
3789
|
message: `Pages with many image layers (>${maxLayers}): ${heavyPages.join(", ")}`,
|
|
3729
3790
|
file: ctx.pdfPath
|
|
@@ -3733,10 +3794,10 @@ var check34 = {
|
|
|
3733
3794
|
return [];
|
|
3734
3795
|
}
|
|
3735
3796
|
};
|
|
3736
|
-
registerCheck(
|
|
3797
|
+
registerCheck(check35);
|
|
3737
3798
|
|
|
3738
3799
|
// src/checks/heuristic/placement-variance.ts
|
|
3739
|
-
var
|
|
3800
|
+
var check36 = {
|
|
3740
3801
|
id: "heuristic.layout.placement-variance",
|
|
3741
3802
|
name: "Placement Variance",
|
|
3742
3803
|
description: "Analyzes text baseline coordinates for layout consistency",
|
|
@@ -3754,7 +3815,7 @@ var check35 = {
|
|
|
3754
3815
|
const uniqueX = new Set(positions.map((p) => Math.round(p.x)));
|
|
3755
3816
|
return [
|
|
3756
3817
|
{
|
|
3757
|
-
checkId:
|
|
3818
|
+
checkId: check36.id,
|
|
3758
3819
|
severity: "info",
|
|
3759
3820
|
message: `Layout analysis: ${uniqueX.size} unique horizontal text positions across ${positions.length} text blocks.`,
|
|
3760
3821
|
file: ctx.pdfPath
|
|
@@ -3762,21 +3823,21 @@ var check35 = {
|
|
|
3762
3823
|
];
|
|
3763
3824
|
}
|
|
3764
3825
|
};
|
|
3765
|
-
registerCheck(
|
|
3826
|
+
registerCheck(check36);
|
|
3766
3827
|
|
|
3767
3828
|
// src/checks/tool-check.ts
|
|
3768
3829
|
async function checkToolAvailability(config, opts = {}) {
|
|
3769
3830
|
const { checks: checks2 } = selectChecks(opts, config);
|
|
3770
3831
|
const toolToChecks = new Map;
|
|
3771
|
-
for (const
|
|
3772
|
-
if (!
|
|
3832
|
+
for (const check37 of checks2) {
|
|
3833
|
+
if (!check37.requiredTools?.length)
|
|
3773
3834
|
continue;
|
|
3774
|
-
for (const tool of
|
|
3835
|
+
for (const tool of check37.requiredTools) {
|
|
3775
3836
|
const existing = toolToChecks.get(tool);
|
|
3776
3837
|
if (existing) {
|
|
3777
|
-
existing.push(
|
|
3838
|
+
existing.push(check37.id);
|
|
3778
3839
|
} else {
|
|
3779
|
-
toolToChecks.set(tool, [
|
|
3840
|
+
toolToChecks.set(tool, [check37.id]);
|
|
3780
3841
|
}
|
|
3781
3842
|
}
|
|
3782
3843
|
}
|
|
@@ -3792,11 +3853,11 @@ async function checkToolAvailability(config, opts = {}) {
|
|
|
3792
3853
|
const missing = results.filter((r) => !r.found).map((r) => r.tool);
|
|
3793
3854
|
const missingSet = new Set(missing);
|
|
3794
3855
|
const skippedChecks = [];
|
|
3795
|
-
for (const
|
|
3796
|
-
if (!
|
|
3856
|
+
for (const check37 of checks2) {
|
|
3857
|
+
if (!check37.requiredTools?.length)
|
|
3797
3858
|
continue;
|
|
3798
|
-
if (
|
|
3799
|
-
skippedChecks.push(
|
|
3859
|
+
if (check37.requiredTools.some((t) => missingSet.has(t))) {
|
|
3860
|
+
skippedChecks.push(check37.id);
|
|
3800
3861
|
}
|
|
3801
3862
|
}
|
|
3802
3863
|
return { available, missing, skippedChecks, toolToChecks };
|
|
@@ -3939,6 +4000,14 @@ ${TABLE_ALIGN_CSS.trim()}`),
|
|
|
3939
4000
|
${pageGeometry}`)
|
|
3940
4001
|
];
|
|
3941
4002
|
}
|
|
4003
|
+
function resolveOldFootnoteLinks(html, ids) {
|
|
4004
|
+
if (ids.size === 0)
|
|
4005
|
+
return html;
|
|
4006
|
+
return html.replace(/ href=(["'])#(fn(?:ref)?\d+(?::\d+)?)\1/g, (link, quote, old) => {
|
|
4007
|
+
const id = ids.get(old);
|
|
4008
|
+
return id && !html.includes(` id="${old}"`) ? ` href=${quote}#${id}${quote}` : link;
|
|
4009
|
+
});
|
|
4010
|
+
}
|
|
3942
4011
|
async function assembleBookHtml(opts) {
|
|
3943
4012
|
const title = opts.title ?? "Document";
|
|
3944
4013
|
const projectCss = opts.projectCss ?? "";
|
|
@@ -3951,6 +4020,7 @@ async function assembleBookHtml(opts) {
|
|
|
3951
4020
|
const md = createMarkdownRenderer(opts.plugins, { language });
|
|
3952
4021
|
let bodyContent = "";
|
|
3953
4022
|
const imageRefs = new Set;
|
|
4023
|
+
const oldFootnoteIds = new Map;
|
|
3954
4024
|
for (const file of files) {
|
|
3955
4025
|
const chapterId = canonicalChapterId(file);
|
|
3956
4026
|
let content;
|
|
@@ -3969,9 +4039,14 @@ async function assembleBookHtml(opts) {
|
|
|
3969
4039
|
}
|
|
3970
4040
|
for (const ref of env.imageRefs ?? [])
|
|
3971
4041
|
imageRefs.add(ref);
|
|
4042
|
+
for (const [, kind, n] of rendered.matchAll(new RegExp(` id="(fn|fnref)-${env.docId}-(\\d+(?::\\d+)?)"`, "g"))) {
|
|
4043
|
+
if (!oldFootnoteIds.has(`${kind}${n}`))
|
|
4044
|
+
oldFootnoteIds.set(`${kind}${n}`, `${kind}-${env.docId}-${n}`);
|
|
4045
|
+
}
|
|
3972
4046
|
bodyContent += rendered + `
|
|
3973
4047
|
`;
|
|
3974
4048
|
}
|
|
4049
|
+
bodyContent = resolveOldFootnoteLinks(bodyContent, oldFootnoteIds);
|
|
3975
4050
|
if (opts.onImageRefs) {
|
|
3976
4051
|
for (const ref of collectHtmlImageRefs(bodyContent))
|
|
3977
4052
|
imageRefs.add(ref);
|
|
@@ -4231,25 +4306,25 @@ async function runChecks(ctx, opts = {}) {
|
|
|
4231
4306
|
}
|
|
4232
4307
|
const release = retainPdfCache();
|
|
4233
4308
|
try {
|
|
4234
|
-
for (const
|
|
4309
|
+
for (const check37 of checks2) {
|
|
4235
4310
|
try {
|
|
4236
|
-
const results = await
|
|
4237
|
-
const severityOverride = getCheckSeverityOverride(
|
|
4311
|
+
const results = await check37.run(ctx);
|
|
4312
|
+
const severityOverride = getCheckSeverityOverride(check37.id, ctx.config);
|
|
4238
4313
|
if (severityOverride) {
|
|
4239
4314
|
for (const r of results) {
|
|
4240
4315
|
r.severity = severityOverride;
|
|
4241
4316
|
}
|
|
4242
4317
|
}
|
|
4243
4318
|
if (results.length === 0) {
|
|
4244
|
-
passed.push(
|
|
4319
|
+
passed.push(check37.id);
|
|
4245
4320
|
} else {
|
|
4246
4321
|
allResults.push(...results);
|
|
4247
4322
|
}
|
|
4248
4323
|
} catch (err) {
|
|
4249
4324
|
allResults.push({
|
|
4250
|
-
checkId:
|
|
4325
|
+
checkId: check37.id,
|
|
4251
4326
|
severity: "error",
|
|
4252
|
-
message: `Check "${
|
|
4327
|
+
message: `Check "${check37.id}" threw: ${err instanceof Error ? err.message : String(err)}`
|
|
4253
4328
|
});
|
|
4254
4329
|
}
|
|
4255
4330
|
}
|
|
@@ -4559,7 +4634,7 @@ async function executeValidation(args) {
|
|
|
4559
4634
|
};
|
|
4560
4635
|
if (args.fix) {
|
|
4561
4636
|
const selected = selectChecks(runnerOptions, config).checks;
|
|
4562
|
-
if (selected.some((
|
|
4637
|
+
if (selected.some((check37) => check37.id === MARKDOWNLINT_CHECK_ID)) {
|
|
4563
4638
|
await applyMarkdownlintFixes(context);
|
|
4564
4639
|
} else {
|
|
4565
4640
|
log.warn(`--fix: ${MARKDOWNLINT_CHECK_ID} is not part of this run — no files were fixed.`);
|
|
@@ -5103,7 +5178,7 @@ class PdfOutput {
|
|
|
5103
5178
|
const rawPdf = pdfxMode ? path7.join(stage, "raw.pdf") : path7.resolve(pdfFile);
|
|
5104
5179
|
await fsp2.mkdir(path7.dirname(path7.resolve(pdfFile)), { recursive: true });
|
|
5105
5180
|
log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
|
|
5106
|
-
const { buildNativePdf } = await import("./engine-
|
|
5181
|
+
const { buildNativePdf } = await import("./engine-17v87vq5.js");
|
|
5107
5182
|
const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
|
|
5108
5183
|
title: config.title,
|
|
5109
5184
|
author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
|
|
@@ -6399,11 +6474,13 @@ import path12 from "node:path";
|
|
|
6399
6474
|
|
|
6400
6475
|
// src/lib/page-size.ts
|
|
6401
6476
|
import { isMap } from "yaml";
|
|
6477
|
+
var PAGE_SIZE_CHECK = "pdf.print.page-size";
|
|
6402
6478
|
function writePageBounds(doc, page) {
|
|
6403
6479
|
ensurePageMap(doc);
|
|
6404
6480
|
doc.setIn(["page", "width"], page.width);
|
|
6405
6481
|
doc.setIn(["page", "height"], page.height);
|
|
6406
|
-
|
|
6482
|
+
if (page.tolerance !== undefined)
|
|
6483
|
+
setCheckOption(doc, PAGE_SIZE_CHECK, "tolerance", page.tolerance);
|
|
6407
6484
|
}
|
|
6408
6485
|
function deletePageBounds(doc) {
|
|
6409
6486
|
const block = doc.get("page", true);
|
|
@@ -6411,7 +6488,7 @@ function deletePageBounds(doc) {
|
|
|
6411
6488
|
doc.delete("page");
|
|
6412
6489
|
return;
|
|
6413
6490
|
}
|
|
6414
|
-
for (const key of ["width", "height"
|
|
6491
|
+
for (const key of ["width", "height"])
|
|
6415
6492
|
block.delete(key);
|
|
6416
6493
|
if (block.items.length === 0)
|
|
6417
6494
|
doc.delete("page");
|
|
@@ -6468,6 +6545,9 @@ function requirePreset(preset, customPage) {
|
|
|
6468
6545
|
} else if (customPage && (!isPositivePoints(customPage.width) || !isPositivePoints(customPage.height))) {
|
|
6469
6546
|
throw new CreateProjectErrorImpl("custom-page-required", "Page overrides need a positive width and height in points (72pt = 1in).");
|
|
6470
6547
|
}
|
|
6548
|
+
if (customPage?.tolerance !== undefined && !isPositivePoints(customPage.tolerance)) {
|
|
6549
|
+
throw new CreateProjectErrorImpl("custom-page-required", "Page tolerance must be a positive number of points.");
|
|
6550
|
+
}
|
|
6471
6551
|
return preset;
|
|
6472
6552
|
}
|
|
6473
6553
|
function resolveScaffoldTargets(requested, preset) {
|
|
@@ -6571,7 +6651,7 @@ async function scaffoldProject(options) {
|
|
|
6571
6651
|
let versionHistoryError;
|
|
6572
6652
|
if (requested === "local-git") {
|
|
6573
6653
|
try {
|
|
6574
|
-
const { providerFor } = await import("./source-provider-
|
|
6654
|
+
const { providerFor } = await import("./source-provider-3g3yrn1f.js");
|
|
6575
6655
|
const provider = providerFor({ type: "local-folder", path: projectDir });
|
|
6576
6656
|
await provider.initVersionHistory({
|
|
6577
6657
|
projectDir,
|
|
@@ -6624,6 +6704,12 @@ import { access as access2, mkdir as mkdir5, readFile as readFile23, writeFile a
|
|
|
6624
6704
|
import { constants as FS2 } from "node:fs";
|
|
6625
6705
|
import path13 from "node:path";
|
|
6626
6706
|
var EXTENSION_KINDS = ["plugin", "look"];
|
|
6707
|
+
var EXTENSION_KIND_ALIASES = { theme: "look" };
|
|
6708
|
+
function extensionKindFor(word) {
|
|
6709
|
+
if (EXTENSION_KINDS.includes(word))
|
|
6710
|
+
return word;
|
|
6711
|
+
return Object.hasOwn(EXTENSION_KIND_ALIASES, word) ? EXTENSION_KIND_ALIASES[word] : undefined;
|
|
6712
|
+
}
|
|
6627
6713
|
var RESERVED_PREFIX = "gp-";
|
|
6628
6714
|
var TEMPLATE_FILES = {
|
|
6629
6715
|
plugin: [
|
|
@@ -6686,9 +6772,9 @@ function escapeJsonScalar(value) {
|
|
|
6686
6772
|
return JSON.stringify(value).slice(1, -1);
|
|
6687
6773
|
}
|
|
6688
6774
|
async function scaffoldExtension(options) {
|
|
6689
|
-
const kind = options.kind;
|
|
6690
|
-
if (kind
|
|
6691
|
-
throw new ExtensionScaffoldError("invalid-name", `Unknown extension kind "${String(kind)}". Choose one of: ${EXTENSION_KINDS.join(", ")}.`);
|
|
6775
|
+
const kind = extensionKindFor(String(options.kind));
|
|
6776
|
+
if (!kind) {
|
|
6777
|
+
throw new ExtensionScaffoldError("invalid-name", `Unknown extension kind "${String(options.kind)}". Choose one of: ${EXTENSION_KINDS.join(", ")}.`);
|
|
6692
6778
|
}
|
|
6693
6779
|
const name = (options.name ?? "").trim();
|
|
6694
6780
|
if (!name) {
|
|
@@ -8978,7 +9064,7 @@ async function resolvePublishProvider(id, book) {
|
|
|
8978
9064
|
const ext = await bookExtensions(book);
|
|
8979
9065
|
const npmEntry = ext.extensions.some((c) => !c.path && c.name === id);
|
|
8980
9066
|
if (npmEntry) {
|
|
8981
|
-
const { restoreForCommand: restoreForCommand2 } = await import("./extension-restore-
|
|
9067
|
+
const { restoreForCommand: restoreForCommand2 } = await import("./extension-restore-q70wqah5.js");
|
|
8982
9068
|
await restoreForCommand2(book.projectDir, { manifestPath: book.manifestPath, failFast: true });
|
|
8983
9069
|
}
|
|
8984
9070
|
const publishers = await discover(ext);
|
|
@@ -9016,7 +9102,7 @@ function infoFor(p) {
|
|
|
9016
9102
|
}
|
|
9017
9103
|
function pluginProvider(p) {
|
|
9018
9104
|
let loading;
|
|
9019
|
-
const load = () => loading ??= import("./plugins-
|
|
9105
|
+
const load = () => loading ??= import("./plugins-tqv1s16f.js").then((m) => m.loadPublishFunction(p));
|
|
9020
9106
|
return {
|
|
9021
9107
|
info: infoFor(p),
|
|
9022
9108
|
async authenticate() {
|
|
@@ -9404,6 +9490,7 @@ var defaultGitHttp = withIdleTimeout(httpNode);
|
|
|
9404
9490
|
|
|
9405
9491
|
// src/lib/version-changes.ts
|
|
9406
9492
|
var decoder = new TextDecoder;
|
|
9493
|
+
var CLOCK_SKEW_SECONDS = 10 * 60;
|
|
9407
9494
|
// src/lib/host-policy.ts
|
|
9408
9495
|
var AUTO_SYNC_MAX_MINUTES = 24 * 60;
|
|
9409
9496
|
// src/lib/remote-auth/github-repos.ts
|
|
@@ -9445,7 +9532,7 @@ class PublishSelectionsStore {
|
|
|
9445
9532
|
return {
|
|
9446
9533
|
version: 1,
|
|
9447
9534
|
global: parsed.global ?? {},
|
|
9448
|
-
projects: parsed.projects
|
|
9535
|
+
projects: readProjects(parsed.projects)
|
|
9449
9536
|
};
|
|
9450
9537
|
}
|
|
9451
9538
|
} catch {}
|
|
@@ -9531,6 +9618,27 @@ class PublishSelectionsStore {
|
|
|
9531
9618
|
});
|
|
9532
9619
|
}
|
|
9533
9620
|
}
|
|
9621
|
+
function readProjects(projects) {
|
|
9622
|
+
const out = {};
|
|
9623
|
+
if (!projects || typeof projects !== "object")
|
|
9624
|
+
return out;
|
|
9625
|
+
for (const [book, providers] of Object.entries(projects)) {
|
|
9626
|
+
if (!providers || typeof providers !== "object")
|
|
9627
|
+
continue;
|
|
9628
|
+
const values = {};
|
|
9629
|
+
for (const [provider, value] of Object.entries(providers)) {
|
|
9630
|
+
if (typeof value === "string") {
|
|
9631
|
+
if (value.trim())
|
|
9632
|
+
values[provider] = { credential: value };
|
|
9633
|
+
} else if (value && typeof value === "object") {
|
|
9634
|
+
values[provider] = value;
|
|
9635
|
+
}
|
|
9636
|
+
}
|
|
9637
|
+
if (Object.keys(values).length > 0)
|
|
9638
|
+
out[book] = values;
|
|
9639
|
+
}
|
|
9640
|
+
return out;
|
|
9641
|
+
}
|
|
9534
9642
|
function normalizeProjectKey(projectDir) {
|
|
9535
9643
|
return projectDir.replace(/[\\/]+$/, "");
|
|
9536
9644
|
}
|
|
@@ -9538,4 +9646,4 @@ function normalizeProjectKey(projectDir) {
|
|
|
9538
9646
|
import { isMap as isMap4 } from "yaml";
|
|
9539
9647
|
// src/lib/root-tokens.ts
|
|
9540
9648
|
import postcss7 from "postcss";
|
|
9541
|
-
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 };
|
|
9649
|
+
export { reportMissingTools, executeValidation, executeAndReport, splitOutPath, runBuild, openPath, startPreviewServer, scaffoldProject, EXTENSION_KINDS, extensionKindFor, scaffoldExtension, BUILT_IN_TEMPLATE_IDS, importExtensionFromFile, importExtensionFromUrl, searchNpmExtensions, publishCredentialKey, publishConnectionStatus, listPublishAccounts, connectGoogleDrive, listBookPublishProviders, resolvePublishProvider, resolvePublishFormat, runPublish, connectPublishProvider, disconnectPublishCredential };
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
EXTENSIONS_DIR,
|
|
9
9
|
LEGACY_PLUGINS_DIR,
|
|
10
10
|
VENDORED_NPM_DIR
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-1dha1nxk.js";
|
|
12
12
|
|
|
13
13
|
// src/lib/git-fs.ts
|
|
14
14
|
import * as nodeFs from "node:fs";
|
|
@@ -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 };
|