Implement the highlighted src intermediate format.

I am going to remove the enum because I realized plain src blocks can just be highlighted src blocks with only RawText entries.
This commit is contained in:
Tom Alexander 2025-02-22 15:44:45 -05:00
parent c067ca9cc8
commit e34e2ef75f
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

View File

@ -24,11 +24,23 @@ pub(crate) struct PlainSrcBlock {
#[derive(Debug, Clone)]
pub(crate) struct HighlightedSrcBlock {
pub(crate) lines: Vec<String>,
pub(crate) lines: Vec<HighlightedSrcLine>,
pub(crate) language: Option<String>,
pub(crate) post_blank: organic::types::PostBlank,
}
#[derive(Debug, Clone)]
pub(crate) struct HighlightedSrcLine {
pub(crate) children: Vec<HighlightedSrcSegment>,
}
#[derive(Debug, Clone)]
pub(crate) enum HighlightedSrcSegment {
RawText(String),
HighlightStart { name: String },
HighlightEnd,
}
intermediate!(
ISrcBlock,
&'orig organic::types::SrcBlock<'parse>,
@ -97,6 +109,14 @@ intermediate!(
}
);
impl HighlightedSrcLine {
pub(crate) fn new() -> HighlightedSrcLine {
HighlightedSrcLine {
children: Vec::new(),
}
}
}
fn ascii_whitespace_value(c: char) -> usize {
match c {
' ' => 1,
@ -107,7 +127,7 @@ fn ascii_whitespace_value(c: char) -> usize {
}
}
fn highlight_nix<L>(lines: &[L]) -> Result<Vec<String>, CustomError>
fn highlight_nix<L>(lines: &[L]) -> Result<Vec<HighlightedSrcLine>, CustomError>
where
L: Borrow<str>,
{
@ -126,28 +146,43 @@ where
.highlight(&config, combined_text.as_bytes(), None, |_| None)
.unwrap();
let mut highlighted_text = Vec::new();
let mut highlighted_text: Vec<HighlightedSrcLine> = Vec::with_capacity(lines.len());
let mut current_line = HighlightedSrcLine::new();
for event in highlights {
match event.unwrap() {
HighlightEvent::Source { start, end } => {
highlighted_text.push(Cow::Borrowed(&combined_text[start..end]));
let mut span = &combined_text[start..end];
while let Some(line_break_index) = span.find('\n') {
let first_line = &span[..(line_break_index + 1)];
current_line
.children
.push(HighlightedSrcSegment::RawText(first_line.to_owned()));
highlighted_text.push(current_line);
current_line = HighlightedSrcLine::new();
span = &span[(line_break_index + 1)..];
}
if !span.is_empty() {
current_line
.children
.push(HighlightedSrcSegment::RawText(span.to_owned()));
}
}
HighlightEvent::HighlightStart(s) => {
let class_name = format!("srchl_{}", highlight_names[s.0]);
highlighted_text.push(Cow::Owned(format!(r#"<span class="{}">"#, class_name)));
current_line
.children
.push(HighlightedSrcSegment::HighlightStart {
name: highlight_names[s.0].to_owned(),
});
}
HighlightEvent::HighlightEnd => {
highlighted_text.push(Cow::Borrowed(r#"</span>"#));
current_line
.children
.push(HighlightedSrcSegment::HighlightEnd);
}
}
}
let highlighted_text = highlighted_text.join("");
let lines = highlighted_text
.split_inclusive('\n')
.map(str::to_owned)
.collect();
Ok(lines)
Ok(highlighted_text)
}
// use tree_sitter::Parser;