Rust语法高亮库tree-sitter-highlight的使用,tree-sitter-highlight为Rust代码提供高效语法解析与着色功能

Tree-sitter Highlight

crates.io 徽章

用法

将此 crate 以及您想要解析的语言特定 crate 添加到您的 Cargo.toml 中:

[dependencies]
tree-sitter-highlight = "0.22.0"
tree-sitter-javascript = "0.21.3"

定义您将识别的高亮名称列表:

let highlight_names = [
    "attribute",
    "comment",
    "constant",
    "constant.builtin",
    "constructor",
    "embedded",
    "function",
    "function.builtin",
    "keyword",
    "module",
    "number",
    "operator",
    "property",
    "property.builtin",
    "punctuation",
    "punctuation.bracket",
    "punctuation.delimiter",
    "punctuation.special",
    "string",
    "string.special",
    "tag",
    "type",
    "type.builtin",
    "variable",
    "variable.builtin",
    "variable.parameter",
];

创建一个高亮器。您需要为每个用于语法高亮的线程创建一个:

use tree_sitter_highlight::Highlighter;

let mut highlighter = Highlighter::new();

从语言仓库的 queries 目录加载一些高亮查询:

use tree_sitter_highlight::HighlightConfiguration;

let javascript_language = tree_sitter_javascript::language();

let mut javascript_config = HighlightConfiguration::new( javascript_language, “javascript”, tree_sitter_javascript::HIGHLIGHT_QUERY, tree_sitter_javascript::INJECTIONS_QUERY, tree_sitter_javascript::LOCALS_QUERY, ).unwrap();

配置识别的名称:

javascript_config.configure(&highlight_names);

高亮一些代码:

use tree_sitter_highlight::HighlightEvent;

let highlights = highlighter.highlight( &javascript_config, b"const x = new Y();", None, |_| None ).unwrap();

for event in highlights { match event.unwrap() { HighlightEvent::Source {start, end} => { eprintln!(“source: {start}-{end}”); }, HighlightEvent::HighlightStart(s) => { eprintln!(“highlight style started: {s:?}”); }, HighlightEvent::HighlightEnd => { eprintln!(“highlight style ended”); }, } }

highlight 的最后一个参数是一个 语言注入 回调。这允许在 Tree-sitter 检测到嵌入式文档时检索其他语言(例如,HTML 中 script 标签内的 JavaScript 代码片段)。

完整示例代码

// 添加依赖到 Cargo.toml
// [dependencies]
// tree-sitter-highlight = "0.22.0"
// tree-sitter-javascript = "0.21.3"

use tree_sitter_highlight::{Highlighter, HighlightConfiguration, HighlightEvent}; use tree_sitter_javascript;

fn main() -> Result<(), Box<dyn std::error::Error>> { // 定义高亮名称列表 let highlight_names = [ “attribute”, “comment”, “constant”, “constant.builtin”, “constructor”, “embedded”, “function”, “function.builtin”, “keyword”, “module”, “number”, “operator”, “property”, “property.builtin”, “punctuation”, “punctuation.bracket”, “punctuation.delimiter”, “punctuation.special”, “string”, “string.special”, “tag”, “type”, “type.builtin”, “variable”, “variable.builtin”, “variable.parameter”, ];

// 创建高亮器
let mut highlighter = Highlighter::new();

// 获取 JavaScript 语言
let javascript_language = tree_sitter_javascript::language();

// 创建高亮配置
let mut javascript_config = HighlightConfiguration::new(
    javascript_language,
    "javascript",
    tree_sitter_javascript::HIGHLIGHT_QUERY,
    tree_sitter_javascript::INJECTIONS_QUERY,
    tree_sitter_javascript::LOCALS_QUERY,
)?;

// 配置识别的名称
javascript_config.configure(&highlight_names);

// 要解析的 JavaScript 代码
let code = b"const x = new Y(); // 这是一个注释";

// 执行高亮
let highlights = highlighter.highlight(
    &javascript_config,
    code,
    None,
    |_| None
)?;

// 处理高亮事件
for event in highlights {
    match event? {
        HighlightEvent::Source { start, end } => {
            // 输出源代码片段
            let text = std::str::from_utf8(&code[start..end])?;
            println!("源代码: '{}'", text);
        },
        HighlightEvent::HighlightStart(style_index) => {
            // 高亮样式开始
            println!("高亮开始: {}", highlight_names[style_index.0]);
        },
        HighlightEvent::HighlightEnd => {
            // 高亮样式结束
            println!("高亮结束");
        },
    }
}

Ok(())

}


