From 521cacbaf4460c26000f353e15c9865e4c6be9df Mon Sep 17 00:00:00 2001 From: Lyle Mantooth Date: Sun, 4 Feb 2024 12:09:24 -0500 Subject: [PATCH] Parse out variants from MML. --- src/mfvi.rs | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/src/mfvi.rs b/src/mfvi.rs index 346ac8b..919371b 100644 --- a/src/mfvi.rs +++ b/src/mfvi.rs @@ -1,8 +1,65 @@ +use std::collections::{BTreeMap, HashSet}; + +#[derive(Clone, Copy)] +pub enum SfxMode { + Off, + On, +} + struct Translation<'a> { find: &'a str, replacement: &'a str, } +#[derive(Clone)] +pub struct Variant<'v> { + keep_delim: &'v str, + remove_delims: HashSet<&'v str>, +} + +impl<'v> Variant<'v> { + pub fn ignores(&self) -> &HashSet<&str> { + &self.remove_delims + } +} + +pub struct VariantList<'v> { + all_delims: HashSet<&'v str>, + variants: BTreeMap<&'v str, Variant<'v>>, +} + +impl<'v> VariantList<'v> { + fn new() -> Self { + VariantList { + all_delims: HashSet::new(), + variants: BTreeMap::new(), + } + } + + fn finish(mut self) -> Self { + for (_, v) in self.variants.iter_mut() { + v.remove_delims = self.all_delims.clone(); + v.remove_delims.remove(v.keep_delim); + } + + if self.variants.is_empty() { + self.variants.insert( + "_default_", + Variant { + keep_delim: "", + remove_delims: self.all_delims.clone(), + }, + ); + } + + self + } + + pub fn get(&self, name: &str) -> Option<&Variant> { + self.variants.get(name) + } +} + pub fn replace_chars(input: &str) -> String { let trs: Vec> = input .lines() @@ -26,3 +83,50 @@ pub fn replace_chars(input: &str) -> String { new } + +pub fn get_variants<'a>(input: &'a str, sfx_mode: SfxMode) -> VariantList<'a> { + input + .lines() + .fold(VariantList::new(), |mut state, line| { + if let Some(l) = line.strip_prefix("#SFXV") { + if let Some((first, second)) = l.trim().rsplit_once(' ') { + use SfxMode::*; + match sfx_mode { + Off => state.all_delims.insert(first), + On => state.all_delims.insert(second), + }; + } + } else if let Some(l) = line.strip_prefix("#VARIANT") { + let (first, second) = { + let rest = l.trim(); + if let Some((f, s)) = rest.rsplit_once(' ') { + (f, s) + } else { + (rest, "_default_") + } + }; + + state.all_delims.insert(first); + + if state.variants.len() == 0 && second != "_default_" { + state.variants.insert( + "_default_", + Variant { + keep_delim: first, + remove_delims: HashSet::new(), + }, + ); + } + state.variants.insert( + second, + Variant { + keep_delim: first, + remove_delims: HashSet::new(), + }, + ); + } + + state + }) + .finish() +}