This commit is contained in:
2026-05-15 20:54:58 +02:00
parent 930a2a7c08
commit 5bd0efe95a
4 changed files with 43 additions and 15 deletions

View File

@@ -1,5 +1,8 @@
use std::{fmt::Write as _, sync::LazyLock};
// #[cfg(target_arch = "wasm32")]
// use wasm_bindgen::prelude::wasm_bindgen;
use regex::Regex;
use serde::Deserialize;
@@ -52,16 +55,31 @@ fn fix_action_icons(input: String) -> String {
.replace(r#"<actions string="Reaction" />"#, "`[reaction]`")
}
fn fix_html(s: String) -> String {
let html_tags_re = Regex::new(r"<[^<>]*>").unwrap();
let s = fix_action_icons(s);
let s = s.replace("<br />", "\n");
let s = html_tags_re.replace_all(&s, "");
s.to_string()
}
fn split_sections(s: &str) -> Vec<String> {
let s = fix_html(s.to_string());
let re_split = Regex::new(r"\r?\n\s*\r?\n").unwrap();
re_split.split(&s).map(String::from).collect()
}
fn parse_ability_section(
markdown: &str,
mut section_start: impl FnMut(&str) -> bool,
mut section_end: impl FnMut(&str) -> bool,
) -> String {
let re_split = Regex::new(r"\n\s*\n").unwrap();
let sections: Vec<&str> = re_split.split(markdown).collect();
let sections = split_sections(markdown);
let relevant_sections = sections
.into_iter()
.iter()
.map(|s| s.trim_start())
.filter(|s| s.starts_with("**"))
.skip_while(|s| !section_start(s))
@@ -82,11 +100,10 @@ fn parse_offensive_abilities(markdown: &str) -> String {
}
fn parse_defensive_abilities(markdown: &str) -> String {
let re_split = Regex::new(r"\n\s*\n").unwrap();
let sections: Vec<&str> = re_split.split(markdown).collect();
let sections = split_sections(markdown);
let relevant_sections = sections
.into_iter()
.iter()
.map(|s| s.trim_start())
.filter(|s| s.starts_with("**"))
.skip_while(|s| !s.starts_with("**HP**"))
@@ -123,6 +140,16 @@ fn plussed(number: i32) -> String {
}
}
// #[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
pub fn find_creature_to_obsidian(name: &str) -> Option<String> {
let mut candidates: Vec<&Creature> = CREATURES.iter().filter(|c| &c.name == &name).collect();
candidates.sort_unstable_by_key(|&creature| creature.legacy_id.is_none());
let &creature = candidates.first()?;
Some(creature_to_obsidian(creature))
}
pub fn creature_to_obsidian(sb: &Creature) -> String {
let traits_str = sb
.traits

View File

@@ -1 +1 @@
pub mod character;
pub mod creature;

View File

@@ -1,6 +1,6 @@
use anyhow::anyhow;
use clap::{Parser, Subcommand};
use nethys_to_obsidian::character::{CREATURES, Creature, creature_to_obsidian};
use nethys_to_obsidian::creature::find_creature_to_obsidian;
/// Convert statblocks from Archives of Nethys into markdownish-blocks compatible with pf2e-stats obsidian plugin.
#[derive(Parser, Debug)]
@@ -19,14 +19,9 @@ fn main() -> anyhow::Result<()> {
let args = Args::parse();
let Command::Creature { name } = args.command;
let mut candidates: Vec<&Creature> = CREATURES.iter().filter(|c| &c.name == &name).collect();
let creature = find_creature_to_obsidian(&name).ok_or(anyhow!("No creature with that name"))?;
candidates.sort_unstable_by_key(|&creature| creature.legacy_id.is_none());
let &creature = candidates
.first()
.ok_or(anyhow!("No creature with that name"))?;
print!("{}", creature_to_obsidian(creature));
print!("{creature}");
Ok(())
}