fml 0.6.2

Friendly Markup Language
Documentation
use crate::{
    ast::*,
    parser::{
        Stream,
        functions::{macros::*, styles::*},
    },
};
use winnow::{
    Result,
    ascii::*,
    combinator::{repeat, *},
    error::{ContextError, ParserError, StrContext},
    prelude::*,
    token::*,
};

pub fn nestables<'i>(input: &mut Stream<'i>) -> Result<FmlValue> {
    alt((quote, list)).parse_next(input)
}

fn quote<'i>(input: &mut Stream<'i>) -> Result<FmlValue> {
    let scope: String = llp!(">").parse_next(input)?;
    let mut state = input.state.clone();
    state.is_sol = true;
    state.is_in_heading = false;
    inner_fml(&scope, state).map(FmlValue::Quote)
}

fn list<'i>(input: &mut Stream<'i>) -> Result<FmlValue> {
    let scope: String = llp!("-").parse_next(input)?;
    let next_line = || {
        alt((
            preceded(
                opt::<_, _, ContextError<_>, _>('\\'),
                (line_ending, '-', space1).take(),
            ),
            preceded('\\', line_ending),
        ))
    };

    let mut items: Vec<String> = repeat(
        1..,
        repeat_till(
            1..,
            alt((preceded(space0, next_line()), not!(line_ending))),
            alt((
                delimited(space0, line_ending, not(("-", space1))),
                preceded(space0, eof),
            )),
        )
        .map(|(x, _): (String, _)| x),
    )
    .parse(&scope[..])
    .map_err(|e| e.into_inner())?;

    let mut state = input.state.clone();
    state.is_in_heading = false;
    state.is_sol = true; // these will allow quoted headings and nested quotes

    let mut values = vec![];
    for item in items {
        values.push(
            fml_values(Stream {
                input: &item,
                state: state.clone(),
            })
            .map(ListItem)?,
        )
    }

    Ok(FmlValue::List(FmlList(values)))
}