Wrap Syntax Highlighted Lines With Spans To Make Line Numbers
This is the code I'm using with the syntect syntax highlighter in rust to wrap each output line with a `<span>`html` tag. Doing so provides a way to add line numbers to code blocks using `::before()`css` in the page's CSS.
Code
#!/usr/bin/env cargo +nightly -Zscript
//! ```cargo
//! [package]
//! edition = "2021"
//! [dependencies]
//! syntect = { version = "5.1.0"}
//! ```
use syntect::easy::HighlightLines;
use syntect::highlighting::{Style, ThemeSet};
use syntect::html::{styled_line_to_highlighted_html, IncludeBackground};
use syntect::parsing::SyntaxSet;
use syntect::util::LinesWithEndings;
fn main() {
let language = "HTML";
let code = "<div>\n Hello, Highligher\n</div>";
let text = highlight_code_with_line_spans(code, language);
print!("{}", text);
}
fn highlight_code_with_line_spans(code: &str, language: &str) -> String {
let mut the_lines = vec![];
let ps = SyntaxSet::load_defaults_newlines();
let ts = ThemeSet::load_defaults();
let syntax = ps.find_syntax_by_name(language).unwrap();
let mut h = HighlightLines::new(syntax, &ts.themes["base16-ocean.dark"]);
for line in LinesWithEndings::from(code) {
let ranges: Vec<(Style, &str)> = h.highlight_line(line.trim_end(), &ps).unwrap();
let highlighted_line = styled_line_to_highlighted_html(&ranges[..], IncludeBackground::No);
let mut spanned_line = String::from(r#"<span class="lineHighlight">"#);
spanned_line.push_str(&highlighted_line.unwrap());
spanned_line.push_str("</span>");
the_lines.push(spanned_line);
}
the_lines.join("\n")
}
Results
<div> Hello, Highligher </div>