Skip to content

Instantly share code, notes, and snippets.

@rambip
Last active September 18, 2023 08:12
Show Gist options
  • Save rambip/a507c312ed61c99c24b2a54f98325721 to your computer and use it in GitHub Desktop.
Save rambip/a507c312ed61c99c24b2a54f98325721 to your computer and use it in GitHub Desktop.
An implementation of a text joiner in a stream of events
struct TextJoiner<'a, 'b> {
source: &'a str,
parser: Peekable<pulldown_cmark::OffsetIter<'a, 'b>>,
}
impl<'a, 'b> TextJoiner<'a, 'b> {
fn new_ext(source: &'a str, options: Options) -> Self {
Self {
source,
parser: pulldown_cmark::Parser::new_ext(source, options)
.into_offset_iter()
.peekable(),
}
}
}
impl<'a, 'b> Iterator for TextJoiner<'a, 'b> {
type Item=(Event<'a>, Range<usize>);
fn next(&mut self) -> Option<Self::Item> {
let is_empty_text = |x| = match x {
Event::Text(t) if t.is_empty() => true,
_ => false
};
while is_empty_text(self.parser.peek()) {
self.parser.next();
};
match self.parser.peek()? {
(Event::Text(_), range) => {
let start = range.start;
let mut end = range.end;
while let Some((Event::Text(_), _)) = self.parser.peek() {
end = self.parser.next().unwrap().1.end;
}
Some((Event::Text(self.source[start..end].into()), start..end))
},
_ => self.parser.next()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment