@optique/man 1.0.0-dev.900 → 1.0.0-dev.921

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/cli.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- const require_man = require('./man-DFKETOWN.cjs');
2
+ const require_man = require('./man-Bah5ZMyV.cjs');
3
3
  require('./roff-Cl0vekdg.cjs');
4
- const require_generator = require('./generator-BkWfsb4u.cjs');
4
+ const require_generator = require('./generator-bugVqGJn.cjs');
5
5
  const __optique_core_constructs = require_man.__toESM(require("@optique/core/constructs"));
6
6
  const __optique_core_primitives = require_man.__toESM(require("@optique/core/primitives"));
7
7
  const __optique_core_valueparser = require_man.__toESM(require("@optique/core/valueparser"));
@@ -17,7 +17,7 @@ const node_url = require_man.__toESM(require("node:url"));
17
17
 
18
18
  //#region deno.json
19
19
  var name = "@optique/man";
20
- var version = "1.0.0-dev.900+d7ebaa88";
20
+ var version = "1.0.0-dev.921+754748bd";
21
21
  var license = "MIT";
22
22
  var exports$1 = {
23
23
  ".": "./src/index.ts",
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import "./roff-CwBRpWCo.js";
3
- import "./man-BBDifH_Y.js";
4
- import { generateManPageAsync } from "./generator-DZnf5j1D.js";
3
+ import "./man-BiY491LQ.js";
4
+ import { generateManPageAsync } from "./generator-CnMxnsMc.js";
5
5
  import { object } from "@optique/core/constructs";
6
6
  import { argument, option } from "@optique/core/primitives";
7
7
  import { choice, string } from "@optique/core/valueparser";
@@ -17,7 +17,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
17
17
 
18
18
  //#region deno.json
19
19
  var name = "@optique/man";
20
- var version = "1.0.0-dev.900+d7ebaa88";
20
+ var version = "1.0.0-dev.921+754748bd";
21
21
  var license = "MIT";
22
22
  var exports = {
23
23
  ".": "./src/index.ts",
@@ -1,4 +1,4 @@
1
- import { formatDocPageAsMan } from "./man-BBDifH_Y.js";
1
+ import { formatDocPageAsMan } from "./man-BiY491LQ.js";
2
2
  import { getDocPageAsync, getDocPageSync } from "@optique/core/parser";
3
3
 
4
4
  //#region src/generator.ts
@@ -1,4 +1,4 @@
1
- const require_man = require('./man-DFKETOWN.cjs');
1
+ const require_man = require('./man-Bah5ZMyV.cjs');
2
2
  const __optique_core_parser = require_man.__toESM(require("@optique/core/parser"));
3
3
 
4
4
  //#region src/generator.ts
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
- const require_man = require('./man-DFKETOWN.cjs');
1
+ const require_man = require('./man-Bah5ZMyV.cjs');
2
2
  const require_roff = require('./roff-Cl0vekdg.cjs');
3
- const require_generator = require('./generator-BkWfsb4u.cjs');
3
+ const require_generator = require('./generator-bugVqGJn.cjs');
4
4
 
5
5
  exports.escapeHyphens = require_roff.escapeHyphens;
6
6
  exports.escapeQuotedValue = require_roff.escapeQuotedValue;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-C_87xXP6.cjs";
2
- import { ManPageOptions, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-xPX8GhXq.cjs";
2
+ import { ManPageOptions, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-Dp4oW-al.cjs";
3
3
  import { Mode, ModeValue, Parser } from "@optique/core/parser";
4
4
  import { Program } from "@optique/core/program";
5
5
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-DlmeL3KB.js";
2
- import { ManPageOptions, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-CGKLHWkS.js";
2
+ import { ManPageOptions, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-CGBnZvZF.js";
3
3
  import { Program } from "@optique/core/program";
4
4
  import { Mode, ModeValue, Parser } from "@optique/core/parser";
5
5
 
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-CwBRpWCo.js";
2
- import { formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-BBDifH_Y.js";
3
- import { generateManPage, generateManPageAsync, generateManPageSync } from "./generator-DZnf5j1D.js";
2
+ import { formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-BiY491LQ.js";
3
+ import { generateManPage, generateManPageAsync, generateManPageSync } from "./generator-CnMxnsMc.js";
4
4
 
5
5
  export { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatDateForMan, formatDocPageAsMan, formatMessageAsRoff, formatUsageTermAsRoff, generateManPage, generateManPageAsync, generateManPageSync };
@@ -28,6 +28,12 @@ const __optique_core_usage = __toESM(require("@optique/core/usage"));
28
28
  /**
29
29
  * Formats a date for use in man pages.
30
30
  *
31
+ * When a `Date` object is given, the month and year are extracted using
32
+ * the host's local timezone (`getMonth()` / `getFullYear()`). This means
33
+ * the same `Date` instant may produce different output on machines in
34
+ * different timezones. Pass a pre-formatted string (e.g., `"January 2026"`)
35
+ * if you need timezone-independent output.
36
+ *
31
37
  * @param date The date to format, or undefined.
32
38
  * @returns The formatted date string, or undefined.
33
39
  * @since 0.10.0
@@ -51,9 +57,6 @@ function formatDateForMan(date) {
51
57
  ];
52
58
  return `${months[date.getMonth()]} ${date.getFullYear()}`;
53
59
  }
54
- function escapeThField(value) {
55
- return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
56
- }
57
60
  function formatCommandNameAsRoff(name) {
58
61
  return `\\fB${require_roff.escapeHyphens(require_roff.escapeRoff(name))}\\fR`;
59
62
  }
@@ -228,8 +231,8 @@ function formatDocSectionEntries(section) {
228
231
  * @param options The man page options.
229
232
  * @returns The complete man page in roff format.
230
233
  * @throws {TypeError} If the program name is empty.
231
- * @throws {RangeError} If the section number is not a valid man page section
232
- * (1–8).
234
+ * @throws {RangeError} If the section number or any `seeAlso` entry's section
235
+ * number is not a valid man page section (1–8).
233
236
  * @since 0.10.0
234
237
  */
235
238
  function formatDocPageAsMan(page, options) {
@@ -244,22 +247,22 @@ function formatDocPageAsMan(page, options) {
244
247
  throw new RangeError(`Invalid man page section number (must be 1–8): ${repr}`);
245
248
  }
246
249
  const lines = [];
247
- const thParts = [require_roff.escapeHyphens(escapeThField(options.name).toUpperCase()), options.section.toString()];
250
+ const thParts = [`"${require_roff.escapeHyphens(require_roff.escapeRequestArg(options.name.toUpperCase()))}"`, options.section.toString()];
248
251
  const hasDate = options.date != null && options.date !== "";
249
252
  const hasVersion = options.version != null && options.version !== "";
250
253
  const hasManual = options.manual != null && options.manual !== "";
251
- if (hasDate) thParts.push(`"${escapeThField(formatDateForMan(options.date))}"`);
254
+ if (hasDate) thParts.push(`"${require_roff.escapeRequestArg(formatDateForMan(options.date))}"`);
252
255
  else if (hasVersion || hasManual) thParts.push("\"\"");
253
- if (hasVersion) thParts.push(`"${require_roff.escapeHyphens(escapeThField(options.name))} ${escapeThField(options.version)}"`);
256
+ if (hasVersion) thParts.push(`"${require_roff.escapeHyphens(require_roff.escapeRequestArg(options.name))} ${require_roff.escapeRequestArg(options.version)}"`);
254
257
  else if (hasManual) thParts.push("\"\"");
255
- if (hasManual) thParts.push(`"${escapeThField(options.manual)}"`);
258
+ if (hasManual) thParts.push(`"${require_roff.escapeRequestArg(options.manual)}"`);
256
259
  lines.push(`.TH ${thParts.join(" ")}`);
257
260
  lines.push(".SH NAME");
258
261
  if (page.brief) lines.push(`${require_roff.escapeHyphens(require_roff.escapeRoff(options.name))} \\- ${require_roff.formatMessageAsRoff(page.brief)}`);
259
262
  else lines.push(require_roff.escapeHyphens(require_roff.escapeRoff(options.name)));
260
263
  if (page.usage) {
261
264
  lines.push(".SH SYNOPSIS");
262
- lines.push(`.B ${require_roff.escapeHyphens(require_roff.escapeRoff(options.name))}`);
265
+ lines.push(`.B "${require_roff.escapeHyphens(require_roff.escapeRequestArg(options.name))}"`);
263
266
  const usageStr = formatUsageAsRoff(page.usage);
264
267
  if (usageStr) lines.push(usageStr);
265
268
  }
@@ -305,10 +308,19 @@ function formatDocPageAsMan(page, options) {
305
308
  lines.push(require_roff.formatMessageAsRoff(options.bugs));
306
309
  }
307
310
  if (options.seeAlso && options.seeAlso.length > 0) {
311
+ for (const ref of options.seeAlso) if (!Number.isInteger(ref.section) || ref.section < 1 || ref.section > 8) {
312
+ let repr;
313
+ try {
314
+ repr = JSON.stringify(ref.section);
315
+ } catch {
316
+ repr = String(typeof ref.section);
317
+ }
318
+ throw new RangeError(`Invalid man page section number for seeAlso entry ${JSON.stringify(ref.name)} (must be 1–8): ${repr}`);
319
+ }
308
320
  lines.push(".SH SEE ALSO");
309
321
  const refs = options.seeAlso.map((ref, i) => {
310
322
  const suffix = i < options.seeAlso.length - 1 ? "," : "";
311
- return `.BR ${require_roff.escapeHyphens(require_roff.escapeRoff(ref.name))} (${ref.section})${suffix}`;
323
+ return `.BR "${require_roff.escapeHyphens(require_roff.escapeRequestArg(ref.name))}" (${ref.section})${suffix}`;
312
324
  });
313
325
  lines.push(refs.join("\n"));
314
326
  }
@@ -5,6 +5,12 @@ import { isDocHidden, isUsageHidden } from "@optique/core/usage";
5
5
  /**
6
6
  * Formats a date for use in man pages.
7
7
  *
8
+ * When a `Date` object is given, the month and year are extracted using
9
+ * the host's local timezone (`getMonth()` / `getFullYear()`). This means
10
+ * the same `Date` instant may produce different output on machines in
11
+ * different timezones. Pass a pre-formatted string (e.g., `"January 2026"`)
12
+ * if you need timezone-independent output.
13
+ *
8
14
  * @param date The date to format, or undefined.
9
15
  * @returns The formatted date string, or undefined.
10
16
  * @since 0.10.0
@@ -28,9 +34,6 @@ function formatDateForMan(date) {
28
34
  ];
29
35
  return `${months[date.getMonth()]} ${date.getFullYear()}`;
30
36
  }
31
- function escapeThField(value) {
32
- return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
33
- }
34
37
  function formatCommandNameAsRoff(name) {
35
38
  return `\\fB${escapeHyphens(escapeRoff(name))}\\fR`;
36
39
  }
@@ -205,8 +208,8 @@ function formatDocSectionEntries(section) {
205
208
  * @param options The man page options.
206
209
  * @returns The complete man page in roff format.
207
210
  * @throws {TypeError} If the program name is empty.
208
- * @throws {RangeError} If the section number is not a valid man page section
209
- * (1–8).
211
+ * @throws {RangeError} If the section number or any `seeAlso` entry's section
212
+ * number is not a valid man page section (1–8).
210
213
  * @since 0.10.0
211
214
  */
212
215
  function formatDocPageAsMan(page, options) {
@@ -221,22 +224,22 @@ function formatDocPageAsMan(page, options) {
221
224
  throw new RangeError(`Invalid man page section number (must be 1–8): ${repr}`);
222
225
  }
223
226
  const lines = [];
224
- const thParts = [escapeHyphens(escapeThField(options.name).toUpperCase()), options.section.toString()];
227
+ const thParts = [`"${escapeHyphens(escapeRequestArg(options.name.toUpperCase()))}"`, options.section.toString()];
225
228
  const hasDate = options.date != null && options.date !== "";
226
229
  const hasVersion = options.version != null && options.version !== "";
227
230
  const hasManual = options.manual != null && options.manual !== "";
228
- if (hasDate) thParts.push(`"${escapeThField(formatDateForMan(options.date))}"`);
231
+ if (hasDate) thParts.push(`"${escapeRequestArg(formatDateForMan(options.date))}"`);
229
232
  else if (hasVersion || hasManual) thParts.push("\"\"");
230
- if (hasVersion) thParts.push(`"${escapeHyphens(escapeThField(options.name))} ${escapeThField(options.version)}"`);
233
+ if (hasVersion) thParts.push(`"${escapeHyphens(escapeRequestArg(options.name))} ${escapeRequestArg(options.version)}"`);
231
234
  else if (hasManual) thParts.push("\"\"");
232
- if (hasManual) thParts.push(`"${escapeThField(options.manual)}"`);
235
+ if (hasManual) thParts.push(`"${escapeRequestArg(options.manual)}"`);
233
236
  lines.push(`.TH ${thParts.join(" ")}`);
234
237
  lines.push(".SH NAME");
235
238
  if (page.brief) lines.push(`${escapeHyphens(escapeRoff(options.name))} \\- ${formatMessageAsRoff(page.brief)}`);
236
239
  else lines.push(escapeHyphens(escapeRoff(options.name)));
237
240
  if (page.usage) {
238
241
  lines.push(".SH SYNOPSIS");
239
- lines.push(`.B ${escapeHyphens(escapeRoff(options.name))}`);
242
+ lines.push(`.B "${escapeHyphens(escapeRequestArg(options.name))}"`);
240
243
  const usageStr = formatUsageAsRoff(page.usage);
241
244
  if (usageStr) lines.push(usageStr);
242
245
  }
@@ -282,10 +285,19 @@ function formatDocPageAsMan(page, options) {
282
285
  lines.push(formatMessageAsRoff(options.bugs));
283
286
  }
284
287
  if (options.seeAlso && options.seeAlso.length > 0) {
288
+ for (const ref of options.seeAlso) if (!Number.isInteger(ref.section) || ref.section < 1 || ref.section > 8) {
289
+ let repr;
290
+ try {
291
+ repr = JSON.stringify(ref.section);
292
+ } catch {
293
+ repr = String(typeof ref.section);
294
+ }
295
+ throw new RangeError(`Invalid man page section number for seeAlso entry ${JSON.stringify(ref.name)} (must be 1–8): ${repr}`);
296
+ }
285
297
  lines.push(".SH SEE ALSO");
286
298
  const refs = options.seeAlso.map((ref, i) => {
287
299
  const suffix = i < options.seeAlso.length - 1 ? "," : "";
288
- return `.BR ${escapeHyphens(escapeRoff(ref.name))} (${ref.section})${suffix}`;
300
+ return `.BR "${escapeHyphens(escapeRequestArg(ref.name))}" (${ref.section})${suffix}`;
289
301
  });
290
302
  lines.push(refs.join("\n"));
291
303
  }
@@ -1,6 +1,6 @@
1
1
  import { Message } from "@optique/core/message";
2
- import { DocPage, DocSection } from "@optique/core/doc";
3
2
  import { UsageTerm } from "@optique/core/usage";
3
+ import { DocPage, DocSection } from "@optique/core/doc";
4
4
 
5
5
  //#region src/man.d.ts
6
6
 
@@ -32,7 +32,9 @@ interface ManPageOptions {
32
32
  readonly section: ManPageSection;
33
33
  /**
34
34
  * The date to display in the man page footer.
35
- * If a Date object is provided, it will be formatted as "Month Year".
35
+ * If a `Date` object is provided, it will be formatted as `"Month Year"`
36
+ * using the host's local timezone. For timezone-independent output (e.g.,
37
+ * in CI), pass a pre-formatted string instead.
36
38
  * If a string is provided, it will be used as-is.
37
39
  */
38
40
  readonly date?: string | Date;
@@ -62,7 +64,7 @@ interface ManPageOptions {
62
64
  */
63
65
  readonly seeAlso?: ReadonlyArray<{
64
66
  readonly name: string;
65
- readonly section: number;
67
+ readonly section: ManPageSection;
66
68
  }>;
67
69
  /**
68
70
  * Environment variables to document in the ENVIRONMENT section.
@@ -80,6 +82,12 @@ interface ManPageOptions {
80
82
  /**
81
83
  * Formats a date for use in man pages.
82
84
  *
85
+ * When a `Date` object is given, the month and year are extracted using
86
+ * the host's local timezone (`getMonth()` / `getFullYear()`). This means
87
+ * the same `Date` instant may produce different output on machines in
88
+ * different timezones. Pass a pre-formatted string (e.g., `"January 2026"`)
89
+ * if you need timezone-independent output.
90
+ *
83
91
  * @param date The date to format, or undefined.
84
92
  * @returns The formatted date string, or undefined.
85
93
  * @since 0.10.0
@@ -122,8 +130,8 @@ declare function formatUsageTermAsRoff(term: UsageTerm): string;
122
130
  * @param options The man page options.
123
131
  * @returns The complete man page in roff format.
124
132
  * @throws {TypeError} If the program name is empty.
125
- * @throws {RangeError} If the section number is not a valid man page section
126
- * (1–8).
133
+ * @throws {RangeError} If the section number or any `seeAlso` entry's section
134
+ * number is not a valid man page section (1–8).
127
135
  * @since 0.10.0
128
136
  */
129
137
  declare function formatDocPageAsMan(page: DocPage, options: ManPageOptions): string;
@@ -1,6 +1,6 @@
1
1
  import { Message } from "@optique/core/message";
2
- import { UsageTerm } from "@optique/core/usage";
3
2
  import { DocPage, DocSection } from "@optique/core/doc";
3
+ import { UsageTerm } from "@optique/core/usage";
4
4
 
5
5
  //#region src/man.d.ts
6
6
 
@@ -32,7 +32,9 @@ interface ManPageOptions {
32
32
  readonly section: ManPageSection;
33
33
  /**
34
34
  * The date to display in the man page footer.
35
- * If a Date object is provided, it will be formatted as "Month Year".
35
+ * If a `Date` object is provided, it will be formatted as `"Month Year"`
36
+ * using the host's local timezone. For timezone-independent output (e.g.,
37
+ * in CI), pass a pre-formatted string instead.
36
38
  * If a string is provided, it will be used as-is.
37
39
  */
38
40
  readonly date?: string | Date;
@@ -62,7 +64,7 @@ interface ManPageOptions {
62
64
  */
63
65
  readonly seeAlso?: ReadonlyArray<{
64
66
  readonly name: string;
65
- readonly section: number;
67
+ readonly section: ManPageSection;
66
68
  }>;
67
69
  /**
68
70
  * Environment variables to document in the ENVIRONMENT section.
@@ -80,6 +82,12 @@ interface ManPageOptions {
80
82
  /**
81
83
  * Formats a date for use in man pages.
82
84
  *
85
+ * When a `Date` object is given, the month and year are extracted using
86
+ * the host's local timezone (`getMonth()` / `getFullYear()`). This means
87
+ * the same `Date` instant may produce different output on machines in
88
+ * different timezones. Pass a pre-formatted string (e.g., `"January 2026"`)
89
+ * if you need timezone-independent output.
90
+ *
83
91
  * @param date The date to format, or undefined.
84
92
  * @returns The formatted date string, or undefined.
85
93
  * @since 0.10.0
@@ -122,8 +130,8 @@ declare function formatUsageTermAsRoff(term: UsageTerm): string;
122
130
  * @param options The man page options.
123
131
  * @returns The complete man page in roff format.
124
132
  * @throws {TypeError} If the program name is empty.
125
- * @throws {RangeError} If the section number is not a valid man page section
126
- * (1–8).
133
+ * @throws {RangeError} If the section number or any `seeAlso` entry's section
134
+ * number is not a valid man page section (1–8).
127
135
  * @since 0.10.0
128
136
  */
129
137
  declare function formatDocPageAsMan(page: DocPage, options: ManPageOptions): string;
package/dist/man.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_man = require('./man-DFKETOWN.cjs');
1
+ const require_man = require('./man-Bah5ZMyV.cjs');
2
2
  require('./roff-Cl0vekdg.cjs');
3
3
 
4
4
  exports.formatDateForMan = require_man.formatDateForMan;
package/dist/man.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { ManPageOptions, ManPageSection, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-xPX8GhXq.cjs";
1
+ import { ManPageOptions, ManPageSection, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-Dp4oW-al.cjs";
2
2
  export { ManPageOptions, ManPageSection, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff };
package/dist/man.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { ManPageOptions, ManPageSection, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-CGKLHWkS.js";
1
+ import { ManPageOptions, ManPageSection, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-CGBnZvZF.js";
2
2
  export { ManPageOptions, ManPageSection, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff };
package/dist/man.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import "./roff-CwBRpWCo.js";
2
- import { formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-BBDifH_Y.js";
2
+ import { formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-BiY491LQ.js";
3
3
 
4
4
  export { formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/man",
3
- "version": "1.0.0-dev.900+d7ebaa88",
3
+ "version": "1.0.0-dev.921+754748bd",
4
4
  "description": "Man page generator for Optique CLI parsers",
5
5
  "keywords": [
6
6
  "CLI",
@@ -84,8 +84,8 @@
84
84
  "optique-man": "./dist/cli.js"
85
85
  },
86
86
  "dependencies": {
87
- "@optique/core": "1.0.0-dev.900+d7ebaa88",
88
- "@optique/run": "1.0.0-dev.900+d7ebaa88"
87
+ "@optique/core": "1.0.0-dev.921+754748bd",
88
+ "@optique/run": "1.0.0-dev.921+754748bd"
89
89
  },
90
90
  "devDependencies": {
91
91
  "@types/node": "^20.19.9",