use std::{borrow::Cow, collections::HashMap, env, error::Error};
use syntastica::renderer::Renderer;
use syntastica_core::style::Style;
use syntastica_parsers_git::{Lang, LanguageSetImpl};
fn main() -> Result<(), Box<dyn Error>> {
let examples: HashMap<String, String> =
toml::from_str(include_str!("./example_programs.toml"))?;
let theme_name = env::args()
.nth(1)
.unwrap_or_else(|| "one::light".to_string());
let theme = syntastica_themes::from_str(&theme_name)
.ok_or_else(|| format!("unknown theme `{theme_name}`"))?;
println!(
"{}",
syntastica::highlight(
&examples["rust"],
Lang::Rust,
&LanguageSetImpl::new(),
&mut TypstRenderer,
theme
)?,
);
Ok(())
}
pub struct TypstRenderer;
impl Renderer for TypstRenderer {
fn head(&mut self) -> Cow<'static, str> {
"#{".into()
}
fn tail(&mut self) -> Cow<'static, str> {
"}".into()
}
fn newline(&mut self) -> Cow<'static, str> {
r"linebreak();".into()
}
fn escape<'a>(&mut self, text: &'a str) -> Cow<'a, str> {
format!("raw({text:?})").into()
}
fn unstyled<'a>(&mut self, text: &'a str) -> Cow<'a, str> {
format!("{text};").into()
}
fn styled<'a>(&mut self, text: &'a str, style: Style) -> Cow<'a, str> {
let (r, g, b) = style.color().into_components();
let mut options = format!("fill:rgb({r},{g},{b}),");
let mut front = String::new();
let mut paren_count = 0;
if let Some(color) = style.bg() {
let (r, g, b) = color.into_components();
front += &format!("highlight(fill:rgb({r},{g},{b}),");
paren_count += 1;
}
if style.underline() {
front += "underline(";
paren_count += 1;
}
if style.strikethrough() {
front += "strike(";
paren_count += 1;
}
if style.italic() {
options += "style:\"italic\",";
}
if style.bold() {
options += "weight:\"bold\",";
}
format!("{front}text({options}{text}){};", ")".repeat(paren_count)).into()
}
}