diff options
Diffstat (limited to 'locale/tools')
| -rw-r--r-- | locale/tools/src/main.rs | 84 | 
1 files changed, 83 insertions, 1 deletions
| diff --git a/locale/tools/src/main.rs b/locale/tools/src/main.rs index 017d9d74..de11cd35 100644 --- a/locale/tools/src/main.rs +++ b/locale/tools/src/main.rs @@ -5,7 +5,7 @@ use std::{      collections::BTreeMap,      fs::{read_to_string, File},      io::Write, -    path::PathBuf, +    path::{Path, PathBuf},  };  #[derive(Parser)] @@ -19,11 +19,82 @@ enum Args {          input: PathBuf,          output: PathBuf,      }, +    ExportGodotCsv { +        input_dir: PathBuf, +        output: PathBuf, +    }, +    ExportPo { +        input: PathBuf, +        output: PathBuf, +    },  }  fn main() -> Result<()> {      let args = Args::parse();      match args { +        Args::ExportPo { input, output } => { +            let ini = load_ini(&input)?; + +            File::create(output)?.write_all( +                ini.into_iter() +                    .map(|(key, value)| { +                        format!( +                            "msgid {}\nmsgstr{}\n", +                            serde_json::to_string(&key).unwrap(), +                            serde_json::to_string(&value).unwrap(), +                        ) +                    }) +                    .collect::<String>() +                    .as_bytes(), +            )?; +            Ok(()) +        } +        Args::ExportGodotCsv { input_dir, output } => { +            let translations = input_dir +                .read_dir()? +                .flat_map(|e| { +                    e.map_err(|e| anyhow!("{e}")) +                        .and_then(|e| { +                            if e.file_name().to_string_lossy().ends_with(".ini") { +                                Ok(Some(( +                                    e.path().file_stem().unwrap().to_str().unwrap().to_string(), +                                    load_ini(&e.path())?, +                                ))) +                            } else { +                                Ok(None) +                            } +                        }) +                        .transpose() +                }) +                .try_collect::<BTreeMap<_, _>>()?; + +            let langs = translations.keys().cloned().collect::<Vec<String>>(); +            let mut tr_tr = BTreeMap::<String, BTreeMap<String, String>>::new(); +            for (k, v) in translations { +                for (kk, vv) in v { +                    tr_tr.entry(kk).or_default().insert(k.clone(), vv); +                } +            } + +            File::create(output)?.write_all( +                format!( +                    "id,{}\n{}", +                    langs.join(","), +                    tr_tr +                        .into_iter() +                        .map(|(k, v)| format!( +                            "{k},{}\n", +                            v.values() +                                .map(|s| serde_json::to_string(s).unwrap()) +                                .collect::<Vec<_>>() +                                .join(",") +                        )) +                        .collect::<String>() +                ) +                .as_bytes(), +            )?; +            Ok(()) +        }          Args::ImportOldPo {              reference,              input, @@ -159,3 +230,14 @@ fn main() -> Result<()> {          }      }  } + +fn load_ini(path: &Path) -> Result<BTreeMap<String, String>> { +    Ok(read_to_string(path)? +        .lines() +        .skip(1) +        .map(|l| { +            let (k, v) = l.split_once("=").ok_or(anyhow!("'=' missing"))?; +            Ok::<_, anyhow::Error>((k.to_owned(), v.replace("\\n", "\n"))) +        }) +        .try_collect()?) +} | 
