mdman/
util.rs

1///! General utilities.
2use crate::EventIter;
3use anyhow::{bail, format_err, Context, Error};
4use pulldown_cmark::{CowStr, Event, TagEnd};
5
6/// Splits the text `foo(1)` into "foo" and `1`.
7pub fn parse_name_and_section(text: &str) -> Result<(&str, u8), Error> {
8    let mut i = text.split_terminator(&['(', ')'][..]);
9    let name = i
10        .next()
11        .ok_or_else(|| format_err!("man reference must have a name"))?;
12    let section = i
13        .next()
14        .ok_or_else(|| format_err!("man reference must have a section such as mycommand(1)"))?;
15    if let Some(s) = i.next() {
16        bail!(
17            "man reference must have the form mycommand(1), got extra part `{}`",
18            s
19        );
20    }
21    let section: u8 = section
22        .parse()
23        .with_context(|| format!("section must be a number, got {}", section))?;
24    Ok((name, section))
25}
26
27/// Extracts the text from a header after `Tag::Heading` has been received.
28pub fn header_text<'e>(parser: &mut EventIter<'e>) -> Result<CowStr<'e>, Error> {
29    let text = match parser.next() {
30        Some((Event::Text(t), _range)) => t,
31        e => bail!("expected plain text in man header, got {:?}", e),
32    };
33    match parser.next() {
34        Some((Event::End(TagEnd::Heading(..)), _range)) => {
35            return Ok(text);
36        }
37        e => bail!("expected plain text in man header, got {:?}", e),
38    }
39}
40
41/// Removes tags from the front and back of a string.
42pub fn unwrap<'t>(text: &'t str, front: &str, back: &str) -> &'t str {
43    text.trim().trim_start_matches(front).trim_end_matches(back)
44}