1 回复

tree-sitter-highlight:Rust语法高亮库使用指南

概述

tree-sitter-highlight是一个基于tree-sitter解析器的Rust语法高亮库,能够为Rust代码提供高效的语法解析和着色功能。该库利用tree-sitter的强大解析能力,准确识别代码结构并应用适当的语法高亮。

主要特性

  • 高性能语法解析
  • 准确的Rust语法识别
  • 可自定义的高亮主题
  • 支持多种输出格式(HTML、ANSI等)

安装方法

在Cargo.toml中添加依赖:

[dependencies]
tree-sitter-highlight = "0.20.0"
tree-sitter-rust = "0.20.0"

基本使用方法

1. 基础语法高亮

use tree_sitter_highlight::{HighlightConfiguration, Highlighter, HtmlRenderer};

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

    let mut highlighter = Highlighter::new();
    let config = HighlightConfiguration::new(
        tree_sitter_rust::language(),
        tree_sitter_rust::HIGHLIGHTS_QUERY,
        tree_sitter_rust::INJECTIONS_QUERY,
        tree_sitter_rust::LOCALS_QUERY,
    ).unwrap();

    let highlights = highlighter.highlight(&config, code.as_bytes(), None, |_| None).unwrap();
    
    let mut renderer = HtmlRenderer::new();
    renderer.render(highlights, code.as_bytes(), &|highlight| {
        match highlight {
            0 => "keyword",    // 关键字
            1 => "function",   // 函数名
            2 => "string",     // 字符串
            _ => "comment",    // 注释
        }
    }).unwrap();
    
    println!("{}", renderer.html());
}

2. 自定义高亮主题

use tree_sitter_highlight::{HighlightConfiguration, Highlighter};

fn custom_highlighter() {
    let code = "fn calculate() -> i32 { 42 }";
    
    let config = HighlightConfiguration::new(
        tree_sitter_rust::language(),
        tree_sitter_rust::HIGHLIGHTS_QUERY,
        tree_sitter_rust::INJECTIONS_QUERY,
        tree_sitter_rust::LOCALS_QUERY,
    ).unwrap();

    let highlighter = Highlighter::new();
    let events = highlighter.highlight(&config, code.as_bytes(), None, |_| None).unwrap();
    
    // 自定义高亮处理
    for event in events {
        match event {
            tree_sitter_highlight::HighlightEvent::Source { start, end } => {
                let text = &code[start..end];
                print!("{}", text);
            }
            tree_sitter_highlight::HighlightEvent::HighlightStart(highlight) => {
                // 根据highlight索引应用自定义样式
                print!("<span class=\"highlight-{}\">", highlight.0);
            }
            tree_sitter_highlight::HighlightEvent::HighlightEnd => {
                print!("</span>");
            }
        }
    }
}

3. 错误处理示例

use tree_sitter_highlight::{HighlightConfiguration, Highlighter, Error};

fn highlight_with_error_handling(code: &str) -> Result<String, Error> {
    let config = HighlightConfiguration::new(
        tree_sitter_rust::language(),
        tree_sitter_rust::HIGHLIGHTS_QUERY,
        tree_sitter_rust::INJECTIONS_QUERY,
        tree_sitter_rust::LOCALS_QUERY,
    )?;
    
    let mut highlighter = Highlighter::new();
    let highlights = highlighter.highlight(&config, code.as_bytes(), None, |_| None)?;
    
    // 处理高亮结果
    Ok(process_highlights(highlights, code))
}

