Update getting the previous character and previous line.
This can be done a lot more efficiently now that we are keeping track of this information in the wrapped input type instead of having to fetch to the original document out of the context tree.
This commit is contained in:
@@ -49,47 +49,6 @@ pub fn immediate_in_section<'r, 's, 'x>(context: Context<'r, 's>, section_name:
|
||||
false
|
||||
}
|
||||
|
||||
/// Get one character from before the current position.
|
||||
pub fn get_one_before<'s>(document: &'s str, current_position: OrgSource<'s>) -> Option<&'s str> {
|
||||
// TODO: This should be replaced with new logic now that we are wrapping the input type.
|
||||
let current_position = Into::<&str>::into(¤t_position);
|
||||
assert!(is_slice_of(document, current_position));
|
||||
if document.as_ptr() as usize == current_position.as_ptr() as usize {
|
||||
return None;
|
||||
}
|
||||
let offset = current_position.as_ptr() as usize - document.as_ptr() as usize;
|
||||
let previous_character_offset = document.floor_char_boundary(offset - 1);
|
||||
Some(&document[previous_character_offset..offset])
|
||||
}
|
||||
|
||||
/// Get the line current_position is on up until current_position
|
||||
pub fn get_current_line_before_position<'s>(
|
||||
document: &'s str,
|
||||
current_position: OrgSource<'s>,
|
||||
) -> Option<OrgSource<'s>> {
|
||||
// TODO: This should be replaced with new logic now that we are wrapping the input type.
|
||||
let current_position = Into::<&str>::into(¤t_position);
|
||||
assert!(is_slice_of(document, current_position));
|
||||
if document.as_ptr() as usize == current_position.as_ptr() as usize {
|
||||
return None;
|
||||
}
|
||||
let offset = current_position.as_ptr() as usize - document.as_ptr() as usize;
|
||||
let mut previous_character_offset = offset;
|
||||
loop {
|
||||
let new_offset = document.floor_char_boundary(previous_character_offset - 1);
|
||||
let new_line = &document[new_offset..offset];
|
||||
let leading_char = new_line
|
||||
.chars()
|
||||
.next()
|
||||
.expect("Impossible to not have at least 1 character to read.");
|
||||
if "\r\n".contains(leading_char) || new_offset == 0 {
|
||||
break;
|
||||
}
|
||||
previous_character_offset = new_offset;
|
||||
}
|
||||
Some((&document[previous_character_offset..offset]).into())
|
||||
}
|
||||
|
||||
/// Check if the child string slice is a slice of the parent string slice.
|
||||
fn is_slice_of(parent: &str, child: &str) -> bool {
|
||||
let parent_start = parent.as_ptr() as usize;
|
||||
@@ -170,22 +129,13 @@ pub fn start_of_line<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
let document_root = context.get_document_root().unwrap();
|
||||
let preceding_character = get_one_before(document_root, input)
|
||||
.map(|slice| slice.chars().next())
|
||||
.flatten();
|
||||
match preceding_character {
|
||||
Some('\n') => {}
|
||||
Some(_) => {
|
||||
// Not at start of line, cannot be a heading
|
||||
return Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||
"Not at start of line".into(),
|
||||
))));
|
||||
}
|
||||
// If None, we are at the start of the file which allows for headings
|
||||
None => {}
|
||||
};
|
||||
Ok((input, ()))
|
||||
if input.is_at_start_of_line() {
|
||||
Ok((input, ()))
|
||||
} else {
|
||||
Err(nom::Err::Error(CustomError::MyError(MyError(
|
||||
"Not at start of line".into(),
|
||||
))))
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that we are at the start of a line
|
||||
@@ -194,10 +144,7 @@ pub fn preceded_by_whitespace<'r, 's>(
|
||||
context: Context<'r, 's>,
|
||||
input: OrgSource<'s>,
|
||||
) -> Res<OrgSource<'s>, ()> {
|
||||
let document_root = context.get_document_root().unwrap();
|
||||
let preceding_character = get_one_before(document_root, input)
|
||||
.map(|slice| slice.chars().next())
|
||||
.flatten();
|
||||
let preceding_character = input.get_preceding_character();
|
||||
match preceding_character {
|
||||
Some('\n') | Some('\r') | Some(' ') | Some('\t') => {}
|
||||
// If None, we are at the start of the file which is not allowed
|
||||
|
||||
Reference in New Issue
Block a user