Skip to content

Commit

Permalink
Started work on localization support
Browse files Browse the repository at this point in the history
  • Loading branch information
TCA166 committed May 14, 2024
1 parent b7f5737 commit 2ca0f72
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ tempfile = "3.2.0"
syn = "1.0"
quote = "1.0"
proc-macro2 = "1.0"
yaml-rust = "0.4"
13 changes: 0 additions & 13 deletions src/jinja_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ static INT_TITLE_TEMPLATE:&str = include_str!("../templates/titleTemplate.html")
pub fn create_env(internal:bool) -> Environment<'static>{
let mut env = Environment::new();
env.add_filter("render_ref", render_ref);
env.add_filter("demangle_generic", demangle_generic);
env.set_auto_escape_callback(|arg0: &str| determine_auto_escape(arg0));
if internal || !Path::new("./templates").exists(){
#[cfg(internal)]
Expand Down Expand Up @@ -84,15 +83,3 @@ fn render_ref(reference: Value, subdir:Option<String>) -> String{
format!("<a href=\"../{}/{}.html\">{}</a>", subdir.unwrap(), reference.get_attr("id").unwrap(), name)
}
}

/// A function that demangles a generic name.
/// It will replace underscores with spaces and capitalize the first letter.
fn demangle_generic(input:Value) -> String{
if input.is_none(){
return "none".to_owned();
}
let mut s = input.as_str().unwrap().replace("_", " ");
let bytes = unsafe { s.as_bytes_mut() };
bytes[0] = bytes[0].to_ascii_uppercase();
s
}
69 changes: 69 additions & 0 deletions src/localizer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::{collections::HashMap, rc::Rc};
use std::fs;
use std::path::Path;
use yaml_rust::YamlLoader;

/// A function that demangles a generic name.
/// It will replace underscores with spaces and capitalize the first letter.
fn demangle_generic(input:&str) -> String{
let mut s = input.replace("_", " ");
let bytes = unsafe { s.as_bytes_mut() };
bytes[0] = bytes[0].to_ascii_uppercase();
s
}

pub struct Localizer{
data: Option<HashMap<String, Rc<String>>>
}

impl Localizer{
pub fn new(localization_src_path:Option<String>) -> Self{
let mut hmap:Option<HashMap<String, Rc<String>>> = None;
if localization_src_path.is_some() {
let path = localization_src_path.unwrap();
// get every file in the directory and subdirectories
let mut data: HashMap<String, Rc<String>> = HashMap::new();
let path = Path::new(&path);
if path.is_dir() {
if let Ok(entries) = fs::read_dir(path) {
for entry in entries {
if let Ok(entry) = entry {
//TODO check if the file has .yml extension
//TODO check if the file has localization data we care about
if let Ok(file_type) = entry.file_type() {
if file_type.is_file() {
// read the file to string
let contents = fs::read_to_string(entry.path()).unwrap();
// parse the yaml
println!("{:?}", contents);
//FIXME are the yml pdx localization files actually yaml?
let loc = YamlLoader::load_from_str(&contents).unwrap();
let loc = loc.get(0).unwrap();
for (key, value) in loc.as_hash().unwrap() {
data.insert(key.as_str().unwrap().to_string(), Rc::new(value.as_str().unwrap().to_string()));
}
}
}
}
}
hmap = Some(data);
}
}
}
println!("{:?}", hmap);
Localizer{
data: hmap
}
}

pub fn localize(&self, key: &str) -> String{
if self.data.is_none(){
return demangle_generic(key)
}
let data = self.data.as_ref().unwrap();
if data.contains_key(key){
return data.get(key).unwrap().as_str().to_string()
}
demangle_generic(key)
}
}
17 changes: 14 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ mod game_object;
mod save_file;
use save_file::SaveFile;

mod localizer;
use localizer::Localizer;

/// A submodule that provides the [GameState] object, which is used as a sort of a dictionary.
/// CK3 save files have a myriad of different objects that reference each other, and in order to allow for centralized storage and easy access, the [GameState] object is used.
mod game_state;
Expand Down Expand Up @@ -43,6 +46,9 @@ fn create_dir_maybe(name: &str) {
/// # Arguments
///
/// 1. `filename` - The name of the save file to parse. If not provided as a command line argument, the program will prompt the user to enter it.
/// 2. `--internal` - A flag that tells the program to use the internal templates instead of the templates in the `templates` folder.
/// 3. `--depth` - A flag that tells the program how deep to render the player's history. Defaults to 3.
/// 4. `--localization` - A flag that tells the program where to find the localization files. If not provided, the program will use a crude localization.
///
/// # Process
///
Expand Down Expand Up @@ -74,6 +80,7 @@ fn main() {
let mut use_internal = false;
#[cfg(not(internal))]
let use_internal = false;
let mut localization_path = None;
let mut depth = 3;
if args.len() < 2{
stdout().write_all(b"Enter the filename: ").unwrap();
Expand All @@ -97,23 +104,27 @@ fn main() {
panic!("Internal templates requested but not compiled in")
}
"--depth" => {
let depth_str = args.get(arg.0 + 1).expect("Depth argument requires a value");
let depth_str = args.get(arg.0 + 3).expect("Depth argument requires a value");
depth = depth_str.parse::<usize>().expect("Depth argument must be a number");
}
_ => {
"--localization" => {
localization_path = Some(args.get(arg.0 + 3).expect("Localization argument requires a value").clone());
}
_ => { //TODO flag arguments aren't skipped later
println!("Unknown argument: {}", arg.1);
}

}
}
}
let localizer = Localizer::new(localization_path);
//initialize the save file
let save = SaveFile::new(filename.as_str()); // now we have an iterator we can work with that returns these large objects
// this is sort of like the first round of filtering where we store the objects we care about
let mut game_state:GameState = GameState::new();
let mut last_name = String::new();
let mut players:Vec<Player> = Vec::new();
//TODO add multiprocessing? mutlithreading?
//MAYBE add multiprocessing? mutlithreading?
for mut i in save.into_iter(){
if i.get_name() != last_name{
print!("{:?}\n", i.get_name());
Expand Down

0 comments on commit 2ca0f72

Please sign in to comment.