mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 20:47:46 +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
|
||||
|
||||
## Usage
|
||||
|
||||
{} [OPTION]... [FILE]
|
||||
```
|
||||
base32 [OPTION]... [FILE]
|
||||
```
|
||||
|
||||
## About
|
||||
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
use std::io::{stdin, Read};
|
||||
|
||||
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;
|
||||
|
||||
const ABOUT: &str = help_section!("about");
|
||||
const USAGE: &str = help_section!("usage");
|
||||
const USAGE: &str = help_usage!();
|
||||
|
||||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
# base64
|
||||
|
||||
## Usage
|
||||
{} [OPTION]... [FILE]
|
||||
```
|
||||
base64 [OPTION]... [FILE]
|
||||
```
|
||||
|
||||
## About
|
||||
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
use uu_base32::base_common;
|
||||
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};
|
||||
|
||||
const ABOUT: &str = help_section!("about");
|
||||
const USAGE: &str = help_section!("usage");
|
||||
const USAGE: &str = help_usage!();
|
||||
|
||||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
<!-- spell-checker:ignore N'th M'th -->
|
||||
# numfmt
|
||||
|
||||
## Usage
|
||||
```
|
||||
numfmt [OPTION]... [NUMBER]...
|
||||
```
|
||||
|
||||
## About
|
||||
|
||||
Convert numbers from/to human-readable strings
|
||||
|
|
|
@ -15,7 +15,7 @@ use units::{IEC_BASES, SI_BASES};
|
|||
use uucore::display::Quotable;
|
||||
use uucore::error::UResult;
|
||||
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 format;
|
||||
|
@ -24,7 +24,7 @@ mod units;
|
|||
|
||||
const ABOUT: &str = help_section!("about");
|
||||
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<()> {
|
||||
for l in args {
|
||||
|
|
|
@ -37,6 +37,69 @@ pub fn main(_args: TokenStream, stream: TokenStream) -> TokenStream {
|
|||
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.
|
||||
///
|
||||
/// 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!"),
|
||||
};
|
||||
let input_str: String = value.parse().unwrap();
|
||||
let input_str = input_str.to_lowercase().trim_matches('"').to_string();
|
||||
|
||||
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()
|
||||
let text = parse_help(&input_str);
|
||||
TokenTree::Literal(Literal::string(&text)).into()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue