Note: This site is currently "Under construction". I'm migrating to a new version of my site building software. Lots of things are in a state of disrepair as a result (for example, footnote links aren't working). It's all part of the process of building in public. Most things should still be readable though.

Syntax Highlighting With Line Numbering And Classes In Rust

This is how I'm doing syntax highlighting in Rust.

This is the main way I'm doing it where instead of adding the styles inline it adds classes.

Code

```cargo
[dependencies]
syntect = "5.1.0"
```

use syntect::html::{ClassedHTMLGenerator, ClassStyle};
use syntect::parsing::SyntaxSet;
use syntect::util::LinesWithEndings;

fn main() {
  let code = r#"fn main() {
  println!("Hello, World");
}"#;

  let lang = "rust";
  let output = highlight_code(code, lang);
  println!("{}", output)
}

fn highlight_code(code: &str, lang: &str) -> String {
  let syntax_set = SyntaxSet::load_defaults_newlines();
  let syntax = syntax_set.find_syntax_by_token(&lang).unwrap_or_else(|| syntax_set.find_syntax_plain_text());
  let mut html_generator = ClassedHTMLGenerator::new_with_class_style(syntax, &syntax_set, ClassStyle::Spaced);
  for line in LinesWithEndings::from(code.trim()) {
      let _ = html_generator.parse_html_for_line_which_includes_newline(line);
  }
  let initial_html = html_generator.finalize();
  let output_html: Vec<_> = initial_html.lines()
    .map(|line| 
        format!(r#"<span class="numberedLine">{}</span>"#, line))
    .collect();
    format!(
        r#"<pre class="numberedLines"><code>{}</code></pre>"#, 
        output_html.join("\n")
    )
}

Results

<pre class="numberedLines"><code><span class="numberedLine"><span class="source rust"><span class="meta function rust"><span class="meta function rust"><span class="storage type function rust">fn</span> </span><span class="entity name function rust">main</span></span><span class="meta function rust"><span class="meta function parameters rust"><span class="punctuation section parameters begin rust">(</span></span><span class="meta function rust"><span class="meta function parameters rust"><span class="punctuation section parameters end rust">)</span></span></span></span><span class="meta function rust"> </span><span class="meta function rust"><span class="meta block rust"><span class="punctuation section block begin rust">{</span></span>
<span class="numberedLine">  <span class="support macro rust">println!</span><span class="meta group rust"><span class="punctuation section group begin rust">(</span></span><span class="meta group rust"><span class="string quoted double rust"><span class="punctuation definition string begin rust">&quot;</span>Hello, World<span class="punctuation definition string end rust">&quot;</span></span></span><span class="meta group rust"><span class="punctuation section group end rust">)</span></span><span class="punctuation terminator rust">;</span></span>
<span class="numberedLine"></span><span class="meta block rust"><span class="punctuation section block end rust">}</span></span></span></span></span></code></pre>
fn main() {
  println!("Hello, World");
}

CSS

.numberedLines {
  counter-reset: lineNumber;
}

.numberedLine {
  counter-increment: lineNumber;
}

.numberedLine:before {
    display: inline-block;
    color: goldenrod;
    content: counter(lineNumber);
    padding-right: 0.7rem;
    text-align: right;
    width: 2rem;
}

References