1use crate::EventIter;
3use anyhow::{bail, format_err, Context, Error};
4use pulldown_cmark::{CowStr, Event, TagEnd};
5
6pub 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
27pub 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
41pub fn unwrap<'t>(text: &'t str, front: &str, back: &str) -> &'t str {
43 text.trim().trim_start_matches(front).trim_end_matches(back)
44}