Merge pull request #3419 from epage/man

docs(man): Add some basic documentation
This commit is contained in:
Ed Page 2022-02-08 10:25:24 -06:00 committed by GitHub
commit fc0eeb28bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 7 deletions

View file

@ -18,3 +18,36 @@ Dual-licensed under [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT).
## About
Generate [ROFF](https://en.wikipedia.org/wiki/Roff_(software)) from a `clap::App`.
### Example
We're going to assume you want to generate your man page as part of your
development rather than your shipped program having a flag to generate it.
In your `Cargo.toml`:
```toml
[build-dependencies]
clap_mangen = "0.1"
```
In your `build.rs`:
```rust,no_run
fn main() -> std::io::Result<()> {
let out_dir = std::path::PathBuf::from(std::env::var_os("OUT_DIR").ok_or_else(|| std::io::ErrorKind::NotFound)?);
let app = clap::App::new("mybin")
.arg(clap::arg!(-n --name <NAME>))
.arg(clap::arg!(-c --count <NUM>));
let man = clap_mangen::Man::new(app);
let mut buffer: Vec<u8> = Default::default();
man.render(&mut buffer)?;
std::fs::write(out_dir.join("mybin.1"), buffer)?;
Ok(())
}
```
Tip: Consider a [cargo xtask](https://github.com/matklad/cargo-xtask) instead of a `build.rs` to reduce build costs.

View file

@ -12,7 +12,7 @@ use render::subcommand_heading;
use roff::{roman, Roff};
use std::io::Write;
/// A manual page as constructed from a clap::App.
/// A manpage writer
pub struct Man<'a> {
app: clap::App<'a>,
title: String,
@ -22,6 +22,7 @@ pub struct Man<'a> {
manual: String,
}
/// Build a [`Man`]
impl<'a> Man<'a> {
/// Create a new manual page.
pub fn new(mut app: clap::App<'a>) -> Self {
@ -45,37 +46,58 @@ impl<'a> Man<'a> {
}
}
/// Override the default title
/// Override the default man page title, written in all caps
pub fn title(mut self, title: impl Into<String>) -> Self {
self.title = title.into();
self
}
/// Override the default section
/// Override the default section this man page is placed in
///
/// Common values:
///
// - `"1"`: User Commands
// - `"2"`: System Calls
// - `"3"`: C Library Functions
// - `"4"`: Devices and Special Files
// - `"5"`: File Formats and Conventions
// - `"6"`: Games et. al.
// - `"7"`: Miscellanea
// - `"8"`: System Administration tools and Daemons
pub fn section(mut self, section: impl Into<String>) -> Self {
self.section = section.into();
self
}
/// Override the default date
/// Override the default date for the last non-trivial change to this man page
///
/// Dates should be written in the form `YYYY-MM-DD`.
pub fn date(mut self, date: impl Into<String>) -> Self {
self.date = date.into();
self
}
/// Override the default source
/// Override the default source your command
///
/// For those few man-pages pages in Sections 1 and 8, probably you just want to write GNU.
pub fn source(mut self, source: impl Into<String>) -> Self {
self.source = source.into();
self
}
/// Override the default manual
/// Override the default manual this page is a member of
pub fn manual(mut self, manual: impl Into<String>) -> Self {
self.manual = manual.into();
self
}
}
/// Render a manual page into writer.
/// Generate ROFF output
impl<'a> Man<'a> {
/// Render a full manual page into the writer.
///
/// If customization is needed, you can call the individual sections you want and mix them into
/// your own ROFF content.
pub fn render(&self, w: &mut dyn Write) -> Result<(), std::io::Error> {
let mut roff = Roff::default();
self._render_title(&mut roff);