diff --git a/Cargo.lock b/Cargo.lock index a7d0bd6..5efc8e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,6 +206,7 @@ dependencies = [ "actix-web", "itertools", "nom", + "regex", "serde", "serde_json", "test-case", diff --git a/Cargo.toml b/Cargo.toml index 9c20bbc..5251bea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ nom = "7.1.3" actix-web = { version = "4.3.0", default_features = false, features = ["macros"] } itertools = "0.10.5" time = { version = "0.3.17", features = ["serde", "serde-human-readable"] } +regex = { version = "1.7.1", default_features = false, features = ["std"] } [dev-dependencies] test-case = "2.2.2" diff --git a/src/data.rs b/src/data.rs index a568f84..65542b7 100644 --- a/src/data.rs +++ b/src/data.rs @@ -66,6 +66,7 @@ pub struct Set { impl Card { pub fn extended_info(&self) -> Result { let mut s = String::with_capacity(1000); + write!(s, "

Click here for rulings.

", &self.name)?; s.push_str("

Printings:

"); for printing in &self.card_sets { write!(s, "{}: {} ({})", printing.set_name, printing.set_code, printing.set_rarity)?; @@ -129,7 +130,7 @@ impl Display for Card { } )?; self.basic_info(f, "
")?; - write!(f, "

{}

", &self.text)?; + write!(f, "

{}

", &self.text)?; Ok(()) } } diff --git a/src/main.rs b/src/main.rs index f036bf8..17a5b7b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use actix_web::{get, http::header, web, App, Either, HttpResponse, HttpServer}; use data::{Card, CardInfo, Set}; use filter::SearchCard; use itertools::Itertools; +use regex::{Captures, Regex}; use serde::Deserialize; use std::{collections::HashMap, fmt::Write, fs::File, io::BufReader, net::Ipv4Addr, sync::LazyLock, time::Instant}; use time::Date; @@ -26,8 +27,19 @@ static CARDS: LazyLock> = LazyLock::new(|| { }); cards }); -static CARDS_BY_ID: LazyLock> = - LazyLock::new(|| CARDS.iter().map(|c| (c.id, Card { text: c.text.replace('\r', "").replace('\n', "
"), ..c.clone() })).collect()); +static CARDS_BY_ID: LazyLock> = LazyLock::new(|| { + CARDS + .iter() + .map(|c| { + let text = PENDULUM_SEPARATOR + .replacen(&c.text.replace('\r', ""), 1, |caps: &Captures| { + format!("


[ {} ]

", caps.iter().flatten().last().map_or_else(|| "Monster Effect", |g| g.as_str())) + }) + .replace('\n', "
"); + (c.id, Card { text, ..c.clone() }) + }) + .collect() +}); static SEARCH_CARDS: LazyLock> = LazyLock::new(|| CARDS.iter().map(SearchCard::from).collect()); static SETS_BY_NAME: LazyLock> = LazyLock::new(|| { serde_json::from_reader::<_, Vec>(BufReader::new(File::open("sets.json").expect("sets.json not found"))) @@ -36,6 +48,8 @@ static SETS_BY_NAME: LazyLock> = LazyLock::new(|| { .map(|s| (s.set_name.to_lowercase(), s)) .collect() }); +static PENDULUM_SEPARATOR: LazyLock = + LazyLock::new(|| Regex::new("(\\n-+)?\\n\\[\\s?(Monster Effect|Flavor Text)\\s?\\]\\n?").unwrap()); static IMG_HOST: LazyLock = LazyLock::new(|| std::env::var("IMG_HOST").unwrap_or_else(|_| String::new())); @@ -105,7 +119,7 @@ async fn card_info(card_id: web::Path) -> AnyResult { description: card.short_info()?, query: None, body: format!( - r#"

Card Image: {}{card} {}
"#, + r#"
Card Image: {}{card}
{}
"#, card.name, IMG_HOST.as_str(), card.id, diff --git a/static/style.css b/static/style.css index ae8294a..9ff1336 100644 --- a/static/style.css +++ b/static/style.css @@ -35,6 +35,8 @@ code { p { text-align: justify; + margin-block-start: 0.2em; + margin-block-end: 0.2em; } form > * { @@ -61,10 +63,6 @@ a { color: var(--hl); } -hr { - border-color: var(--hl); -} - h2 { margin-block-end: 0; margin-block-start: 0;