Support spaces after the end of a lesser block.

This commit is contained in:
Tom Alexander 2023-09-06 18:25:35 -04:00
parent 3fc3a5d1ef
commit c4d7e646fc
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 12 additions and 6 deletions

View File

@ -0,0 +1,4 @@
# There are trailing spaces after the begin and end src lines
#+begin_src
echo "this is a source block."
#+end_src

View File

@ -7,6 +7,7 @@ use nom::character::complete::space1;
use nom::combinator::consumed; use nom::combinator::consumed;
use nom::combinator::eof; use nom::combinator::eof;
use nom::combinator::opt; use nom::combinator::opt;
use nom::combinator::recognize;
use nom::combinator::verify; use nom::combinator::verify;
use nom::multi::many_till; use nom::multi::many_till;
use nom::sequence::tuple; use nom::sequence::tuple;
@ -40,7 +41,7 @@ pub fn verse_block<'b, 'g, 'r, 's>(
) -> Res<OrgSource<'s>, VerseBlock<'s>> { ) -> Res<OrgSource<'s>, VerseBlock<'s>> {
let (remaining, name) = lesser_block_begin("verse")(context, input)?; let (remaining, name) = lesser_block_begin("verse")(context, input)?;
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?; let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
let (remaining, _nl) = line_ending(remaining)?; let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
let lesser_block_end_specialized = lesser_block_end("verse"); let lesser_block_end_specialized = lesser_block_end("verse");
let contexts = [ let contexts = [
ContextElement::ConsumeTrailingWhitespace(true), ContextElement::ConsumeTrailingWhitespace(true),
@ -95,7 +96,7 @@ pub fn comment_block<'b, 'g, 'r, 's>(
) -> Res<OrgSource<'s>, CommentBlock<'s>> { ) -> Res<OrgSource<'s>, CommentBlock<'s>> {
let (remaining, name) = lesser_block_begin("comment")(context, input)?; let (remaining, name) = lesser_block_begin("comment")(context, input)?;
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?; let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
let (remaining, _nl) = line_ending(remaining)?; let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
let lesser_block_end_specialized = lesser_block_end("comment"); let lesser_block_end_specialized = lesser_block_end("comment");
let contexts = [ let contexts = [
ContextElement::ConsumeTrailingWhitespace(true), ContextElement::ConsumeTrailingWhitespace(true),
@ -135,7 +136,7 @@ pub fn example_block<'b, 'g, 'r, 's>(
) -> Res<OrgSource<'s>, ExampleBlock<'s>> { ) -> Res<OrgSource<'s>, ExampleBlock<'s>> {
let (remaining, _name) = lesser_block_begin("example")(context, input)?; let (remaining, _name) = lesser_block_begin("example")(context, input)?;
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?; let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
let (remaining, _nl) = line_ending(remaining)?; let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
let lesser_block_end_specialized = lesser_block_end("example"); let lesser_block_end_specialized = lesser_block_end("example");
let contexts = [ let contexts = [
ContextElement::ConsumeTrailingWhitespace(true), ContextElement::ConsumeTrailingWhitespace(true),
@ -176,7 +177,7 @@ pub fn export_block<'b, 'g, 'r, 's>(
let (remaining, name) = lesser_block_begin("export")(context, input)?; let (remaining, name) = lesser_block_begin("export")(context, input)?;
// https://orgmode.org/worg/org-syntax.html#Blocks claims that export blocks must have a single word for data but testing shows no data and multi-word data still parses as an export block. // https://orgmode.org/worg/org-syntax.html#Blocks claims that export blocks must have a single word for data but testing shows no data and multi-word data still parses as an export block.
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?; let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
let (remaining, _nl) = line_ending(remaining)?; let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
let lesser_block_end_specialized = lesser_block_end("export"); let lesser_block_end_specialized = lesser_block_end("export");
let contexts = [ let contexts = [
ContextElement::ConsumeTrailingWhitespace(true), ContextElement::ConsumeTrailingWhitespace(true),
@ -217,7 +218,7 @@ pub fn src_block<'b, 'g, 'r, 's>(
let (remaining, name) = lesser_block_begin("src")(context, input)?; let (remaining, name) = lesser_block_begin("src")(context, input)?;
// https://orgmode.org/worg/org-syntax.html#Blocks claims that data is mandatory and must follow the LANGUAGE SWITCHES ARGUMENTS pattern but testing has shown that no data and incorrect data here will still parse to a src block. // https://orgmode.org/worg/org-syntax.html#Blocks claims that data is mandatory and must follow the LANGUAGE SWITCHES ARGUMENTS pattern but testing has shown that no data and incorrect data here will still parse to a src block.
let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?; let (remaining, parameters) = opt(tuple((space1, data)))(remaining)?;
let (remaining, _nl) = line_ending(remaining)?; let (remaining, _nl) = recognize(tuple((space0, line_ending)))(remaining)?;
let lesser_block_end_specialized = lesser_block_end("src"); let lesser_block_end_specialized = lesser_block_end("src");
let contexts = [ let contexts = [
ContextElement::ConsumeTrailingWhitespace(true), ContextElement::ConsumeTrailingWhitespace(true),
@ -275,9 +276,10 @@ fn _lesser_block_end<'b, 'g, 'r, 's, 'c>(
) -> Res<OrgSource<'s>, OrgSource<'s>> { ) -> Res<OrgSource<'s>, OrgSource<'s>> {
start_of_line(input)?; start_of_line(input)?;
let (remaining, _leading_whitespace) = space0(input)?; let (remaining, _leading_whitespace) = space0(input)?;
let (remaining, (_begin, _name, _ws)) = tuple(( let (remaining, (_begin, _name, _ws, _ending)) = tuple((
tag_no_case("#+end_"), tag_no_case("#+end_"),
tag_no_case(current_name_lower), tag_no_case(current_name_lower),
space0,
alt((eof, line_ending)), alt((eof, line_ending)),
))(remaining)?; ))(remaining)?;
let source = get_consumed(input, remaining); let source = get_consumed(input, remaining);