raw
1use nom::{
2 IResult, Parser,
3 branch::alt,
4 bytes::complete::tag,
5 character::complete::{anychar, char},
6 combinator::{not, peek, recognize, value},
7 multi::many1,
8 sequence::{preceded, terminated},
9};
10
11use crate::ast::Inline;
12
13pub(super) fn strikethrough<'a>() -> impl FnMut(&'a str) -> IResult<&'a str, Inline> {
14 move |input: &'a str| {
15 let (input, _) = terminated(tag("~~"), peek(not(char('~')))).parse(input)?;
16 let not_a_closing_tag = (tag("~~"), char('~'));
17 let closing_tag = preceded(peek(not(not_a_closing_tag)), tag("~~"));
18 let content_parser = recognize(many1(preceded(
19 peek(not(closing_tag)),
20 alt((value('~', tag("\\~")), anychar)),
21 )));
22 let (input, content) = recognize(content_parser).parse(input)?;
23 let (input, _) = tag("~~").parse(input)?;
24
25 let (_, inline) = crate::parser::inline::inline_many1().parse(content)?;
26
27 Ok((input, Inline::Strikethrough(inline)))
28 }
29}
30