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

View file

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