gutterpress 0.11.17-alpha.5 → 0.11.17-alpha.7
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/dist/api/index.d.ts +2 -2
- package/dist/api/index.js +4 -2
- package/dist/{build-jr9mqwgr.js → build-nbwgzcgv.js} +4 -4
- package/dist/{cli-2xpwjanr.js → cli-2yvrfr58.js} +1 -1
- package/dist/{cli-82tvm0sg.js → cli-v3xmpvs8.js} +191 -118
- package/dist/{cli-5sg6hcqa.js → cli-vsgj1n9s.js} +1 -1
- package/dist/{cli-c3enmb58.js → cli-ycbg7mxk.js} +4 -4
- package/dist/cli.js +12 -12
- package/dist/{components-dhgv2sm7.yaml → components-zzqdpt3m.yaml} +1 -1
- package/dist/{doctor-zxk3pamr.js → doctor-dmagdmyw.js} +2 -2
- package/dist/{engine-eactk9nn.js → engine-5d1rpxxq.js} +2 -2
- package/dist/{engine-63r7pxsy.js → engine-yf2w9hj7.js} +1 -1
- package/dist/{ext-4vapkh0p.js → ext-twnqxfba.js} +4 -4
- package/dist/{gutterpress-viewer-1n793gwd.js → gutterpress-viewer-ez7k4ha7.js} +19 -1
- package/dist/{index-mb8mzwye.js → index-09h3n36d.js} +2 -2
- package/dist/{index-5ez30g3a.js → index-k0k4syyd.js} +215 -120
- package/dist/{index-5gp6mkmf.js → index-vmcfahe2.js} +3 -3
- package/dist/index.js +5 -3
- package/dist/lib/markdown/assemble.d.ts +3 -1
- package/dist/lib/markdown/gutterpress-css.d.ts +1 -1
- package/dist/lib/markdown/markers.d.ts +27 -154
- package/dist/lib/markdown/renderer.d.ts +10 -1
- package/dist/lib/snippets.d.ts +23 -0
- package/dist/{new-hzs75cmd.js → new-mvtamd8q.js} +4 -4
- package/dist/{page-templates-7md4ev7d.css → page-templates-tx9ryt19.css} +4 -11
- package/dist/{preflight-4k8dtsfs.js → preflight-et7fnz7v.js} +4 -4
- package/dist/{preview-whg4rwg6.js → preview-xzvwzsyz.js} +4 -4
- package/dist/{publish-4vtd7qve.js → publish-2x100s48.js} +4 -4
- package/dist/render.js +187 -114
- package/dist/{validate-c32mm2bh.js → validate-nrpa6kah.js} +4 -4
- package/package.json +1 -1
package/dist/api/index.d.ts
CHANGED
|
@@ -32,8 +32,8 @@ export { TARGETS, TARGET_IDS, publishTargetFor } from "../lib/targets.ts";
|
|
|
32
32
|
export type { PublishTarget, TargetOverlay } from "../lib/targets.ts";
|
|
33
33
|
export { listBuiltInTemplates, listCustomTemplates, saveProjectAsTemplate, importTemplateFromFolder, BUILT_IN_TEMPLATE_IDS, } from "../lib/project-templates.ts";
|
|
34
34
|
export type { TemplateInfo, SaveProjectAsTemplateOptions, } from "../lib/project-templates.ts";
|
|
35
|
-
export { extractVariables, substituteVariables, listSnippets, saveSnippet, deleteSnippet, listMergedSnippets, listMarkerComponents, SNIPPETS_DIR, } from "../lib/snippets.ts";
|
|
36
|
-
export type { MarkerComponent, SnippetEntry, SnippetSource } from "../lib/snippets.ts";
|
|
35
|
+
export { extractVariables, substituteVariables, listSnippets, saveSnippet, deleteSnippet, listMergedSnippets, listMarkerComponents, listLocationVariants, SNIPPETS_DIR, } from "../lib/snippets.ts";
|
|
36
|
+
export type { LocationVariant, MarkerComponent, SnippetEntry, SnippetSource } from "../lib/snippets.ts";
|
|
37
37
|
export { listProjectExtensions, describeExtension, addExtension, checkExtensionUpdates, listNpmVersions, updateExtensions, removeExtension, setExtensionEnabled, reorderExtensions, validateProjectExtensions, readExtensionCss, listBuiltInStyleSets, addBuiltInStyleSet, sameExtension, RECOMMENDED_EXTENSIONS, BUILT_IN_STYLE_SET_IDS, EXTENSIONS_DIR, PLUGINS_DIR, } from "../lib/extension-manager.ts";
|
|
38
38
|
export type { ProjectExtensionEntry, ExtensionValidationResult, RecommendedExtension, ExtensionSourceKind, BuiltInStyleSet, BuiltInStyleSetId, AddExtensionOptions, ExtensionUpdateCheck, ExtensionUpdateResult, CheckExtensionUpdatesOptions, UpdateExtensionsOptions, } from "../lib/extension-manager.ts";
|
|
39
39
|
export { BUNDLED_EXTENSIONS, isBundledExtension, isPathSpecifier, parseExtensionSpecifier, } from "../lib/extension-specifier.ts";
|
package/dist/api/index.js
CHANGED
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
listCustomTemplates,
|
|
71
71
|
listGitHubBranches,
|
|
72
72
|
listGitHubRepositories,
|
|
73
|
+
listLocationVariants,
|
|
73
74
|
listMarkerComponents,
|
|
74
75
|
listMergedSnippets,
|
|
75
76
|
listNpmVersions,
|
|
@@ -135,11 +136,11 @@ import {
|
|
|
135
136
|
testRemoteAccess,
|
|
136
137
|
updateExtensions,
|
|
137
138
|
validateProjectExtensions
|
|
138
|
-
} from "../index-
|
|
139
|
+
} from "../index-k0k4syyd.js";
|
|
139
140
|
import"../index-ht1bcqdd.js";
|
|
140
141
|
import {
|
|
141
142
|
BuildError
|
|
142
|
-
} from "../index-
|
|
143
|
+
} from "../index-vmcfahe2.js";
|
|
143
144
|
import {
|
|
144
145
|
DEFAULT_PRINT_OPTS,
|
|
145
146
|
assertMilestone,
|
|
@@ -242,6 +243,7 @@ export {
|
|
|
242
243
|
listNpmVersions,
|
|
243
244
|
listMergedSnippets,
|
|
244
245
|
listMarkerComponents,
|
|
246
|
+
listLocationVariants,
|
|
245
247
|
listLocalBranches,
|
|
246
248
|
listGitHubRepositories,
|
|
247
249
|
listGitHubBranches,
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runBuild,
|
|
3
3
|
splitOutPath
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-v3xmpvs8.js";
|
|
5
5
|
import {
|
|
6
6
|
log
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-vsgj1n9s.js";
|
|
8
8
|
import {
|
|
9
9
|
UsageError,
|
|
10
10
|
parseFormat,
|
|
11
11
|
parsePdfxFlavor,
|
|
12
12
|
rejectExtraPositionals,
|
|
13
13
|
rejectUnknownFlags
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-2yvrfr58.js";
|
|
15
15
|
import"./cli-ht1bcqdd.js";
|
|
16
|
-
import"./cli-
|
|
16
|
+
import"./cli-ycbg7mxk.js";
|
|
17
17
|
import {
|
|
18
18
|
BuildError
|
|
19
19
|
} from "./cli-46ycxe6r.js";
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
// package.json
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "gutterpress",
|
|
7
|
-
version: "0.11.17-alpha.
|
|
7
|
+
version: "0.11.17-alpha.7",
|
|
8
8
|
description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
|
|
9
9
|
author: "itlackey",
|
|
10
10
|
license: "MPL-2.0",
|
|
@@ -13,12 +13,12 @@ import {
|
|
|
13
13
|
stampCreator,
|
|
14
14
|
stripAnnotations,
|
|
15
15
|
warn
|
|
16
|
-
} from "./cli-
|
|
16
|
+
} from "./cli-vsgj1n9s.js";
|
|
17
17
|
import {
|
|
18
18
|
DEBOUNCE,
|
|
19
19
|
UsageError,
|
|
20
20
|
resolvePort
|
|
21
|
-
} from "./cli-
|
|
21
|
+
} from "./cli-2yvrfr58.js";
|
|
22
22
|
import {
|
|
23
23
|
blackTextToGray
|
|
24
24
|
} from "./cli-ht1bcqdd.js";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
getAssetPath,
|
|
28
28
|
getAssetsDir,
|
|
29
29
|
lastPageMode
|
|
30
|
-
} from "./cli-
|
|
30
|
+
} from "./cli-ycbg7mxk.js";
|
|
31
31
|
import {
|
|
32
32
|
BuildError,
|
|
33
33
|
EXIT_CODES
|
|
@@ -1169,6 +1169,16 @@ function resolveContainerShape(name, pluginName, decl) {
|
|
|
1169
1169
|
...check
|
|
1170
1170
|
};
|
|
1171
1171
|
}
|
|
1172
|
+
function presetVariantOf(name, pluginName, rawDecl) {
|
|
1173
|
+
const preset = rawDecl.preset !== undefined ? rawDecl.preset : {};
|
|
1174
|
+
if (typeof preset !== "object" || preset === null || Array.isArray(preset)) {
|
|
1175
|
+
throw new Error(`Plugin "${pluginName}"'s marker "@${name}" has a \`preset\` that is not a plain object.`);
|
|
1176
|
+
}
|
|
1177
|
+
if (preset.variant !== undefined && typeof preset.variant !== "string") {
|
|
1178
|
+
throw new Error(`Plugin "${pluginName}"'s marker "@${name}" has a \`preset.variant\` that is not a string.`);
|
|
1179
|
+
}
|
|
1180
|
+
return preset.variant;
|
|
1181
|
+
}
|
|
1172
1182
|
function resolveMarkerDeclaration(name, rawDecl, rawRegistry, originOf) {
|
|
1173
1183
|
const pluginName = originOf.get(name);
|
|
1174
1184
|
if (typeof rawDecl !== "object" || rawDecl === null || Array.isArray(rawDecl)) {
|
|
@@ -1197,35 +1207,70 @@ function resolveMarkerDeclaration(name, rawDecl, rawRegistry, originOf) {
|
|
|
1197
1207
|
if (targetRaw.alias !== undefined) {
|
|
1198
1208
|
throw new Error(`Plugin "${pluginName}"'s marker "@${name}" aliases "@${rawDecl.alias}", which is itself an alias. ` + `Chained aliases are not supported — alias the base marker directly.`);
|
|
1199
1209
|
}
|
|
1200
|
-
const preset = rawDecl.preset !== undefined ? rawDecl.preset : {};
|
|
1201
|
-
if (typeof preset !== "object" || preset === null || Array.isArray(preset)) {
|
|
1202
|
-
throw new Error(`Plugin "${pluginName}"'s marker "@${name}" has a \`preset\` that is not a plain object.`);
|
|
1203
|
-
}
|
|
1204
|
-
if (preset.variant !== undefined && typeof preset.variant !== "string") {
|
|
1205
|
-
throw new Error(`Plugin "${pluginName}"'s marker "@${name}" has a \`preset.variant\` that is not a string.`);
|
|
1206
|
-
}
|
|
1207
1210
|
const container = resolveContainerShape(rawDecl.alias, originOf.get(rawDecl.alias), targetRaw);
|
|
1208
|
-
return { name, baseKind: rawDecl.alias, presetVariant:
|
|
1211
|
+
return { name, baseKind: rawDecl.alias, presetVariant: presetVariantOf(name, pluginName, rawDecl), ...container };
|
|
1209
1212
|
}
|
|
1210
|
-
|
|
1213
|
+
const presetVariant = presetVariantOf(name, pluginName, rawDecl);
|
|
1214
|
+
return {
|
|
1215
|
+
name,
|
|
1216
|
+
baseKind: name,
|
|
1217
|
+
...presetVariant !== undefined ? { presetVariant } : {},
|
|
1218
|
+
...resolveContainerShape(name, pluginName, rawDecl)
|
|
1219
|
+
};
|
|
1211
1220
|
}
|
|
1212
1221
|
var CORE_MARKER_OWNER = "Gutterpress";
|
|
1213
1222
|
var CORE_DECLARED_MARKERS = {
|
|
1214
1223
|
columns: {
|
|
1215
1224
|
class: "gp-columns",
|
|
1225
|
+
preset: { variant: "2" },
|
|
1216
1226
|
variants: { 1: "gp-columns-1", 2: "gp-columns-2", 3: "gp-columns-3", 4: "gp-columns-4", 5: "gp-columns-5" }
|
|
1217
|
-
}
|
|
1227
|
+
},
|
|
1228
|
+
page: { variants: { blank: "gp-page-blank", "full-bleed": "gp-page-full-bleed" } }
|
|
1218
1229
|
};
|
|
1230
|
+
var LOCATION_KINDS = ["page", "chapter", "section"];
|
|
1231
|
+
var LOCATION_KEYS = ["variants", "label", "snippet"];
|
|
1232
|
+
function isLocationDeclaration(name, rawDecl) {
|
|
1233
|
+
return LOCATION_KINDS.includes(name) && rawDecl !== null && typeof rawDecl === "object" && !Array.isArray(rawDecl) && Object.hasOwn(rawDecl, "variants") && Object.keys(rawDecl).every((k) => LOCATION_KEYS.includes(k));
|
|
1234
|
+
}
|
|
1235
|
+
function addLocationVariants(kind, rawDecl, pluginName, into) {
|
|
1236
|
+
const { variants, label, snippet } = rawDecl;
|
|
1237
|
+
const where = `Plugin "${pluginName}" declares @${kind} variants`;
|
|
1238
|
+
if (variants === null || typeof variants !== "object" || Array.isArray(variants)) {
|
|
1239
|
+
throw new Error(`${where} that are not a plain object of { word: 'class' }.`);
|
|
1240
|
+
}
|
|
1241
|
+
if (label !== undefined && typeof label !== "string")
|
|
1242
|
+
throw new Error(`${where} with a \`label\` that is not a string.`);
|
|
1243
|
+
if (snippet !== undefined && typeof snippet !== "string")
|
|
1244
|
+
throw new Error(`${where} with a \`snippet\` that is not a string.`);
|
|
1245
|
+
for (const [word, cls] of Object.entries(variants)) {
|
|
1246
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(word)) {
|
|
1247
|
+
throw new Error(`${where} with an invalid word "${word}" — use letters, digits, hyphens and underscores.`);
|
|
1248
|
+
}
|
|
1249
|
+
if (typeof cls !== "string" || !cls.trim()) {
|
|
1250
|
+
throw new Error(`${where}: variant "${word}" needs a non-empty class string.`);
|
|
1251
|
+
}
|
|
1252
|
+
const taken = into[kind].get(word);
|
|
1253
|
+
if (taken) {
|
|
1254
|
+
throw new Error(`@${kind} variant "${word}" is declared by both plugin "${taken.owner}" and plugin "${pluginName}". ` + `Variant words must be unique across every loaded plugin — rename one of them.`);
|
|
1255
|
+
}
|
|
1256
|
+
into[kind].set(word, { class: cls.trim(), owner: pluginName, ...label ? { label } : {}, ...snippet ? { snippet } : {} });
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1219
1259
|
function buildDeclaredMarkerRegistry(sources) {
|
|
1220
1260
|
const rawRegistry = new Map;
|
|
1221
1261
|
const originOf = new Map;
|
|
1262
|
+
const locationVariants = { page: new Map, chapter: new Map, section: new Map };
|
|
1222
1263
|
for (const { pluginName, markers } of [{ pluginName: CORE_MARKER_OWNER, markers: CORE_DECLARED_MARKERS }, ...sources]) {
|
|
1223
1264
|
if (!markers)
|
|
1224
1265
|
continue;
|
|
1225
1266
|
for (const [name, rawDecl] of Object.entries(markers)) {
|
|
1226
1267
|
validateDeclaredMarkerName(name, pluginName);
|
|
1268
|
+
if (isLocationDeclaration(name, rawDecl)) {
|
|
1269
|
+
addLocationVariants(name, rawDecl, pluginName, locationVariants);
|
|
1270
|
+
continue;
|
|
1271
|
+
}
|
|
1227
1272
|
if (KNOWN_KINDS.includes(name) || pluginName !== CORE_MARKER_OWNER && name in CORE_DECLARED_MARKERS) {
|
|
1228
|
-
throw new Error(`Plugin "${pluginName}" declares marker "@${name}", which is a core Gutterpress marker name ` + `(${[...KNOWN_KINDS, ...Object.keys(CORE_DECLARED_MARKERS)].map((k) => `@${k}`).join(", ")}). ` + `Core marker names cannot be shadowed — ` + `rename the plugin's marker.`);
|
|
1273
|
+
throw new Error(`Plugin "${pluginName}" declares marker "@${name}", which is a core Gutterpress marker name ` + `(${[...KNOWN_KINDS, ...Object.keys(CORE_DECLARED_MARKERS).filter((k) => !KNOWN_KINDS.includes(k))].map((k) => `@${k}`).join(", ")}). ` + `Core marker names cannot be shadowed — ` + `rename the plugin's marker.`);
|
|
1229
1274
|
}
|
|
1230
1275
|
if (rawRegistry.has(name)) {
|
|
1231
1276
|
throw new Error(`Marker "@${name}" is declared by both plugin "${originOf.get(name)}" and plugin "${pluginName}". ` + `Declared marker names must be unique across every loaded plugin — rename one of them.`);
|
|
@@ -1238,6 +1283,7 @@ function buildDeclaredMarkerRegistry(sources) {
|
|
|
1238
1283
|
for (const [name, rawDecl] of rawRegistry) {
|
|
1239
1284
|
resolved.set(name, resolveMarkerDeclaration(name, rawDecl, rawRegistry, originOf));
|
|
1240
1285
|
}
|
|
1286
|
+
resolved.locationVariants = locationVariants;
|
|
1241
1287
|
return resolved;
|
|
1242
1288
|
}
|
|
1243
1289
|
function declaredKindWords(declaredMarkers) {
|
|
@@ -1293,6 +1339,9 @@ function scanForUnknownDeclaredMarkers(state, declaredMarkers) {
|
|
|
1293
1339
|
function variantClassFor(decl, word) {
|
|
1294
1340
|
return word && decl.variants && Object.hasOwn(decl.variants, word) ? decl.variants[word] : "";
|
|
1295
1341
|
}
|
|
1342
|
+
function nearVariant(word, variants) {
|
|
1343
|
+
return variants.find((v) => v.toLowerCase() === word.toLowerCase()) || (word.length >= 3 ? nearestDeclaredMarkerName(word, variants) : null);
|
|
1344
|
+
}
|
|
1296
1345
|
function warnUnknownVariant(env, meta, decl) {
|
|
1297
1346
|
const word = meta.name;
|
|
1298
1347
|
if (!word)
|
|
@@ -1300,9 +1349,16 @@ function warnUnknownVariant(env, meta, decl) {
|
|
|
1300
1349
|
const variants = Object.keys(decl.variants || {});
|
|
1301
1350
|
if (variants.includes(word))
|
|
1302
1351
|
return;
|
|
1303
|
-
const near =
|
|
1352
|
+
const near = nearVariant(word, variants);
|
|
1304
1353
|
warn2(env, meta.__line, "unknown_variant", `"${word}" is not a variant of @${meta.kind}, so it adds no styling. ` + (variants.length ? `Variants: ${variants.join(", ")}.` : `@${meta.kind} has no variants.`) + (near ? ` Did you mean "${near}"?` : ""), meta);
|
|
1305
1354
|
}
|
|
1355
|
+
function warnNearMissVariant(env, meta, kind, variants) {
|
|
1356
|
+
const words = [...variants.keys()];
|
|
1357
|
+
const near = nearVariant(meta.name, words);
|
|
1358
|
+
if (!near)
|
|
1359
|
+
return;
|
|
1360
|
+
warn2(env, meta.__line, "unknown_variant", `"${meta.name}" is not a variant of @${kind}, so it is only a ${kind} name and adds no styling. ` + `Variants: ${words.join(", ")}. Did you mean "${near}"?`, meta);
|
|
1361
|
+
}
|
|
1306
1362
|
function plugin(md, pluginOptions = {}) {
|
|
1307
1363
|
const options = {
|
|
1308
1364
|
preferPagesInSpreads: false,
|
|
@@ -1310,6 +1366,7 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1310
1366
|
};
|
|
1311
1367
|
const declaredMarkers = options.declaredMarkers instanceof Map && options.declaredMarkers.size > 0 ? options.declaredMarkers : buildDeclaredMarkerRegistry([]);
|
|
1312
1368
|
const declaredWords = declaredKindWords(declaredMarkers);
|
|
1369
|
+
const locationVariants = declaredMarkers.locationVariants || buildDeclaredMarkerRegistry([]).locationVariants;
|
|
1313
1370
|
function markerBlock(state, startLine, endLine, silent) {
|
|
1314
1371
|
const pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
1315
1372
|
const max = state.eMarks[startLine];
|
|
@@ -1388,20 +1445,35 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1388
1445
|
const at = declaredFrameIndex(kind);
|
|
1389
1446
|
if (at === -1)
|
|
1390
1447
|
return false;
|
|
1391
|
-
|
|
1392
|
-
const frame = declaredFrames.pop();
|
|
1393
|
-
out.push(new state.Token("layout_component_close", frame.tag, -1));
|
|
1394
|
-
}
|
|
1448
|
+
drainDeclaredFrames(at);
|
|
1395
1449
|
return true;
|
|
1396
1450
|
}
|
|
1397
|
-
function
|
|
1398
|
-
|
|
1451
|
+
function sectionAbove(length) {
|
|
1452
|
+
const section = stack.get("section");
|
|
1453
|
+
return !!section && section.inColumns && declaredFrameIndex("columns") === length - 1;
|
|
1454
|
+
}
|
|
1455
|
+
function sectionHostDepth() {
|
|
1456
|
+
const section = stack.get("section");
|
|
1457
|
+
if (section && !section.inColumns)
|
|
1458
|
+
return 0;
|
|
1459
|
+
return declaredFrameIndex("columns") + 1;
|
|
1460
|
+
}
|
|
1461
|
+
function drainDeclaredFrames(keep = 0) {
|
|
1462
|
+
while (declaredFrames.length > keep) {
|
|
1463
|
+
if (sectionAbove(declaredFrames.length)) {
|
|
1464
|
+
stack.close("section");
|
|
1465
|
+
continue;
|
|
1466
|
+
}
|
|
1399
1467
|
const frame = declaredFrames.pop();
|
|
1400
1468
|
out.push(new state.Token("layout_component_close", frame.tag, -1));
|
|
1401
1469
|
}
|
|
1402
1470
|
}
|
|
1403
1471
|
function drainDeclaredFramesAtEof() {
|
|
1404
1472
|
while (declaredFrames.length) {
|
|
1473
|
+
if (sectionAbove(declaredFrames.length)) {
|
|
1474
|
+
stack.close("section");
|
|
1475
|
+
continue;
|
|
1476
|
+
}
|
|
1405
1477
|
const frame = declaredFrames.pop();
|
|
1406
1478
|
if (!frame.decl.autoCloseAtEof) {
|
|
1407
1479
|
warn2(state.env, frame.line || 0, "declared_marker_eof_close", `An open @${frame.kind} reached end-of-document; closing it automatically. Add ` + `@end-${frame.kind} to close it explicitly, or declare autoCloseAt: ["eof"] on this ` + `marker if running to end-of-document is expected.`, null);
|
|
@@ -1478,14 +1550,16 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1478
1550
|
function openChapter(meta) {
|
|
1479
1551
|
const t = new state.Token("layout_chapter_open", "div", 1);
|
|
1480
1552
|
t.meta = { line: meta.__line };
|
|
1481
|
-
const
|
|
1553
|
+
const variant = locationVariants.chapter.get(meta.name);
|
|
1554
|
+
const label = variant ? "" : meta.name;
|
|
1555
|
+
const classes = [variant?.class, meta.attrs?.class].filter(Boolean).join(" ");
|
|
1482
1556
|
addClasses(t, "chapter", classes);
|
|
1483
|
-
attachDataAttrs(t, "chapter",
|
|
1557
|
+
attachDataAttrs(t, "chapter", label, meta.attrs || {});
|
|
1484
1558
|
const explicit = (classes.match(/(?:^|\s)(chapter-\d+)(?=\s|$)/) || [])[1] || "";
|
|
1485
1559
|
const fromAttr = meta.attrs?.ch ? `chapter-${meta.attrs.ch}` : "";
|
|
1486
1560
|
stack.open({
|
|
1487
1561
|
kind: "chapter",
|
|
1488
|
-
label:
|
|
1562
|
+
label: label || "",
|
|
1489
1563
|
counterClass: explicit || fromAttr,
|
|
1490
1564
|
openerEmitted: false
|
|
1491
1565
|
}, t);
|
|
@@ -1509,7 +1583,11 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1509
1583
|
const explicit = meta.attrs && meta.attrs.class ? meta.attrs.class : "";
|
|
1510
1584
|
const counterClass = chapter ? chapter.counterClass : "";
|
|
1511
1585
|
const tokens = explicit ? explicit.split(/\s+/) : [];
|
|
1512
|
-
const
|
|
1586
|
+
const withCounter = counterClass && !tokens.includes(counterClass) ? explicit ? `${explicit} ${counterClass}` : counterClass : explicit;
|
|
1587
|
+
const variant = locationVariants.page.get(meta.name);
|
|
1588
|
+
if (!variant && meta.name)
|
|
1589
|
+
warnNearMissVariant(state.env, meta, "page", locationVariants.page);
|
|
1590
|
+
const merged = [variant?.class, withCounter].filter(Boolean).join(" ");
|
|
1513
1591
|
addClasses(t, "page", merged);
|
|
1514
1592
|
attachDataAttrs(t, "page", meta.name, meta.attrs || {});
|
|
1515
1593
|
const label = chapter ? chapter.label : "";
|
|
@@ -1545,10 +1623,11 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1545
1623
|
__component: { component: meta.kind, kind: decl.baseKind, variant, attrs }
|
|
1546
1624
|
};
|
|
1547
1625
|
}
|
|
1548
|
-
function openSection(meta) {
|
|
1626
|
+
function openSection(meta, inColumns = false) {
|
|
1549
1627
|
const t = new state.Token("layout_section_open", "div", 1);
|
|
1550
1628
|
const component = meta.__component || null;
|
|
1551
|
-
|
|
1629
|
+
const variant = component ? null : locationVariants.section.get(meta.name);
|
|
1630
|
+
addClasses(t, "section", [variant?.class, meta.attrs && meta.attrs.class].filter(Boolean).join(" "));
|
|
1552
1631
|
if (component)
|
|
1553
1632
|
attachDataAttrs(t, component.kind, component.variant, meta.attrs || {});
|
|
1554
1633
|
else
|
|
@@ -1558,25 +1637,11 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1558
1637
|
kind: "section",
|
|
1559
1638
|
classes: meta.attrs && meta.attrs.class || "",
|
|
1560
1639
|
sawContent: false,
|
|
1640
|
+
...inColumns ? { inColumns: true } : {},
|
|
1561
1641
|
meta: { name: meta.name || null, attrs: { ...meta.attrs || {} }, component },
|
|
1562
1642
|
openToken: t
|
|
1563
1643
|
}, t);
|
|
1564
1644
|
}
|
|
1565
|
-
function breakHost() {
|
|
1566
|
-
return stack.get("section") || stack.get("page") || stack.get("spread");
|
|
1567
|
-
}
|
|
1568
|
-
function gridClassOf(frame) {
|
|
1569
|
-
if (!frame || !frame.classes)
|
|
1570
|
-
return null;
|
|
1571
|
-
return frame.classes.split(/\s+/).find((c) => c.startsWith("gp-grid-")) || null;
|
|
1572
|
-
}
|
|
1573
|
-
function warnBreakInsideGrid(kind, line, meta) {
|
|
1574
|
-
const host = breakHost();
|
|
1575
|
-
const gridClass = gridClassOf(host);
|
|
1576
|
-
if (!gridClass)
|
|
1577
|
-
return;
|
|
1578
|
-
warn2(state.env, line, "break_inside_grid", `@${kind} inside a grid container: the enclosing @${host.kind} carries .${gridClass}, so this break's <div> becomes a grid ITEM — it takes a cell of its own, corrupts the grid's placement, and print and the live preview then disagree about which page the content after it lands on. Move the break outside the grid @${host.kind}, or remove it — grid rows already flow and fragment across pages on their own.`, meta);
|
|
1579
|
-
}
|
|
1580
1645
|
function warnIfEmptyDecoratedSection(closingKind, closingLine) {
|
|
1581
1646
|
const sec = stack.get("section");
|
|
1582
1647
|
if (!sec || sec.sawContent)
|
|
@@ -1641,14 +1706,18 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1641
1706
|
continue;
|
|
1642
1707
|
}
|
|
1643
1708
|
if (kind === "section") {
|
|
1644
|
-
|
|
1709
|
+
const keep = sectionHostDepth();
|
|
1710
|
+
drainDeclaredFrames(keep);
|
|
1645
1711
|
warnIfEmptyDecoratedSection("section", line);
|
|
1646
1712
|
stack.close("section");
|
|
1647
1713
|
const spread = stack.get("spread");
|
|
1648
1714
|
if (spread && spread.noPagesYet) {
|
|
1649
1715
|
warn2(state.env, line, "spread_without_pages", "@section inside a spread without an explicit @page. Allowed (adhoc spread), but explicit @page markers give stronger control.", meta);
|
|
1650
1716
|
}
|
|
1651
|
-
|
|
1717
|
+
if (meta.name && !locationVariants.section.has(meta.name)) {
|
|
1718
|
+
warnNearMissVariant(state.env, meta, "section", locationVariants.section);
|
|
1719
|
+
}
|
|
1720
|
+
openSection(meta, keep > 0);
|
|
1652
1721
|
continue;
|
|
1653
1722
|
}
|
|
1654
1723
|
if (kind === "continue") {
|
|
@@ -1657,7 +1726,8 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1657
1726
|
warn2(state.env, line, "continue_without_section", "@continue used without an open @section; ignoring marker.", meta);
|
|
1658
1727
|
continue;
|
|
1659
1728
|
}
|
|
1660
|
-
|
|
1729
|
+
const keep = sectionHostDepth();
|
|
1730
|
+
drainDeclaredFrames(keep);
|
|
1661
1731
|
const contMeta = {
|
|
1662
1732
|
name: section.meta.name,
|
|
1663
1733
|
attrs: { ...section.meta.attrs || {} }
|
|
@@ -1672,11 +1742,10 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1672
1742
|
cls.push("gp-continued");
|
|
1673
1743
|
contMeta.attrs.class = cls.join(" ");
|
|
1674
1744
|
stack.close("section");
|
|
1675
|
-
openSection(contMeta);
|
|
1745
|
+
openSection(contMeta, keep > 0);
|
|
1676
1746
|
continue;
|
|
1677
1747
|
}
|
|
1678
1748
|
if (kind === "page-break") {
|
|
1679
|
-
warnBreakInsideGrid("page-break", line, meta);
|
|
1680
1749
|
const t = new state.Token("layout_page_break", "div", 0);
|
|
1681
1750
|
t.meta = { line };
|
|
1682
1751
|
t.attrSet("class", "gp-page-break");
|
|
@@ -1685,7 +1754,6 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1685
1754
|
continue;
|
|
1686
1755
|
}
|
|
1687
1756
|
if (kind === "column-break") {
|
|
1688
|
-
warnBreakInsideGrid("column-break", line, meta);
|
|
1689
1757
|
const t = new state.Token("layout_column_break", "div", 0);
|
|
1690
1758
|
t.meta = { line };
|
|
1691
1759
|
t.attrSet("class", "gp-column-break");
|
|
@@ -1694,7 +1762,7 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1694
1762
|
continue;
|
|
1695
1763
|
}
|
|
1696
1764
|
if (kind === "end-section") {
|
|
1697
|
-
drainDeclaredFrames();
|
|
1765
|
+
drainDeclaredFrames(sectionHostDepth());
|
|
1698
1766
|
warnIfEmptyDecoratedSection("end-section", line);
|
|
1699
1767
|
stack.close("section");
|
|
1700
1768
|
continue;
|
|
@@ -1773,6 +1841,25 @@ function plugin(md, pluginOptions = {}) {
|
|
|
1773
1841
|
};
|
|
1774
1842
|
md.renderer.rules.layout_marker = () => "";
|
|
1775
1843
|
}
|
|
1844
|
+
var NO_MARGIN_BOXES = [
|
|
1845
|
+
"top-left-corner",
|
|
1846
|
+
"top-left",
|
|
1847
|
+
"top-center",
|
|
1848
|
+
"top-right",
|
|
1849
|
+
"top-right-corner",
|
|
1850
|
+
"bottom-left-corner",
|
|
1851
|
+
"bottom-left",
|
|
1852
|
+
"bottom-center",
|
|
1853
|
+
"bottom-right",
|
|
1854
|
+
"bottom-right-corner",
|
|
1855
|
+
"left-top",
|
|
1856
|
+
"left-middle",
|
|
1857
|
+
"left-bottom",
|
|
1858
|
+
"right-top",
|
|
1859
|
+
"right-middle",
|
|
1860
|
+
"right-bottom"
|
|
1861
|
+
].map((box) => ` @${box} { content: none; }`).join(`
|
|
1862
|
+
`);
|
|
1776
1863
|
var MARKER_CSS = `
|
|
1777
1864
|
/* The UA default of 8px body margin is a screen affordance with no meaning
|
|
1778
1865
|
in paged media, and engines disagree about it: a polyfill that treats the
|
|
@@ -1792,11 +1879,48 @@ body { margin: 0; }
|
|
|
1792
1879
|
.gp-column-break { break-after: column; height: 0; font-size: 0; line-height: 0; visibility: hidden; }
|
|
1793
1880
|
|
|
1794
1881
|
:where(h1,h2,h3,h4,h5,h6) { break-after: avoid; }
|
|
1882
|
+
/* A lead-in paragraph ("**ROLL A DIE!**" above a roll table, "You will need:"
|
|
1883
|
+
above a list) stays with the table or list it introduces, the way a heading
|
|
1884
|
+
stays with what follows it -- otherwise the label can end a column or page
|
|
1885
|
+
with its table starting on the next (#370). Standard break-after; the
|
|
1886
|
+
:has() selector is Chromium's own. :where() keeps specificity at zero so an
|
|
1887
|
+
author rule such as p { break-after: auto } wins. Deliberately table/ul/ol only,
|
|
1888
|
+
also when a @section wraps it (the second rule): the lead-in then keeps with
|
|
1889
|
+
the section that opens with the table or list. */
|
|
1890
|
+
:where(p):has(+ :where(table, ul, ol)) { break-after: avoid; }
|
|
1891
|
+
:where(p):has(+ :where(.section) > :where(table, ul, ol):first-child) { break-after: avoid; }
|
|
1795
1892
|
:where(img, svg, video) { max-width: 100%; }
|
|
1796
1893
|
:where(p > img:only-child, figure > img) { width: fit-content; max-width: 100%; height: auto; vertical-align: bottom; }
|
|
1797
1894
|
:where(p) > :where(img:not([class])) { max-height: calc(var(--gp-content-h) - 4px); object-fit: contain; }
|
|
1798
1895
|
:where(figure) { break-inside: avoid; }
|
|
1799
|
-
|
|
1896
|
+
|
|
1897
|
+
/* Core page variants — \`@page blank\` and \`@page full-bleed\` (CORE_DECLARED_MARKERS).
|
|
1898
|
+
Each is the \`.page\` the marker already emits plus one class; the class
|
|
1899
|
+
assigns the page to a NAMED page, and the named \`@page\` block below is
|
|
1900
|
+
plain CSS Paged Media. Authors never write these names.
|
|
1901
|
+
|
|
1902
|
+
SPEC GAP FILLED: none. Named pages (\`@page <name>\`, \`page:\`) and margin
|
|
1903
|
+
box \`content: none\` are standard and implemented in Chromium; this is
|
|
1904
|
+
author vocabulary that expands to them (permanent, like @columns), not a
|
|
1905
|
+
shim, so nothing here is deleted when Chrome catches up. Both pages are
|
|
1906
|
+
named \`gp-\`, which the shrink-to-fit audit (engine/compiler/build.ts)
|
|
1907
|
+
leaves out of its per-page limits, so they cannot loosen it for other pages.
|
|
1908
|
+
|
|
1909
|
+
The folio still COUNTS on these pages (only what is drawn is cleared), and
|
|
1910
|
+
a book that assigns \`page:\` to every \`.page\` in its own unlayered CSS
|
|
1911
|
+
overrides the assignment, as any unlayered rule overrides this layer. */
|
|
1912
|
+
@page gp-page-blank {
|
|
1913
|
+
${NO_MARGIN_BOXES}
|
|
1914
|
+
}
|
|
1915
|
+
.page.gp-page-blank { page: gp-page-blank; }
|
|
1916
|
+
|
|
1917
|
+
/* full-bleed: zero page margin, so the content box IS the sheet. The margin
|
|
1918
|
+
boxes are cleared too — with zero margins they would land on the trim line. */
|
|
1919
|
+
@page gp-page-full-bleed {
|
|
1920
|
+
margin: 0;
|
|
1921
|
+
${NO_MARGIN_BOXES}
|
|
1922
|
+
}
|
|
1923
|
+
.page.gp-page-full-bleed { page: gp-page-full-bleed; }
|
|
1800
1924
|
|
|
1801
1925
|
`;
|
|
1802
1926
|
|
|
@@ -1856,26 +1980,24 @@ var GUTTERPRESS_CSS = `
|
|
|
1856
1980
|
.gp-tight { --gp-gap: 0.5em; }
|
|
1857
1981
|
.gp-loose { --gp-gap: 2em; }
|
|
1858
1982
|
|
|
1859
|
-
/* column runs — plain CSS Multi-column,
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
every author who opens a section just to start a column run a panel they
|
|
1864
|
-
did not ask for, and the book then needs a reset rule to take it back.
|
|
1865
|
-
With a neutral primitive the author opts into columns and nothing else.
|
|
1983
|
+
/* column runs — plain CSS Multi-column, emitted by the core @columns marker
|
|
1984
|
+
(markers.js): @columns [1-5] ... @end-columns is the ONE way to lay
|
|
1985
|
+
content out in columns, and @column-break moves to the next column.
|
|
1986
|
+
The classes below are the CSS that marker emits, not author vocabulary.
|
|
1866
1987
|
|
|
1867
1988
|
Permanent vocabulary, not a shim: Chromium implements multicol natively
|
|
1868
1989
|
and these rules are the standard properties verbatim, so there is no
|
|
1869
1990
|
spec gap here to remove later. Deliberately minimal — column-fill is
|
|
1870
|
-
NOT set
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
wins because it comes later at the same specificity. */
|
|
1877
|
-
.gp-columns, .gp-columns-1, .gp-columns-2, .gp-columns-3, .gp-columns-4, .gp-columns-5 {
|
|
1991
|
+
NOT set (the CSS initial balance applies).
|
|
1992
|
+
Themes style a run through two tokens instead of writing column rules:
|
|
1993
|
+
--gp-column-gap default 1.5em
|
|
1994
|
+
--gp-column-rule default none (any column-rule shorthand value)
|
|
1995
|
+
Both hooks sit at zero specificity (:where), so any author rule wins.
|
|
1996
|
+
.gp-columns is two columns on its own; a count class (bare @columns
|
|
1997
|
+
emits gp-columns-2) wins because it comes later at the same specificity. */
|
|
1998
|
+
:where(.gp-columns, .gp-columns-1, .gp-columns-2, .gp-columns-3, .gp-columns-4, .gp-columns-5) {
|
|
1878
1999
|
column-gap: var(--gp-column-gap, 1.5em);
|
|
2000
|
+
column-rule: var(--gp-column-rule, none);
|
|
1879
2001
|
}
|
|
1880
2002
|
.gp-columns { columns: 2; }
|
|
1881
2003
|
.gp-columns-1 { columns: 1; }
|
|
@@ -1884,54 +2006,8 @@ var GUTTERPRESS_CSS = `
|
|
|
1884
2006
|
.gp-columns-4 { columns: 4; }
|
|
1885
2007
|
.gp-columns-5 { columns: 5; }
|
|
1886
2008
|
|
|
1887
|
-
/* the per-shape decisions the paragraph above deliberately leaves to the
|
|
1888
|
-
author, named instead of left as raw CSS every book was reinventing
|
|
1889
|
-
(CLAUDE.md §0: "behavior broadly useful to non-technical authors belongs
|
|
1890
|
-
in core").
|
|
1891
|
-
Permanent vocabulary, standard properties verbatim — same rationale as
|
|
1892
|
-
the column/grid runs above. One name each, no aliases:
|
|
1893
|
-
.gp-columns-all column-span: all a heading or block that
|
|
1894
|
-
spans every column in the
|
|
1895
|
-
run it sits inside.
|
|
1896
|
-
.gp-columns-flow column-fill: auto a run that FRAGMENTS across
|
|
1897
|
-
pages — every page's
|
|
1898
|
-
columns fill instead of
|
|
1899
|
-
only the last one
|
|
1900
|
-
balancing (the dead-column
|
|
1901
|
-
collapse the build's
|
|
1902
|
-
engine.multicol.dead-column
|
|
1903
|
-
warning names this fix
|
|
1904
|
-
for).
|
|
1905
|
-
.gp-columns-balanced column-fill: balance a run that fits on ONE
|
|
1906
|
-
page (the CSS initial
|
|
1907
|
-
value — ragged columns
|
|
1908
|
-
would be wrong here). */
|
|
1909
|
-
.gp-columns-all { column-span: all; }
|
|
1910
|
-
.gp-columns-flow { column-fill: auto; }
|
|
1911
|
-
.gp-columns-balanced { column-fill: balance; }
|
|
1912
|
-
|
|
1913
|
-
/* grid runs — the SLOTTED counterpart to the column runs above. Grid places
|
|
1914
|
-
each child into the next cell, across then down (deterministic slots: card
|
|
1915
|
-
layouts, stat blocks, image-plus-caption pairs); columns FLOW one text run
|
|
1916
|
-
down then across. Same neutral-primitive rationale as .gp-columns-*, and
|
|
1917
|
-
permanent vocabulary for the same reason: standard CSS Grid verbatim, no
|
|
1918
|
-
spec gap to remove later. MEASURED (Chromium 151, gp-grid evidence pack):
|
|
1919
|
-
grid rows fragment across sheets with EXACT print/viewer parity — 2- and
|
|
1920
|
-
3-col, unequal item heights, mid-row cuts, multi-sheet overflow,
|
|
1921
|
-
break-inside:avoid, gap geometry — so a grid taller than the page is safe,
|
|
1922
|
-
no fit-one-page constraint. Two things to know, not fix:
|
|
1923
|
-
- on a min-height page root (MARKER_CSS), default align-content
|
|
1924
|
-
stretches rows apart to fill the page — identically in both engines.
|
|
1925
|
-
Authors wanting packed rows set align-content: start.
|
|
1926
|
-
- a @page-break / @column-break marker DIRECTLY inside a grid container
|
|
1927
|
-
becomes a grid item and corrupts placement (the one measured parity
|
|
1928
|
-
break); markers.js diagnoses it (break_inside_grid).
|
|
1929
|
-
--gp-grid-gap is author-settable. */
|
|
1930
|
-
.gp-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--gp-grid-gap, 1.5em); }
|
|
1931
|
-
.gp-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gp-grid-gap, 1.5em); }
|
|
1932
|
-
|
|
1933
2009
|
/* fragmentation controls — generic pagination utilities for any element,
|
|
1934
|
-
independent of the column
|
|
2010
|
+
independent of the column vocabulary above (a book reached for
|
|
1935
2011
|
these just as often outside a multicol run: keeping a card whole,
|
|
1936
2012
|
forcing a section to start a fresh page). Standard properties only —
|
|
1937
2013
|
this project is Chromium-only (CLAUDE.md), so there are no legacy
|
|
@@ -2089,13 +2165,10 @@ var GP_CLASSES = new Set([
|
|
|
2089
2165
|
"gp-columns-3",
|
|
2090
2166
|
"gp-columns-4",
|
|
2091
2167
|
"gp-columns-5",
|
|
2092
|
-
"gp-
|
|
2093
|
-
"gp-
|
|
2094
|
-
"gp-columns-balanced",
|
|
2168
|
+
"gp-page-blank",
|
|
2169
|
+
"gp-page-full-bleed",
|
|
2095
2170
|
"gp-no-break",
|
|
2096
2171
|
"gp-break-before",
|
|
2097
|
-
"gp-grid-2",
|
|
2098
|
-
"gp-grid-3",
|
|
2099
2172
|
"gp-shape",
|
|
2100
2173
|
"gp-pin",
|
|
2101
2174
|
"gp-top",
|
|
@@ -9650,7 +9723,7 @@ class PdfOutput {
|
|
|
9650
9723
|
const rawPdf = pdfxMode ? path13.join(stage, "raw.pdf") : path13.resolve(pdfFile);
|
|
9651
9724
|
await fsp2.mkdir(path13.dirname(path13.resolve(pdfFile)), { recursive: true });
|
|
9652
9725
|
log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
|
|
9653
|
-
const { buildNativePdf } = await import("./engine-
|
|
9726
|
+
const { buildNativePdf } = await import("./engine-yf2w9hj7.js");
|
|
9654
9727
|
const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
|
|
9655
9728
|
title: config.title,
|
|
9656
9729
|
author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
|
|
@@ -1131,7 +1131,7 @@ var preview_shell_default = "./preview-shell-xwn84kqr.js";
|
|
|
1131
1131
|
var CGATS21_CRPC1_default = "./CGATS21_CRPC1-g0e3k7kr.icc";
|
|
1132
1132
|
|
|
1133
1133
|
// src/assets/engine/gutterpress-viewer.js
|
|
1134
|
-
var gutterpress_viewer_default = "./gutterpress-viewer-
|
|
1134
|
+
var gutterpress_viewer_default = "./gutterpress-viewer-ez7k4ha7.js";
|
|
1135
1135
|
|
|
1136
1136
|
// src/assets/engine/gutterpress-agent.js
|
|
1137
1137
|
var gutterpress_agent_default = "./gutterpress-agent-cazqstr1.js";
|
|
@@ -1185,7 +1185,7 @@ var package_default2 = "./package-aenwjew3.json";
|
|
|
1185
1185
|
var README_default2 = "./README-3nj919rm.md";
|
|
1186
1186
|
|
|
1187
1187
|
// src/assets/extension-templates/theme/components.yaml
|
|
1188
|
-
var components_default = "./components-
|
|
1188
|
+
var components_default = "./components-zzqdpt3m.yaml";
|
|
1189
1189
|
|
|
1190
1190
|
// src/assets/extension-templates/theme/snippets/callout.md
|
|
1191
1191
|
var callout_default = "./callout-hv56m16h.md";
|
|
@@ -1200,7 +1200,7 @@ var base_default = "./base-ypqh9n7f.css";
|
|
|
1200
1200
|
var components_default2 = "./components-aam0fe2z.css";
|
|
1201
1201
|
|
|
1202
1202
|
// src/assets/extension-templates/theme/styles/page-templates.css
|
|
1203
|
-
var page_templates_default = "./page-templates-
|
|
1203
|
+
var page_templates_default = "./page-templates-tx9ryt19.css";
|
|
1204
1204
|
|
|
1205
1205
|
// src/assets/extension-templates/theme/styles/page-rules.css
|
|
1206
1206
|
var page_rules_default = "./page-rules-nsj3aw42.css";
|
|
@@ -2226,7 +2226,7 @@ ${mapCss}`;
|
|
|
2226
2226
|
if (pageBackgrounds.length)
|
|
2227
2227
|
log(`audit: ${pageBackgrounds.length} unreferenced @page background image(s)`);
|
|
2228
2228
|
for (const d of multicol)
|
|
2229
|
-
diagnose("engine.multicol.dead-column", `${d} runs over more than one page in columns, and only the last page's columns get balanced — earlier pages are left with an empty column.
|
|
2229
|
+
diagnose("engine.multicol.dead-column", `${d} runs over more than one page in columns, and only the last page's columns get balanced — earlier pages are left with an empty column. End the @columns run where the page ends and open a new @columns for the next page, or set column-fill: auto on ${d} in your stylesheet so every page's columns fill.`);
|
|
2230
2230
|
if (multicol.length)
|
|
2231
2231
|
log(`audit: ${multicol.length} fragmenting multicol warning(s)`);
|
|
2232
2232
|
}
|