use eframe::egui;
use lala::cli::{
html_view, latex_view, markdown_view, mermaid_view, parse_args_default, StartupMode,
};
use lala::LalaApp;
use std::fs;
use std::process;
fn setup_custom_fonts(ctx: &egui::Context) {
use egui::FontFamily;
use std::sync::Arc;
let mut fonts = egui::FontDefinitions::default();
if let Ok(font_data) =
std::fs::read("/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf")
.or_else(|_| std::fs::read("/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc"))
.or_else(|_| std::fs::read("/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc"))
.or_else(|_| std::fs::read("/System/Library/Fonts/Hiragino Sans GB.ttc"))
.or_else(|_| std::fs::read("/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc"))
{
fonts.font_data.insert(
"NotoSansCJK".to_owned(),
Arc::new(egui::FontData::from_owned(font_data)),
);
fonts
.families
.entry(FontFamily::Proportional)
.or_default()
.insert(0, "NotoSansCJK".to_owned());
fonts
.families
.entry(FontFamily::Monospace)
.or_default()
.insert(0, "NotoSansCJK".to_owned());
}
if !fonts.font_data.contains_key("NotoSansCJK") {
if let Ok(font_data) = std::fs::read("/usr/share/fonts/truetype/fonts-japanese-gothic.ttf")
.or_else(|_| std::fs::read("/usr/share/fonts/opentype/ipafont-gothic/ipag.ttf"))
{
fonts.font_data.insert(
"IPAGothic".to_owned(),
Arc::new(egui::FontData::from_owned(font_data)),
);
fonts
.families
.entry(FontFamily::Proportional)
.or_default()
.insert(0, "IPAGothic".to_owned());
fonts
.families
.entry(FontFamily::Monospace)
.or_default()
.insert(0, "IPAGothic".to_owned());
}
}
ctx.set_fonts(fonts);
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
let mode = parse_args_default();
match mode {
StartupMode::MarkdownPreview { file, no_color } => {
let content = fs::read_to_string(&file).unwrap_or_else(|err| {
eprintln!("Error reading file {file:?}: {err}");
process::exit(1);
});
if no_color {
println!("{content}");
} else {
markdown_view::render_markdown_to_terminal(&content);
}
return Ok(());
}
StartupMode::HtmlPreview { file, no_color } => {
let content = fs::read_to_string(&file).unwrap_or_else(|err| {
eprintln!("Error reading file {file:?}: {err}");
process::exit(1);
});
if no_color {
html_view::render_html_plain(&content);
} else {
html_view::render_html_to_terminal(&content);
}
return Ok(());
}
StartupMode::MermaidPreview { file, no_color } => {
let content = fs::read_to_string(&file).unwrap_or_else(|err| {
eprintln!("Error reading file {file:?}: {err}");
process::exit(1);
});
if no_color {
mermaid_view::render_mermaid_plain(&content);
} else {
mermaid_view::render_mermaid_to_terminal(&content);
}
return Ok(());
}
StartupMode::LatexPreview { file, no_color } => {
let content = fs::read_to_string(&file).unwrap_or_else(|err| {
eprintln!("Error reading file {file:?}: {err}");
process::exit(1);
});
if no_color {
latex_view::render_latex_plain(&content);
} else {
latex_view::render_latex_to_terminal(&content);
}
return Ok(());
}
StartupMode::ViewFile { file, line_numbers } => {
let content = fs::read_to_string(&file).unwrap_or_else(|err| {
eprintln!("Error reading file {file:?}: {err}");
process::exit(1);
});
if line_numbers {
for (i, line) in content.lines().enumerate() {
println!("{:>6} {}", i + 1, line);
}
} else {
print!("{content}");
}
return Ok(());
}
StartupMode::CliCommandExecuted => {
return Ok(());
}
_ => {}
}
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default()
.with_inner_size([1280.0, 720.0])
.with_title("Lala - Modern Text Editor"),
..Default::default()
};
eframe::run_native(
"lala",
options,
Box::new(|cc| {
setup_custom_fonts(&cc.egui_ctx);
Ok(Box::new(LalaApp::new(cc)))
}),
)?;
Ok(())
}