diff --git a/+ b/+ deleted file mode 100644 index 3546263..0000000 --- a/+ +++ /dev/null @@ -1,122 +0,0 @@ -mod keymaps; -mod cml_functions; - -use colored::*; -use std::io::Write; -use rust_translate::translate; -use random_word::gen_len; -use keymaps::get_keymap_rus; -use cml_functions::*; - -// TODO: -// [ ] Line wrapping / character cap -// [x] Working cursor navigation -// [ ] Proper has_max_len (see below) -// [x] Allow full caps translation (_YU / _Yu) -// [x] Allow typing within text -// [ ] Clean up result (whitespaces) -// -// BUG: -// [x] Space -> Arrow left -> backspace -> panic -// [x] 4x space -> backspace -> -> sp -> bs -> panic -// [x] 2x space -> 2x backspace -> panic -// [x] Cursor inserts, doesnt overwrite -// [x] special letter -> left -> space -> cursor pos wrong - -fn main() { - let result = diff_string_copy("hellollo".to_string(), "hello".to_string()); - println!("\n{:?}", result); - - - loop { - let learned_word = learn_new_word(); - if learned_word.is_none() { - break; - }; - } - //println!("Congrats!! You learned a new Word: {}", learned_word); -} - - -#[tokio::main] -async fn learn_new_word() -> Option { - //print!("Welcome! Which word do you want to learn?\n> "); - std::io::stdout().flush().unwrap(); - - //let mut vocab = String::new(); - //io::stdin().read_line(&mut vocab).expect("Failed to read line"); - //vocab = vocab.trim().to_string(); - - let vocab = gen_len(4, random_word::Lang::En).expect("no word found").to_string(); - - let vocab_tr = translate(&vocab, "en", "ru").await.unwrap(); - println!("\n{}: {}", vocab.red(), vocab_tr.green()); - - println!("Please repeat in russian 🇷🇺 (2x ESC to quit)"); - let input_opt = cml_input_line(get_keymap_rus()); - - input_opt.as_ref()?; - - let input = input_opt.unwrap().to_string(); - //println!("] '{}'", input); - - if input == vocab_tr { - println!("Well done!"); - } - else { - println!("sorry, thats wrong!"); - if input.to_lowercase() == vocab_tr.to_lowercase() { - println!("upper/lowecase counts!!"); - }; - } - - Some(vocab.to_string()) -} - -fn diff_string_copy(original: String, copy: String) -> Vec { - let mut diff_indicies: Vec = Vec::new(); - let mut cp = copy.chars(); - - - for letter in original.chars() { - - //print!("{}", letter); - - #[allow(unused_assignments)] - let mut cp_letter: Option = None; - - let mut found = false; - - loop { - cp_letter = cp.next(); - - if let Some(cp_lt_unpacked) = cp_letter { - // print!("{}", letter); - - if cp_lt_unpacked == letter { - print!("{}", letter); - found = true; - break; - } - else { - // different letter - print!("#"); - } - } - else { - // cp iter has run out - diff_indicies.push(1); - println!(""); - return diff_indicies; - } - } - - if !found { - diff_indicies.push(1); - } - - } - println!("\nended"); - diff_indicies -} - diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target diff --git a/README.md b/README.md new file mode 100644 index 0000000..2a9064c --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# Russian Typing Trainer + +An interactive typing program i built to learn the Cyrillic alphabet and terminal modes (two birds, one stone). +You're given a word in Russian and have to type it out using English keys. +Your keystrokes are automatically translated into Russian (Cyrillic) characters. + +## Usage + +- Type using standard English keys. Input is translated to Cyrillic automatically +- To type a double letter (look below), prefix with `_` (example: `_yu -> ю`) +- Press ESC twice to exit + +## Example output +```bash +pour: налить +Please repeat in russian 🇷🇺 (2x ESC to quit) +] налить +Well done! +``` + +## Keymap + +| Input | Cyrillic | +|-------|----------| +| `zh` | ж / Ж | +| `ch` | ч / Ч | +| `yu` | ю / Ю | +| `ye` | е / Е | +| `yo` | ё / Ё | +| `ya` | я / Я | +| `iy` | ы / Ы | +| `sh` | ш / Ш | +| `kh` | х / Х | +| `ts` | ц / Ц | +| `_i` | й / Й | +| `k` | к / К | +| `o` | о / О | +| `m` | м / М | +| `v` | в / В | +| `g` | г / Г | +| `l` | л / Л | +| `d` | д / Д | +| `f` | ф / Ф | +| `i` | и / И | +| `x` | х / Х | +| `z` | з / З | +| `r` | р / Р | +| `t` | т / Т | +| `a` | а / А | +| `p` | п / П | +| `n` | н / Н | +| `s` | с / С | +| `e` | э / Э | +| `u` | у / Y | +| `b` | б / Б | +| `y` | ы / Ы | +| `'` | ь | diff --git a/src/main.rs.backup b/src/main.rs.backup deleted file mode 100644 index 39daf91..0000000 --- a/src/main.rs.backup +++ /dev/null @@ -1,55 +0,0 @@ -use std::io::{self, Read, Write}; -use std::process; - -use raw::IntoRawMode; -use termion::*; - -fn main() { - let stdin = io::stdin().lock(); - let mut stdout = io::stdout().into_raw_mode().unwrap(); - - let mut input_buffer = String::new(); - - let _translation_map = vec![ - ("-f-", "Ф"), - ("-I-", "И") - ]; - - for byte in stdin.bytes() { - match byte.unwrap() { - // Handle special key (like backspace or enter) - 27 => { - // Handle escape sequences for arrow keys, etc. - continue; - } - 10 => { // Enter key - // Process the current input buffer and reset - writeln!(stdout, "\nYou typed: {}", input_buffer).unwrap(); - input_buffer.clear(); - process::exit(0); - } - 127 => { // Backspace key - input_buffer.pop(); - write!(stdout, "\x1b[2K\r{}", input_buffer).unwrap(); - } - c => { - // Append the character to the input buffer - let ch = c as char; - input_buffer.push(ch); - - // Check if the input matches any translation pattern - //for (pattern, replacement) in &translation_map { - // let re = Regex::new(pattern).unwrap(); - // if re.is_match(&input_buffer) { - // input_buffer = re.replace_all(&input_buffer, *replacement).to_string(); - // break; // Once we replace it, exit the loop - // } - //} - - // Clear the screen and redraw input (to simulate live updating) - write!(stdout, "\x1b[2K\r{}", input_buffer).unwrap(); - stdout.flush().unwrap(); - } - } - } -} diff --git a/src/main.rs.typewriter.backup b/src/main.rs.typewriter.backup deleted file mode 100644 index b19410e..0000000 --- a/src/main.rs.typewriter.backup +++ /dev/null @@ -1,33 +0,0 @@ -use std::io::{self, Read, Write}; - -use termion::raw::IntoRawMode; - -fn main() { - let _stdout = io::stdout().into_raw_mode(); - let stdin = io::stdin().lock(); - let mut input = String::new(); - - for byte in stdin.bytes() { - let inp = byte.unwrap(); - let inp_char = inp as char; - - match inp { - 127 => { - if !input.is_empty() { - input.pop(); - print!("\x08 \x08"); - } - }, - b'\r' => { - print!("\r"); - println!(); - }, - _ => { - input.push(inp_char); - print!("{}", inp_char); - } - } - - io::stdout().flush().unwrap(); - } -}