diff options
| author | metamuffin <metamuffin@disroot.org> | 2025-10-07 17:32:43 +0200 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2025-10-07 17:32:43 +0200 |
| commit | 30bfe4dc801fdfd3ab8d7a5e36bba67eee70d33b (patch) | |
| tree | 59c6b9676e555f2264a1e8bd0f2b4f0fa7acd4e7 /server/tools | |
| parent | f01b9bb2375e1dbaede262c6281dc3a3d068cbb1 (diff) | |
| download | hurrycurry-30bfe4dc801fdfd3ab8d7a5e36bba67eee70d33b.tar hurrycurry-30bfe4dc801fdfd3ab8d7a5e36bba67eee70d33b.tar.bz2 hurrycurry-30bfe4dc801fdfd3ab8d7a5e36bba67eee70d33b.tar.zst | |
Split book exporting to own crate; move locale tool to server dir
Diffstat (limited to 'server/tools')
| -rw-r--r-- | server/tools/Cargo.toml | 3 | ||||
| -rw-r--r-- | server/tools/src/book_html.css | 41 | ||||
| -rw-r--r-- | server/tools/src/book_html.rs | 89 | ||||
| -rw-r--r-- | server/tools/src/diagram_dot.rs | 11 | ||||
| -rw-r--r-- | server/tools/src/diagram_svg.rs | 152 | ||||
| -rw-r--r-- | server/tools/src/main.rs | 33 |
6 files changed, 12 insertions, 317 deletions
diff --git a/server/tools/Cargo.toml b/server/tools/Cargo.toml index 1c427c81..ffffa426 100644 --- a/server/tools/Cargo.toml +++ b/server/tools/Cargo.toml @@ -9,9 +9,6 @@ log = "0.4.28" env_logger = "0.11.8" clap = { version = "4.5.47", features = ["derive"] } hurrycurry-protocol = { path = "../protocol" } -hurrycurry-server = { path = ".." } hurrycurry-locale = { path = "../locale" } hurrycurry-data = { path = "../data" } serde_json = "1.0.145" -serde = { version = "1.0.225", features = ["derive"] } -markup = "0.15.0" diff --git a/server/tools/src/book_html.css b/server/tools/src/book_html.css deleted file mode 100644 index 9171aa5e..00000000 --- a/server/tools/src/book_html.css +++ /dev/null @@ -1,41 +0,0 @@ -/* - Hurry Curry! - a game about cooking - Copyright (C) 2025 Hurry Curry! Contributors - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, version 3 of the License only. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -*/ -body { - margin: 0px; - background-color: rgb(74, 74, 74); - scroll-behavior: smooth; -} - -.pagegroup { - margin-left: auto; - margin-right: auto; - display: block; - width: 64em; -} - -.page { - display: inline-block; - background-color: antiquewhite; - box-sizing: border-box; - padding: 2em; - margin: 1em; - aspect-ratio: 0.707; - width: 30em; - height: auto; - overflow-y: auto; -} diff --git a/server/tools/src/book_html.rs b/server/tools/src/book_html.rs deleted file mode 100644 index 08a12e88..00000000 --- a/server/tools/src/book_html.rs +++ /dev/null @@ -1,89 +0,0 @@ -/* - Hurry Curry! - a game about cooking - Copyright (C) 2025 Hurry Curry! Contributors - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, version 3 of the License only. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -*/ - -use crate::diagram_svg::diagram_svg; -use hurrycurry_locale::{ - Locale, - message::{MessageDisplayExt, PLAIN}, -}; -use hurrycurry_protocol::{ - Gamedata, Message, - book::{Book, BookPage, Diagram}, -}; - -pub fn render_html_book(data: &Gamedata, book: &Book, locale: &Locale) -> String { - BookR { book, data, locale }.to_string() -} - -markup::define! { - BookR<'a>(data: &'a Gamedata, book: &'a Book, locale: &'a Locale) { - @markup::doctype() - html { - head { - style { @include_str!("book_html.css").replace(" ", "").replace("\n", "") } - title { "Recipe Book - Hurry Curry!" } - } - body { - @for (index, page) in book.pages.iter().enumerate() { - @PageR { data, locale, page, index } - } - } - } - } - - PageR<'a>(index: usize, data: &'a Gamedata, locale: &'a Locale, page: &'a BookPage) { - section.pagegroup[id=format!("page{index}")] { - @match page { - BookPage::Cover => { - div.page {} - div.page {} - } - BookPage::Recipe { title, description, diagram } => { - div.page { - h1 { @MessageR { data, locale, message: title } } - p { @MessageR { data, locale, message: description } } - } - div.page { - @DiagramR { data, diagram } - } - } - BookPage::Text { .. } => { - div.page {} - div.page {} - } - BookPage::Contents { title, table } => { - div.page { - h1 { @MessageR { data, locale, message: title } } - ol { @for (label, page) in table { - li { a[href=format!("#page{page}")] { @MessageR { data, locale, message: label } } } - }} - } - div.page {} - } - } - } - } - - MessageR<'a>(data: &'a Gamedata, locale: &'a Locale, message: &'a Message) { - @message.display_message(*locale, *data, &PLAIN) - } - - DiagramR<'a>(data: &'a Gamedata, diagram: &'a Diagram) { - @markup::raw(diagram_svg(data, diagram).unwrap()) - } -} diff --git a/server/tools/src/diagram_dot.rs b/server/tools/src/diagram_dot.rs index fb223dbf..1701f4ab 100644 --- a/server/tools/src/diagram_dot.rs +++ b/server/tools/src/diagram_dot.rs @@ -16,7 +16,6 @@ */ -use crate::diagram_svg::node_color; use anyhow::{Result, bail}; use hurrycurry_protocol::{ Gamedata, Message, @@ -91,6 +90,16 @@ pub fn diagram_dot(data: &Gamedata, diagram: &Diagram, use_position: bool) -> Re Ok(out) } +fn node_color(node: &DiagramNode) -> &'static str { + match node.style { + NodeStyle::FinalProduct => "#555", + NodeStyle::IntermediateProduct => "#333", + NodeStyle::ProcessActive => "#47c42b", + NodeStyle::ProcessPassive => "#c4a32b", + NodeStyle::ProcessInstant => "#5452d8", + } +} + fn node_style(attrs: &mut Vec<String>, node: &DiagramNode) { let shape = match node.style { NodeStyle::FinalProduct => "circle", diff --git a/server/tools/src/diagram_svg.rs b/server/tools/src/diagram_svg.rs deleted file mode 100644 index d006ce78..00000000 --- a/server/tools/src/diagram_svg.rs +++ /dev/null @@ -1,152 +0,0 @@ -/* - Hurry Curry! - a game about cooking - Copyright (C) 2025 Hurry Curry! Contributors - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, version 3 of the License only. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -*/ - -use anyhow::Result; -use hurrycurry_protocol::{ - Gamedata, Message, - book::{Diagram, DiagramNode, NodeStyle}, - glam::Vec2, -}; -use std::fmt::Write; - -const SIZE: f32 = 64.; -const HSIZE: f32 = SIZE / 2.; - -pub fn diagram_svg(data: &Gamedata, diagram: &Diagram) -> Result<String> { - let mut out = String::new(); - - let (vb_min, vb_max) = diagram - .nodes - .iter() - .map(|n| (n.position, n.position)) - .reduce(|(xa, xb), (ya, yb)| (xa.min(ya), xb.max(yb))) - .unwrap(); - - writeln!( - out, - r#"<svg xmlns="http://www.w3.org/2000/svg" viewBox="{} {} {} {}" width="{}" height="{}">"#, - vb_min.x - HSIZE, - vb_min.y - HSIZE, - vb_max.x + HSIZE, - vb_max.y + HSIZE, - vb_max.x - vb_min.x + SIZE, - vb_max.y - vb_min.y + SIZE, - )?; - - for node in &diagram.nodes { - match node.label { - Message::Translation { .. } => {} - Message::Text(_) => {} - Message::Item(item_index) => { - image_node( - &mut out, - node, - format!("items/{}.png", data.item_name(item_index)), - )?; - } - Message::Tile(tile_index) => { - image_node( - &mut out, - node, - format!("tiles/{}.png", data.tile_name(tile_index)), - )?; - } - } - } - for edge in &diagram.edges { - let src_node = &diagram.nodes[edge.src]; - let dst_node = &diagram.nodes[edge.dst]; - let src = node_edge_connect_pos(src_node, dst_node); - let mut dst = node_edge_connect_pos(dst_node, src_node); - - let dir = (src - dst).normalize_or_zero(); - let tip0 = dst; - let tip1 = dst + (dir + dir.perp() * 0.5) * 10.; - let tip2 = dst + (dir + dir.perp() * -0.5) * 10.; - dst += dir * 5.; // prevent miter line cap from peeking out - - // line path - writeln!( - out, - r#"<path fill="none" stroke="black" stroke-width="2" d="M{} {} L{} {}" />"#, - src.x, src.y, dst.x, dst.y, - )?; - // tip path - writeln!( - out, - r#"<path fill="black" stroke="none" d="M{} {} L{} {} L{} {} Z" />"#, - tip0.x, tip0.y, tip1.x, tip1.y, tip2.x, tip2.y - )?; - } - - writeln!(out, "</svg>")?; - Ok(out) -} - -fn node_edge_connect_pos(src: &DiagramNode, dst: &DiagramNode) -> Vec2 { - let dir = (dst.position - src.position).normalize_or_zero(); - if matches!( - src.style, - NodeStyle::FinalProduct | NodeStyle::IntermediateProduct - ) { - src.position + dir * HSIZE // circle - } else { - src.position + dir / dir.y.abs() * HSIZE // square (only +Y and -Y sides) - } -} - -pub(crate) fn node_color(node: &DiagramNode) -> &'static str { - match node.style { - NodeStyle::FinalProduct => "#555", - NodeStyle::IntermediateProduct => "#333", - NodeStyle::ProcessActive => "#47c42b", - NodeStyle::ProcessPassive => "#c4a32b", - NodeStyle::ProcessInstant => "#5452d8", - } -} - -fn image_node(out: &mut String, node: &DiagramNode, path: String) -> Result<()> { - if matches!( - node.style, - NodeStyle::FinalProduct | NodeStyle::IntermediateProduct - ) { - writeln!( - out, - r#"<circle cx="{}" cy="{}" r="{}" stroke="none" fill="{}" />"#, - node.position.x, - node.position.y, - HSIZE, - node_color(node) - )?; - } else { - writeln!( - out, - r#"<rect x="{}" y="{}" width="{SIZE}" height="{SIZE}" stroke="none" fill="{}" />"#, - node.position.x - HSIZE, - node.position.y - HSIZE, - node_color(node) - )?; - } - writeln!( - out, - r#"<image href="{path}" x="{}" y="{}" width="{SIZE}" height="{SIZE}" />"#, - node.position.x - HSIZE, - node.position.y - HSIZE, - )?; - Ok(()) -} diff --git a/server/tools/src/main.rs b/server/tools/src/main.rs index 8d8e4fd0..07c5d45b 100644 --- a/server/tools/src/main.rs +++ b/server/tools/src/main.rs @@ -16,17 +16,13 @@ */ -pub mod book_html; pub mod diagram_dot; -pub mod diagram_svg; pub mod graph; pub mod graph_summary; pub mod map_linter; use crate::{ - book_html::render_html_book, diagram_dot::{diagram_dot, diagram_dot_svg}, - diagram_svg::diagram_svg, graph::graph, graph_summary::graph_summary, map_linter::check_map, @@ -34,10 +30,9 @@ use crate::{ use anyhow::Result; use clap::Parser; use hurrycurry_data::{ - book::{book, diagram_layout::diagram_layout, print_book, recipe_diagram::recipe_diagram}, + book::{diagram_layout::diagram_layout, recipe_diagram::recipe_diagram}, index::DataIndex, }; -use hurrycurry_locale::FALLBACK_LOCALE; #[derive(Parser)] enum Action { @@ -46,12 +41,8 @@ enum Action { GraphSingle { out: String, #[arg(short)] - custom_svg: bool, - #[arg(short)] dot_out: bool, }, - Book, - BookHtml, MapDemands { map: String, }, @@ -73,11 +64,7 @@ fn main() -> Result<()> { match action { Action::Graph => graph()?, Action::GraphSummary => graph_summary()?, - Action::GraphSingle { - out, - custom_svg, - dot_out, - } => { + Action::GraphSingle { out, dot_out } => { let mut index = DataIndex::default(); index.reload()?; let (data, serverdata) = index.generate("5star")?; @@ -85,28 +72,12 @@ fn main() -> Result<()> { let mut diagram = recipe_diagram(&data, &serverdata, &[out])?; let out = if dot_out { diagram_dot(&data, &diagram, false)? - } else if custom_svg { - diagram_layout(&mut diagram)?; - diagram_svg(&data, &diagram)? } else { diagram_layout(&mut diagram)?; diagram_dot_svg(&data, &diagram)? }; println!("{out}"); } - Action::Book => { - let mut index = DataIndex::default(); - index.reload()?; - let (data, serverdata) = index.generate("5star")?; - print_book(&data, &serverdata)? - } - Action::BookHtml => { - let mut index = DataIndex::default(); - index.reload()?; - let (data, serverdata) = index.generate("5star")?; - let book = book(&data, &serverdata)?; - println!("{}", render_html_book(&data, &book, &FALLBACK_LOCALE)); - } Action::MapDemands { map } => { let mut index = DataIndex::default(); index.reload()?; |