fn process_highlights(highlights: Vec<tree_sitter_highlight::HighlightEvent>, code: &str) -> String {
    let mut result = String::new();
    // 实现高亮处理逻辑
    result
}

高级用法

批量处理多个文件

use std::fs;
use tree_sitter_highlight::{HighlightConfiguration, Highlighter, HtmlRenderer};

fn highlight_directory(path: &str) {
    let config = HighlightConfiguration::new(
        tree_sitter_rust::language(),
        tree_sitter_rust::HIGHLIGHTS_QUERY,
        tree_sitter_rust::INJECTIONS_QUERY,
        tree_sitter_rust::LOCALS_QUERY,
    ).unwrap();

    let mut highlighter = Highlighter::new();
    
    for entry in fs::read_dir(path).unwrap() {
        let entry = entry.unwrap();
        if entry.path().extension().unwrap() == "rs" {
            let content = fs::read_to_string(entry.path()).unwrap();
            let highlights = highlighter.highlight(&config, content.as_bytes(), None, |_| None).unwrap();
            
            let mut renderer = HtmlRenderer::new();
            renderer.render(highlights, content.as_bytes(), &|highlight| {
                // 自定义高亮映射
                highlight.to_string()
            }).unwrap();
            
            // 保存或处理高亮结果
        }
    }
}

性能提示

  • 重用Highlighter实例以提高性能
  • 对于大量文件处理,考虑使用并行处理
  • 适当缓存配置和解析结果

这个库为Rust开发者提供了强大的语法高亮能力,特别适合代码编辑器、文档生成器和代码展示工具的开发。

完整示例代码

use std::fs;
use std::path::Path;
use tree_sitter_highlight::{HighlightConfiguration, Highlighter, HtmlRenderer, HighlightEvent, Error};

// 基础语法高亮示例
fn basic_highlight_example() -> Result<(), Error> {
    let code = r#"
        fn main() {
            // 这是一个注释
            println!("Hello, World!");
            let x = 42;
            let s = "字符串";
        }
    "#;

    // 创建高亮器配置
    let config = HighlightConfiguration::new(
        tree_sitter_rust::language(),
        tree_sitter_rust::HIGHLIGHTS_QUERY,
        tree_sitter_rust::INJECTIONS_QUERY,
        tree_sitter_rust::LOCALS_QUERY,
    )?;

    let mut highlighter = Highlighter::new();
    let highlights = highlighter.highlight(&config, code.as_bytes(), None, |_| None)?;
    
    // 使用HTML渲染器
    let mut renderer = HtmlRenderer::new();
    renderer.render(highlights, code.as_bytes(), &|highlight| {
        // 定义高亮样式映射
        match highlight.0 {
            0 => "keyword",      // 关键字
            1 => "function",     // 函数名
            2 => "string",       // 字符串
            3 => "comment",      // 注释
            4 => "type",         // 类型
            5 => "variable",     // 变量
            _ => "default",      // 默认样式
        }
    })?;
    
    println!("生成的HTML:\n{}", renderer.html());
    Ok(())
}

// 自定义高亮处理器
struct CustomHighlighter {
    output: String,
}

impl CustomHighlighter {
    fn new() -> Self {
        Self { output: String::new() }
    }
    
    fn highlight(&mut self, code: &str, config: &HighlightConfiguration) -> Result<(), Error> {
        let highlighter = Highlighter::new();
        let events = highlighter.highlight(config, code.as_bytes(), None, |_| None)?;
        
        for event in events {
            match event {
                HighlightEvent::Source { start, end } => {
                    let text = &code[start..end];
                    self.output.push_str(text);
                }
                HighlightEvent::HighlightStart(highlight) => {
                    // 根据高亮类型添加自定义标签
                    let tag = match highlight.0 {
                        0 => "<b>",
                        1 => "<span class=\"fn\">",
                        2 => "<span class=\"str\">",
                        3 => "<i>",
                        _ => "<span>",
                    };
                    self.output.push_str(tag);
                }
                HighlightEvent::HighlightEnd => {
                    self.output.push_str("</span>");
                }
            }
        }
        Ok(())
    }
}

