CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Tools/langtool/src/main.rs
Views: 1401
use std::io;12mod section;34mod inifile;5use inifile::IniFile;67use clap::Parser;89#[derive(Parser, Debug)]10struct Args {11#[command(subcommand)]12cmd: Command,13#[arg(short, long)]14dry_run: bool,15}1617#[derive(Parser, Debug)]18enum Command {19CopyMissingLines {20#[arg(short, long)]21dont_comment_missing: bool,22},23CommentUnknownLines {},24RemoveUnknownLines {},25AddNewKey {26section: String,27key: String,28},29AddNewKeyValue {30section: String,31key: String,32value: String,33},34MoveKey {35old: String,36new: String,37key: String,38},39CopyKey {40old: String,41new: String,42key: String,43},44RenameKey {45section: String,46old: String,47new: String,48},49SortSection {50section: String,51},52RemoveKey {53section: String,54key: String,55},56}5758fn copy_missing_lines(59reference_ini: &IniFile,60target_ini: &mut IniFile,61comment_missing: bool,62) -> io::Result<()> {63for reference_section in &reference_ini.sections {64// Insert any missing full sections.65if !target_ini.insert_section_if_missing(reference_section) {66if let Some(target_section) = target_ini.get_section_mut(&reference_section.name) {67for line in &reference_section.lines {68target_section.insert_line_if_missing(line);69}7071//target_section.remove_lines_if_not_in(reference_section);72if comment_missing {73target_section.comment_out_lines_if_not_in(reference_section);74}75}76} else {77// Note: insert_section_if_missing will copy the entire section,78// no need to loop over the lines here.79println!("Inserted missing section: {}", reference_section.name);80}81}82Ok(())83}8485fn deal_with_unknown_lines(86reference_ini: &IniFile,87target_ini: &mut IniFile,88remove: bool,89) -> io::Result<()> {90for reference_section in &reference_ini.sections {91if let Some(target_section) = target_ini.get_section_mut(&reference_section.name) {92if remove {93target_section.remove_lines_if_not_in(reference_section);94} else {95target_section.comment_out_lines_if_not_in(reference_section);96}97}98}99Ok(())100}101102fn move_key(target_ini: &mut IniFile, old: &str, new: &str, key: &str) -> io::Result<()> {103if let Some(old_section) = target_ini.get_section_mut(old) {104if let Some(line) = old_section.remove_line(key) {105if let Some(new_section) = target_ini.get_section_mut(new) {106new_section.insert_line_if_missing(&line);107} else {108println!("No new section {}", new);109}110} else {111println!("No key {} in section {}", key, old);112}113} else {114println!("No old section {}", old);115}116Ok(())117}118119fn copy_key(target_ini: &mut IniFile, old: &str, new: &str, key: &str) -> io::Result<()> {120if let Some(old_section) = target_ini.get_section_mut(old) {121if let Some(line) = old_section.get_line(key) {122if let Some(new_section) = target_ini.get_section_mut(new) {123new_section.insert_line_if_missing(&line);124} else {125println!("No new section {}", new);126}127} else {128println!("No key {} in section {}", key, old);129}130} else {131println!("No old section {}", old);132}133Ok(())134}135136fn remove_key(target_ini: &mut IniFile, section: &str, key: &str) -> io::Result<()> {137if let Some(old_section) = target_ini.get_section_mut(section) {138old_section.remove_line(key);139} else {140println!("No section {}", section);141}142Ok(())143}144145fn add_new_key(target_ini: &mut IniFile, section: &str, key: &str, value: &str) -> io::Result<()> {146if let Some(section) = target_ini.get_section_mut(section) {147section.insert_line_if_missing(&format!("{} = {}", key, value));148} else {149println!("No section {}", section);150}151Ok(())152}153154fn rename_key(target_ini: &mut IniFile, section: &str, old: &str, new: &str) -> io::Result<()> {155if let Some(section) = target_ini.get_section_mut(section) {156section.rename_key(old, new);157} else {158println!("No section {}", section);159}160Ok(())161}162163fn sort_section(target_ini: &mut IniFile, section: &str) -> io::Result<()> {164if let Some(section) = target_ini.get_section_mut(section) {165section.sort();166} else {167println!("No section {}", section);168}169Ok(())170}171172// TODO: Look into using https://github.com/Byron/google-apis-rs/tree/main/gen/translate2 for initial translations.173174fn main() {175let opt = Args::parse();176177// TODO: Grab extra arguments from opt somehow.178let args: Vec<String> = vec![]; //std::env::args().skip(1).collect();179let mut filenames = args;180181let root = "../../assets/lang";182let reference_ini_filename = "en_US.ini";183184let mut reference_ini =185IniFile::parse(&format!("{}/{}", root, reference_ini_filename)).unwrap();186187if filenames.is_empty() {188// Grab them all.189for path in std::fs::read_dir(root).unwrap() {190let path = path.unwrap();191if path.file_name() == reference_ini_filename {192continue;193}194let filename = path.file_name();195let filename = filename.to_string_lossy();196if !filename.ends_with(".ini") {197continue;198}199filenames.push(path.file_name().to_string_lossy().to_string());200}201}202203for filename in filenames {204let reference_ini = &reference_ini;205if filename == "langtool" {206// Get this from cargo run for some reason.207continue;208}209let target_ini_filename = format!("{}/{}", root, filename);210println!("Langtool processing {}", target_ini_filename);211212let mut target_ini = IniFile::parse(&target_ini_filename).unwrap();213214match opt.cmd {215Command::CopyMissingLines {216dont_comment_missing,217} => {218copy_missing_lines(reference_ini, &mut target_ini, !dont_comment_missing).unwrap();219}220Command::CommentUnknownLines {} => {221deal_with_unknown_lines(reference_ini, &mut target_ini, false).unwrap();222}223Command::RemoveUnknownLines {} => {224deal_with_unknown_lines(reference_ini, &mut target_ini, true).unwrap();225}226Command::SortSection { ref section } => sort_section(&mut target_ini, section).unwrap(),227Command::RenameKey {228ref section,229ref old,230ref new,231} => rename_key(&mut target_ini, section, old, new).unwrap(),232Command::AddNewKey {233ref section,234ref key,235} => add_new_key(&mut target_ini, section, key, key).unwrap(),236Command::AddNewKeyValue {237ref section,238ref key,239ref value,240} => add_new_key(&mut target_ini, section, key, value).unwrap(),241Command::MoveKey {242ref old,243ref new,244ref key,245} => {246move_key(&mut target_ini, old, new, key).unwrap();247}248Command::CopyKey {249ref old,250ref new,251ref key,252} => {253copy_key(&mut target_ini, old, new, key).unwrap();254}255Command::RemoveKey {256ref section,257ref key,258} => {259remove_key(&mut target_ini, section, key).unwrap();260}261}262263if !opt.dry_run {264target_ini.write().unwrap();265}266}267268println!("Langtool processing {}", reference_ini_filename);269270// Some commands also apply to the reference ini.271match opt.cmd {272Command::AddNewKey {273ref section,274ref key,275} => {276add_new_key(&mut reference_ini, section, key, key).unwrap();277}278Command::AddNewKeyValue {279ref section,280ref key,281ref value,282} => {283add_new_key(&mut reference_ini, section, key, value).unwrap();284}285Command::SortSection { ref section } => sort_section(&mut reference_ini, section).unwrap(),286Command::RenameKey {287ref section,288ref old,289ref new,290} => {291if old == new {292println!("WARNING: old == new");293}294rename_key(&mut reference_ini, section, old, new).unwrap();295}296Command::MoveKey {297ref old,298ref new,299ref key,300} => {301move_key(&mut reference_ini, old, new, key).unwrap();302}303Command::CopyKey {304ref old,305ref new,306ref key,307} => {308copy_key(&mut reference_ini, old, new, key).unwrap();309}310Command::RemoveKey {311ref section,312ref key,313} => {314remove_key(&mut reference_ini, section, key).unwrap();315}316_ => {}317}318319if !opt.dry_run {320reference_ini.write().unwrap();321}322}323324325