Record line number in OrgSource.

This will be used for elements who have limits on the number of lines inside of them. This includes LaTeX fragment bodies and text markup.
This commit is contained in:
Tom Alexander 2023-08-27 23:21:41 -04:00
parent 20c17c40be
commit 1952d175c0
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

View File

@ -18,6 +18,7 @@ pub struct OrgSource<'s> {
end: usize, // exclusive end: usize, // exclusive
start_of_line: usize, start_of_line: usize,
preceding_character: Option<char>, preceding_character: Option<char>,
line_number: usize,
} }
impl<'s> OrgSource<'s> { impl<'s> OrgSource<'s> {
@ -31,6 +32,7 @@ impl<'s> OrgSource<'s> {
end: input.len(), end: input.len(),
start_of_line: 0, start_of_line: 0,
preceding_character: None, preceding_character: None,
line_number: 1,
} }
} }
@ -56,6 +58,10 @@ impl<'s> OrgSource<'s> {
assert!(other.end <= self.end); assert!(other.end <= self.end);
self.slice(..(other.start - self.start)) self.slice(..(other.start - self.start))
} }
pub fn get_line_number(&self) -> usize {
self.line_number
}
} }
impl<'s> InputTake for OrgSource<'s> { impl<'s> InputTake for OrgSource<'s> {
@ -119,10 +125,14 @@ where
} }
let skipped_text = &self.full_source[self.start..new_start]; let skipped_text = &self.full_source[self.start..new_start];
let start_of_line = skipped_text let mut start_of_line = self.start_of_line;
.rfind('\n') let mut line_number = self.line_number;
.map(|idx| self.start + idx + 1) for (offset, character) in skipped_text.char_indices() {
.unwrap_or(self.start_of_line); if character == '\n' {
start_of_line = self.start + offset + 1;
line_number += 1;
}
}
OrgSource { OrgSource {
full_source: self.full_source, full_source: self.full_source,
@ -130,6 +140,7 @@ where
end: new_end, end: new_end,
start_of_line, start_of_line,
preceding_character: skipped_text.chars().last(), preceding_character: skipped_text.chars().last(),
line_number,
} }
} }
} }
@ -369,4 +380,13 @@ mod tests {
assert_eq!(input.get_preceding_character(), None); assert_eq!(input.get_preceding_character(), None);
assert_eq!(input.slice(8..).get_preceding_character(), Some('💛')); assert_eq!(input.slice(8..).get_preceding_character(), Some('💛'));
} }
#[test]
fn line_number() {
let input = OrgSource::new("lorem\nfoo\nbar\nbaz\nipsum");
assert_eq!(input.get_line_number(), 1);
assert_eq!(input.slice(5..).get_line_number(), 1);
assert_eq!(input.slice(6..).get_line_number(), 2);
assert_eq!(input.slice(6..).slice(10..).get_line_number(), 4);
}
} }