// 批量处理文件的高亮函数
fn batch_highlight_files(dir_path: &str) -> Result<(), Box<dyn std::error::Error>> {
    let config = HighlightConfiguration::new(
        tree_sitter_rust::language(),
        tree_sitter_rust::HIGHLIGHTS_QUERY,
        tree_sitter_rust::INJECTIONS_QUERY,
        tree_sitter_rust::LOCALS_QUERY,
    )?;

    let mut highlighter = Highlighter::new();
    let path = Path::new(dir_path);
    
    if path.is_dir() {
        for entry in fs::read_dir(path)? {
            let entry = entry?;
            let file_path = entry.path();
            
            if file_path.extension().map(|ext| ext == "rs").unwrap_or(false) {
                println!("处理文件: {:?}", file_path);
                
                let content = fs::read_to_string(&file_path)?;
                let highlights = highlighter.highlight(&config, content.as_bytes(), None, |_| None)?;
                
                let mut renderer = HtmlRenderer::new();
                renderer.render(highlights, content.as_bytes(), &|highlight| {
                    // 自定义高亮样式映射
                    match highlight.0 {
                        0 => "rust-keyword",
                        1 => "rust-function",
                        2 => "rust-string",
                        3 => "rust-comment",
                        4 => "rust-type",
                        5 => "rust-variable",
                        _ => "rust-default",
                    }
                })?;
                
                // 这里可以保存HTML结果到文件
                let html_output = renderer.html();
                println!("生成HTML内容长度: {} 字符", html_output.len());
            }
        }
    }
    
    Ok(())
}

// 主函数
fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("=== tree-sitter-highlight 示例 ===");
    
    // 示例1: 基础高亮
    println!("\n1. 基础语法高亮示例:");
    basic_highlight_example()?;
    
    // 示例2: 自定义高亮
    println!("\n2. 自定义高亮示例:");
    let code = "fn calculate(a: i32, b: i32) -> i32 { a + b }";
    let config = HighlightConfiguration::new(
        tree_sitter_rust::language(),
        tree_sitter_rust::HIGHLIGHTS_QUERY,
        tree_sitter_rust::INJECTIONS_QUERY,
        tree_sitter_rust::LOCALS_QUERY,
    )?;
    
    let mut custom_highlighter = CustomHighlighter::new();
    custom_highlighter.highlight(code, &config)?;
    println!("自定义高亮结果: {}", custom_highlighter.output);
    
    // 示例3: 批量处理(注释掉以避免实际文件操作)
    // println!("\n3. 批量文件处理示例:");
    // batch_highlight_files("./src")?;
    
    println!("\n所有示例执行完成!");
    Ok(())
}

// 错误处理包装函数
fn highlight_with_proper_error_handling(code: &str) -> Result<String, Error> {
    let config = HighlightConfiguration::new(
        tree_sitter_rust::language(),
        tree_sitter_rust::HIGHLIGHTS_QUERY,
        tree_sitter_rust::INJECTIONS_QUERY,
        tree_sitter_rust::LOCALS_QUERY,
    )?;
    
    let mut highlighter = Highlighter::new();
    let highlights = highlighter.highlight(&config, code.as_bytes(), None, |_| None)?;
    
    let mut result = String::new();
    let mut in_highlight = false;
    
    for event in highlights {
        match event {
            HighlightEvent::Source { start, end } => {
                result.push_str(&code[start..end]);
            }
            HighlightEvent::HighlightStart(_) => {
                if !in_highlight {
                    result.push_str("<span class=\"highlight\">");
                    in_highlight = true;
                }
            }
            HighlightEvent::HighlightEnd => {
                if in_highlight {
                    result.push_str("</span>");
                    in_highlight = false;
                }
            }
        }
    }
    
    Ok(result)
}

这个完整的示例演示了tree-sitter-highlight库的主要功能,包括基础语法高亮、自定义高亮处理、错误处理和批量文件处理。示例代码包含了详细的注释,帮助理解每个部分的功能和用法。

回到顶部