feat: add flag to output css classes instead of inline styles in HTML highlighter output

Co-authored-by: Amaan Qureshi <amaanq12@gmail.com>
This commit is contained in:
Jonathan Raphaelson 2024-12-14 23:43:22 -07:00 committed by GitHub
parent 495fe2a6c5
commit 8368f9994d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 86 additions and 46 deletions

View file

@ -304,9 +304,9 @@ impl TSHighlighter {
output
.renderer
.set_carriage_return_highlight(self.carriage_return_index.map(Highlight));
let result = output
.renderer
.render(highlights, source_code, &|s| self.attribute_strings[s.0]);
let result = output.renderer.render(highlights, source_code, &|s, out| {
out.extend(self.attribute_strings[s.0]);
});
match result {
Err(Error::Cancelled | Error::Unknown) => ErrorCode::Timeout,
Err(Error::InvalidLanguage) => ErrorCode::InvalidLanguage,

View file

@ -1103,28 +1103,28 @@ impl HtmlRenderer {
self.line_offsets.push(0);
}
pub fn render<'a, F>(
pub fn render<F>(
&mut self,
highlighter: impl Iterator<Item = Result<HighlightEvent, Error>>,
source: &'a [u8],
source: &[u8],
attribute_callback: &F,
) -> Result<(), Error>
where
F: Fn(Highlight) -> &'a [u8],
F: Fn(Highlight, &mut Vec<u8>),
{
let mut highlights = Vec::new();
for event in highlighter {
match event {
Ok(HighlightEvent::HighlightStart(s)) => {
highlights.push(s);
self.start_highlight(s, attribute_callback);
self.start_highlight(s, &attribute_callback);
}
Ok(HighlightEvent::HighlightEnd) => {
highlights.pop();
self.end_highlight();
}
Ok(HighlightEvent::Source { start, end }) => {
self.add_text(&source[start..end], &highlights, attribute_callback);
self.add_text(&source[start..end], &highlights, &attribute_callback);
}
Err(a) => return Err(a),
}
@ -1153,30 +1153,23 @@ impl HtmlRenderer {
})
}
fn add_carriage_return<'a, F>(&mut self, attribute_callback: &F)
fn add_carriage_return<F>(&mut self, attribute_callback: &F)
where
F: Fn(Highlight) -> &'a [u8],
F: Fn(Highlight, &mut Vec<u8>),
{
if let Some(highlight) = self.carriage_return_highlight {
let attribute_string = (attribute_callback)(highlight);
if !attribute_string.is_empty() {
self.html.extend(b"<span ");
self.html.extend(attribute_string);
self.html.extend(b"></span>");
}
self.html.extend(b"<span ");
(attribute_callback)(highlight, &mut self.html);
self.html.extend(b"></span>");
}
}
fn start_highlight<'a, F>(&mut self, h: Highlight, attribute_callback: &F)
fn start_highlight<F>(&mut self, h: Highlight, attribute_callback: &F)
where
F: Fn(Highlight) -> &'a [u8],
F: Fn(Highlight, &mut Vec<u8>),
{
let attribute_string = (attribute_callback)(h);
self.html.extend(b"<span");
if !attribute_string.is_empty() {
self.html.extend(b" ");
self.html.extend(attribute_string);
}
self.html.extend(b"<span ");
(attribute_callback)(h, &mut self.html);
self.html.extend(b">");
}
@ -1184,9 +1177,9 @@ impl HtmlRenderer {
self.html.extend(b"</span>");
}
fn add_text<'a, F>(&mut self, src: &[u8], highlights: &[Highlight], attribute_callback: &F)
fn add_text<F>(&mut self, src: &[u8], highlights: &[Highlight], attribute_callback: &F)
where
F: Fn(Highlight) -> &'a [u8],
F: Fn(Highlight, &mut Vec<u8>),
{
pub const fn html_escape(c: u8) -> Option<&'static [u8]> {
match c as char {