From 90848df5de3cf2e7d99ee8c2a7a07b768f207f7a Mon Sep 17 00:00:00 2001 From: Laurenz Date: Mon, 29 Apr 2019 17:25:23 +0200 Subject: [PATCH] =?UTF-8?q?Create=20command=20line=20interface=20?= =?UTF-8?q?=F0=9F=92=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 4 +++ src/bin/main.rs | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/bin/main.rs diff --git a/Cargo.toml b/Cargo.toml index 0ab4fe2e3..068ea471e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,7 @@ unicode-segmentation = "1.2" unicode-xid = "0.1.0" byteorder = "1" smallvec = "0.6.9" + +[[bin]] +name = "typst" +path = "src/bin/main.rs" diff --git a/src/bin/main.rs b/src/bin/main.rs new file mode 100644 index 000000000..cb404c57b --- /dev/null +++ b/src/bin/main.rs @@ -0,0 +1,72 @@ +use std::env; +use std::fs::File; +use std::error::Error; +use std::process; +use std::io::Read; +use std::path::{Path, PathBuf}; + +use typeset::Compiler; +use typeset::{font::FileSystemFontProvider, font_info}; +use typeset::export::pdf::PdfExporter; + + +fn run() -> Result<(), Box> { + let args: Vec = env::args().collect(); + if args.len() < 2 || args.len() > 3 { + help_and_quit(); + } + + // Open the input file. + let mut file = File::open(&args[1]).map_err(|_| "failed to open source file")?; + + // The output file name. + let output_filename = if args.len() <= 2 { + let source_path = Path::new(&args[1]); + let stem = source_path.file_stem().ok_or_else(|| "missing destation file name")?; + let base = source_path.parent().ok_or_else(|| "missing destation folder")?; + base.join(format!("{}.pdf", stem.to_string_lossy())) + } else { + PathBuf::from(&args[2]) + }; + + // Read the input file. + let mut src = String::new(); + file.read_to_string(&mut src).map_err(|_| "failed to read from source file")?; + + // Create a compiler with a font provider that provides three fonts + // (two sans-serif fonts and a fallback for the emoji). + let mut compiler = Compiler::new(); + compiler.add_font_provider(FileSystemFontProvider::new("fonts", vec![ + ("NotoSans-Regular.ttf", font_info!(["NotoSans", "Noto", SansSerif])), + ("NotoSans-Italic.ttf", font_info!(["NotoSans", "Noto", SansSerif], italic)), + ("NotoSans-Bold.ttf", font_info!(["NotoSans", "Noto", SansSerif], bold)), + ("NotoSans-BoldItalic.ttf", font_info!(["NotoSans", "Noto", SansSerif], italic, bold)), + ("NotoSansMath-Regular.ttf", font_info!(["NotoSansMath", "Noto", SansSerif])), + ("NotoEmoji-Regular.ttf", font_info!(["NotoEmoji", "Noto", SansSerif, Serif, Monospace])), + ])); + + // Compile the source code with the compiler. + let document = compiler.typeset(&src)?; + + + // Export the document into a PDF file. + let exporter = PdfExporter::new(); + let output_file = File::create(&output_filename)?; + exporter.export(&document, output_file)?; + + Ok(()) +} + +fn main() { + if let Err(err) = run() { + eprintln!("error: {}", err); + process::exit(1); + } +} + +/// Print a usage message and quit. +fn help_and_quit() { + let name = env::args().next().unwrap_or("help".to_string()); + println!("usage: {} []", name); + process::exit(0); +}