Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/examples/complex-app-custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ An example command-line tool

###### **Subcommands:**

* `test` [alias: `tester`] — does testing things
* `test` — does testing things
* `only-hidden-options` — Demo that `Options` is not printed if all options are hidden

###### **Arguments:**
Expand Down Expand Up @@ -38,7 +38,7 @@ An example command-line tool



## `complex-app test` [alias: `tester`]
## `complex-app test`

does testing things

Expand Down
6 changes: 4 additions & 2 deletions docs/examples/complex-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ An example command-line tool

###### **Subcommands:**

* `test` [alias: `tester`] — does testing things
* `test` — does testing things
* `only-hidden-options` — Demo that `Options` is not printed if all options are hidden

###### **Arguments:**
Expand Down Expand Up @@ -44,12 +44,14 @@ An example command-line tool



## `complex-app test` [alias: `tester`]
## `complex-app test`

does testing things

**Usage:** `complex-app test [OPTIONS]`

**Command Alias:** `tester`

###### **Options:**

* `-l`, `--list` — lists test values
Expand Down
69 changes: 38 additions & 31 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ mod test_readme {
#![doc = include_str!("../README.md")]
}

mod utils;

use std::fmt::{self, Write};

use clap::builder::PossibleValue;

use utils::pluralize;

//======================================
// Public API types
//======================================
Expand All @@ -28,6 +32,7 @@ pub struct MarkdownOptions {
title: Option<String>,
show_footer: bool,
show_table_of_contents: bool,
show_aliases: bool,
}

impl MarkdownOptions {
Expand All @@ -37,6 +42,7 @@ impl MarkdownOptions {
title: None,
show_footer: true,
show_table_of_contents: true,
show_aliases: true,
};
}

Expand All @@ -60,6 +66,13 @@ impl MarkdownOptions {

return self;
}

/// Whether to show aliases for arguments and commands.
pub fn show_aliases(mut self, show: bool) -> Self {
self.show_aliases = show;

return self;
}
}

impl Default for MarkdownOptions {
Expand Down Expand Up @@ -166,7 +179,7 @@ fn write_help_markdown(
// Write the commands/subcommands sections
//----------------------------------------

build_command_markdown(buffer, Vec::new(), command, 0).unwrap();
build_command_markdown(buffer, Vec::new(), command, 0, options).unwrap();

//-----------------
// Write the footer
Expand Down Expand Up @@ -278,6 +291,7 @@ fn build_command_markdown(
parent_command_path: Vec<String>,
command: &clap::Command,
depth: usize,
options: &MarkdownOptions,
) -> std::fmt::Result {
// Don't document commands marked with `clap(hide = true)` (which includes
// `print-all-help`).
Expand Down Expand Up @@ -307,12 +321,7 @@ fn build_command_markdown(
)
}
*/
let aliases = command.get_visible_aliases().collect::<Vec<&str>>();
let aliases = get_alias_str(&aliases)
.map(|s| format!(" {s}"))
.unwrap_or_default();

writeln!(buffer, "## `{}`{aliases}\n", command_path.join(" "),)?;
writeln!(buffer, "## `{}`\n", command_path.join(" "))?;

if let Some(long_about) = command.get_long_about() {
writeln!(buffer, "{}\n", long_about)?;
Expand Down Expand Up @@ -343,6 +352,17 @@ fn build_command_markdown(
.replace("Usage: ", "")
)?;

if options.show_aliases {
let aliases = command.get_visible_aliases().collect::<Vec<&str>>();
if let Some(aliases_str) = get_alias_string(&aliases) {
writeln!(
buffer,
"**{}:** {aliases_str}\n",
pluralize(aliases.len(), "Command Alias", "Command Aliases")
)?;
}
}

if let Some(help) = command.get_after_long_help() {
writeln!(buffer, "{}\n", help)?;
} else if let Some(help) = command.get_after_help() {
Expand All @@ -362,17 +382,13 @@ fn build_command_markdown(
}

let title_name = get_canonical_name(subcommand);
let aliases = subcommand.get_visible_aliases().collect::<Vec<&str>>();
let aliases = get_alias_str(&aliases)
.map(|s| format!(" {s}"))
.unwrap_or_default();

let about = match subcommand.get_about() {
Some(about) => about.to_string(),
None => String::new(),
};

writeln!(buffer, "* `{title_name}`{aliases} — {about}",)?;
writeln!(buffer, "* `{title_name}` — {about}",)?;
}

write!(buffer, "\n")?;
Expand Down Expand Up @@ -425,6 +441,7 @@ fn build_command_markdown(
command_path.clone(),
subcommand,
depth + 1,
options,
)?;
}

Expand Down Expand Up @@ -474,8 +491,12 @@ fn write_arg_markdown(buffer: &mut String, arg: &clap::Arg) -> fmt::Result {
}

if let Some(aliases) = arg.get_visible_aliases().as_deref() {
if let Some(aliases) = get_alias_str(aliases) {
write!(buffer, " {aliases}")?;
if let Some(aliases_str) = get_alias_string(aliases) {
write!(
buffer,
" [{}: {aliases_str}]",
pluralize(aliases.len(), "alias", "aliases")
)?;
}
}

Expand Down Expand Up @@ -605,30 +626,16 @@ fn indent(s: &str, first: &str, rest: &str) -> String {
result
}

fn wrap_with(s: &str, wrapper: &str) -> String {
format!("{wrapper}{s}{wrapper}")
}

fn wrap_with_backticks(s: &str) -> String {
wrap_with(s, "`")
}

fn get_alias_str(aliases: &[&str]) -> Option<String> {
fn get_alias_string(aliases: &[&str]) -> Option<String> {
if aliases.is_empty() {
return None;
}

let prefix = if aliases.len() == 1 {
"alias"
} else {
"aliases"
};

Some(format!(
"[{prefix}: {}]",
"{}",
aliases
.iter()
.map(|s| wrap_with_backticks(s))
.map(|alias| format!("`{alias}`"))
.collect::<Vec<_>>()
.join(", ")
))
Expand Down
6 changes: 6 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub fn pluralize<T>(len: usize, singular: T, plural: T) -> T {
match len {
1 => singular,
_ => plural,
}
}
1 change: 1 addition & 0 deletions tests/test_examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ fn test_example_complex_app() {
.title("Some Custom Title for Complex App".to_string())
.show_footer(false)
.show_table_of_contents(false)
.show_aliases(false)
),
include_str!("../docs/examples/complex-app-custom.md"),
"Mismatch testing CUSTOM Markdown output"
Expand Down