This commit is contained in:
LordMZTE 2021-11-17 18:29:39 +01:00
parent f496f1fab6
commit 33ba1c05a0
2 changed files with 78 additions and 44 deletions

View File

@ -2,10 +2,12 @@
name = "synmtx"
version = "0.1.0"
edition = "2021"
authors = ["LordMZTE <lord@mzte.de>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "3.0.0-beta.5", features = ["derive"] }
html-escape = "0.2.9"
miette = { version = "3.2.0", features = ["fancy"] }
syntect = "4.6.0"

View File

@ -3,7 +3,8 @@ use std::{
path::PathBuf,
};
use clap::Parser;
use clap::{crate_authors, crate_version, Parser};
use miette::{bail, IntoDiagnostic, WrapErr};
use syntect::{
easy::HighlightFile,
highlighting::{Color, Style, ThemeSet},
@ -11,65 +12,96 @@ use syntect::{
};
#[derive(Parser)]
#[clap(
version = crate_version!(),
author = crate_authors!(),
)]
struct Opt {
#[clap(about = "The file to highlight")]
file: PathBuf,
#[clap(
long,
short,
default_value = "dracula",
about = "The color scheme to use"
)]
theme: String,
#[clap(subcommand)]
cmd: Cmd,
}
fn main() {
#[derive(Parser)]
enum Cmd {
#[clap(about = "Print available themes and exit")]
ListThemes,
#[clap(about = "Highlight a file", alias = "hl")]
Highlight {
#[clap(about = "The file to highlight")]
file: PathBuf,
#[clap(
long,
short,
default_value = "dracula",
about = "The color scheme to use"
)]
theme: String,
},
}
fn main() -> miette::Result<()> {
let opt = Opt::parse();
let ss = SyntaxSet::load_defaults_newlines();
let mut ts = ThemeSet::load_defaults();
ts.themes.insert(
"dracula".to_string(),
// TODO: do expensive tmTheme parsing in build script
ThemeSet::load_from_reader(&mut Cursor::new(include_bytes!(
"../assets/dracula_theme/Dracula.tmTheme"
)))
.expect("Failed to load static dracula theme"),
.into_diagnostic()
.wrap_err("Failed to load static dracula theme")?,
);
let theme = if let Some(t) = ts.themes.get(&opt.theme) {
t
} else {
eprintln!("No such theme!");
// TODO dont exit successfully
return;
};
match opt.cmd {
Cmd::ListThemes => {
for theme in ts.themes.keys() {
println!("{}", theme);
}
let mut h = HighlightFile::new(opt.file, &ss, theme).unwrap();
Ok(())
},
Cmd::Highlight { file, theme } => {
let ss = SyntaxSet::load_defaults_newlines();
let theme = if let Some(t) = ts.themes.get(&theme) {
t
} else {
bail!("No such theme! Use list-themes to list themes.");
};
print!("<pre>");
for line in h.reader.lines() {
let line = line.unwrap();
let regions = h.highlight_lines.highlight(&line, &ss);
let mut h = HighlightFile::new(file, &ss, theme)
.into_diagnostic()
.wrap_err("Failed to open file")?;
for (
Style {
foreground: Color { r, g, b, .. },
..
},
txt,
) in regions
{
print!(
r##"<font color="#{:02x}{:02x}{:02x}">{}</font>"##,
r,
g,
b,
html_escape::encode_text(txt)
);
}
print!("<pre>");
for line in h.reader.lines() {
let line = line.into_diagnostic().wrap_err("Failed to read file")?;
let regions = h.highlight_lines.highlight(&line, &ss);
println!();
for (
Style {
foreground: Color { r, g, b, .. },
..
},
txt,
) in regions
{
print!(
r##"<font color="#{:02x}{:02x}{:02x}">{}</font>"##,
r,
g,
b,
html_escape::encode_text(txt)
);
}
println!();
}
println!("</pre>");
Ok(())
},
}
println!("</pre>");
}