mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-01 13:37:48 +00:00
add help_usage
macro
This commit is contained in:
parent
dedb969d75
commit
c8e88e1898
7 changed files with 82 additions and 46 deletions
|
@ -1,8 +1,9 @@
|
||||||
# base32
|
# base32
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
```
|
||||||
{} [OPTION]... [FILE]
|
base32 [OPTION]... [FILE]
|
||||||
|
```
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,12 @@
|
||||||
use std::io::{stdin, Read};
|
use std::io::{stdin, Read};
|
||||||
|
|
||||||
use clap::Command;
|
use clap::Command;
|
||||||
use uucore::{encoding::Format, error::UResult, help_section};
|
use uucore::{encoding::Format, error::UResult, help_section, help_usage};
|
||||||
|
|
||||||
pub mod base_common;
|
pub mod base_common;
|
||||||
|
|
||||||
const ABOUT: &str = help_section!("about");
|
const ABOUT: &str = help_section!("about");
|
||||||
const USAGE: &str = help_section!("usage");
|
const USAGE: &str = help_usage!();
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
# base64
|
# base64
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
{} [OPTION]... [FILE]
|
```
|
||||||
|
base64 [OPTION]... [FILE]
|
||||||
|
```
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
use uu_base32::base_common;
|
use uu_base32::base_common;
|
||||||
pub use uu_base32::uu_app;
|
pub use uu_base32::uu_app;
|
||||||
|
|
||||||
use uucore::{encoding::Format, error::UResult, help_section};
|
use uucore::{encoding::Format, error::UResult, help_section, help_usage};
|
||||||
|
|
||||||
use std::io::{stdin, Read};
|
use std::io::{stdin, Read};
|
||||||
|
|
||||||
const ABOUT: &str = help_section!("about");
|
const ABOUT: &str = help_section!("about");
|
||||||
const USAGE: &str = help_section!("usage");
|
const USAGE: &str = help_usage!();
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
<!-- spell-checker:ignore N'th M'th -->
|
<!-- spell-checker:ignore N'th M'th -->
|
||||||
# numfmt
|
# numfmt
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
```
|
||||||
|
numfmt [OPTION]... [NUMBER]...
|
||||||
|
```
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
Convert numbers from/to human-readable strings
|
Convert numbers from/to human-readable strings
|
||||||
|
|
|
@ -15,7 +15,7 @@ use units::{IEC_BASES, SI_BASES};
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::UResult;
|
use uucore::error::UResult;
|
||||||
use uucore::ranges::Range;
|
use uucore::ranges::Range;
|
||||||
use uucore::{format_usage, help_section, InvalidEncodingHandling};
|
use uucore::{format_usage, help_section, help_usage, InvalidEncodingHandling};
|
||||||
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod format;
|
pub mod format;
|
||||||
|
@ -24,7 +24,7 @@ mod units;
|
||||||
|
|
||||||
const ABOUT: &str = help_section!("about");
|
const ABOUT: &str = help_section!("about");
|
||||||
const LONG_HELP: &str = help_section!("long help");
|
const LONG_HELP: &str = help_section!("long help");
|
||||||
const USAGE: &str = "{} [OPTION]... [NUMBER]...";
|
const USAGE: &str = help_usage!();
|
||||||
|
|
||||||
fn handle_args<'a>(args: impl Iterator<Item = &'a str>, options: &NumfmtOptions) -> UResult<()> {
|
fn handle_args<'a>(args: impl Iterator<Item = &'a str>, options: &NumfmtOptions) -> UResult<()> {
|
||||||
for l in args {
|
for l in args {
|
||||||
|
|
|
@ -37,6 +37,69 @@ pub fn main(_args: TokenStream, stream: TokenStream) -> TokenStream {
|
||||||
TokenStream::from(new)
|
TokenStream::from(new)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_help(section: &str) -> String {
|
||||||
|
let section = section.to_lowercase();
|
||||||
|
let section = section.trim_matches('"');
|
||||||
|
let mut content = String::new();
|
||||||
|
let mut path = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||||
|
|
||||||
|
// The package name will be something like uu_numfmt, hence we split once
|
||||||
|
// on '_' and take the second element. The help section should then be in a
|
||||||
|
// file called numfmt.md
|
||||||
|
path.push(format!(
|
||||||
|
"{}.md",
|
||||||
|
std::env::var("CARGO_PKG_NAME")
|
||||||
|
.unwrap()
|
||||||
|
.split_once('_')
|
||||||
|
.unwrap()
|
||||||
|
.1,
|
||||||
|
));
|
||||||
|
|
||||||
|
File::open(path)
|
||||||
|
.unwrap()
|
||||||
|
.read_to_string(&mut content)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
content
|
||||||
|
.lines()
|
||||||
|
.skip_while(|&l| {
|
||||||
|
l.strip_prefix("##")
|
||||||
|
.map_or(true, |l| l.trim().to_lowercase() != section)
|
||||||
|
})
|
||||||
|
.skip(1)
|
||||||
|
.take_while(|l| !l.starts_with("##"))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n")
|
||||||
|
.trim()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the usage from the "Usage" section in the help file.
|
||||||
|
///
|
||||||
|
/// The usage is assumed to be surrounded by markdown code fences. It may span
|
||||||
|
/// multiple lines. The first word of each line is assumed to be the name of
|
||||||
|
/// the util and is replaced by "{}" so that the output of this function can be
|
||||||
|
/// used with `uucore::format_usage`.
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn help_usage(_input: TokenStream) -> TokenStream {
|
||||||
|
let text: String = parse_help("usage")
|
||||||
|
.strip_suffix("```")
|
||||||
|
.unwrap()
|
||||||
|
.lines()
|
||||||
|
.skip(1) // Skip the "```" of markdown syntax
|
||||||
|
.map(|l| {
|
||||||
|
// Replace the util name (assumed to be the first word) with "{}"
|
||||||
|
// to be replaced with the runtime value later.
|
||||||
|
if let Some((_util, args)) = l.split_once(' ') {
|
||||||
|
format!("{{}} {}", args)
|
||||||
|
} else {
|
||||||
|
"{}".to_string()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
TokenTree::Literal(Literal::string(&text)).into()
|
||||||
|
}
|
||||||
|
|
||||||
/// Reads a section from the help file of the util as a `str` literal.
|
/// Reads a section from the help file of the util as a `str` literal.
|
||||||
///
|
///
|
||||||
/// It is read verbatim, without parsing or escaping. The name of the help file
|
/// It is read verbatim, without parsing or escaping. The name of the help file
|
||||||
|
@ -61,41 +124,6 @@ pub fn help_section(input: TokenStream) -> TokenStream {
|
||||||
_ => panic!("Input to help_section should be a string literal!"),
|
_ => panic!("Input to help_section should be a string literal!"),
|
||||||
};
|
};
|
||||||
let input_str: String = value.parse().unwrap();
|
let input_str: String = value.parse().unwrap();
|
||||||
let input_str = input_str.to_lowercase().trim_matches('"').to_string();
|
let text = parse_help(&input_str);
|
||||||
|
TokenTree::Literal(Literal::string(&text)).into()
|
||||||
let mut content = String::new();
|
|
||||||
let mut path = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
|
|
||||||
|
|
||||||
// The package name will be something like uu_numfmt, hence we split once
|
|
||||||
// on '_' and take the second element. The help section should then be in a
|
|
||||||
// file called numfmt.md
|
|
||||||
path.push(format!(
|
|
||||||
"{}.md",
|
|
||||||
std::env::var("CARGO_PKG_NAME")
|
|
||||||
.unwrap()
|
|
||||||
.split_once('_')
|
|
||||||
.unwrap()
|
|
||||||
.1,
|
|
||||||
));
|
|
||||||
|
|
||||||
File::open(path)
|
|
||||||
.unwrap()
|
|
||||||
.read_to_string(&mut content)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let text = content
|
|
||||||
.lines()
|
|
||||||
.skip_while(|&l| {
|
|
||||||
l.strip_prefix("##")
|
|
||||||
.map_or(true, |l| l.trim().to_lowercase() != input_str)
|
|
||||||
})
|
|
||||||
.skip(1)
|
|
||||||
.take_while(|l| !l.starts_with("##"))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("\n")
|
|
||||||
.trim()
|
|
||||||
.to_string();
|
|
||||||
|
|
||||||
let str = TokenTree::Literal(Literal::string(&text));
|
|
||||||
str.into()
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue