gutterpress 0.11.18-alpha.4 → 0.11.18-alpha.5

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.js CHANGED
@@ -136,11 +136,11 @@ import {
136
136
  testRemoteAccess,
137
137
  updateExtensions,
138
138
  validateProjectExtensions
139
- } from "../index-1ergtg60.js";
139
+ } from "../index-r2ry6j3x.js";
140
140
  import"../index-ht1bcqdd.js";
141
141
  import {
142
142
  BuildError
143
- } from "../index-jt552wtf.js";
143
+ } from "../index-pb4fj8m2.js";
144
144
  import {
145
145
  DEFAULT_PRINT_OPTS,
146
146
  assertMilestone,
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  runBuild,
3
3
  splitOutPath
4
- } from "./cli-dmcy8kay.js";
4
+ } from "./cli-dxs69beq.js";
5
5
  import {
6
6
  log
7
- } from "./cli-36v78t6w.js";
7
+ } from "./cli-bx24fj78.js";
8
8
  import {
9
9
  UsageError,
10
10
  parseFormat,
11
11
  parsePdfxFlavor,
12
12
  rejectExtraPositionals,
13
13
  rejectUnknownFlags
14
- } from "./cli-88hddvbz.js";
14
+ } from "./cli-q90qmcvp.js";
15
15
  import"./cli-ht1bcqdd.js";
16
- import"./cli-5x7s8bap.js";
16
+ import"./cli-dm3pa0cw.js";
17
17
  import {
18
18
  BuildError
19
19
  } from "./cli-46ycxe6r.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "./cli-88hddvbz.js";
