Want to contribute? Fork me on Codeberg.org!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
1.7 KiB

use std::path::Path;
use askama::Template;
use derive_more::From;
use lazy_static::lazy_static;
use svg_units::{SVGMeasure, SVGUnit};
#[derive(Template)]
#[template(path = "document.xml")]
struct DocumentTemplate<'a> {
dimensions: &'a DocumentDimensions,
keyboard: kle_serial::Keyboard,
}
struct DocumentDimensions {
width: SVGMeasure,
height: SVGMeasure,
margin: SVGMeasure,
}
lazy_static! {
static ref LETTER_LANDSCAPE: DocumentDimensions = DocumentDimensions {
width: SVGMeasure::new(11.0, SVGUnit::Inch),
height: SVGMeasure::new(8.5, SVGUnit::Inch),
margin: SVGMeasure::new(0.25, SVGUnit::Inch),
};
}
mod filters {
use svg_units::{SVGMeasure, SVGUnit};
pub fn kle_font_units(kle_font_units: &usize) -> askama::Result<SVGMeasure> {
Ok(SVGMeasure::new(
(6 + kle_font_units * 2) as f64,
SVGUnit::Pixel,
))
}
}
#[derive(From, Debug)]
pub enum Error {
Io(std::io::Error),
Template(askama::Error),
LayoutParse(serde_json::Error),
}
pub type Result<T> = std::result::Result<T, Error>;
pub fn render_file<P, Q>(input_path: P, output_path: Q) -> Result<()>
where
P: AsRef<Path>,
Q: AsRef<Path>,
{
use std::{
fs::{self, OpenOptions},
io::Write,
};
let mut file = OpenOptions::new()
.write(true)
.truncate(true)
.create(true)
.open(output_path)?;
write!(file, "{}", render(&fs::read_to_string(input_path)?)?)?;
Ok(())
}
pub fn render(input: &str) -> Result<String> {
let document = DocumentTemplate {
dimensions: &LETTER_LANDSCAPE,
keyboard: serde_json::from_str(input)?,
};
Ok(document.render()?)
}