Skip to content

Instantly share code, notes, and snippets.

@dimfeld
Last active January 18, 2021 00:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dimfeld/d92473d958c723d6e6618a2e9367abed to your computer and use it in GitHub Desktop.
Save dimfeld/d92473d958c723d6e6618a2e9367abed to your computer and use it in GitHub Desktop.
nom parser that parse a block of text containing a mix of plaintext and directives
/// Parse a line of text, counting anything that doesn't match a directive as plain text.
fn parse_inline(input: &str) -> IResult<&str, Vec<Expression>> {
let mut output = Vec::new();
let mut current_input = input;
while !current_input.is_empty() {
let mut found_directive = false;
for (current_index, _) in current_input.char_indices() {
// println!("{} {}", current_index, current_input);
match directive(&current_input[current_index..]) {
Ok((remaining, parsed)) => {
// println!("Matched {:?} remaining {}", parsed, remaining);
let leading_text = &current_input[0..current_index];
if !leading_text.is_empty() {
output.push(Expression::Text(leading_text));
}
output.push(parsed);
current_input = remaining;
found_directive = true;
break;
}
Err(nom::Err::Error(_)) => {
// None of the parsers matched at the current position, so this character is just part of the text.
// The iterator will go to the next character so there's nothing to do here.
}
Err(e) => {
// On any other error, just return the error.
return Err(e);
}
}
}
if !found_directive {
output.push(Expression::Text(current_input));
break;
}
}
Ok(("", output))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment