Skip to content

Commit

Permalink
feat(mangen): Support flatten_help
Browse files Browse the repository at this point in the history
The `flatten_help` argument combines all subcommands on a single page.
Until now this wasn't supported for `mangen`. With this command the
sections `SYNOPSIS` as well as `SUBCOMMANDS` are changed to imitate the
style of `git stash --help`.

Signed-off-by: Paul Spooren <[email protected]>
  • Loading branch information
aparcar committed Oct 16, 2024
1 parent a216137 commit c2c7c26
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 15 deletions.
6 changes: 5 additions & 1 deletion clap_mangen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,11 @@ impl Man {
fn _render_subcommands_section(&self, roff: &mut Roff) {
let heading = subcommand_heading(&self.cmd);
roff.control("SH", [heading]);
render::subcommands(roff, &self.cmd, &self.section);
if self.cmd.is_flatten_help_set() {
render::flat_subcommands(roff, &self.cmd);
} else {
render::subcommands(roff, &self.cmd, &self.section);
}
}

/// Render the EXTRA section into the writer.
Expand Down
74 changes: 61 additions & 13 deletions clap_mangen/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ pub(crate) fn description(roff: &mut Roff, cmd: &clap::Command) {
}
}

pub(crate) fn synopsis(roff: &mut Roff, cmd: &clap::Command) {
let name = cmd.get_bin_name().unwrap_or_else(|| cmd.get_name());
pub(crate) fn command_with_args(cmd: &clap::Command, name: String) -> Vec<Inline> {
let mut line = vec![bold(name), roman(" ")];

for opt in cmd.get_arguments().filter(|i| !i.is_hide_set()) {
let (lhs, rhs) = option_markers(opt);
match (opt.get_short(), opt.get_long()) {
Expand Down Expand Up @@ -74,18 +72,46 @@ pub(crate) fn synopsis(roff: &mut Roff, cmd: &clap::Command) {
line.push(roman(" "));
}

if cmd.has_subcommands() {
let (lhs, rhs) = subcommand_markers(cmd);
line.push(roman(lhs));
line.push(italic(
cmd.get_subcommand_value_name()
.unwrap_or_else(|| subcommand_heading(cmd))
.to_lowercase(),
));
line.push(roman(rhs));
line
}

pub(crate) fn synopsis(roff: &mut Roff, cmd: &clap::Command) {
let name = cmd.get_bin_name().unwrap_or_else(|| cmd.get_name());
let flatten = cmd.is_flatten_help_set();

let mut ord_v = Vec::new();
if flatten {
for subcommand in cmd.get_subcommands() {
ord_v.push((
subcommand.get_display_order(),
format!("{} {}", name, subcommand.get_name().to_owned()),
subcommand,
));
}
ord_v.sort_by(|a, b| (a.0, &a.1).cmp(&(b.0, &b.1)));
} else {
ord_v.push((cmd.get_display_order(), name.to_string(), cmd));
}

roff.text(line);
for (_, name, cmd) in ord_v {
let mut line = command_with_args(cmd, name);

if cmd.has_subcommands() && !flatten {
let (lhs, rhs) = subcommand_markers(cmd);
line.push(roman(lhs));
line.push(italic(
cmd.get_subcommand_value_name()
.unwrap_or_else(|| subcommand_heading(cmd))
.to_lowercase(),
));
line.push(roman(rhs));
}
roff.text(line);

if flatten {
roff.control("br", []);
}
}
}

pub(crate) fn options(roff: &mut Roff, cmd: &clap::Command) {
Expand Down Expand Up @@ -220,6 +246,28 @@ pub(crate) fn subcommands(roff: &mut Roff, cmd: &clap::Command, section: &str) {
}
}

pub(crate) fn flat_subcommands(roff: &mut Roff, cmd: &clap::Command) {
for sub in cmd.get_subcommands().filter(|s| !s.is_hide_set()) {
roff.control("TP", []);

let name = sub.get_name().to_string();

let mut line = command_with_args(sub, name);

if let Some(about) = sub.get_long_about().or_else(|| sub.get_about()) {
line.push(roman("\n"));
line.push(roman(about.to_string()));
}

if let Some(after_help) = sub.get_after_help() {
line.push(roman("\n"));
line.push(roman(after_help.to_string()));
}

roff.text(line);
}
}

pub(crate) fn version(cmd: &clap::Command) -> String {
format!(
"v{}",
Expand Down
29 changes: 29 additions & 0 deletions clap_mangen/tests/snapshots/flatten_help.roff
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH my-app 1 "my-app "
.SH NAME
my\-app
.SH SYNOPSIS
\fBmy\-app test\fR [\fB\-d \fR]... [\fB\-c \fR] [\fB\-h\fR|\fB\-\-help\fR]
.br
\fBmy\-app help\fR
.br
.SH DESCRIPTION
.SH OPTIONS
.TP
\fB\-c\fR

.TP
\fB\-v\fR

.TP
\fB\-h\fR, \fB\-\-help\fR
Print help
.SH SUBCOMMANDS
.TP
\fBtest\fR [\fB\-d \fR]... [\fB\-c \fR] [\fB\-h\fR|\fB\-\-help\fR]
Subcommand
with a second line
.TP
\fBhelp\fR
Print this message or the help of the given subcommand(s)
2 changes: 1 addition & 1 deletion clap_mangen/tests/testsuite/roff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,5 @@ fn flatten_help_false() {
fn flatten_help_true() {
let name = "my-app";
let cmd = common::basic_command(name).flatten_help(true);
common::assert_matches(snapbox::file!["../snapshots/basic.bash.roff"], cmd);
common::assert_matches(snapbox::file!["../snapshots/flatten_help.roff"], cmd);
}

0 comments on commit c2c7c26

Please sign in to comment.