show_highlight/
show_highlight.rs1use std::env;
2use std::error::Error;
3use std::fs;
4
5use highlight_spans::Grammar;
6use render_ansi::{highlight_to_ansi_with_mode_and_background, ColorMode};
7use theme_engine::load_theme;
8
9fn parse_grammar(input: &str) -> Result<Grammar, String> {
11 Grammar::from_name(input).ok_or_else(|| {
12 format!(
13 "unknown grammar '{}'; use one of: {}",
14 input,
15 Grammar::supported_names().join(", ")
16 )
17 })
18}
19
20fn print_usage() {
22 eprintln!("Usage:");
23 eprintln!(
24 " cargo run -p render-ansi --example show_highlight -- <source-file> [theme] [grammar] [--color-mode truecolor|ansi256|ansi16] [--theme-bg]"
25 );
26 eprintln!();
27 eprintln!("Examples:");
28 eprintln!(" cargo run -p render-ansi --example show_highlight -- sample.cls");
29 eprintln!(
30 " cargo run -p render-ansi --example show_highlight -- sample.cls solarized-dark objectscript"
31 );
32 eprintln!(
33 " cargo run -p render-ansi --example show_highlight -- sample.sql tokyonight-dark sql"
34 );
35 eprintln!(
36 " cargo run -p render-ansi --example show_highlight -- sample.sql tokyonight-dark sql --color-mode ansi256"
37 );
38 eprintln!(
39 " cargo run -p render-ansi --example show_highlight -- sample.sql tokyonight-dark sql --color-mode ansi16"
40 );
41 eprintln!(
42 " cargo run -p render-ansi --example show_highlight -- sample.sql tokyonight-dark sql --theme-bg"
43 );
44}
45
46fn parse_color_mode(input: &str) -> Result<ColorMode, String> {
48 ColorMode::from_name(input).ok_or_else(|| {
49 format!(
50 "unknown color mode '{}'; use one of: {}",
51 input,
52 ColorMode::supported_names().join(", ")
53 )
54 })
55}
56
57fn main() -> Result<(), Box<dyn Error>> {
64 let args: Vec<String> = env::args().collect();
65 if args.len() < 2 {
66 print_usage();
67 return Ok(());
68 }
69
70 let source_path = &args[1];
71 let theme_name = args.get(2).map(String::as_str).unwrap_or("tokyonight-dark");
72 let grammar_name = args.get(3).map(String::as_str).unwrap_or("objectscript");
73 let mut color_mode = ColorMode::TrueColor;
74 let mut preserve_terminal_background = true;
75
76 let mut i = 4usize;
77 while i < args.len() {
78 match args[i].as_str() {
79 "--color-mode" => {
80 i += 1;
81 let Some(value) = args.get(i) else {
82 return Err("expected value after --color-mode".into());
83 };
84 color_mode =
85 parse_color_mode(value).map_err(|msg| format!("invalid color mode: {msg}"))?;
86 }
87 "--theme-bg" => {
88 preserve_terminal_background = false;
89 }
90 "--terminal-bg" => {
91 preserve_terminal_background = true;
92 }
93 flag => {
94 return Err(format!("unknown option '{flag}'").into());
95 }
96 }
97 i += 1;
98 }
99
100 let grammar = parse_grammar(grammar_name).map_err(|msg| format!("invalid grammar: {msg}"))?;
101 let source = fs::read(source_path)?;
102 let theme = load_theme(theme_name)?;
103
104 let rendered = highlight_to_ansi_with_mode_and_background(
105 &source,
106 grammar,
107 &theme,
108 color_mode,
109 preserve_terminal_background,
110 )?;
111 println!("{rendered}");
112
113 Ok(())
114}