fml 0.1.0

Friendly Markup Language
#[macro_export]
macro_rules! delimited_pat {
	($left:expr, $body:expr, $right:expr) => {
		choice((
			choice((just("\\"), $right)).not().rewind(),
			esc_np().ignored(),
		))
		.ignore_then($body)
		.repeated()
		.at_least(1)
		.to_slice()
		.delimited_by($left, $right)
	};
	($left:expr, $right:expr) => {
		delimited_pat!($left, any(), $right)
	};
	($token:expr) => {
		delimited_pat!($token, $token)
	};
}

/// Returns two variables.\
/// First variable calls to_slice on the expression.\
/// Second just collects the expression to a String.\
/// May optionally include delimeters
#[macro_export]
macro_rules! to_both {
	($expr:expr $(, ($left_delim:expr, $right_delim:expr))?) => {
		(
			$expr.to_slice()
			$(
				.delimited_by($left_delim, $right_delim)
			)?,

			$expr.collect::<String>()
			$(
				.delimited_by($left_delim, $right_delim)
			)?
		)
	};
}

macro_rules! code_block_wrap {
	($expr:expr) => {
		ident()
			.or_not()
			.then_ignore(whitespace())
			.then(expr)
			.delimited_by(just("```"), whitespace().then(just("```")))
	};
}

/// Line-Long-Pattern declaration.\
/// Accepts a token that must appear at the beginning of the line,
/// followed by at least one inline-whitespace.
#[macro_export]
macro_rules! llp {
	($expr:expr) => {
		{
			// Start of Line
			let sol = choice((
				regex(r"^").ignored(),
				empty().delimited_by(newline(), empty()),
			));
			let esc_nl = just('\\').ignore_then(newline());
			let not_nl = choice((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),+) => {
		llp!(choice(($left, $($right),+)))
	};
}