Extract the line number from the switches.
This commit is contained in:
parent
3d7f411cf9
commit
317293f0f2
@ -0,0 +1,7 @@
|
|||||||
|
#+begin_example -n -10
|
||||||
|
foo
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
#+begin_example +n -15
|
||||||
|
bar
|
||||||
|
#+end_example
|
@ -0,0 +1,7 @@
|
|||||||
|
#+begin_example -n 0
|
||||||
|
foo
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
#+begin_example +n 0
|
||||||
|
bar
|
||||||
|
#+end_example
|
@ -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,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
@ -108,7 +108,10 @@ pub struct LatexEnvironment<'s> {
|
|||||||
pub source: &'s str,
|
pub source: &'s str,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type LineNumber = usize;
|
/// A line number used in switches to lesser blocks.
|
||||||
|
///
|
||||||
|
/// This must be signed because emacs subtracts 1 from the actual value in the org-mode text, which makes a 0 turn into a -1.
|
||||||
|
pub type LineNumber = isize;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SwitchNumberLines {
|
pub enum SwitchNumberLines {
|
||||||
|
Loading…
Reference in New Issue
Block a user