added README and gitignore
This commit is contained in:
@@ -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<String> {
|
||||
//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<u16> {
|
||||
let mut diff_indicies: Vec<u16> = Vec::new();
|
||||
let mut cp = copy.chars();
|
||||
|
||||
|
||||
for letter in original.chars() {
|
||||
|
||||
//print!("{}", letter);
|
||||
|
||||
#[allow(unused_assignments)]
|
||||
let mut cp_letter: Option<char> = 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
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
target
|
||||
@@ -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` | ы / Ы |
|
||||
| `'` | ь |
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user