Order results from radical search by strokes

This commit is contained in:
Hiers 2024-12-24 23:56:28 +00:00
parent 983e09b0ab
commit 407aae7a0b
2 changed files with 55 additions and 9 deletions

View file

@ -1,15 +1,16 @@
use std::{ use std::{
io::{stdin, stdout, Write}, io::{stdin, stdout, Write},
collections::HashSet, collections::HashSet,
fs
}; };
use kradical_parsing::radk; use kradical_parsing::radk;
pub fn search_by_radical(query: &mut String, radk_list: &[radk::Membership]) -> Option<()> { pub fn search_by_radical(query: &mut String, radk_list: &[radk::Membership], stroke_info: &[String]) -> Option<()> {
let mut result: HashSet<_> = HashSet::new(); let mut result: HashSet<_> = HashSet::new();
let mut aux: HashSet<_> = HashSet::new(); let mut aux: HashSet<_> = HashSet::new();
if !radk_list.is_empty() { if !radk_list.is_empty() && !stroke_info.is_empty() {
result.clear(); result.clear();
/* First iteration: get the baseline for the results */ /* First iteration: get the baseline for the results */
@ -46,14 +47,43 @@ pub fn search_by_radical(query: &mut String, radk_list: &[radk::Membership]) ->
} }
} }
} }
for r in result {
print!("{r} "); /* Hash sets are unordered; Will now order the results */
let mut vec: Vec<Vec<String>> = Vec::with_capacity(30); /* The kanji we care about will have at most 30 strokes */
for _i in 0..29 {
vec.push(Vec::new());
} }
println!();
} else { /*
* A vector of vectors is useful here to store kanji by number of strokes
* First vector's index will indicate the number of strokes (minus 1 because it starts at 0)
* Second vector will hold all of the kanji that is written in that number of strokes
*/
for r in &result {
for (i, s) in stroke_info.iter().enumerate() {
if s.contains(r.as_str()) {
vec[i].push(r.to_string());
break;
}
}
}
for (i, v) in vec.iter().enumerate() {
if !v.is_empty() {
let ii = i + 1;
print!("\x1b[90m{:02} -\x1b[m", ii);
for l in v {
print!(" {l}");
}
println!();
}
}
} else if radk_list.is_empty() {
eprintln!("Error while reading radkfile\nIf you don't have the radkfile, download it from\n\ eprintln!("Error while reading radkfile\nIf you don't have the radkfile, download it from\n\
https://www.edrdg.org/krad/kradinf.html and place it in \"~/.local/share/\" on Linux or \"~\\AppData\\Local\\\" on Windows.\n\ https://www.edrdg.org/krad/kradinf.html and place it in \"~/.local/share/\" on Linux or \"~\\AppData\\Local\\\" on Windows.\n\
This file is needed to search radicals by strokes."); This file is needed to search radicals by strokes.");
} else {
eprintln!("File \"/usr/local/share/ykdt/kanji_strokes\" is missing!");
} }
Some(()) Some(())
} }
@ -117,3 +147,11 @@ fn search_by_strokes(query: &mut String, radk_list: &[radk::Membership], n: usiz
} }
} }
pub fn get_stroke_info() -> Result<Vec<String>, std::io::Error> {
#[allow(deprecated)]
let file = fs::read_to_string("/usr/local/share/ykdt/kanji_strokes")?;
let stroke_info: Vec<String> = Vec::from_iter(file.split('\n').map(|s| s.to_owned()));
Ok(stroke_info)
}

View file

@ -11,6 +11,7 @@ use std::{
use word_search::word_search; use word_search::word_search;
use kanji_search::search_by_radical; use kanji_search::search_by_radical;
use kanji_search::get_stroke_info;
use sentence_search::sentence_search; use sentence_search::sentence_search;
@ -42,6 +43,7 @@ fn main() -> Result<(), ureq::Error> {
let path = get_radkfile_path().unwrap(); let path = get_radkfile_path().unwrap();
let mut radk_list = Vec::new(); let mut radk_list = Vec::new();
let mut stroke_info = Vec::new();
let mut try_load = true; let mut try_load = true;
@ -53,11 +55,12 @@ fn main() -> Result<(), ureq::Error> {
loop { loop {
if options.interactive || options.query.trim().is_empty() { if options.interactive || options.query.trim().is_empty() {
while query.is_empty() || query == ":" || query == "" || query == "_" || query == "_" { while query.is_empty() || query == ":" || query == "" || query == "_" || query == "_" {
query.clear();
print!("=> "); print!("=> ");
stdout().flush().unwrap(); stdout().flush().unwrap();
query.clear();
match stdin().read_line(&mut query) { match stdin().read_line(&mut query) {
Ok(n) => if n == 0 { return Ok(()); /* Exit on EOF */ } Ok(n) => if n == 0 { return Ok(()); } /* Exit on EOF */
Err(e) => eprintln!("Error: {e}") Err(e) => eprintln!("Error: {e}")
} }
query = query.trim().to_string(); query = query.trim().to_string();
@ -76,10 +79,15 @@ fn main() -> Result<(), ureq::Error> {
Err(_e) => radk_list, Err(_e) => radk_list,
} }
}; };
stroke_info = { match get_stroke_info() {
Ok(stroke_info) => stroke_info,
Err(_e) => stroke_info,
}
};
try_load = false; try_load = false;
} }
/* if search_by_radical failed, then something is very wrong */ /* if search_by_radical failed, then something is very wrong */
if search_by_radical(&mut query, &radk_list).is_none() { if search_by_radical(&mut query, &radk_list, &stroke_info).is_none() {
eprintln!("Couldn't parse input"); eprintln!("Couldn't parse input");
} }