fml 0.6.5

Friendly Markup Language
Documentation
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)
}

// Sup&Sub Scripts
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)
}