3
+ } from "./cli-q90qmcvp.js";
4
4
  import {
5
5
  execCapture,
6
6
  findTool,
@@ -1116,7 +1116,7 @@ import { fileURLToPath } from "node:url";
1116
1116
  var favicon_default = "./favicon-272ga6y0.ico";
1117
1117
 
1118
1118
  // src/assets/manifest.schema.json
1119
- var manifest_schema_default = "./manifest.schema-5pzhscqh.json";
1119
+ var manifest_schema_default = "./manifest.schema-nc30dyfs.json";
1120
1120
 
1121
1121
  // src/assets/preview/scripts/preview-interface.js
1122
1122
  var preview_interface_default = "./preview-interface-2n1d9pbf.js";
@@ -1209,7 +1209,7 @@ var page_rules_default = "./page-rules-nsj3aw42.css";
1209
1209
  var book_default = "./book-ted3tzrp.css";
1210
1210
 
1211
1211
  // src/assets/themes/clean-book/theme.css
1212
- var theme_default = "./theme-j2bagrfx.css";
1212
+ var theme_default = "./theme-5729pyq1.css";
1213
1213
 
1214
1214
  // src/assets/themes/clean-book/package.json
1215
1215
  var package_default3 = "./package-97gm31sg.json";
@@ -13,12 +13,12 @@ import {
13
13
  stampCreator,
14
14
  stripAnnotations,
15
15
  warn
16
- } from "./cli-36v78t6w.js";
16
+ } from "./cli-bx24fj78.js";
17
17
  import {
18
18
  DEBOUNCE,
19
19
  UsageError,
20
20
  resolvePort
21
- } from "./cli-88hddvbz.js";
21
+ } from "./cli-q90qmcvp.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-5x7s8bap.js";
30
+ } from "./cli-dm3pa0cw.js";
31
31
  import {
32
32
  BuildError,
33
33
  EXIT_CODES
@@ -6351,6 +6351,7 @@ var ruleRiskyProps = "printsafe/no-risky-print-effects";
6351
6351
  var ruleSyntax = "printsafe/syntax-error";
6352
6352
  var rulePageContainment = "printsafe/page-containment";
6353
6353
  var rulePreviewCannotFollow = "printsafe/preview-cannot-follow";
6354
+ var ruleEngineHyphenation = "printsafe/engine-hyphenation";
6354
6355
  function extractUrls(value) {
6355
6356
  const urls = [];
6356
6357
  const re = /url\(\s*(['"]?)(.*?)\1\s*\)/gi;
@@ -6552,6 +6553,10 @@ function previewBlindSpot(decl) {
6552
6553
  }
6553
6554
  return null;
6554
6555
  }
6556
+ function isAutoHyphenation(decl) {
6557
+ const prop = decl.prop.toLowerCase();
6558
+ return (prop === "hyphens" || prop === "-webkit-hyphens") && decl.value.trim().toLowerCase() === "auto";
6559
+ }
6555
6560
  function nodeLoc(node) {
6556
6561
  return {
6557
6562
  line: node.source?.start?.line ?? 1,
@@ -6670,6 +6675,16 @@ function checkCssRaw(css, from) {
6670
6675
  warnings.push({ rule: rulePreviewCannotFollow, severity: "warning", message, ...nodeLoc(decl) });
6671
6676
  }
6672
6677
  });
6678
+ root.walkDecls((decl) => {
6679
+ if (!isAutoHyphenation(decl))
6680
+ return;
6681
+ warnings.push({
6682
+ rule: ruleEngineHyphenation,
6683
+ severity: "warning",
6684
+ message: `"${decl.prop}: auto" depends on the browser's hyphenation dictionaries, so the desktop app and the CLI (and different operating systems) can break lines and pages differently. Use "hyphens: manual" with soft hyphens (­) for identical pages everywhere.`,
6685
+ ...nodeLoc(decl)
6686
+ });
6687
+ });
6673
6688
  root.walkRules((rule) => {
6674
6689
  if (rule.parent?.type === "atrule") {
6675
6690
  const at = rule.parent.name.toLowerCase();
@@ -10082,7 +10097,7 @@ class PdfOutput {
10082
10097
  const rawPdf = pdfxMode ? path13.join(stage, "raw.pdf") : path13.resolve(pdfFile);
10083
10098
  await fsp2.mkdir(path13.dirname(path13.resolve(pdfFile)), { recursive: true });
10084
10099
  log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
10085
- const { buildNativePdf } = await import("./engine-6zfj0jte.js");
10100
+ const { buildNativePdf } = await import("./engine-vvtkew4q.js");
10086
10101
  const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
10087
10102
  title: config.title,
10088
10103
  author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
@@ -4,7 +4,7 @@ import {
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "gutterpress",
7
- version: "0.11.18-alpha.4",
7
+ version: "0.11.18-alpha.5",
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",
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  UsageError,
7
7
  package_default,
8
8
  rejectUnknownFlags
9
- } from "./cli-88hddvbz.js";
9
+ } from "./cli-q90qmcvp.js";
10
10
  import {
11
11
  EXIT_CODES
12
12
  } from "./cli-46ycxe6r.js";
@@ -18,14 +18,14 @@ import {
18
18
  import { defineCommand, parseArgs, runMain } from "citty";
19
19
  import { statSync } from "node:fs";
20
20
  var SUBCOMMANDS = {
21
- new: () => import("./new-ede0f1nm.js").then((m) => m.default),
22
- preview: () => import("./preview-y2dxxbrk.js").then((m) => m.default),
23
- build: () => import("./build-63nwjhzf.js").then((m) => m.default),
24
- publish: () => import("./publish-n60n0hm1.js").then((m) => m.default),
25
- validate: () => import("./validate-2c7sfyxn.js").then((m) => m.default),
26
- preflight: () => import("./preflight-b6c3k3qt.js").then((m) => m.default),
27
- doctor: () => import("./doctor-n1cwrwx2.js").then((m) => m.default),
28
- ext: () => import("./ext-ddfjfcg4.js").then((m) => m.default)
21
+ new: () => import("./new-zrvm9vpe.js").then((m) => m.default),
22
+ preview: () => import("./preview-xd02xc2h.js").then((m) => m.default),
23
+ build: () => import("./build-hc743bws.js").then((m) => m.default),
24
+ publish: () => import("./publish-1yzay4z4.js").then((m) => m.default),
25
+ validate: () => import("./validate-gmma4d2t.js").then((m) => m.default),
26
+ preflight: () => import("./preflight-h003cdh9.js").then((m) => m.default),
27
+ doctor: () => import("./doctor-vq5xetqk.js").then((m) => m.default),
28
+ ext: () => import("./ext-zspsqk4y.js").then((m) => m.default)
29
29
  };
30
30
  var VERSION = package_default.version;
31
31
  var main = defineCommand({
@@ -50,7 +50,7 @@ async function preflightRequiredInvocations(rawArgs) {
50
50
  const [command, ...commandArgs] = rawArgs;
51
51
  try {
52
52
  if (command === "new") {
53
- const { newArgs } = await import("./new-ede0f1nm.js");
53
+ const { newArgs } = await import("./new-zrvm9vpe.js");
54
54
  rejectUnknownFlags(commandArgs, newArgs, "new");
55
55
  const parsed = parseArgs(commandArgs, {
56
56
  ...newArgs,
@@ -62,7 +62,7 @@ async function preflightRequiredInvocations(rawArgs) {
62
62
  return;
63
63
  }
64
64
  if (command === "preflight") {
65
- const { preflightArgs } = await import("./preflight-b6c3k3qt.js");
65
+ const { preflightArgs } = await import("./preflight-h003cdh9.js");
66
66
  rejectUnknownFlags(commandArgs, preflightArgs, "preflight");
67
67
  const parsed = parseArgs(commandArgs, {
68
68
  ...preflightArgs,
@@ -82,7 +82,7 @@ async function preflightRequiredInvocations(rawArgs) {
82
82
  }
83
83
  if (subcommand.startsWith("-"))
84
84
  return;
85
- const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-ddfjfcg4.js");
85
+ const { EXT_SUBCOMMANDS, extAddArgs, extRemoveArgs, extEnableArgs, extDisableArgs } = await import("./ext-zspsqk4y.js");
86
86
  if (!EXT_SUBCOMMANDS.includes(subcommand)) {
87
87
  throw new UsageError(`gutterpress ext: unknown command "${subcommand}"`);
88
88
  }
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  getSystemDiagnostics,
3
3
  log
4
- } from "./cli-36v78t6w.js";
4
+ } from "./cli-bx24fj78.js";
5
5
  import {
6
6
  UsageError,
7
7
  rejectExtraPositionals,
8
8
  rejectUnknownFlags
9
- } from "./cli-88hddvbz.js";
9
+ } from "./cli-q90qmcvp.js";
10
10
  import"./cli-46ycxe6r.js";
11
11
  import"./cli-7fkhgtfn.js";
12
12
  import"./cli-37x76zdn.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  build
3
- } from "./cli-5x7s8bap.js";
3
+ } from "./cli-dm3pa0cw.js";
4
4
  import {
5
5
  BuildError
6
6
  } from "./cli-46ycxe6r.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  build
3
- } from "./index-qbd874dh.js";
3
+ } from "./index-89zg3jtk.js";
4
4
  import {
5
5
  BuildError
6
- } from "./index-jt552wtf.js";
6
+ } from "./index-pb4fj8m2.js";
7
7
  import"./index-rzm1phg0.js";
8
8
  import"./index-37x76zdn.js";
9
9
 
@@ -12,17 +12,17 @@ import {
12
12
  searchNpmExtensions,
13
13
  setExtensionEnabled,
14
14
  updateExtensions
15
- } from "./cli-dmcy8kay.js";
16
- import"./cli-36v78t6w.js";
15
+ } from "./cli-dxs69beq.js";
16
+ import"./cli-bx24fj78.js";
17
17
  import {
18
18
  UsageError,
19
19
  exitForUsage,
20
20
  rejectExtraPositionals,
21
21
  rejectUnknownFlags,
22
22
  resolveProjectDir
23
- } from "./cli-88hddvbz.js";
23
+ } from "./cli-q90qmcvp.js";
24
24
  import"./cli-ht1bcqdd.js";
25
- import"./cli-5x7s8bap.js";
25
+ import"./cli-dm3pa0cw.js";
26
26
  import {
27
27
  EXIT_CODES
28
28
  } from "./cli-46ycxe6r.js";
@@ -19,7 +19,7 @@ import {
19
19
  stringValueAt,
20
20
  toFolioPage,
21
21
  wantsRecto
22
- } from "./index-jt552wtf.js";
22
+ } from "./index-pb4fj8m2.js";
23
23
  import {
24
24
  launchChromium
25
25
  } from "./index-rzm1phg0.js";
@@ -148,7 +148,7 @@ import { fileURLToPath } from "node:url";
148
148
  var favicon_default = "./favicon-272ga6y0.ico";
149
149
 
150
150
  // src/assets/manifest.schema.json
151
- var manifest_schema_default = "./manifest.schema-5pzhscqh.json";
151
+ var manifest_schema_default = "./manifest.schema-nc30dyfs.json";
152
152
 
153
153
  // src/assets/preview/scripts/preview-interface.js
154
154
  var preview_interface_default = "./preview-interface-2n1d9pbf.js";
@@ -241,7 +241,7 @@ var page_rules_default = "./page-rules-nsj3aw42.css";
241
241
  var book_default = "./book-ted3tzrp.css";
242
242
 
243
243
  // src/assets/themes/clean-book/theme.css
244
- var theme_default = "./theme-j2bagrfx.css";
244
+ var theme_default = "./theme-5729pyq1.css";
245
245
 
246
246
  // src/assets/themes/clean-book/package.json
247
247
  var package_default3 = "./package-97gm31sg.json";
@@ -9,7 +9,7 @@ import {
9
9
  getAssetsDir,
10
10
  lastPageMode,
11
11
  parseSize
12
- } from "./index-jt552wtf.js";
12
+ } from "./index-pb4fj8m2.js";
13
13
  import {
14
14
  INSTALL_HINTS,
15
15
  execCapture,
@@ -5916,7 +5916,7 @@ import git from "isomorphic-git";
5916
5916
  // package.json
5917
5917
  var package_default = {
5918
5918
  name: "gutterpress",
5919
- version: "0.11.18-alpha.4",
5919
+ version: "0.11.18-alpha.5",
5920
5920
  description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
5921
5921
  author: "itlackey",
5922
5922
  license: "MPL-2.0",
@@ -7787,6 +7787,7 @@ var ruleRiskyProps = "printsafe/no-risky-print-effects";
7787
7787
  var ruleSyntax = "printsafe/syntax-error";
7788
7788
  var rulePageContainment = "printsafe/page-containment";
7789
7789
  var rulePreviewCannotFollow = "printsafe/preview-cannot-follow";
7790
+ var ruleEngineHyphenation = "printsafe/engine-hyphenation";
7790
7791
  function extractUrls(value) {
7791
7792
  const urls = [];
7792
7793
  const re = /url\(\s*(['"]?)(.*?)\1\s*\)/gi;
@@ -7988,6 +7989,10 @@ function previewBlindSpot(decl) {
7988
7989
  }
7989
7990
  return null;
7990
7991
  }
7992
+ function isAutoHyphenation(decl) {
7993
+ const prop = decl.prop.toLowerCase();
7994
+ return (prop === "hyphens" || prop === "-webkit-hyphens") && decl.value.trim().toLowerCase() === "auto";
7995
+ }
7991
7996
  function nodeLoc(node) {
7992
7997
  return {
7993
7998
  line: node.source?.start?.line ?? 1,
@@ -8106,6 +8111,16 @@ function checkCssRaw(css, from) {
8106
8111
  warnings.push({ rule: rulePreviewCannotFollow, severity: "warning", message, ...nodeLoc(decl) });
8107
8112
  }
8108
8113
  });
8114
+ root.walkDecls((decl) => {
8115
+ if (!isAutoHyphenation(decl))
8116
+ return;
8117
+ warnings.push({
8118
+ rule: ruleEngineHyphenation,
8119
+ severity: "warning",
8120
+ message: `"${decl.prop}: auto" depends on the browser's hyphenation dictionaries, so the desktop app and the CLI (and different operating systems) can break lines and pages differently. Use "hyphens: manual" with soft hyphens (­) for identical pages everywhere.`,
8121
+ ...nodeLoc(decl)
8122
+ });
8123
+ });
8109
8124
  root.walkRules((rule) => {
8110
8125
  if (rule.parent?.type === "atrule") {
8111
8126
  const at = rule.parent.name.toLowerCase();
@@ -10662,7 +10677,7 @@ class PdfOutput {
10662
10677
  const rawPdf = pdfxMode ? path13.join(stage, "raw.pdf") : path13.resolve(pdfFile);
10663
10678
  await fsp2.mkdir(path13.dirname(path13.resolve(pdfFile)), { recursive: true });
10664
10679
  log.info("Rendering HTML to PDF via the Gutterpress engine (native Chromium pagination)");
10665
- const { buildNativePdf } = await import("./engine-zw8626be.js");
10680
+ const { buildNativePdf } = await import("./engine-wjz5yhmp.js");
10666
10681
  const engineDiagnostics = await buildNativePdf(htmlFile, rawPdf, {
10667
10682
  title: config.title,
10668
10683
  author: config.authors.length > 0 ? config.authors.join(", ") : undefined,
package/dist/index.js CHANGED
@@ -153,14 +153,14 @@ import {
153
153
  testRemoteAccess,
154
154
  updateExtensions,
155
155
  validateProjectExtensions
156
- } from "./index-1ergtg60.js";
156
+ } from "./index-r2ry6j3x.js";
157
157
  import"./index-ht1bcqdd.js";
158
158
  import {
159
159
  BUILD_DIAGNOSTIC_CODES
160
- } from "./index-qbd874dh.js";
160
+ } from "./index-89zg3jtk.js";
161
161
  import {
162
162
  BuildError
163
- } from "./index-jt552wtf.js";
163
+ } from "./index-pb4fj8m2.js";
164
164
  import {
165
165
  DEFAULT_PRINT_OPTS,
166
166
  assertMilestone,
@@ -3,6 +3,7 @@ export declare const ruleRiskyProps = "printsafe/no-risky-print-effects";
3
3
  export declare const ruleSyntax = "printsafe/syntax-error";
4
4
  export declare const rulePageContainment = "printsafe/page-containment";
5
5
  export declare const rulePreviewCannotFollow = "printsafe/preview-cannot-follow";
6
+ export declare const ruleEngineHyphenation = "printsafe/engine-hyphenation";
6
7
  export interface PrintSafeWarning {
7
8
  rule: string;
8
9
  severity: "error" | "warning";
@@ -243,7 +243,7 @@
243
243
  },
244
244
  "rules": {
245
245
  "type": "object",
246
- "description": "Per-rule level overrides, keyed by rule id: a printsafe rule (printsafe/no-risky-print-effects, printsafe/page-containment, printsafe/preview-cannot-follow, printsafe/no-remote-urls) or a check id such as source.accessibility.heading-order. \"off\" silences the rule; \"warn\" / \"error\" set its severity. An id that matches no rule is ignored. To silence one site instead, put a `gutterpress-disable-next-line <rule-id> -- reason` comment (CSS `/* */` or markdown `<!-- -->`) on the line above it.",
246
+ "description": "Per-rule level overrides, keyed by rule id: a printsafe rule (printsafe/no-risky-print-effects, printsafe/page-containment, printsafe/preview-cannot-follow, printsafe/engine-hyphenation, printsafe/no-remote-urls) or a check id such as source.accessibility.heading-order. \"off\" silences the rule; \"warn\" / \"error\" set its severity. An id that matches no rule is ignored. To silence one site instead, put a `gutterpress-disable-next-line <rule-id> -- reason` comment (CSS `/* */` or markdown `<!-- -->`) on the line above it.",
247
247
  "additionalProperties": { "enum": ["off", "warn", "error"] },
248
248
  "examples": [{ "printsafe/no-risky-print-effects": "off" }]
249
249
  }
@@ -7,17 +7,17 @@ import {
7
7
  TARGET_IDS,
8
8
  scaffoldExtension,
9
9
  scaffoldProject
10
- } from "./cli-dmcy8kay.js";
10
+ } from "./cli-dxs69beq.js";
11
11
  import {
12
12
  resolveGhostscript
13
- } from "./cli-36v78t6w.js";
13
+ } from "./cli-bx24fj78.js";
14
14
  import {
15
15
  UsageError,
16
16
  rejectExtraPositionals,
17
17
  rejectUnknownFlags
18
- } from "./cli-88hddvbz.js";
18
+ } from "./cli-q90qmcvp.js";
19
19
  import"./cli-ht1bcqdd.js";
20
- import"./cli-5x7s8bap.js";
20
+ import"./cli-dm3pa0cw.js";
21
21
  import {
22
22
  EXIT_CODES
23
23
  } from "./cli-46ycxe6r.js";
@@ -2,17 +2,17 @@ import {
2
2
  executeValidation,
3
3
  publishTargetFor,
4
4
  reportMissingTools
5
- } from "./cli-dmcy8kay.js";
5
+ } from "./cli-dxs69beq.js";
6
6
  import {
7
7
  log
8
- } from "./cli-36v78t6w.js";
8
+ } from "./cli-bx24fj78.js";
9
9
  import {
10
10
  UsageError,
11
11
  rejectExtraPositionals,
12
12
  rejectUnknownFlags
13
- } from "./cli-88hddvbz.js";
13
+ } from "./cli-q90qmcvp.js";
14
14
  import"./cli-ht1bcqdd.js";
15
- import"./cli-5x7s8bap.js";
15
+ import"./cli-dm3pa0cw.js";
16
16
  import {
17
17
  BuildError,
18
18
  EXIT_CODES
@@ -7,10 +7,10 @@ import {
7
7
  runBuild,
8
8
  splitOutPath,
9
9
  startPreviewServer
10
- } from "./cli-dmcy8kay.js";
10
+ } from "./cli-dxs69beq.js";
11
11
  import {
12
12
  log
13
- } from "./cli-36v78t6w.js";
13
+ } from "./cli-bx24fj78.js";
14
14
  import {
15
15
  UsageError,
16
16
  parseFormat,
@@ -18,9 +18,9 @@ import {
18
18
  rejectExtraPositionals,
19
19
  rejectUnknownFlags,
20
20
  resolvePort
21
- } from "./cli-88hddvbz.js";
21
+ } from "./cli-q90qmcvp.js";
22
22
  import"./cli-ht1bcqdd.js";
23
- import"./cli-5x7s8bap.js";
23
+ import"./cli-dm3pa0cw.js";
24
24
  import {
25
25
  BuildError
26
26
  } from "./cli-46ycxe6r.js";
@@ -11,18 +11,18 @@ import {
11
11
  publishProviderFor,
12
12
  resolvePublishFormat,
13
13
  runPublish
14
- } from "./cli-dmcy8kay.js";
14
+ } from "./cli-dxs69beq.js";
15
15
  import {
16
16
  FileTokenStore,
17
17
  log
18
- } from "./cli-36v78t6w.js";
18
+ } from "./cli-bx24fj78.js";
19
19
  import {
20
20
  UsageError,
21
21
  rejectExtraPositionals,
22
22
  rejectUnknownFlags
23
- } from "./cli-88hddvbz.js";
23
+ } from "./cli-q90qmcvp.js";
24
24
  import"./cli-ht1bcqdd.js";
25
- import"./cli-5x7s8bap.js";
25
+ import"./cli-dm3pa0cw.js";
26
26
  import {
27
27
  EXIT_CODES
28
28
  } from "./cli-46ycxe6r.js";
@@ -44,7 +44,10 @@ h1 { font-size: var(--fs-h1); margin: 0 0 0.6em; }
44
44
  h2 { font-size: var(--fs-h2); margin: 1.4em 0 0.4em; }
45
45
  h3 { font-size: var(--fs-h3); margin: 1.2em 0 0.3em; }
46
46
 
47
- p { margin: 0 0 0.8em; text-align: justify; hyphens: auto; }
47
+ /* hyphens: manual, not auto: auto breaks words only where the running Chromium
48
+ ships dictionaries (desktop app and CLI differ), which changes the page count.
49
+ Authors add soft hyphens (&shy;) where they want a break. */
50
+ p { margin: 0 0 0.8em; text-align: justify; hyphens: manual; }
48
51
 
49
52
  a { color: var(--color-accent); text-decoration: none; }
50
53
 
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  executeAndReport
3
- } from "./cli-dmcy8kay.js";
3
+ } from "./cli-dxs69beq.js";
4
4
  import {
5
5
  log
6
- } from "./cli-36v78t6w.js";
6
+ } from "./cli-bx24fj78.js";
7
7
  import {
8
8
  UsageError,
9
9
  rejectExtraPositionals,
10
10
  rejectUnknownFlags
11
- } from "./cli-88hddvbz.js";
11
+ } from "./cli-q90qmcvp.js";
12
12
  import"./cli-ht1bcqdd.js";
13
- import"./cli-5x7s8bap.js";
13
+ import"./cli-dm3pa0cw.js";
14
14
  import {
15
15
  BuildError,
16
16
  EXIT_CODES
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gutterpress",
3
- "version": "0.11.18-alpha.4",
3
+ "version": "0.11.18-alpha.5",
4
4
  "description": "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
5
5
  "author": "itlackey",
6
6
  "license": "MPL-2.0",