Syntax Highlighting In Rust Apps With The syntect Crate

April 2023

TODO

    Merge this into: id: 2b1ep9iz

Inline Styles Included

This is the first approach I'm using. It adds inline styles but doesn't wrap things in a `

html tag. I'm taking care of that already which lets me add additional styles when I want.

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

use syntect::easy::HighlightLines;
use syntect::highlighting::ThemeSet;
use syntect::html::{styled_line_to_highlighted_html, IncludeBackground};
use syntect::parsing::SyntaxSet;

fn main() {
    let ps = SyntaxSet::load_defaults_newlines();
    let ts = ThemeSet::load_defaults();
    let syntax = ps.find_syntax_by_name("HTML").unwrap();
    let mut h = HighlightLines::new(syntax, &ts.themes["base16-ocean.dark"]);
    let regions = h.highlight_line(r#"<h1>
    Alfa
    </h1>"#, &ps).unwrap();
    let html = styled_line_to_highlighted_html(&regions[..], IncludeBackground::No).unwrap();
    println!("{}", html);
}
Output:
<span style="color:#c0c5ce;">&lt;</span><span style="color:#bf616a;">h1</span><span style="color:#c0c5ce;">&gt;
    Alfa
    &lt;/</span><span style="color:#bf616a;">h1</span><span style="color:#c0c5ce;">&gt;</span>

Core Usage

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

fn main() {
    let current_code = r#"<h1>Alfa</h1>
<p>Bravo</p>"#;
    let syntax_set = SyntaxSet::load_defaults_newlines();
    let syntax = syntax_set.find_syntax_by_name("HTML").unwrap();
    let mut html_generator =
        ClassedHTMLGenerator::new_with_class_style(syntax, &syntax_set, ClassStyle::Spaced);
    for line in LinesWithEndings::from(current_code) {
        html_generator.parse_html_for_line_which_includes_newline(line);
    }
    let output_html = html_generator.finalize();
    dbg!(output_html);
}

TODO

    show how to generate the css file

Alternate Approach

The crate offers a way to style things directly inline as well. That code looks like this:

use syntect::highlighting::ThemeSet;
use syntect::html::highlighted_html_for_string;
use syntect::parsing::SyntaxSet;

fn main() {
    let ss = SyntaxSet::load_defaults_newlines();
    let ts = ThemeSet::load_defaults();
    let syntax = ss.find_syntax_by_extension("rs").unwrap();
    let source_text = String::from("<h1>Alfa</h1>");
    let highlighted =
        highlighted_html_for_string(&source_text, &ss, &syntax, &ts.themes["base16-ocean.dark"])
            .unwrap();
    dbg!(highlighted);
}

I installed the crate that got all these working with:

cargo add syntect

end of line

References

A syntax highlighting library for Rust that uses Sublime Text syntax definitions. It aims to be a good solution for any Rust project that needs syntax highlighting

I copied the code I'm using directly from this example.

Sublime Syntax files are YAML files with a small header, followed by a list of contexts. Each context has a list of patterns that describe how to highlight text in that context, and how to change the current text.