|
|
|
@@ -6,10 +6,12 @@ use nom::character::complete::space0;
|
|
|
|
use nom::character::complete::space1;
|
|
|
|
use nom::character::complete::space1;
|
|
|
|
use nom::combinator::consumed;
|
|
|
|
use nom::combinator::consumed;
|
|
|
|
use nom::combinator::eof;
|
|
|
|
use nom::combinator::eof;
|
|
|
|
|
|
|
|
use nom::combinator::map;
|
|
|
|
use nom::combinator::opt;
|
|
|
|
use nom::combinator::opt;
|
|
|
|
use nom::combinator::recognize;
|
|
|
|
use nom::combinator::recognize;
|
|
|
|
use nom::combinator::verify;
|
|
|
|
use nom::combinator::verify;
|
|
|
|
use nom::multi::many_till;
|
|
|
|
use nom::multi::many_till;
|
|
|
|
|
|
|
|
use nom::multi::separated_list1;
|
|
|
|
use nom::sequence::tuple;
|
|
|
|
use nom::sequence::tuple;
|
|
|
|
|
|
|
|
|
|
|
|
use super::org_source::OrgSource;
|
|
|
|
use super::org_source::OrgSource;
|
|
|
|
@@ -29,9 +31,11 @@ use crate::parser::util::text_until_exit;
|
|
|
|
use crate::types::CommentBlock;
|
|
|
|
use crate::types::CommentBlock;
|
|
|
|
use crate::types::ExampleBlock;
|
|
|
|
use crate::types::ExampleBlock;
|
|
|
|
use crate::types::ExportBlock;
|
|
|
|
use crate::types::ExportBlock;
|
|
|
|
|
|
|
|
use crate::types::LineNumber;
|
|
|
|
use crate::types::Object;
|
|
|
|
use crate::types::Object;
|
|
|
|
use crate::types::PlainText;
|
|
|
|
use crate::types::PlainText;
|
|
|
|
use crate::types::SrcBlock;
|
|
|
|
use crate::types::SrcBlock;
|
|
|
|
|
|
|
|
use crate::types::SwitchNumberLines;
|
|
|
|
use crate::types::VerseBlock;
|
|
|
|
use crate::types::VerseBlock;
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
|
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
|
|
@@ -130,7 +134,7 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
|
|
|
|
input: OrgSource<'s>,
|
|
|
|
input: OrgSource<'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, example_switches)))(remaining)?;
|
|
|
|
let (remaining, _nl) = recognize(tuple((space0, 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 = [
|
|
|
|
@@ -150,13 +154,20 @@ pub(crate) fn example_block<'b, 'g, 'r, 's>(
|
|
|
|
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
|
|
|
let (remaining, _end) = lesser_block_end_specialized(&parser_context, remaining)?;
|
|
|
|
|
|
|
|
|
|
|
|
let source = get_consumed(input, remaining);
|
|
|
|
let source = get_consumed(input, remaining);
|
|
|
|
|
|
|
|
let (switches, number_lines) = {
|
|
|
|
|
|
|
|
if let Some(parameters) = parameters {
|
|
|
|
|
|
|
|
(Some(parameters.source), parameters.number_lines)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
(None, None)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
Ok((
|
|
|
|
Ok((
|
|
|
|
remaining,
|
|
|
|
remaining,
|
|
|
|
ExampleBlock {
|
|
|
|
ExampleBlock {
|
|
|
|
source: source.into(),
|
|
|
|
source: source.into(),
|
|
|
|
name: source.into(),
|
|
|
|
name: source.into(),
|
|
|
|
switches: parameters.map(|parameters| Into::<&str>::into(parameters)),
|
|
|
|
switches,
|
|
|
|
number_lines: None, // TODO
|
|
|
|
number_lines,
|
|
|
|
contents: contents.into(),
|
|
|
|
contents: contents.into(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
))
|
|
|
|
))
|
|
|
|
@@ -302,3 +313,64 @@ fn _lesser_block_begin<'b, 'g, 'r, 's, 'c>(
|
|
|
|
))(remaining)?;
|
|
|
|
))(remaining)?;
|
|
|
|
Ok((remaining, name))
|
|
|
|
Ok((remaining, name))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ExampleSwitches<'s> {
|
|
|
|
|
|
|
|
source: &'s str,
|
|
|
|
|
|
|
|
number_lines: Option<SwitchNumberLines>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum SwitchState {
|
|
|
|
|
|
|
|
Normal,
|
|
|
|
|
|
|
|
NewLineNumber,
|
|
|
|
|
|
|
|
ContinuedLineNumber,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
|
|
|
|
|
|
|
fn example_switches<'s>(input: OrgSource<'s>) -> Res<OrgSource<'s>, ExampleSwitches<'s>> {
|
|
|
|
|
|
|
|
let mut number_lines = None;
|
|
|
|
|
|
|
|
let (remaining, (source, words)) = consumed(separated_list1(
|
|
|
|
|
|
|
|
space1,
|
|
|
|
|
|
|
|
map(is_not(" \t\r\n"), |val| Into::<&str>::into(val)),
|
|
|
|
|
|
|
|
))(input)?;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut state = SwitchState::Normal;
|
|
|
|
|
|
|
|
for word in words {
|
|
|
|
|
|
|
|
state = match (state, word) {
|
|
|
|
|
|
|
|
(SwitchState::Normal, "-n") => SwitchState::NewLineNumber,
|
|
|
|
|
|
|
|
(SwitchState::Normal, "+n") => SwitchState::ContinuedLineNumber,
|
|
|
|
|
|
|
|
(SwitchState::NewLineNumber, _) => {
|
|
|
|
|
|
|
|
let val = word
|
|
|
|
|
|
|
|
.parse::<LineNumber>()
|
|
|
|
|
|
|
|
.expect("TODO: I should be able to return CustomError from nom parsers.");
|
|
|
|
|
|
|
|
if val < 0 {
|
|
|
|
|
|
|
|
number_lines = Some(SwitchNumberLines::New(0));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// Note that this can result in a negative 1 if the val is originally 0.
|
|
|
|
|
|
|
|
number_lines = Some(SwitchNumberLines::New(val - 1));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
SwitchState::Normal
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
(SwitchState::ContinuedLineNumber, _) => {
|
|
|
|
|
|
|
|
let val = word
|
|
|
|
|
|
|
|
.parse::<LineNumber>()
|
|
|
|
|
|
|
|
.expect("TODO: I should be able to return CustomError from nom parsers.");
|
|
|
|
|
|
|
|
if val < 0 {
|
|
|
|
|
|
|
|
number_lines = Some(SwitchNumberLines::Continued(0));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// Note that this can result in a negative 1 if the val is originally 0.
|
|
|
|
|
|
|
|
number_lines = Some(SwitchNumberLines::Continued(val - 1));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
SwitchState::Normal
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
(state @ SwitchState::Normal, _) => state,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok((
|
|
|
|
|
|
|
|
remaining,
|
|
|
|
|
|
|
|
ExampleSwitches {
|
|
|
|
|
|
|
|
source: Into::<&str>::into(source),
|
|
|
|
|
|
|
|
number_lines,
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
}
|
|
|
|
|