Split markdown parsing and highlighting

This commit is contained in:
2025-07-07 13:10:45 +02:00
parent e0fd726f02
commit 462c27e111
7 changed files with 243 additions and 440 deletions

View File

@ -3,6 +3,8 @@ use std::{
ops::{Deref, Range},
};
use eyre::{bail, eyre};
#[derive(Clone, Eq, PartialEq)]
pub struct Span<'a> {
complete_str: &'a str,
@ -17,6 +19,13 @@ impl<'a> Span<'a> {
}
}
pub const fn empty() -> Self {
Span {
complete_str: "",
range: 0..0,
}
}
pub fn get(&self, slice: Range<usize>) -> Option<Self> {
let start = self.range.start.checked_add(slice.start)?;
let end = self.range.start.checked_add(slice.end)?;
@ -41,26 +50,49 @@ impl<'a> Span<'a> {
Some((head, tail))
}
pub fn trim_end_matches(&self, p: &str) -> Self {
if !self.ends_with(p) {
return self.clone();
}
Self {
range: self.range.start..self.range.end - p.len(),
complete_str: self.complete_str,
}
}
/// Try to merge the spans.
///
/// If either spans is empty, this just returns the other one.
/// This only works if spans are pointing into the same backing buffer, and are adjacent.
pub fn try_merge(&self, other: &Self) -> Option<Self> {
pub fn try_merge(&self, other: &Self) -> eyre::Result<Self> {
if self.is_empty() {
return Ok(other.clone());
}
if other.is_empty() {
return Ok(self.clone());
}
if self.complete_str.as_ptr() != other.complete_str.as_ptr() {
return None;
bail!("Can't merge different strings");
}
if self.range.end == other.range.start {
Some(Self {
Ok(Self {
range: self.range.start..other.range.end,
..*self
})
} else if self.range.start == other.range.end {
Some(Self {
Ok(Self {
range: other.range.start..self.range.end,
..*self
})
} else {
None
Err(eyre!("String: {:?}", self.complete_str)
.wrap_err(eyre!("Span 2: {:?}", other.deref()))
.wrap_err(eyre!("Span 1: {:?}", self.deref()))
.wrap_err("Can't merge disjoint string spans"))
}
}
}