@optique/man 1.0.0-dev.921 → 1.0.1
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 +5 -5
- package/dist/cli.js +5 -5
- package/dist/{generator-CnMxnsMc.js → generator-D5cbsYWL.js} +7 -3
- package/dist/{generator-bugVqGJn.cjs → generator-DXD_dkL9.cjs} +7 -3
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +3 -3
- package/dist/{man-CGBnZvZF.d.ts → man-B1Q2mhit.d.ts} +19 -0
- package/dist/{man-BiY491LQ.js → man-BE1OY_lJ.js} +89 -19
- package/dist/{man-Bah5ZMyV.cjs → man-CkvscTlM.cjs} +89 -19
- package/dist/{man-Dp4oW-al.d.cts → man-DKwa47XV.d.cts} +19 -0
- package/dist/man.cjs +2 -2
- package/dist/man.d.cts +1 -1
- package/dist/man.d.ts +1 -1
- package/dist/man.js +2 -2
- package/dist/{roff-CwBRpWCo.js → roff-CCdIQO7B.js} +9 -4
- package/dist/{roff-C_87xXP6.d.cts → roff-COeDIWWF.d.cts} +17 -2
- package/dist/{roff-DlmeL3KB.d.ts → roff-CgYQDHBN.d.ts} +17 -2
- package/dist/{roff-Cl0vekdg.cjs → roff-DJ-LkRXl.cjs} +9 -4
- package/dist/roff.cjs +1 -1
- package/dist/roff.d.cts +2 -2
- package/dist/roff.d.ts +2 -2
- package/dist/roff.js +1 -1
- package/package.json +3 -3
package/dist/cli.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_man = require('./man-
|
|
3
|
-
require('./roff-
|
|
4
|
-
const require_generator = require('./generator-
|
|
2
|
+
const require_man = require('./man-CkvscTlM.cjs');
|
|
3
|
+
require('./roff-DJ-LkRXl.cjs');
|
|
4
|
+
const require_generator = require('./generator-DXD_dkL9.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.
|
|
20
|
+
var version = "1.0.1";
|
|
21
21
|
var license = "MIT";
|
|
22
22
|
var exports$1 = {
|
|
23
23
|
".": "./src/index.ts",
|
|
@@ -341,7 +341,7 @@ function isProgram(value) {
|
|
|
341
341
|
*/
|
|
342
342
|
function isParser(value) {
|
|
343
343
|
try {
|
|
344
|
-
return value != null && typeof value === "object" && "parse" in value && typeof value.parse === "function" && "
|
|
344
|
+
return value != null && typeof value === "object" && "parse" in value && typeof value.parse === "function" && "mode" in value && "usage" in value && "getDocFragments" in value && typeof value.getDocFragments === "function";
|
|
345
345
|
} catch {
|
|
346
346
|
return false;
|
|
347
347
|
}
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./roff-
|
|
3
|
-
import "./man-
|
|
4
|
-
import { generateManPageAsync } from "./generator-
|
|
2
|
+
import "./roff-CCdIQO7B.js";
|
|
3
|
+
import "./man-BE1OY_lJ.js";
|
|
4
|
+
import { generateManPageAsync } from "./generator-D5cbsYWL.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.
|
|
20
|
+
var version = "1.0.1";
|
|
21
21
|
var license = "MIT";
|
|
22
22
|
var exports = {
|
|
23
23
|
".": "./src/index.ts",
|
|
@@ -341,7 +341,7 @@ function isProgram(value) {
|
|
|
341
341
|
*/
|
|
342
342
|
function isParser(value) {
|
|
343
343
|
try {
|
|
344
|
-
return value != null && typeof value === "object" && "parse" in value && typeof value.parse === "function" && "
|
|
344
|
+
return value != null && typeof value === "object" && "parse" in value && typeof value.parse === "function" && "mode" in value && "usage" in value && "getDocFragments" in value && typeof value.getDocFragments === "function";
|
|
345
345
|
} catch {
|
|
346
346
|
return false;
|
|
347
347
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { formatDocPageAsMan } from "./man-
|
|
1
|
+
import { formatDocPageAsMan } from "./man-BE1OY_lJ.js";
|
|
2
2
|
import { getDocPageAsync, getDocPageSync } from "@optique/core/parser";
|
|
3
3
|
|
|
4
4
|
//#region src/generator.ts
|
|
@@ -9,7 +9,7 @@ function isParser(value) {
|
|
|
9
9
|
try {
|
|
10
10
|
if (value == null || typeof value !== "object") return false;
|
|
11
11
|
const p = value;
|
|
12
|
-
return "parse" in p && typeof p.parse === "function" && "complete" in p && typeof p.complete === "function" && "
|
|
12
|
+
return "parse" in p && typeof p.parse === "function" && "complete" in p && typeof p.complete === "function" && "mode" in p && (p.mode === "sync" || p.mode === "async") && "usage" in p && Array.isArray(p.usage) && "initialState" in p && "suggest" in p && typeof p.suggest === "function" && "getDocFragments" in p && typeof p.getDocFragments === "function";
|
|
13
13
|
} catch {
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
@@ -50,6 +50,9 @@ function extractParserAndOptions(parserOrProgram, options) {
|
|
|
50
50
|
author: programOptions.author ?? metadata.author,
|
|
51
51
|
bugs: programOptions.bugs ?? metadata.bugs,
|
|
52
52
|
examples: programOptions.examples ?? metadata.examples,
|
|
53
|
+
brief: programOptions.brief ?? metadata.brief,
|
|
54
|
+
description: programOptions.description ?? metadata.description,
|
|
55
|
+
footer: programOptions.footer ?? metadata.footer,
|
|
53
56
|
seeAlso: programOptions.seeAlso,
|
|
54
57
|
environment: programOptions.environment,
|
|
55
58
|
files: programOptions.files,
|
|
@@ -65,6 +68,7 @@ function extractParserAndOptions(parserOrProgram, options) {
|
|
|
65
68
|
}
|
|
66
69
|
function generateManPageSync(parserOrProgram, options) {
|
|
67
70
|
const { parser, mergedOptions } = extractParserAndOptions(parserOrProgram, options);
|
|
71
|
+
if (parser.mode === "async") throw new TypeError("Cannot use an async parser with generateManPageSync(). Use generateManPageAsync() or generateManPage() instead.");
|
|
68
72
|
const docPage = getDocPageSync(parser) ?? { sections: [] };
|
|
69
73
|
return formatDocPageAsMan(docPage, mergedOptions);
|
|
70
74
|
}
|
|
@@ -75,7 +79,7 @@ async function generateManPageAsync(parserOrProgram, options) {
|
|
|
75
79
|
}
|
|
76
80
|
function generateManPage(parserOrProgram, options) {
|
|
77
81
|
const { parser, mergedOptions } = extractParserAndOptions(parserOrProgram, options);
|
|
78
|
-
if (parser
|
|
82
|
+
if (parser.mode === "async") return generateManPageAsync(parser, mergedOptions);
|
|
79
83
|
return generateManPageSync(parser, mergedOptions);
|
|
80
84
|
}
|
|
81
85
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_man = require('./man-
|
|
1
|
+
const require_man = require('./man-CkvscTlM.cjs');
|
|
2
2
|
const __optique_core_parser = require_man.__toESM(require("@optique/core/parser"));
|
|
3
3
|
|
|
4
4
|
//#region src/generator.ts
|
|
@@ -9,7 +9,7 @@ function isParser(value) {
|
|
|
9
9
|
try {
|
|
10
10
|
if (value == null || typeof value !== "object") return false;
|
|
11
11
|
const p = value;
|
|
12
|
-
return "parse" in p && typeof p.parse === "function" && "complete" in p && typeof p.complete === "function" && "
|
|
12
|
+
return "parse" in p && typeof p.parse === "function" && "complete" in p && typeof p.complete === "function" && "mode" in p && (p.mode === "sync" || p.mode === "async") && "usage" in p && Array.isArray(p.usage) && "initialState" in p && "suggest" in p && typeof p.suggest === "function" && "getDocFragments" in p && typeof p.getDocFragments === "function";
|
|
13
13
|
} catch {
|
|
14
14
|
return false;
|
|
15
15
|
}
|
|
@@ -50,6 +50,9 @@ function extractParserAndOptions(parserOrProgram, options) {
|
|
|
50
50
|
author: programOptions.author ?? metadata.author,
|
|
51
51
|
bugs: programOptions.bugs ?? metadata.bugs,
|
|
52
52
|
examples: programOptions.examples ?? metadata.examples,
|
|
53
|
+
brief: programOptions.brief ?? metadata.brief,
|
|
54
|
+
description: programOptions.description ?? metadata.description,
|
|
55
|
+
footer: programOptions.footer ?? metadata.footer,
|
|
53
56
|
seeAlso: programOptions.seeAlso,
|
|
54
57
|
environment: programOptions.environment,
|
|
55
58
|
files: programOptions.files,
|
|
@@ -65,6 +68,7 @@ function extractParserAndOptions(parserOrProgram, options) {
|
|
|
65
68
|
}
|
|
66
69
|
function generateManPageSync(parserOrProgram, options) {
|
|
67
70
|
const { parser, mergedOptions } = extractParserAndOptions(parserOrProgram, options);
|
|
71
|
+
if (parser.mode === "async") throw new TypeError("Cannot use an async parser with generateManPageSync(). Use generateManPageAsync() or generateManPage() instead.");
|
|
68
72
|
const docPage = (0, __optique_core_parser.getDocPageSync)(parser) ?? { sections: [] };
|
|
69
73
|
return require_man.formatDocPageAsMan(docPage, mergedOptions);
|
|
70
74
|
}
|
|
@@ -75,7 +79,7 @@ async function generateManPageAsync(parserOrProgram, options) {
|
|
|
75
79
|
}
|
|
76
80
|
function generateManPage(parserOrProgram, options) {
|
|
77
81
|
const { parser, mergedOptions } = extractParserAndOptions(parserOrProgram, options);
|
|
78
|
-
if (parser
|
|
82
|
+
if (parser.mode === "async") return generateManPageAsync(parser, mergedOptions);
|
|
79
83
|
return generateManPageSync(parser, mergedOptions);
|
|
80
84
|
}
|
|
81
85
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const require_man = require('./man-
|
|
2
|
-
const require_roff = require('./roff-
|
|
3
|
-
const require_generator = require('./generator-
|
|
1
|
+
const require_man = require('./man-CkvscTlM.cjs');
|
|
2
|
+
const require_roff = require('./roff-DJ-LkRXl.cjs');
|
|
3
|
+
const require_generator = require('./generator-DXD_dkL9.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
|
-
import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-
|
|
2
|
-
import { ManPageOptions, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-
|
|
1
|
+
import { RoffFormatOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-COeDIWWF.cjs";
|
|
2
|
+
import { ManPageOptions, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-DKwa47XV.cjs";
|
|
3
3
|
import { Mode, ModeValue, Parser } from "@optique/core/parser";
|
|
4
4
|
import { Program } from "@optique/core/program";
|
|
5
5
|
|
|
@@ -14,10 +14,10 @@ interface GenerateManPageOptions extends ManPageOptions {}
|
|
|
14
14
|
/**
|
|
15
15
|
* Options for generating a man page from a {@link Program}.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* metadata
|
|
20
|
-
*
|
|
17
|
+
* For Program inputs, `name`, `version`, `author`, `bugs`, `examples`,
|
|
18
|
+
* `brief`, `description`, and `footer` default to values from
|
|
19
|
+
* `program.metadata`.
|
|
20
|
+
* These fields are optional here and may be provided to override metadata.
|
|
21
21
|
*
|
|
22
22
|
* @since 0.10.0
|
|
23
23
|
*/
|
|
@@ -159,4 +159,4 @@ declare function generateManPage(parser: Parser<"sync", unknown, unknown>, optio
|
|
|
159
159
|
declare function generateManPage(parser: Parser<"async", unknown, unknown>, options: GenerateManPageOptions): Promise<string>;
|
|
160
160
|
declare function generateManPage<M extends Mode>(parser: Parser<M, unknown, unknown>, options: GenerateManPageOptions): ModeValue<M, string>;
|
|
161
161
|
//#endregion
|
|
162
|
-
export { type GenerateManPageOptions, type GenerateManPageProgramOptions, type ManPageOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatDateForMan, formatDocPageAsMan, formatMessageAsRoff, formatUsageTermAsRoff, generateManPage, generateManPageAsync, generateManPageSync };
|
|
162
|
+
export { type GenerateManPageOptions, type GenerateManPageProgramOptions, type ManPageOptions, type RoffFormatOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatDateForMan, formatDocPageAsMan, formatMessageAsRoff, formatUsageTermAsRoff, generateManPage, generateManPageAsync, generateManPageSync };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-
|
|
2
|
-
import { ManPageOptions, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-
|
|
1
|
+
import { RoffFormatOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-CgYQDHBN.js";
|
|
2
|
+
import { ManPageOptions, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-B1Q2mhit.js";
|
|
3
3
|
import { Program } from "@optique/core/program";
|
|
4
4
|
import { Mode, ModeValue, Parser } from "@optique/core/parser";
|
|
5
5
|
|
|
@@ -14,10 +14,10 @@ interface GenerateManPageOptions extends ManPageOptions {}
|
|
|
14
14
|
/**
|
|
15
15
|
* Options for generating a man page from a {@link Program}.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* metadata
|
|
20
|
-
*
|
|
17
|
+
* For Program inputs, `name`, `version`, `author`, `bugs`, `examples`,
|
|
18
|
+
* `brief`, `description`, and `footer` default to values from
|
|
19
|
+
* `program.metadata`.
|
|
20
|
+
* These fields are optional here and may be provided to override metadata.
|
|
21
21
|
*
|
|
22
22
|
* @since 0.10.0
|
|
23
23
|
*/
|
|
@@ -159,4 +159,4 @@ declare function generateManPage(parser: Parser<"sync", unknown, unknown>, optio
|
|
|
159
159
|
declare function generateManPage(parser: Parser<"async", unknown, unknown>, options: GenerateManPageOptions): Promise<string>;
|
|
160
160
|
declare function generateManPage<M extends Mode>(parser: Parser<M, unknown, unknown>, options: GenerateManPageOptions): ModeValue<M, string>;
|
|
161
161
|
//#endregion
|
|
162
|
-
export { type GenerateManPageOptions, type GenerateManPageProgramOptions, type ManPageOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatDateForMan, formatDocPageAsMan, formatMessageAsRoff, formatUsageTermAsRoff, generateManPage, generateManPageAsync, generateManPageSync };
|
|
162
|
+
export { type GenerateManPageOptions, type GenerateManPageProgramOptions, type ManPageOptions, type RoffFormatOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatDateForMan, formatDocPageAsMan, formatMessageAsRoff, formatUsageTermAsRoff, generateManPage, generateManPageAsync, generateManPageSync };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-
|
|
2
|
-
import { formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-
|
|
3
|
-
import { generateManPage, generateManPageAsync, generateManPageSync } from "./generator-
|
|
1
|
+
import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-CCdIQO7B.js";
|
|
2
|
+
import { formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-BE1OY_lJ.js";
|
|
3
|
+
import { generateManPage, generateManPageAsync, generateManPageSync } from "./generator-D5cbsYWL.js";
|
|
4
4
|
|
|
5
5
|
export { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatDateForMan, formatDocPageAsMan, formatMessageAsRoff, formatUsageTermAsRoff, generateManPage, generateManPageAsync, generateManPageSync };
|
|
@@ -78,6 +78,24 @@ interface ManPageOptions {
|
|
|
78
78
|
* Exit status codes to document in the EXIT STATUS section.
|
|
79
79
|
*/
|
|
80
80
|
readonly exitStatus?: DocSection;
|
|
81
|
+
/**
|
|
82
|
+
* A brief description of the program for the NAME section.
|
|
83
|
+
* Overrides the brief from the {@link DocPage} if both are present.
|
|
84
|
+
* @since 1.0.0
|
|
85
|
+
*/
|
|
86
|
+
readonly brief?: Message;
|
|
87
|
+
/**
|
|
88
|
+
* A detailed description of the program for the DESCRIPTION section.
|
|
89
|
+
* Overrides the description from the {@link DocPage} if both are present.
|
|
90
|
+
* @since 1.0.0
|
|
91
|
+
*/
|
|
92
|
+
readonly description?: Message;
|
|
93
|
+
/**
|
|
94
|
+
* Footer text appended at the end of the man page.
|
|
95
|
+
* Overrides the footer from the {@link DocPage} if both are present.
|
|
96
|
+
* @since 1.0.0
|
|
97
|
+
*/
|
|
98
|
+
readonly footer?: Message;
|
|
81
99
|
}
|
|
82
100
|
/**
|
|
83
101
|
* Formats a date for use in man pages.
|
|
@@ -90,6 +108,7 @@ interface ManPageOptions {
|
|
|
90
108
|
*
|
|
91
109
|
* @param date The date to format, or undefined.
|
|
92
110
|
* @returns The formatted date string, or undefined.
|
|
111
|
+
* @throws {RangeError} If the given `Date` object is invalid.
|
|
93
112
|
* @since 0.10.0
|
|
94
113
|
*/
|
|
95
114
|
declare function formatDateForMan(date: string | Date | undefined): string | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { escapeHyphens, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-
|
|
1
|
+
import { escapeHyphens, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-CCdIQO7B.js";
|
|
2
2
|
import { isDocHidden, isUsageHidden } from "@optique/core/usage";
|
|
3
3
|
|
|
4
4
|
//#region src/man.ts
|
|
@@ -13,11 +13,13 @@ import { isDocHidden, isUsageHidden } from "@optique/core/usage";
|
|
|
13
13
|
*
|
|
14
14
|
* @param date The date to format, or undefined.
|
|
15
15
|
* @returns The formatted date string, or undefined.
|
|
16
|
+
* @throws {RangeError} If the given `Date` object is invalid.
|
|
16
17
|
* @since 0.10.0
|
|
17
18
|
*/
|
|
18
19
|
function formatDateForMan(date) {
|
|
19
20
|
if (date === void 0) return void 0;
|
|
20
21
|
if (typeof date === "string") return date;
|
|
22
|
+
if (Number.isNaN(date.getTime())) throw new RangeError("Invalid Date object.");
|
|
21
23
|
const months = [
|
|
22
24
|
"January",
|
|
23
25
|
"February",
|
|
@@ -46,28 +48,61 @@ function formatCommandNameAsRoff(name) {
|
|
|
46
48
|
* @since 0.10.0
|
|
47
49
|
*/
|
|
48
50
|
function formatUsageTermAsRoff(term) {
|
|
51
|
+
return formatUsageTermAsRoffInternal(term, false);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Returns whether a usage list contains exactly one visible term that
|
|
55
|
+
* produces its own brackets. When true, a parent wrapper can safely elide
|
|
56
|
+
* its own brackets to avoid redundant nesting. Multiple bracket-producing
|
|
57
|
+
* siblings must keep their individual brackets for disambiguation.
|
|
58
|
+
*/
|
|
59
|
+
function hasSingleBracketedTerm(terms) {
|
|
60
|
+
const visible = terms.filter((t$1) => !("hidden" in t$1 && isUsageHidden(t$1.hidden)));
|
|
61
|
+
if (visible.length !== 1) return false;
|
|
62
|
+
const t = visible[0];
|
|
63
|
+
return t.type === "option" || t.type === "optional" || t.type === "multiple" && t.min < 1 || t.type === "passthrough";
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns whether a usage list's single visible term has the given type.
|
|
67
|
+
*/
|
|
68
|
+
function hasSingleVisibleTermOfType(terms, type) {
|
|
69
|
+
const visible = terms.filter((t) => !("hidden" in t && isUsageHidden(t.hidden)));
|
|
70
|
+
return visible.length === 1 && visible[0].type === type;
|
|
71
|
+
}
|
|
72
|
+
function formatUsageTermAsRoffInternal(term, insideBrackets) {
|
|
49
73
|
if ("hidden" in term && isUsageHidden(term.hidden)) return "";
|
|
50
74
|
switch (term.type) {
|
|
51
75
|
case "argument": return `\\fI${escapeRoff(term.metavar)}\\fR`;
|
|
52
76
|
case "option": {
|
|
53
77
|
const names = term.names.map((name) => `\\fB${escapeHyphens(name)}\\fR`).join(" | ");
|
|
54
78
|
const metavarPart = term.metavar ? ` \\fI${escapeRoff(term.metavar)}\\fR` : "";
|
|
79
|
+
if (insideBrackets) return `${names}${metavarPart}`;
|
|
55
80
|
return `[${names}${metavarPart}]`;
|
|
56
81
|
}
|
|
57
82
|
case "command": return formatCommandNameAsRoff(term.name);
|
|
58
83
|
case "optional": {
|
|
59
|
-
const
|
|
84
|
+
const childrenBracketed = hasSingleBracketedTerm(term.terms);
|
|
85
|
+
const childIsMultiple = childrenBracketed && hasSingleVisibleTermOfType(term.terms, "multiple");
|
|
86
|
+
const inner = formatUsageAsRoffInternal(term.terms, childrenBracketed);
|
|
60
87
|
if (inner === "") return "";
|
|
88
|
+
if (insideBrackets && childrenBracketed && !childIsMultiple) return inner;
|
|
61
89
|
return `[${inner}]`;
|
|
62
90
|
}
|
|
63
91
|
case "multiple": {
|
|
64
|
-
const
|
|
92
|
+
const wrapInBrackets = term.min < 1;
|
|
93
|
+
const childrenBracketed = hasSingleBracketedTerm(term.terms);
|
|
94
|
+
const childIsMultiple = childrenBracketed && hasSingleVisibleTermOfType(term.terms, "multiple");
|
|
95
|
+
const passInsideBrackets = wrapInBrackets && childrenBracketed && !childIsMultiple;
|
|
96
|
+
const inner = formatUsageAsRoffInternal(term.terms, passInsideBrackets);
|
|
65
97
|
if (inner === "") return "";
|
|
66
|
-
if (
|
|
98
|
+
if (wrapInBrackets) {
|
|
99
|
+
if (insideBrackets && passInsideBrackets) return `${inner} ...`;
|
|
100
|
+
return `[${inner} ...]`;
|
|
101
|
+
}
|
|
67
102
|
return `${inner} ...`;
|
|
68
103
|
}
|
|
69
104
|
case "exclusive": {
|
|
70
|
-
const alternatives = term.terms.map((t) =>
|
|
105
|
+
const alternatives = term.terms.map((t) => formatUsageAsRoffInternal(t, false)).filter((s) => s !== "");
|
|
71
106
|
if (alternatives.length === 0) return "";
|
|
72
107
|
if (alternatives.length === 1) return alternatives[0];
|
|
73
108
|
return `(${alternatives.join(" | ")})`;
|
|
@@ -88,7 +123,10 @@ function formatUsageTermAsRoff(term) {
|
|
|
88
123
|
* @returns The roff-formatted string.
|
|
89
124
|
*/
|
|
90
125
|
function formatUsageAsRoff(usage) {
|
|
91
|
-
return usage
|
|
126
|
+
return formatUsageAsRoffInternal(usage, false);
|
|
127
|
+
}
|
|
128
|
+
function formatUsageAsRoffInternal(usage, insideBrackets) {
|
|
129
|
+
return usage.map((term) => formatUsageTermAsRoffInternal(term, insideBrackets)).filter((s) => s !== "").join(" ");
|
|
92
130
|
}
|
|
93
131
|
/**
|
|
94
132
|
* Formats a {@link DocEntry}'s term for man page output.
|
|
@@ -160,6 +198,26 @@ function formatDocUsageAsRoff(usage) {
|
|
|
160
198
|
return usage.map(formatDocUsageTermAsRoff).filter((s) => s !== "").join(" ");
|
|
161
199
|
}
|
|
162
200
|
/**
|
|
201
|
+
* Infers the section title from entry kinds when no explicit title is given.
|
|
202
|
+
* Returns `"COMMANDS"` for command-only sections, `"ARGUMENTS"` for
|
|
203
|
+
* argument-only sections, and `"OPTIONS"` otherwise.
|
|
204
|
+
*
|
|
205
|
+
* @param entries The entries in the section.
|
|
206
|
+
* @returns The inferred section title in uppercase.
|
|
207
|
+
*/
|
|
208
|
+
function inferSectionTitle(entries) {
|
|
209
|
+
const kinds = /* @__PURE__ */ new Set();
|
|
210
|
+
for (const entry of entries) {
|
|
211
|
+
if ("hidden" in entry.term && isDocHidden(entry.term.hidden)) continue;
|
|
212
|
+
kinds.add(entry.term.type);
|
|
213
|
+
}
|
|
214
|
+
if (kinds.size === 1) {
|
|
215
|
+
if (kinds.has("command")) return "COMMANDS";
|
|
216
|
+
if (kinds.has("argument")) return "ARGUMENTS";
|
|
217
|
+
}
|
|
218
|
+
return "OPTIONS";
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
163
221
|
* Formats a {@link DocSection} as roff markup with .TP macros.
|
|
164
222
|
*
|
|
165
223
|
* @param section The section to format.
|
|
@@ -175,8 +233,14 @@ function formatDocSectionEntries(section) {
|
|
|
175
233
|
if (entry.description) {
|
|
176
234
|
let desc = formatMessageAsRoff(entry.description);
|
|
177
235
|
if (entry.default) desc += ` [${formatMessageAsRoff(entry.default)}]`;
|
|
236
|
+
if (entry.choices) desc += ` (choices: ${formatMessageAsRoff(entry.choices, { quotes: false })})`;
|
|
178
237
|
lines.push(desc);
|
|
179
|
-
} else if (entry.default
|
|
238
|
+
} else if (entry.default || entry.choices) {
|
|
239
|
+
const parts = [];
|
|
240
|
+
if (entry.default) parts.push(`[${formatMessageAsRoff(entry.default)}]`);
|
|
241
|
+
if (entry.choices) parts.push(`(choices: ${formatMessageAsRoff(entry.choices, { quotes: false })})`);
|
|
242
|
+
lines.push(parts.join(" "));
|
|
243
|
+
}
|
|
180
244
|
}
|
|
181
245
|
return lines.join("\n");
|
|
182
246
|
}
|
|
@@ -235,7 +299,8 @@ function formatDocPageAsMan(page, options) {
|
|
|
235
299
|
if (hasManual) thParts.push(`"${escapeRequestArg(options.manual)}"`);
|
|
236
300
|
lines.push(`.TH ${thParts.join(" ")}`);
|
|
237
301
|
lines.push(".SH NAME");
|
|
238
|
-
|
|
302
|
+
const brief = options.brief ?? page.brief;
|
|
303
|
+
if (brief) lines.push(`${escapeHyphens(escapeRoff(options.name))} \\- ${formatMessageAsRoff(brief)}`);
|
|
239
304
|
else lines.push(escapeHyphens(escapeRoff(options.name)));
|
|
240
305
|
if (page.usage) {
|
|
241
306
|
lines.push(".SH SYNOPSIS");
|
|
@@ -243,15 +308,16 @@ function formatDocPageAsMan(page, options) {
|
|
|
243
308
|
const usageStr = formatUsageAsRoff(page.usage);
|
|
244
309
|
if (usageStr) lines.push(usageStr);
|
|
245
310
|
}
|
|
246
|
-
|
|
311
|
+
const description = options.description ?? page.description;
|
|
312
|
+
if (description) {
|
|
247
313
|
lines.push(".SH DESCRIPTION");
|
|
248
|
-
lines.push(formatMessageAsRoff(
|
|
314
|
+
lines.push(formatMessageAsRoff(description));
|
|
249
315
|
}
|
|
250
316
|
for (const section of page.sections) {
|
|
251
317
|
if (section.entries.length === 0) continue;
|
|
252
318
|
const content = formatDocSectionEntries(section);
|
|
253
319
|
if (content === "") continue;
|
|
254
|
-
const title = section.title?.toUpperCase() ??
|
|
320
|
+
const title = section.title?.toUpperCase() ?? inferSectionTitle(section.entries);
|
|
255
321
|
lines.push(`.SH "${escapeRequestArg(title)}"`);
|
|
256
322
|
lines.push(content);
|
|
257
323
|
}
|
|
@@ -276,13 +342,15 @@ function formatDocPageAsMan(page, options) {
|
|
|
276
342
|
lines.push(content);
|
|
277
343
|
}
|
|
278
344
|
}
|
|
279
|
-
|
|
345
|
+
const examples = options.examples ?? page.examples;
|
|
346
|
+
if (examples) {
|
|
280
347
|
lines.push(".SH EXAMPLES");
|
|
281
|
-
lines.push(formatMessageAsRoff(
|
|
348
|
+
lines.push(formatMessageAsRoff(examples));
|
|
282
349
|
}
|
|
283
|
-
|
|
350
|
+
const bugs = options.bugs ?? page.bugs;
|
|
351
|
+
if (bugs) {
|
|
284
352
|
lines.push(".SH BUGS");
|
|
285
|
-
lines.push(formatMessageAsRoff(
|
|
353
|
+
lines.push(formatMessageAsRoff(bugs));
|
|
286
354
|
}
|
|
287
355
|
if (options.seeAlso && options.seeAlso.length > 0) {
|
|
288
356
|
for (const ref of options.seeAlso) if (!Number.isInteger(ref.section) || ref.section < 1 || ref.section > 8) {
|
|
@@ -301,13 +369,15 @@ function formatDocPageAsMan(page, options) {
|
|
|
301
369
|
});
|
|
302
370
|
lines.push(refs.join("\n"));
|
|
303
371
|
}
|
|
304
|
-
|
|
372
|
+
const author = options.author ?? page.author;
|
|
373
|
+
if (author) {
|
|
305
374
|
lines.push(".SH AUTHOR");
|
|
306
|
-
lines.push(formatMessageAsRoff(
|
|
375
|
+
lines.push(formatMessageAsRoff(author));
|
|
307
376
|
}
|
|
308
|
-
|
|
377
|
+
const footer = options.footer ?? page.footer;
|
|
378
|
+
if (footer) {
|
|
309
379
|
lines.push(".PP");
|
|
310
|
-
lines.push(formatMessageAsRoff(
|
|
380
|
+
lines.push(formatMessageAsRoff(footer));
|
|
311
381
|
}
|
|
312
382
|
return lines.join("\n");
|
|
313
383
|
}
|
|
@@ -21,7 +21,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
}) : target, mod));
|
|
22
22
|
|
|
23
23
|
//#endregion
|
|
24
|
-
const require_roff = require('./roff-
|
|
24
|
+
const require_roff = require('./roff-DJ-LkRXl.cjs');
|
|
25
25
|
const __optique_core_usage = __toESM(require("@optique/core/usage"));
|
|
26
26
|
|
|
27
27
|
//#region src/man.ts
|
|
@@ -36,11 +36,13 @@ const __optique_core_usage = __toESM(require("@optique/core/usage"));
|
|
|
36
36
|
*
|
|
37
37
|
* @param date The date to format, or undefined.
|
|
38
38
|
* @returns The formatted date string, or undefined.
|
|
39
|
+
* @throws {RangeError} If the given `Date` object is invalid.
|
|
39
40
|
* @since 0.10.0
|
|
40
41
|
*/
|
|
41
42
|
function formatDateForMan(date) {
|
|
42
43
|
if (date === void 0) return void 0;
|
|
43
44
|
if (typeof date === "string") return date;
|
|
45
|
+
if (Number.isNaN(date.getTime())) throw new RangeError("Invalid Date object.");
|
|
44
46
|
const months = [
|
|
45
47
|
"January",
|
|
46
48
|
"February",
|
|
@@ -69,28 +71,61 @@ function formatCommandNameAsRoff(name) {
|
|
|
69
71
|
* @since 0.10.0
|
|
70
72
|
*/
|
|
71
73
|
function formatUsageTermAsRoff(term) {
|
|
74
|
+
return formatUsageTermAsRoffInternal(term, false);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Returns whether a usage list contains exactly one visible term that
|
|
78
|
+
* produces its own brackets. When true, a parent wrapper can safely elide
|
|
79
|
+
* its own brackets to avoid redundant nesting. Multiple bracket-producing
|
|
80
|
+
* siblings must keep their individual brackets for disambiguation.
|
|
81
|
+
*/
|
|
82
|
+
function hasSingleBracketedTerm(terms) {
|
|
83
|
+
const visible = terms.filter((t$1) => !("hidden" in t$1 && (0, __optique_core_usage.isUsageHidden)(t$1.hidden)));
|
|
84
|
+
if (visible.length !== 1) return false;
|
|
85
|
+
const t = visible[0];
|
|
86
|
+
return t.type === "option" || t.type === "optional" || t.type === "multiple" && t.min < 1 || t.type === "passthrough";
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Returns whether a usage list's single visible term has the given type.
|
|
90
|
+
*/
|
|
91
|
+
function hasSingleVisibleTermOfType(terms, type) {
|
|
92
|
+
const visible = terms.filter((t) => !("hidden" in t && (0, __optique_core_usage.isUsageHidden)(t.hidden)));
|
|
93
|
+
return visible.length === 1 && visible[0].type === type;
|
|
94
|
+
}
|
|
95
|
+
function formatUsageTermAsRoffInternal(term, insideBrackets) {
|
|
72
96
|
if ("hidden" in term && (0, __optique_core_usage.isUsageHidden)(term.hidden)) return "";
|
|
73
97
|
switch (term.type) {
|
|
74
98
|
case "argument": return `\\fI${require_roff.escapeRoff(term.metavar)}\\fR`;
|
|
75
99
|
case "option": {
|
|
76
100
|
const names = term.names.map((name) => `\\fB${require_roff.escapeHyphens(name)}\\fR`).join(" | ");
|
|
77
101
|
const metavarPart = term.metavar ? ` \\fI${require_roff.escapeRoff(term.metavar)}\\fR` : "";
|
|
102
|
+
if (insideBrackets) return `${names}${metavarPart}`;
|
|
78
103
|
return `[${names}${metavarPart}]`;
|
|
79
104
|
}
|
|
80
105
|
case "command": return formatCommandNameAsRoff(term.name);
|
|
81
106
|
case "optional": {
|
|
82
|
-
const
|
|
107
|
+
const childrenBracketed = hasSingleBracketedTerm(term.terms);
|
|
108
|
+
const childIsMultiple = childrenBracketed && hasSingleVisibleTermOfType(term.terms, "multiple");
|
|
109
|
+
const inner = formatUsageAsRoffInternal(term.terms, childrenBracketed);
|
|
83
110
|
if (inner === "") return "";
|
|
111
|
+
if (insideBrackets && childrenBracketed && !childIsMultiple) return inner;
|
|
84
112
|
return `[${inner}]`;
|
|
85
113
|
}
|
|
86
114
|
case "multiple": {
|
|
87
|
-
const
|
|
115
|
+
const wrapInBrackets = term.min < 1;
|
|
116
|
+
const childrenBracketed = hasSingleBracketedTerm(term.terms);
|
|
117
|
+
const childIsMultiple = childrenBracketed && hasSingleVisibleTermOfType(term.terms, "multiple");
|
|
118
|
+
const passInsideBrackets = wrapInBrackets && childrenBracketed && !childIsMultiple;
|
|
119
|
+
const inner = formatUsageAsRoffInternal(term.terms, passInsideBrackets);
|
|
88
120
|
if (inner === "") return "";
|
|
89
|
-
if (
|
|
121
|
+
if (wrapInBrackets) {
|
|
122
|
+
if (insideBrackets && passInsideBrackets) return `${inner} ...`;
|
|
123
|
+
return `[${inner} ...]`;
|
|
124
|
+
}
|
|
90
125
|
return `${inner} ...`;
|
|
91
126
|
}
|
|
92
127
|
case "exclusive": {
|
|
93
|
-
const alternatives = term.terms.map((t) =>
|
|
128
|
+
const alternatives = term.terms.map((t) => formatUsageAsRoffInternal(t, false)).filter((s) => s !== "");
|
|
94
129
|
if (alternatives.length === 0) return "";
|
|
95
130
|
if (alternatives.length === 1) return alternatives[0];
|
|
96
131
|
return `(${alternatives.join(" | ")})`;
|
|
@@ -111,7 +146,10 @@ function formatUsageTermAsRoff(term) {
|
|
|
111
146
|
* @returns The roff-formatted string.
|
|
112
147
|
*/
|
|
113
148
|
function formatUsageAsRoff(usage) {
|
|
114
|
-
return usage
|
|
149
|
+
return formatUsageAsRoffInternal(usage, false);
|
|
150
|
+
}
|
|
151
|
+
function formatUsageAsRoffInternal(usage, insideBrackets) {
|
|
152
|
+
return usage.map((term) => formatUsageTermAsRoffInternal(term, insideBrackets)).filter((s) => s !== "").join(" ");
|
|
115
153
|
}
|
|
116
154
|
/**
|
|
117
155
|
* Formats a {@link DocEntry}'s term for man page output.
|
|
@@ -183,6 +221,26 @@ function formatDocUsageAsRoff(usage) {
|
|
|
183
221
|
return usage.map(formatDocUsageTermAsRoff).filter((s) => s !== "").join(" ");
|
|
184
222
|
}
|
|
185
223
|
/**
|
|
224
|
+
* Infers the section title from entry kinds when no explicit title is given.
|
|
225
|
+
* Returns `"COMMANDS"` for command-only sections, `"ARGUMENTS"` for
|
|
226
|
+
* argument-only sections, and `"OPTIONS"` otherwise.
|
|
227
|
+
*
|
|
228
|
+
* @param entries The entries in the section.
|
|
229
|
+
* @returns The inferred section title in uppercase.
|
|
230
|
+
*/
|
|
231
|
+
function inferSectionTitle(entries) {
|
|
232
|
+
const kinds = /* @__PURE__ */ new Set();
|
|
233
|
+
for (const entry of entries) {
|
|
234
|
+
if ("hidden" in entry.term && (0, __optique_core_usage.isDocHidden)(entry.term.hidden)) continue;
|
|
235
|
+
kinds.add(entry.term.type);
|
|
236
|
+
}
|
|
237
|
+
if (kinds.size === 1) {
|
|
238
|
+
if (kinds.has("command")) return "COMMANDS";
|
|
239
|
+
if (kinds.has("argument")) return "ARGUMENTS";
|
|
240
|
+
}
|
|
241
|
+
return "OPTIONS";
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
186
244
|
* Formats a {@link DocSection} as roff markup with .TP macros.
|
|
187
245
|
*
|
|
188
246
|
* @param section The section to format.
|
|
@@ -198,8 +256,14 @@ function formatDocSectionEntries(section) {
|
|
|
198
256
|
if (entry.description) {
|
|
199
257
|
let desc = require_roff.formatMessageAsRoff(entry.description);
|
|
200
258
|
if (entry.default) desc += ` [${require_roff.formatMessageAsRoff(entry.default)}]`;
|
|
259
|
+
if (entry.choices) desc += ` (choices: ${require_roff.formatMessageAsRoff(entry.choices, { quotes: false })})`;
|
|
201
260
|
lines.push(desc);
|
|
202
|
-
} else if (entry.default
|
|
261
|
+
} else if (entry.default || entry.choices) {
|
|
262
|
+
const parts = [];
|
|
263
|
+
if (entry.default) parts.push(`[${require_roff.formatMessageAsRoff(entry.default)}]`);
|
|
264
|
+
if (entry.choices) parts.push(`(choices: ${require_roff.formatMessageAsRoff(entry.choices, { quotes: false })})`);
|
|
265
|
+
lines.push(parts.join(" "));
|
|
266
|
+
}
|
|
203
267
|
}
|
|
204
268
|
return lines.join("\n");
|
|
205
269
|
}
|
|
@@ -258,7 +322,8 @@ function formatDocPageAsMan(page, options) {
|
|
|
258
322
|
if (hasManual) thParts.push(`"${require_roff.escapeRequestArg(options.manual)}"`);
|
|
259
323
|
lines.push(`.TH ${thParts.join(" ")}`);
|
|
260
324
|
lines.push(".SH NAME");
|
|
261
|
-
|
|
325
|
+
const brief = options.brief ?? page.brief;
|
|
326
|
+
if (brief) lines.push(`${require_roff.escapeHyphens(require_roff.escapeRoff(options.name))} \\- ${require_roff.formatMessageAsRoff(brief)}`);
|
|
262
327
|
else lines.push(require_roff.escapeHyphens(require_roff.escapeRoff(options.name)));
|
|
263
328
|
if (page.usage) {
|
|
264
329
|
lines.push(".SH SYNOPSIS");
|
|
@@ -266,15 +331,16 @@ function formatDocPageAsMan(page, options) {
|
|
|
266
331
|
const usageStr = formatUsageAsRoff(page.usage);
|
|
267
332
|
if (usageStr) lines.push(usageStr);
|
|
268
333
|
}
|
|
269
|
-
|
|
334
|
+
const description = options.description ?? page.description;
|
|
335
|
+
if (description) {
|
|
270
336
|
lines.push(".SH DESCRIPTION");
|
|
271
|
-
lines.push(require_roff.formatMessageAsRoff(
|
|
337
|
+
lines.push(require_roff.formatMessageAsRoff(description));
|
|
272
338
|
}
|
|
273
339
|
for (const section of page.sections) {
|
|
274
340
|
if (section.entries.length === 0) continue;
|
|
275
341
|
const content = formatDocSectionEntries(section);
|
|
276
342
|
if (content === "") continue;
|
|
277
|
-
const title = section.title?.toUpperCase() ??
|
|
343
|
+
const title = section.title?.toUpperCase() ?? inferSectionTitle(section.entries);
|
|
278
344
|
lines.push(`.SH "${require_roff.escapeRequestArg(title)}"`);
|
|
279
345
|
lines.push(content);
|
|
280
346
|
}
|
|
@@ -299,13 +365,15 @@ function formatDocPageAsMan(page, options) {
|
|
|
299
365
|
lines.push(content);
|
|
300
366
|
}
|
|
301
367
|
}
|
|
302
|
-
|
|
368
|
+
const examples = options.examples ?? page.examples;
|
|
369
|
+
if (examples) {
|
|
303
370
|
lines.push(".SH EXAMPLES");
|
|
304
|
-
lines.push(require_roff.formatMessageAsRoff(
|
|
371
|
+
lines.push(require_roff.formatMessageAsRoff(examples));
|
|
305
372
|
}
|
|
306
|
-
|
|
373
|
+
const bugs = options.bugs ?? page.bugs;
|
|
374
|
+
if (bugs) {
|
|
307
375
|
lines.push(".SH BUGS");
|
|
308
|
-
lines.push(require_roff.formatMessageAsRoff(
|
|
376
|
+
lines.push(require_roff.formatMessageAsRoff(bugs));
|
|
309
377
|
}
|
|
310
378
|
if (options.seeAlso && options.seeAlso.length > 0) {
|
|
311
379
|
for (const ref of options.seeAlso) if (!Number.isInteger(ref.section) || ref.section < 1 || ref.section > 8) {
|
|
@@ -324,13 +392,15 @@ function formatDocPageAsMan(page, options) {
|
|
|
324
392
|
});
|
|
325
393
|
lines.push(refs.join("\n"));
|
|
326
394
|
}
|
|
327
|
-
|
|
395
|
+
const author = options.author ?? page.author;
|
|
396
|
+
if (author) {
|
|
328
397
|
lines.push(".SH AUTHOR");
|
|
329
|
-
lines.push(require_roff.formatMessageAsRoff(
|
|
398
|
+
lines.push(require_roff.formatMessageAsRoff(author));
|
|
330
399
|
}
|
|
331
|
-
|
|
400
|
+
const footer = options.footer ?? page.footer;
|
|
401
|
+
if (footer) {
|
|
332
402
|
lines.push(".PP");
|
|
333
|
-
lines.push(require_roff.formatMessageAsRoff(
|
|
403
|
+
lines.push(require_roff.formatMessageAsRoff(footer));
|
|
334
404
|
}
|
|
335
405
|
return lines.join("\n");
|
|
336
406
|
}
|
|
@@ -78,6 +78,24 @@ interface ManPageOptions {
|
|
|
78
78
|
* Exit status codes to document in the EXIT STATUS section.
|
|
79
79
|
*/
|
|
80
80
|
readonly exitStatus?: DocSection;
|
|
81
|
+
/**
|
|
82
|
+
* A brief description of the program for the NAME section.
|
|
83
|
+
* Overrides the brief from the {@link DocPage} if both are present.
|
|
84
|
+
* @since 1.0.0
|
|
85
|
+
*/
|
|
86
|
+
readonly brief?: Message;
|
|
87
|
+
/**
|
|
88
|
+
* A detailed description of the program for the DESCRIPTION section.
|
|
89
|
+
* Overrides the description from the {@link DocPage} if both are present.
|
|
90
|
+
* @since 1.0.0
|
|
91
|
+
*/
|
|
92
|
+
readonly description?: Message;
|
|
93
|
+
/**
|
|
94
|
+
* Footer text appended at the end of the man page.
|
|
95
|
+
* Overrides the footer from the {@link DocPage} if both are present.
|
|
96
|
+
* @since 1.0.0
|
|
97
|
+
*/
|
|
98
|
+
readonly footer?: Message;
|
|
81
99
|
}
|
|
82
100
|
/**
|
|
83
101
|
* Formats a date for use in man pages.
|
|
@@ -90,6 +108,7 @@ interface ManPageOptions {
|
|
|
90
108
|
*
|
|
91
109
|
* @param date The date to format, or undefined.
|
|
92
110
|
* @returns The formatted date string, or undefined.
|
|
111
|
+
* @throws {RangeError} If the given `Date` object is invalid.
|
|
93
112
|
* @since 0.10.0
|
|
94
113
|
*/
|
|
95
114
|
declare function formatDateForMan(date: string | Date | undefined): string | undefined;
|
package/dist/man.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_man = require('./man-
|
|
2
|
-
require('./roff-
|
|
1
|
+
const require_man = require('./man-CkvscTlM.cjs');
|
|
2
|
+
require('./roff-DJ-LkRXl.cjs');
|
|
3
3
|
|
|
4
4
|
exports.formatDateForMan = require_man.formatDateForMan;
|
|
5
5
|
exports.formatDocPageAsMan = require_man.formatDocPageAsMan;
|
package/dist/man.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ManPageOptions, ManPageSection, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-
|
|
1
|
+
import { ManPageOptions, ManPageSection, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-DKwa47XV.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-
|
|
1
|
+
import { ManPageOptions, ManPageSection, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-B1Q2mhit.js";
|
|
2
2
|
export { ManPageOptions, ManPageSection, formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff };
|
package/dist/man.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./roff-
|
|
2
|
-
import { formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-
|
|
1
|
+
import "./roff-CCdIQO7B.js";
|
|
2
|
+
import { formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff } from "./man-BE1OY_lJ.js";
|
|
3
3
|
|
|
4
4
|
export { formatDateForMan, formatDocPageAsMan, formatUsageTermAsRoff };
|
|
@@ -96,17 +96,21 @@ function escapeHyphens(text) {
|
|
|
96
96
|
* is done in formatMessageAsRoff after all terms are joined.
|
|
97
97
|
*
|
|
98
98
|
* @param term The message term to format.
|
|
99
|
+
* @param options Optional formatting options.
|
|
99
100
|
* @returns The roff-formatted string.
|
|
100
101
|
*/
|
|
101
|
-
function formatTermAsRoff(term) {
|
|
102
|
+
function formatTermAsRoff(term, options) {
|
|
102
103
|
switch (term.type) {
|
|
103
104
|
case "text": return escapeBackslashes(term.text);
|
|
104
105
|
case "optionName": return `\\fB${escapeHyphens(term.optionName)}\\fR`;
|
|
105
106
|
case "optionNames": return term.optionNames.map((name) => `\\fB${escapeHyphens(name)}\\fR`).join(", ");
|
|
106
107
|
case "metavar": return `\\fI${escapeBackslashes(term.metavar)}\\fR`;
|
|
107
|
-
case "value":
|
|
108
|
+
case "value":
|
|
109
|
+
if (options?.quotes === false) return escapeBackslashes(term.value);
|
|
110
|
+
return `"${escapeQuotedValue(term.value)}"`;
|
|
108
111
|
case "values":
|
|
109
112
|
if (term.values.length === 0) return "";
|
|
113
|
+
if (options?.quotes === false) return term.values.map((v) => escapeBackslashes(v)).join(" ");
|
|
110
114
|
return term.values.map((v) => `"${escapeQuotedValue(v)}"`).join(" ");
|
|
111
115
|
case "envVar": return `\\fB${escapeBackslashes(term.envVar)}\\fR`;
|
|
112
116
|
case "commandLine": return `\\fB${escapeHyphens(escapeBackslashes(term.commandLine))}\\fR`;
|
|
@@ -148,11 +152,12 @@ function formatTermAsRoff(term) {
|
|
|
148
152
|
* ```
|
|
149
153
|
*
|
|
150
154
|
* @param msg The message to format.
|
|
155
|
+
* @param options Optional formatting options.
|
|
151
156
|
* @returns The roff-formatted string.
|
|
152
157
|
* @since 0.10.0
|
|
153
158
|
*/
|
|
154
|
-
function formatMessageAsRoff(msg) {
|
|
155
|
-
const joined = msg.map(formatTermAsRoff).join("");
|
|
159
|
+
function formatMessageAsRoff(msg, options) {
|
|
160
|
+
const joined = msg.map((t) => formatTermAsRoff(t, options)).join("");
|
|
156
161
|
const escaped = escapeLineStarts(joined);
|
|
157
162
|
return escaped.replace(/\n\n+/g, "\n.PP\n");
|
|
158
163
|
}
|
|
@@ -2,6 +2,20 @@ import { Message } from "@optique/core/message";
|
|
|
2
2
|
|
|
3
3
|
//#region src/roff.d.ts
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Options for roff formatting of messages.
|
|
7
|
+
*
|
|
8
|
+
* @since 1.0.0
|
|
9
|
+
*/
|
|
10
|
+
interface RoffFormatOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Whether to wrap `value` and `values` terms in double quotes.
|
|
13
|
+
* Defaults to `true`.
|
|
14
|
+
*
|
|
15
|
+
* @since 1.0.0
|
|
16
|
+
*/
|
|
17
|
+
readonly quotes?: boolean;
|
|
18
|
+
}
|
|
5
19
|
/**
|
|
6
20
|
* Escapes special roff characters in plain text.
|
|
7
21
|
*
|
|
@@ -89,9 +103,10 @@ declare function escapeHyphens(text: string): string;
|
|
|
89
103
|
* ```
|
|
90
104
|
*
|
|
91
105
|
* @param msg The message to format.
|
|
106
|
+
* @param options Optional formatting options.
|
|
92
107
|
* @returns The roff-formatted string.
|
|
93
108
|
* @since 0.10.0
|
|
94
109
|
*/
|
|
95
|
-
declare function formatMessageAsRoff(msg: Message): string;
|
|
110
|
+
declare function formatMessageAsRoff(msg: Message, options?: RoffFormatOptions): string;
|
|
96
111
|
//#endregion
|
|
97
|
-
export { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff };
|
|
112
|
+
export { RoffFormatOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff };
|
|
@@ -2,6 +2,20 @@ import { Message } from "@optique/core/message";
|
|
|
2
2
|
|
|
3
3
|
//#region src/roff.d.ts
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Options for roff formatting of messages.
|
|
7
|
+
*
|
|
8
|
+
* @since 1.0.0
|
|
9
|
+
*/
|
|
10
|
+
interface RoffFormatOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Whether to wrap `value` and `values` terms in double quotes.
|
|
13
|
+
* Defaults to `true`.
|
|
14
|
+
*
|
|
15
|
+
* @since 1.0.0
|
|
16
|
+
*/
|
|
17
|
+
readonly quotes?: boolean;
|
|
18
|
+
}
|
|
5
19
|
/**
|
|
6
20
|
* Escapes special roff characters in plain text.
|
|
7
21
|
*
|
|
@@ -89,9 +103,10 @@ declare function escapeHyphens(text: string): string;
|
|
|
89
103
|
* ```
|
|
90
104
|
*
|
|
91
105
|
* @param msg The message to format.
|
|
106
|
+
* @param options Optional formatting options.
|
|
92
107
|
* @returns The roff-formatted string.
|
|
93
108
|
* @since 0.10.0
|
|
94
109
|
*/
|
|
95
|
-
declare function formatMessageAsRoff(msg: Message): string;
|
|
110
|
+
declare function formatMessageAsRoff(msg: Message, options?: RoffFormatOptions): string;
|
|
96
111
|
//#endregion
|
|
97
|
-
export { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff };
|
|
112
|
+
export { RoffFormatOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff };
|
|
@@ -97,17 +97,21 @@ function escapeHyphens(text) {
|
|
|
97
97
|
* is done in formatMessageAsRoff after all terms are joined.
|
|
98
98
|
*
|
|
99
99
|
* @param term The message term to format.
|
|
100
|
+
* @param options Optional formatting options.
|
|
100
101
|
* @returns The roff-formatted string.
|
|
101
102
|
*/
|
|
102
|
-
function formatTermAsRoff(term) {
|
|
103
|
+
function formatTermAsRoff(term, options) {
|
|
103
104
|
switch (term.type) {
|
|
104
105
|
case "text": return escapeBackslashes(term.text);
|
|
105
106
|
case "optionName": return `\\fB${escapeHyphens(term.optionName)}\\fR`;
|
|
106
107
|
case "optionNames": return term.optionNames.map((name) => `\\fB${escapeHyphens(name)}\\fR`).join(", ");
|
|
107
108
|
case "metavar": return `\\fI${escapeBackslashes(term.metavar)}\\fR`;
|
|
108
|
-
case "value":
|
|
109
|
+
case "value":
|
|
110
|
+
if (options?.quotes === false) return escapeBackslashes(term.value);
|
|
111
|
+
return `"${escapeQuotedValue(term.value)}"`;
|
|
109
112
|
case "values":
|
|
110
113
|
if (term.values.length === 0) return "";
|
|
114
|
+
if (options?.quotes === false) return term.values.map((v) => escapeBackslashes(v)).join(" ");
|
|
111
115
|
return term.values.map((v) => `"${escapeQuotedValue(v)}"`).join(" ");
|
|
112
116
|
case "envVar": return `\\fB${escapeBackslashes(term.envVar)}\\fR`;
|
|
113
117
|
case "commandLine": return `\\fB${escapeHyphens(escapeBackslashes(term.commandLine))}\\fR`;
|
|
@@ -149,11 +153,12 @@ function formatTermAsRoff(term) {
|
|
|
149
153
|
* ```
|
|
150
154
|
*
|
|
151
155
|
* @param msg The message to format.
|
|
156
|
+
* @param options Optional formatting options.
|
|
152
157
|
* @returns The roff-formatted string.
|
|
153
158
|
* @since 0.10.0
|
|
154
159
|
*/
|
|
155
|
-
function formatMessageAsRoff(msg) {
|
|
156
|
-
const joined = msg.map(formatTermAsRoff).join("");
|
|
160
|
+
function formatMessageAsRoff(msg, options) {
|
|
161
|
+
const joined = msg.map((t) => formatTermAsRoff(t, options)).join("");
|
|
157
162
|
const escaped = escapeLineStarts(joined);
|
|
158
163
|
return escaped.replace(/\n\n+/g, "\n.PP\n");
|
|
159
164
|
}
|
package/dist/roff.cjs
CHANGED
package/dist/roff.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-
|
|
2
|
-
export { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff };
|
|
1
|
+
import { RoffFormatOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-COeDIWWF.cjs";
|
|
2
|
+
export { RoffFormatOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff };
|
package/dist/roff.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-
|
|
2
|
-
export { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff };
|
|
1
|
+
import { RoffFormatOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-CgYQDHBN.js";
|
|
2
|
+
export { RoffFormatOptions, escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff };
|
package/dist/roff.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-
|
|
1
|
+
import { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff } from "./roff-CCdIQO7B.js";
|
|
2
2
|
|
|
3
3
|
export { escapeHyphens, escapeQuotedValue, escapeRequestArg, escapeRoff, formatMessageAsRoff };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/man",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
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/
|
|
88
|
-
"@optique/
|
|
87
|
+
"@optique/run": "1.0.1",
|
|
88
|
+
"@optique/core": "1.0.1"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@types/node": "^20.19.9",
|