rust-cli / roff-rs

ROFF (man page format) generation library
docs.rs/roff
Apache License 2.0
59 stars 11 forks source link

Inline struct don't implment Display #19

Closed wwood closed 2 years ago

wwood commented 2 years ago

Hi,

I find this crate helpful, because I can use roff to generate a man page, and also convert the roff to a prettyish HTML for online help. Thanks.

In the 0.1 version of this crate, I was able to do things like this:

use roff::bold;
...
    Section::new("Frequently asked questions (FAQ)").paragraph(&format!(
        "{} CoverM makes use of \
        the system temporary directory (often {}) to store intermediate files. This can cause \
        problems if the amount of storage available there is small or used by many programs. \
        To fix, set the {} environment variable e.g. to set it to use the current directory: {}\n\n\
        {} Either is fine, CoverM determines which is being used by virtue of being less than \
        or greater than 1.",
        bold("Can the temporary directory used be changed?"),
        monospace_roff("/tmp"),
        monospace_roff("TMPDIR"),
        monospace_roff("TMPDIR=. coverm genome <etc>"),
        bold(
            "For thresholding arguments e.g. --dereplication-ani and --min-read-percent-identity, \
        should a percentage (e.g 97%) or fraction (e.g. 0.97) be specified?"
        )
    ))
}

However, in the current version, that fails because bold now returns an Inline, and Inline doesn't implement Display. Would it be possible to impl that? Otherwise I'm stuck doing hacks like this:

fn bold(s: &str) -> String {
    Roff::new().text([roff_bold(s)]).to_roff()
}

Also, come to think of it, maybe would be worth implementing monospace_roff in this crate? My impl is

pub fn monospace_roff(s: &str) -> String {
    format!("\\f[C]{}\\f[R]", s)
}

Thanks in advance, ben

epage commented 2 years ago

I'm trying to figure out if this works within the new API which is fundamentally different than the old one. It isn't intended for dealing with nesting but is meant to be a lower level sequence of roff directives. For example, our rendering of font selections is specialized for newlines.

btw I've not seen \f[C] yet in the docs I've found. Where can I read more on [] with \f?

wwood commented 2 years ago

Isn't it just something along these lines:

impl fmt::Display for Inline {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}",
match self {
   Bold(s) =>format!("\fB{}\fR", s),
... 
})
    }
}

Maybe I'm confused.

Sorry can't remember where I got the monospace code from. Possibly it is just a hack to make it look like monospace in HTML when converting roff -> markdown -> HTML, since all man page text is monospace I think. Maybe a suggestion of mine best ignored. Here's a concrete example of how I use it: https://github.com/wwood/CoverM/blob/main/release.sh#L39

Thanks.

epage commented 2 years ago

See https://github.com/rust-cli/roff-rs/blob/master/src/lib.rs#L271 for where we specialize the behavior

wwood commented 2 years ago

Right, but making use of that would require a Line struct to be generated, just for the purposes of rendering. I suppose I was thinking that Line's render() could call the Inline's Display method.

Seems you disagree, so OK. No problem. I will workaround.