use crate::{
ast::*,
parser::{
Stream,
functions::{
macros::*,
styles::{
delimiteds::{content_warning, rich_text},
*,
},
},
},
};
use winnow::{
Result,
ascii::*,
combinator::{repeat, *},
error::{ContextError, ParserError, StrContext},
prelude::*,
token::*,
};
pub fn scripts<'i>(input: &mut Stream<'i>) -> Result<FmlValue> {
alt((superscript, subscript)).parse_next(input)
}
pub fn line_scripts<'i>(input: &mut Stream<'i>) -> Result<FmlValue> {
alt((sup_line, sub_line)).parse_next(input)
}
macro_rules! line {
($parser:expr, $map:expr, $input:expr) => {{
let scope: String = llp!($parser).parse_next($input)?;
let mut state = $input.state.clone();
state.is_in_script = true;
inner_fml(&scope, state).map($map)
}};
}
fn sup_line<'i>(input: &mut Stream<'i>) -> Result<FmlValue> {
line!("#^", FmlValue::Superline, input)
}
fn sub_line<'i>(input: &mut Stream<'i>) -> Result<FmlValue> {
line!(alt(("#_", "#!")), FmlValue::Subline, input)
}
fn script_body<'i>(input: &mut Stream<'i>) -> Result<&'i str> {
let escapes = || ('\\', alt(('[', '|', '}', '\\')));
let body_pt = slice_till!(1.., alt((escapes().take(), not!(escapes(), "[", "|", "}"))));
let body = alt((
body_pt,
alt((rich_text.take(), content_warning.take(), "[", "|")),
));
delimited("{", body, "}").parse_next(input)
}
fn superscript<'i>(input: &mut Stream<'i>) -> Result<FmlValue> {
let scope = preceded('^', script_body).parse_next(input)?;
let mut state = input.state.clone();
state.is_in_script = true;
inner_fml(&scope, state).map(FmlValue::Superscript)
}
fn subscript<'i>(input: &mut Stream<'i>) -> Result<FmlValue> {
let scope = preceded('_', script_body).parse_next(input)?;
let mut state = input.state.clone();
state.is_in_script = true;
inner_fml(&scope, state).map(FmlValue::Subscript)
}