From 76bf715e551236715c43de34193bd00671e65b98 Mon Sep 17 00:00:00 2001 From: p11 Date: Fri, 30 May 2025 01:56:52 +0200 Subject: [PATCH] Characters always try to display charas --- src/chara.rs | 13 ++++------ src/main.rs | 68 +++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/chara.rs b/src/chara.rs index 2fa5da6..9307599 100644 --- a/src/chara.rs +++ b/src/chara.rs @@ -1,10 +1,7 @@ use chara::CharacterDefinition; use maud::{Markup, html}; -pub fn render_character(def: &CharacterDefinition, relative_path: &str) -> Markup { - let relative_path = relative_path.rsplit_once('/'); - let relative_path = relative_path.map_or("", |(l, _r)| l); - +pub fn render_character(name: &str, def: &CharacterDefinition, relative_path: &str) -> Markup { html! { style { (CHARACTER_CSS) } @@ -12,7 +9,7 @@ pub fn render_character(def: &CharacterDefinition, relative_path: &str) -> Marku div.character-container { @for layer in &def.layers { img.character-layer - id=(format!("{}-layer", layer.internal_name)) + id=(format!("{name}-{}-layer", layer.internal_name)) src=(layer.entries.first().map(|e| format!("/{relative_path}/{}", e.path)).unwrap_or_default()) style=(format!("display: {};", if !layer.entries.is_empty() && !layer.entries[0].path.is_empty() { @@ -33,11 +30,11 @@ pub fn render_character(def: &CharacterDefinition, relative_path: &str) -> Marku @for (i, entry) in layer.entries.iter().enumerate() { label.option { input type="radio" - name=(layer.internal_name) - value=(entry.path) + name=(format!("{name}-{}", layer.internal_name)) + value=(format!("/{relative_path}/{}", entry.path)) checked[i==0] onchange=(format!( - "var img=document.getElementById('{}-layer');img.src=this.value;img.style.display=this.value==''?'none':'block';", + "var img=document.getElementById('{name}-{}-layer');img.src=this.value;img.style.display=this.value==''?'none':'block';", layer.internal_name )); (entry.name) diff --git a/src/main.rs b/src/main.rs index 3629f1e..1ef4770 100644 --- a/src/main.rs +++ b/src/main.rs @@ -378,7 +378,6 @@ fn handle_connection( reply_binary(stream, &relative_path, "image", &ending, path) } "mp3" | "wav" => reply_binary(stream, &relative_path, "audio", &ending, path), - "chara" => reply_chara(stream, &relative_path, path), _ => fail(stream), } return; @@ -459,22 +458,6 @@ fn load_character_file(path: &Path) -> Option { .map(|content| CharacterDefinition::parse(&content)) } -fn reply_chara(mut stream: TcpStream, relative_path: &str, mut path: PathBuf) { - path.push(relative_path); - - let Some(def) = load_character_file(&path) else { - fail(stream); - return; - }; - - let _ = write!(stream, "HTTP/1.1 200 OK\r\n"); - let _ = write!(stream, "Content-Type: text/html\r\n"); - let _ = write!(stream, "\r\n"); - - let html = render_character(&def, relative_path); - let _ = stream.write_all(html.into_string().as_bytes()); -} - fn handle_relative_connection( info: Arc, mut stream: TcpStream, @@ -638,12 +621,28 @@ fn handle_relative_connection( } } + fn chara_handler(path: &Path, relative_path: &str) -> impl Fn(&str, &mut W, usize) { + move |entry, output, _level| { + let mut chara_path = path.to_path_buf(); + chara_path.push(relative_path); + chara_path.push(format!("{entry}.chara")); + + let Some(def) = load_character_file(&chara_path) else { + return; + }; + + let html = render_character(entry, &def, relative_path); + let _ = output.write_all(html.into_string().as_bytes()); + } + } + if back { let _ = writeln!(stream, "

{title}

"); } enum TabInfo { Lines(Vec), + Chara(Vec), Game(IndexMap, Box>), Description, Comment(Vec), @@ -677,6 +676,7 @@ fn handle_relative_connection( let mut current_title: Box = "".into(); let mut current_lines = Vec::new(); + let mut chara = false; for line in BufReader::new(pk_file).lines() { let Ok(line) = line else { @@ -686,16 +686,36 @@ fn handle_relative_connection( if !current_title.is_empty() { sections.push(Tab { title: current_title, - info: TabInfo::Lines(current_lines), + info: if chara { + TabInfo::Chara(current_lines) + } else { + TabInfo::Lines(current_lines) + }, }) } + + chara = title == "Characters"; current_title = title.into(); current_lines = vec![line]; continue; } - current_lines.push(line); + if chara && line.starts_with('#') { + let mut count = 0; + for c in line.chars() { + if c == '#' { + count += 1; + continue; + } + + break; + } + current_lines.push(line.clone()); + current_lines.push(format!("+ {}", line[count..].trim())); + } else { + current_lines.push(line); + } } sections.push(Tab { @@ -810,6 +830,16 @@ fn handle_relative_connection( .with_use_textboxes(true), ); } + TabInfo::Chara(lines) => { + convert_extended( + lines, + &mut stream, + Settings::default() + .with_handler(chara_handler(path, relative_path)) + .with_start_level(1) + .with_use_textboxes(true), + ); + } TabInfo::Game(config_map) => { if render_novel( config_map,