Skip to content

Commit 2486e7e

Browse files
committed
feat(man): replace possible values list with flag-value pairs
Replace the "Possible values:" bullet list with tagged paragraphs showing each value as a flag-value pair (e.g. `--bytes-format plain`), matching conventional man page style. Also add conflict documentation for options that have declared conflicts (e.g. --json-input conflicts with --quantity, etc.) using clap's `get_arg_conflicts_with` API. https://claude.ai/code/session_01CrXuWDMVQsiUBoy6ceACsF
1 parent d0d11f3 commit 2486e7e

2 files changed

Lines changed: 63 additions & 32 deletions

File tree

exports/pdu.1

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
.SH NAME
33
pdu \- Summarize disk usage of the set of files, recursively for directories.
44
.SH SYNOPSIS
5-
\fBpdu\fR [\fB\-\-json\-input\fR] [\fB\-\-json\-output\fR] [\fB\-b\fR|\fB\-\-bytes\-format\fR \fIBYTES_FORMAT\fR] [\fB\-H\fR|\fB\-\-deduplicate\-hardlinks\fR] [\fB\-x\fR|\fB\-\-one\-file\-system\fR] [\fB\-\-top\-down\fR] [\fB\-\-align\-right\fR] [\fB\-q\fR|\fB\-\-quantity\fR \fIQUANTITY\fR] [\fB\-d\fR|\fB\-\-max\-depth\fR \fIMAX_DEPTH\fR] [\fB\-w\fR|\fB\-\-total\-width\fR \fITOTAL_WIDTH\fR] [\fB\-\-column\-width\fR \fITREE_WIDTH\fR \fIBAR_WIDTH\fR] [\fB\-m\fR|\fB\-\-min\-ratio\fR \fIMIN_RATIO\fR] [\fB\-\-no\-sort\fR] [\fB\-s\fR|\fB\-\-silent\-errors\fR] [\fB\-p\fR|\fB\-\-progress\fR] [\fB\-\-threads\fR \fITHREADS\fR] [\fB\-\-omit\-json\-shared\-details\fR] [\fB\-\-omit\-json\-shared\-summary\fR] [\fIFILES\fR]
5+
\fBpdu\fR [\fB\-\-json\-input\fR] [\fB\-\-json\-output\fR] [\fB\-b\fR|\fB\-\-bytes\-format\fR \fIBYTES_FORMAT\fR] [\fB\-H\fR|\fB\-\-deduplicate\-hardlinks\fR] [\fB\-x\fR|\fB\-\-one\-file\-system\fR] [\fB\-\-top\-down\fR] [\fB\-\-align\-right\fR] [\fB\-q\fR|\fB\-\-quantity\fR \fIQUANTITY\fR] [\fB\-d\fR|\fB\-\-max\-depth\fR \fIMAX_DEPTH\fR] [\fB\-w\fR|\fB\-\-total\-width\fR \fITOTAL_WIDTH\fR] [\fB\-\-column\-width\fR \fITREE_WIDTH\fR \fIBAR_WIDTH\fR] [\fB\-m\fR|\fB\-\-min\-ratio\fR \fIMIN_RATIO\fR] [\fB\-\-no\-sort\fR] [\fB\-s\fR|\fB\-\-silent\-errors\fR] [\fB\-p\fR|\fB\-\-progress\fR] [\fB\-\-threads\fR \fITHREADS\fR] [\fB\-\-omit\-json\-shared\-details\fR] [\fB\-\-omit\-json\-shared\-summary\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fIFILES\fR]
66
.SH DESCRIPTION
77
Summarize disk usage of the set of files, recursively for directories.
88
.PP
@@ -16,23 +16,24 @@ List of files and/or directories
1616
.TP
1717
\fB\-\-json\-input\fR
1818
Read JSON data from stdin
19+
.br
20+
Conflicts with \fB\-\-quantity\fR, \fB\-\-deduplicate\-hardlinks\fR, \fB\-\-one\-file\-system\fR.
1921
.TP
2022
\fB\-\-json\-output\fR
2123
Print JSON data instead of an ASCII chart
2224
.TP
2325
\fB\-b\fR, \fB\-\-bytes\-format\fR \fI<BYTES_FORMAT>\fR [default: metric]
2426
How to display the numbers of bytes
25-
.br
26-
27-
.br
28-
\fIPossible values:\fR
29-
.RS 14
30-
.IP \(bu 2
31-
plain: Display plain number of bytes without units
32-
.IP \(bu 2
33-
metric: Use metric scale, i.e. 1K = 1000B, 1M = 1000K, and so on
34-
.IP \(bu 2
35-
binary: Use binary scale, i.e. 1K = 1024B, 1M = 1024K, and so on
27+
.RS
28+
.TP
29+
\fB\-\-bytes\-format plain\fR
30+
Display plain number of bytes without units
31+
.TP
32+
\fB\-\-bytes\-format metric\fR
33+
Use metric scale, i.e. 1K = 1000B, 1M = 1000K, and so on
34+
.TP
35+
\fB\-\-bytes\-format binary\fR
36+
Use binary scale, i.e. 1K = 1024B, 1M = 1024K, and so on
3637
.RE
3738
.TP
3839
\fB\-H\fR, \fB\-\-deduplicate\-hardlinks\fR, \fB\-\-detect\-links\fR, \fB\-\-dedupe\-links\fR
@@ -49,24 +50,25 @@ Set the root of the bars to the right
4950
.TP
5051
\fB\-q\fR, \fB\-\-quantity\fR \fI<QUANTITY>\fR [default: block-size]
5152
Aspect of the files/directories to be measured
52-
.br
53-
54-
.br
55-
\fIPossible values:\fR
56-
.RS 14
57-
.IP \(bu 2
58-
apparent\-size: Measure apparent sizes
59-
.IP \(bu 2
60-
block\-size: Measure block sizes (block\-count * 512B)
61-
.IP \(bu 2
62-
block\-count: Count numbers of blocks
53+
.RS
54+
.TP
55+
\fB\-\-quantity apparent\-size\fR
56+
Measure apparent sizes
57+
.TP
58+
\fB\-\-quantity block\-size\fR
59+
Measure block sizes (block\-count * 512B)
60+
.TP
61+
\fB\-\-quantity block\-count\fR
62+
Count numbers of blocks
6363
.RE
6464
.TP
6565
\fB\-d\fR, \fB\-\-max\-depth\fR, \fB\-\-depth\fR \fI<MAX_DEPTH>\fR [default: 10]
6666
Maximum depth to display the data. Could be either "inf" or a positive integer
6767
.TP
6868
\fB\-w\fR, \fB\-\-total\-width\fR, \fB\-\-width\fR \fI<TOTAL_WIDTH>\fR
6969
Width of the visualization
70+
.br
71+
Conflicts with \fB\-\-column\-width\fR.
7072
.TP
7173
\fB\-\-column\-width\fR \fI<TREE_WIDTH>\fR\fI \fR\fI<BAR_WIDTH>\fR
7274
Maximum widths of the tree column and width of the bar column
@@ -91,6 +93,12 @@ Do not output `.shared.details` in the JSON output
9193
.TP
9294
\fB\-\-omit\-json\-shared\-summary\fR
9395
Do not output `.shared.summary` in the JSON output
96+
.TP
97+
\fB\-h\fR, \fB\-\-help\fR
98+
Print help (see a summary with '\-h')
99+
.TP
100+
\fB\-V\fR, \fB\-\-version\fR
101+
Print version
94102
.SH EXAMPLES
95103
.TP
96104
Show disk usage chart of current working directory

src/man_page.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use std::{borrow::Cow, fmt::Write};
44

55
/// Renders the man page for `pdu` as a string in roff format.
66
pub fn render_man_page() -> String {
7-
let command = Args::command();
7+
let mut command = Args::command();
8+
command.build();
89
let mut out = String::new();
910
render_title(&mut out, &command);
1011
render_name_section(&mut out, &command);
@@ -133,11 +134,11 @@ fn render_options_section(out: &mut String, command: &Command) {
133134
if arg.is_hide_set() {
134135
continue;
135136
}
136-
render_option_entry(out, arg);
137+
render_option_entry(out, command, arg);
137138
}
138139
}
139140

140-
fn render_option_entry(out: &mut String, arg: &Arg) {
141+
fn render_option_entry(out: &mut String, command: &Command, arg: &Arg) {
141142
out.push_str(".TP\n");
142143
if arg.is_positional() {
143144
render_option_header_positional(out, arg);
@@ -151,6 +152,7 @@ fn render_option_entry(out: &mut String, arg: &Arg) {
151152
.unwrap_or_default();
152153
writeln!(out, "{}", roff_escape(&help)).unwrap();
153154
render_possible_values(out, arg);
155+
render_conflicts(out, command, arg);
154156
}
155157

156158
fn render_option_header_positional(out: &mut String, arg: &Arg) {
@@ -230,26 +232,47 @@ fn render_possible_values(out: &mut String, arg: &Arg) {
230232
if possible_values.is_empty() {
231233
return;
232234
}
233-
out.push_str(".br\n\n.br\n");
234-
out.push_str("\\fIPossible values:\\fR\n");
235-
out.push_str(".RS 14\n");
235+
let flag = arg
236+
.get_long()
237+
.map(|long| format!("\\-\\-{}", roff_escape(long)))
238+
.unwrap_or_default();
239+
out.push_str(".RS\n");
236240
for value in &possible_values {
237241
let name = value.get_name();
238242
if let Some(help) = value.get_help() {
239243
writeln!(
240244
out,
241-
".IP \\(bu 2\n{}: {}",
245+
".TP\n\\fB{flag} {}\\fR\n{}",
242246
roff_escape(name),
243-
roff_escape(&help.to_string())
247+
roff_escape(&help.to_string()),
244248
)
245249
.unwrap();
246250
} else {
247-
writeln!(out, ".IP \\(bu 2\n{}", roff_escape(name)).unwrap();
251+
writeln!(out, ".TP\n\\fB{flag} {}\\fR", roff_escape(name)).unwrap();
248252
}
249253
}
250254
out.push_str(".RE\n");
251255
}
252256

257+
fn render_conflicts(out: &mut String, command: &Command, arg: &Arg) {
258+
let conflicts = command.get_arg_conflicts_with(arg);
259+
if conflicts.is_empty() {
260+
return;
261+
}
262+
let conflict_names: Vec<_> = conflicts
263+
.iter()
264+
.filter_map(|conflict_arg| {
265+
conflict_arg
266+
.get_long()
267+
.map(|long| format!("\\fB\\-\\-{}\\fR", roff_escape(long)))
268+
})
269+
.collect();
270+
if conflict_names.is_empty() {
271+
return;
272+
}
273+
writeln!(out, ".br\nConflicts with {}.", conflict_names.join(", ")).unwrap();
274+
}
275+
253276
fn render_examples_section(out: &mut String, command: &Command) {
254277
let text = match command.get_after_long_help() {
255278
Some(text) => text.to_string(),

0 commit comments

Comments
 (0)