use std::path::PathBuf;
use super::parse_file_or_stdin;
use clap::Args;
use usage::docs::markdown::MarkdownRenderer;
#[derive(Args)]
#[clap(visible_alias = "md")]
pub struct Markdown {
#[clap(short, long)]
file: PathBuf,
#[clap(short, long, requires = "out_dir", conflicts_with = "out_file")]
multi: bool,
#[clap(long)]
html_encode: bool,
#[clap(long, value_hint = clap::ValueHint::DirPath)]
out_dir: Option<PathBuf>,
#[clap(long, value_hint = clap::ValueHint::FilePath, required_unless_present = "multi")]
out_file: Option<PathBuf>,
#[clap(long)]
replace_pre_with_code_fences: bool,
#[clap(long)]
url_prefix: Option<String>,
}
impl Markdown {
pub fn run(&self) -> miette::Result<()> {
let write = |path: &PathBuf, md: &str| -> miette::Result<()> {
println!("writing to {}", path.display());
xx::file::write(
path,
format!(
"<!-- @generated by usage-cli from usage spec -->\n{}\n",
md.trim()
),
)?;
Ok(())
};
let spec = parse_file_or_stdin(&self.file)?;
let mut ctx = MarkdownRenderer::new(spec.clone())
.with_html_encode(self.html_encode)
.with_replace_pre_with_code_fences(self.replace_pre_with_code_fences);
if let Some(url_prefix) = &self.url_prefix {
ctx = ctx.with_url_prefix(url_prefix);
}
if self.multi {
ctx = ctx.with_multi(true);
let commands = spec.cmd.all_subcommands().into_iter().filter(|c| !c.hide);
for cmd in commands {
let md = ctx.render_cmd(cmd)?;
let dir = cmd
.full_cmd
.iter()
.take(cmd.full_cmd.len() - 1)
.map(|c| c.to_string())
.collect::<Vec<_>>()
.join("/");
let path = self
.out_dir
.as_ref()
.unwrap()
.join(dir)
.join(format!("{}.md", cmd.name));
write(&path, &md)?;
}
let md_idx = ctx.render_index()?;
let path_idx = self.out_dir.as_ref().unwrap().join("index.md");
write(&path_idx, &md_idx)?;
} else {
let md = ctx.render_spec()?;
let path = self.out_file.as_ref().unwrap();
write(path, &md)?;
}
Ok(())
}
}