fml 0.5.0

Friendly Markup Language
Documentation
#[macro_export]
macro_rules! delimited_slice {
	($left:expr, $body:expr, $right:expr) => {
		choice((
			just('\\').ignore_then(just('\\').rewind()).ignored(),
			choice((just("\\").ignore_then($right), $right))
				.not()
				.rewind(),
			just("\\").ignore_then($right.rewind()).ignored(),
		))
		.ignore_then($body)
		.repeated()
		.at_least(1)
		.to_slice()
		.delimited_by($left, $right)
		.try_map(|s: &str, span| {
			if $crate::parser::functions::is_blank(s) {
				Err(Simple::new(None, span))
			} else {
				Ok(s)
			}
		})
	};
	($left:expr, $right:expr) => {
		delimited_slice!($left, any(), $right)
	};
	($token:expr) => {
		delimited_slice!($token, $token)
	};
}

#[macro_export]
macro_rules! delimited_string {
	($left:expr, $body:expr, $right:expr) => {
		choice((
			just('\\').ignore_then(just('\\')),
			$body.and_is(choice((just('\\').ignore_then($right), $right)).not()),
			just('\\').ignore_then($body),
		))
		.repeated()
		.at_least(1)
		.collect::<String>()
		.delimited_by($left, $right)
	};
	($left:expr, $right:expr) => {
		delimited_string!($left, any(), $right)
	};
	($token:expr) => {
		delimited_string!($token, $token)
	};
}

/// Line-Long-Slice declaration.\
/// Accepts a token that must appear at the beginning of the line,
/// followed by at least one inline-whitespace.
#[macro_export]
macro_rules! lls {
	($expr:expr) => {
		{
			// Start of Line
			let sol = choice((
				regex(r"^").ignored(),
				newline(),
			));
			let esc_nl = just('\\').ignore_then(newline());
			let not_nl = choice((just('\\').ignore_then(just('\\').rewind()).ignored(), esc_nl, newline().not().rewind())).ignore_then(any());
			// Text lasting until linebreak
			let line_text = not_nl.repeated().at_least(1).to_slice();
			// Inline-Whitespace then Line-Text
			let iws_linetext = inline_whitespace().at_least(1).ignore_then(line_text);

			sol.ignore_then($expr).ignore_then(iws_linetext)
		}
	};
	($left:expr, $($right:expr),+) => {
		lls!(choice(($left, $($right),+)))
	};
}