syntax/lib.rs
1//! Tree-sitter syntax classification for isolated code blocks.
2//!
3//! [`highlight`] takes a source string and a fence tag and returns the
4//! highlighted spans as `(byte range, kind)` pairs, in document order.
5//! Everything outside those spans is unhighlighted text. There is no color
6//! and no rendering here — kinds map to colors through
7//! [`SyntaxPalette::color`](theme::SyntaxPalette::color) — and no injection
8//! machinery: the fence already names the grammar, so a block is one parse
9//! with one highlights query. Languages are a table ([`lang::LANGS`], one row
10//! per feature); a grammar with no match returns `None` and the caller renders
11//! plain text.
12//!
13//! A language the table does not carry is a [`Lang::new`](lang::Lang::new)
14//! `static` of your own, highlighted through
15//! [`Lang::highlight`](lang::Lang::highlight) — the same path the built-in rows
16//! take, so nothing about the query cache or the capture vocabulary has to be
17//! rebuilt to add one.
18
19use std::ops::Range;
20use theme::HighlightKind;
21
22pub mod lang;
23
24/// The exact tree-sitter these grammars were built against. Reach for a
25/// `LanguageFn` through here rather than declaring your own tree-sitter, or
26/// [`Lang::new`](lang::Lang::new) will not accept it — two versions in the
27/// graph are two unrelated types with one name.
28pub use tree_sitter;
29pub use tree_sitter_language;
30
31/// Highlight `source` as `language` (a fence tag — `rs`, `py`, `tsx`, …).
32/// `None` when the tag names no language.
33pub fn highlight(source: &str, language: &str) -> Option<Vec<(Range<usize>, HighlightKind)>> {
34 lang::resolve(language)?.highlight(source)
35}