generated from ElnuDev/rust-project
Move svg-units and dyesub into separate crates
This commit is contained in:
parent
18c1e84b79
commit
fb10870a3b
14 changed files with 59 additions and 13 deletions
14
dyesub/Cargo.toml
Normal file
14
dyesub/Cargo.toml
Normal 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
74
dyesub/src/lib.rs
Normal 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()?)
|
||||
}
|
66
dyesub/templates/document.xml
Normal file
66
dyesub/templates/document.xml
Normal 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 |
Loading…
Add table
Add a link
Reference in a new issue