Preserve the leading whitespace before an escape.

This commit is contained in:
Tom Alexander
2023-10-04 13:23:57 -04:00
parent 7ee48ff65c
commit 169bf69f5e
3 changed files with 35 additions and 28 deletions

View File

@@ -9,15 +9,12 @@ use nom::character::complete::space1;
use nom::combinator::consumed;
use nom::combinator::eof;
use nom::combinator::map;
use nom::combinator::not;
use nom::combinator::opt;
use nom::combinator::peek;
use nom::combinator::recognize;
use nom::combinator::verify;
use nom::multi::many0;
use nom::multi::many_till;
use nom::multi::separated_list1;
use nom::sequence::preceded;
use nom::sequence::tuple;
use super::org_source::OrgSource;
@@ -156,10 +153,7 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
let parser_context = parser_context.with_additional_node(&contexts[2]);
let parameters = parameters.map(|(_, parameters)| parameters);
let (remaining, contents) = many0(preceded(
not(parser_with_context!(exit_matcher_parser)(&parser_context)),
map(content_line, Into::<&str>::into),
))(remaining)?;
let (remaining, contents) = content(&parser_context, remaining)?;
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
let source = get_consumed(input, remaining);
@@ -441,8 +435,35 @@ fn switch_word<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn content_line<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, OrgSource<'s>> {
let (remaining, _) = opt(tuple((space0, tag(","), peek(alt((tag("#+"), tag("*")))))))(input)?;
let (remaining, line_post_escape) = recognize(many_till(anychar, line_ending))(remaining)?;
Ok((remaining, line_post_escape))
pub(crate) fn content<'b, 'g, 'r, 's>(
context: RefContext<'b, 'g, 'r, 's>,
input: OrgSource<'s>,
) -> Res<OrgSource<'s>, String> {
let mut ret = String::new();
let mut remaining = input;
let exit_matcher_parser = parser_with_context!(exit_matcher_parser)(context);
loop {
if exit_matcher_parser(remaining).is_ok() {
break;
}
let (remain, (pre_escape_whitespace, line)) = content_line(remaining)?;
pre_escape_whitespace.map(|val| ret.push_str(Into::<&str>::into(val)));
ret.push_str(line.into());
remaining = remain;
}
Ok((remaining, ret))
}
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
fn content_line<'s>(
input: OrgSource<'s>,
) -> Res<OrgSource<'s>, (Option<OrgSource<'s>>, OrgSource<'s>)> {
let (remaining, pre_escape_whitespace) = opt(map(
tuple((space0, tag(","), peek(alt((tag("#+"), tag("*")))))),
|(pre_comma, _, _)| pre_comma,
))(input)?;
let (remaining, line_post_escape) = recognize(many_till(anychar, line_ending))(remaining)?;
Ok((remaining, (pre_escape_whitespace, line_post_escape)))
}