Move svg-units and dyesub into separate crates

This commit is contained in:
Elnu 2023-08-22 14:56:18 -07:00
parent 18c1e84b79
commit fb10870a3b
14 changed files with 59 additions and 13 deletions

14
dyesub/Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "dyesub"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
svg-units = { path = "../svg-units" }
askama = "0.12.0"
derive_more = "0.99.17"
kle-serial = "0.2.2"
lazy_static = "1.4.0"
serde_json = "1.0.105"

74
dyesub/src/lib.rs Normal file
View file

@ -0,0 +1,74 @@
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()?)
}

View file

@ -0,0 +1,66 @@
<svg version="1.1"
width="{{ dimensions.width }}" height="{{ dimensions.height }}"
xmlns="http://www.w3.org/2000/svg">
<defs>
<style type="text/css"><![CDATA[@import url('https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c:wght@700&display=swap');]]></style>
</defs>
{% let u = SVGMeasure::new(14.0, SVGUnit::Millimeter) %}
{% let padding = SVGMeasure::new(2.5, SVGUnit::Millimeter) %}
{% let dy = "0.125em" %}
{% for key in keyboard.keys %}
{% let x = u * key.x + padding * key.x + dimensions.margin %}
{% let y = u * key.y + padding * key.y + dimensions.margin %}
{% let width = u * key.width %}
{% let height = u * key.height %}
<g x="{{ x }}" y="{{ y }}" transform="translate({{ x.to_user_units() }},{{ y.to_user_units() }})" width="{{ width }}" height="{{ height }}">
<rect width="{{ width }}" height="{{ height }}" fill="none" stroke="#cccccc" stroke-width="1pt" rx="2mm" />
{# top-left #}
{% if let Some(legend) = key.legends[0] %}
<text x="{{ width * 0.25 }}" y="{{ height * 0.25 }}" dominant-baseline="middle" text-anchor="middle" style="font-family: 'M PLUS Rounded 1c'" font-size="{{ legend.size|kle_font_units }}" dy="{{ dy }}">{{ legend.text }}</text>
{% endif %}
{# top-center #}
{% if let Some(legend) = key.legends[1] %}
<text x="{{ width * 0.5 }}" y="{{ height * 0.25 }}" dominant-baseline="middle" text-anchor="middle" style="font-family: 'M PLUS Rounded 1c'" font-size="{{ legend.size|kle_font_units }}" dy="{{ dy }}">{{ legend.text }}</text>
{% endif %}
{# top-right #}
{% if let Some(legend) = key.legends[2] %}
<text x="{{ width * 0.75 }}" y="{{ height * 0.25 }}" dominant-baseline="middle" text-anchor="middle" style="font-family: 'M PLUS Rounded 1c'" font-size="{{ legend.size|kle_font_units }}" dy="{{ dy }}">{{ legend.text }}</text>
{% endif %}
{# middle-left #}
{% if let Some(legend) = key.legends[3] %}
<text x="{{ width * 0.25 }}" y="{{ height * 0.5 }}" dominant-baseline="middle" text-anchor="middle" style="font-family: 'M PLUS Rounded 1c'" font-size="{{ legend.size|kle_font_units }}" dy="{{ dy }}">{{ legend.text }}</text>
{% endif %}
{# middle-center #}
{% if let Some(legend) = key.legends[4] %}
<text x="{{ width * 0.5 }}" y="{{ height * 0.5 }}" dominant-baseline="middle" text-anchor="middle" style="font-family: 'M PLUS Rounded 1c'" font-size="{{ legend.size|kle_font_units }}" dy="{{ dy }}">{{ legend.text }}</text>
{% endif %}
{# middle-right #}
{% if let Some(legend) = key.legends[5] %}
<text x="{{ width * 0.75 }}" y="{{ height * 0.5 }}" dominant-baseline="middle" text-anchor="middle" style="font-family: 'M PLUS Rounded 1c'" font-size="{{ legend.size|kle_font_units }}" dy="{{ dy }}">{{ legend.text }}</text>
{% endif %}
{# bottom-left #}
{% if let Some(legend) = key.legends[6] %}
<text x="{{ width * 0.25 }}" y="{{ height * 0.75 }}" dominant-baseline="middle" text-anchor="middle" style="font-family: 'M PLUS Rounded 1c'" font-size="{{ legend.size|kle_font_units }}" dy="{{ dy }}">{{ legend.text }}</text>
{% endif %}
{# bottom-center #}
{% if let Some(legend) = key.legends[7] %}
<text x="{{ width * 0.55 }}" y="{{ height * 0.75 }}" dominant-baseline="middle" text-anchor="middle" style="font-family: 'M PLUS Rounded 1c'" font-size="{{ legend.size|kle_font_units }}" dy="{{ dy }}">{{ legend.text }}</text>
{% endif %}
{# bottom-right #}
{% if let Some(legend) = key.legends[8] %}
<text x="{{ width * 0.75 }}" y="{{ height * 0.75 }}" dominant-baseline="middle" text-anchor="middle" style="font-family: 'M PLUS Rounded 1c'" font-size="{{ legend.size|kle_font_units }}" dy="{{ dy }}">{{ legend.text }}</text>
{% endif %}
{# TODO 9-11 are side #}
</g>
{% endfor %}
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB