mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 04:27:45 +00:00
uudoc: support after_help and read directly from markdown file
This commit is contained in:
parent
e307f624e8
commit
e155a5ea6d
2 changed files with 74 additions and 1 deletions
|
@ -91,6 +91,15 @@ fn main() -> io::Result<()> {
|
|||
continue;
|
||||
}
|
||||
let p = format!("docs/src/utils/{}.md", name);
|
||||
|
||||
let markdown = File::open(format!("src/uu/{name}/{name}.md"))
|
||||
.and_then(|mut f: File| {
|
||||
let mut s = String::new();
|
||||
f.read_to_string(&mut s)?;
|
||||
Ok(s)
|
||||
})
|
||||
.ok();
|
||||
|
||||
if let Ok(f) = File::create(&p) {
|
||||
MDWriter {
|
||||
w: Box::new(f),
|
||||
|
@ -98,6 +107,7 @@ fn main() -> io::Result<()> {
|
|||
name,
|
||||
tldr_zip: &mut tldr_zip,
|
||||
utils_per_platform: &utils_per_platform,
|
||||
markdown,
|
||||
}
|
||||
.markdown()?;
|
||||
println!("Wrote to '{}'", p);
|
||||
|
@ -115,6 +125,7 @@ struct MDWriter<'a, 'b> {
|
|||
name: &'a str,
|
||||
tldr_zip: &'b mut Option<ZipArchive<File>>,
|
||||
utils_per_platform: &'b HashMap<&'b str, Vec<String>>,
|
||||
markdown: Option<String>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> MDWriter<'a, 'b> {
|
||||
|
@ -124,6 +135,7 @@ impl<'a, 'b> MDWriter<'a, 'b> {
|
|||
self.usage()?;
|
||||
self.description()?;
|
||||
self.options()?;
|
||||
self.after_help()?;
|
||||
self.examples()
|
||||
}
|
||||
|
||||
|
@ -184,6 +196,10 @@ impl<'a, 'b> MDWriter<'a, 'b> {
|
|||
}
|
||||
|
||||
fn description(&mut self) -> io::Result<()> {
|
||||
if let Some(after_help) = self.markdown_section("about") {
|
||||
return writeln!(self.w, "\n\n{}", after_help);
|
||||
}
|
||||
|
||||
if let Some(about) = self
|
||||
.command
|
||||
.get_long_about()
|
||||
|
@ -195,6 +211,22 @@ impl<'a, 'b> MDWriter<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
fn after_help(&mut self) -> io::Result<()> {
|
||||
if let Some(after_help) = self.markdown_section("after help") {
|
||||
return writeln!(self.w, "\n\n{}", after_help);
|
||||
}
|
||||
|
||||
if let Some(after_help) = self
|
||||
.command
|
||||
.get_after_long_help()
|
||||
.or_else(|| self.command.get_after_help())
|
||||
{
|
||||
writeln!(self.w, "\n\n{}", after_help)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn examples(&mut self) -> io::Result<()> {
|
||||
if let Some(zip) = self.tldr_zip {
|
||||
let content = if let Some(f) =
|
||||
|
@ -295,6 +327,32 @@ impl<'a, 'b> MDWriter<'a, 'b> {
|
|||
}
|
||||
writeln!(self.w, "</dl>\n")
|
||||
}
|
||||
|
||||
fn markdown_section(&self, section: &str) -> Option<String> {
|
||||
let md = self.markdown.as_ref()?;
|
||||
let section = section.to_lowercase();
|
||||
|
||||
fn is_section_header(line: &str, section: &str) -> bool {
|
||||
line.strip_prefix("##")
|
||||
.map_or(false, |l| l.trim().to_lowercase() == section)
|
||||
}
|
||||
|
||||
let result = md
|
||||
.lines()
|
||||
.skip_while(|&l| !is_section_header(l, §ion))
|
||||
.skip(1)
|
||||
.take_while(|l| !l.starts_with("##"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
.trim()
|
||||
.to_string();
|
||||
|
||||
if result != "" {
|
||||
Some(result)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_zip_content(archive: &mut ZipArchive<impl Read + Seek>, name: &str) -> Option<String> {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (C) ~ Roy Ivy III <rivy.dev@gmail.com>; MIT license
|
||||
// spell-checker:ignore backticks
|
||||
|
||||
extern crate proc_macro;
|
||||
use std::{fs::File, io::Read, path::PathBuf};
|
||||
|
@ -37,6 +38,19 @@ pub fn main(_args: TokenStream, stream: TokenStream) -> TokenStream {
|
|||
TokenStream::from(new)
|
||||
}
|
||||
|
||||
// FIXME: This is currently a stub. We could do much more here and could
|
||||
// even pull in a full markdown parser to get better results.
|
||||
/// Render markdown into a format that's easier to read in the terminal.
|
||||
///
|
||||
/// For now, all this function does is remove backticks.
|
||||
/// Some ideas for future improvement:
|
||||
/// - Render headings as bold
|
||||
/// - Convert triple backticks to indented
|
||||
/// - Printing tables in a nice format
|
||||
fn render_markdown(s: &str) -> String {
|
||||
s.replace('`', "")
|
||||
}
|
||||
|
||||
/// 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
|
||||
|
@ -81,7 +95,8 @@ pub fn help_section(input: TokenStream) -> TokenStream {
|
|||
let section = get_argument(&input, 0, "section");
|
||||
let filename = get_argument(&input, 1, "filename");
|
||||
let text = parse_help(§ion, &filename);
|
||||
TokenTree::Literal(Literal::string(&text)).into()
|
||||
let rendered = render_markdown(&text);
|
||||
TokenTree::Literal(Literal::string(&rendered)).into()
|
||||
}
|
||||
|
||||
/// Get an argument from the input vector of `TokenTree`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue