From c5de9b9663c6b80662e4bf74046865e400d58587 Mon Sep 17 00:00:00 2001 From: mii443 Date: Mon, 23 Sep 2024 16:31:57 +0900 Subject: [PATCH] support reconversion by TSF --- src-tauri/src/converter/mod.rs | 8 +-- src-tauri/src/handler.rs | 32 ++++++++++++ src-tauri/src/tsf_conversion.rs | 91 +++++++++++++++++++++++++++++++-- 3 files changed, 124 insertions(+), 7 deletions(-) diff --git a/src-tauri/src/converter/mod.rs b/src-tauri/src/converter/mod.rs index 58db1ae..5afedf9 100644 --- a/src-tauri/src/converter/mod.rs +++ b/src-tauri/src/converter/mod.rs @@ -1,6 +1,6 @@ pub mod converter; -mod hiragana; -mod katakana; -mod roman_to_kanji; -mod calculator; +pub mod hiragana; +pub mod katakana; +pub mod roman_to_kanji; +pub mod calculator; mod none_converter; \ No newline at end of file diff --git a/src-tauri/src/handler.rs b/src-tauri/src/handler.rs index 8651fa1..26bb836 100644 --- a/src-tauri/src/handler.rs +++ b/src-tauri/src/handler.rs @@ -33,6 +33,10 @@ impl ConversionHandler { impl ConversionHandler { fn tsf_conversion(&mut self, contents: &str, config: &Config) -> CallbackResult { + if config.skip_url && Regex::new(r"(http://|https://){1}[\w\.\-/:\#\?=\&;%\~\+]+").unwrap().is_match(&contents) { + return CallbackResult::Next; + } + if self.tsf_conversion.is_none() { self.tsf_conversion = Some(TsfConversion::new()); @@ -41,6 +45,34 @@ impl ConversionHandler { let tsf_conversion = self.tsf_conversion.as_mut().unwrap(); + let converted = tsf_conversion.convert(contents).unwrap_or("Failed to convert".to_string()); + + println!("TSF conversion: {} -> {}", contents, converted); + + self.last_text = contents.to_string().clone(); + + let sock = UdpSocket::bind("127.0.0.1:0").unwrap(); + let msg_buf = encoder::encode(&OscPacket::Message(OscMessage { + addr: "/chatbox/input".to_string(), + args: vec![ + OscType::String(converted.clone()), + OscType::Bool(false), + OscType::Bool(true) + ] + })).unwrap(); + + sock.send_to(&msg_buf, "127.0.0.1:9000").unwrap(); + + let datetime = Local::now(); + if self.app_handle + .emit_all("addLog", Log { + time: datetime.format("%Y %m/%d %H:%M:%S").to_string(), + original: contents.to_string().clone(), + converted + }).is_err() { + println!("App handle add log failed."); + } + CallbackResult::Next } } diff --git a/src-tauri/src/tsf_conversion.rs b/src-tauri/src/tsf_conversion.rs index 124e673..a204d39 100644 --- a/src-tauri/src/tsf_conversion.rs +++ b/src-tauri/src/tsf_conversion.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use crate::tsf::{search_candidate_provider::SearchCandidateProvider, set_thread_local_input_settings}; +use crate::{converter::{converter::Converter, hiragana::HiraganaConverter, roman_to_kanji::RomanToKanjiConverter}, tsf::{search_candidate_provider::SearchCandidateProvider, set_thread_local_input_settings}}; pub struct TsfConversion { pub conversion_history: Vec, @@ -7,6 +7,9 @@ pub struct TsfConversion { pub now_reconvertion: bool, pub target_text: String, pub search_candidate_provider: SearchCandidateProvider, + pub reconversion_candidates: Option>, + pub reconversion_index: Option, + pub reconversion_prefix: Option, } impl TsfConversion { @@ -19,10 +22,92 @@ impl TsfConversion { now_reconvertion: false, target_text: String::new(), search_candidate_provider: SearchCandidateProvider::create().unwrap(), + reconversion_candidates: None, + reconversion_index: None, + reconversion_prefix: None, } } - pub fn convert(&self, text: &str) -> Result { - Ok(self.search_candidate_provider.get_candidates(text, 10)?[0].clone()) + pub fn convert(&mut self, text: &str) -> Result { + println!(); + println!("History: {:?}, {:?}", self.conversion_history, self.clipboard_history); + println!("{} == {}", text, self.conversion_history.last().unwrap_or(&("".to_string())).clone()); + let same_as_last_conversion = text.to_string() == self.conversion_history.last().unwrap_or(&("".to_string())).clone(); + + if !same_as_last_conversion && self.now_reconvertion { + self.now_reconvertion = false; + self.reconversion_prefix = None; + self.reconversion_index = None; + self.reconversion_candidates = None; + } + + if !self.now_reconvertion && !same_as_last_conversion { + println!("Convert using roman_to_kanji"); + let o_minus_1 = self.conversion_history.get(if self.conversion_history.len() > 0 { self.conversion_history.len() - 1 } else { 0 }).unwrap_or(&("".to_string())).clone(); + let mut first_diff_position = o_minus_1.chars().zip(text.chars()).position(|(a, b)| a != b); + + if o_minus_1 != text && first_diff_position.is_none() { + first_diff_position = Some(o_minus_1.chars().count()); + } + let diff = text.chars().skip(first_diff_position.unwrap_or(0)).collect::(); + + let roman_to_kanji_converter = RomanToKanjiConverter; + let converted = roman_to_kanji_converter.convert(&diff)?; + self.conversion_history.push(o_minus_1.chars().zip(text.chars()).take_while(|(a, b)| a == b).map(|(a, _)| a).collect::() + &converted); + self.clipboard_history.push(text.to_string()); + return Ok(self.conversion_history.last().unwrap().clone()); + } + + if same_as_last_conversion || self.now_reconvertion { + println!("Convert using TSF"); + self.now_reconvertion = true; + let mut diff_hiragana = String::new(); + if self.reconversion_prefix.is_none() { + let o_minus_2 = self.conversion_history.get(if self.conversion_history.len() > 1 { self.conversion_history.len() - 2 } else { 0 }).unwrap_or(&("".to_string())).clone(); + let i_minus_1 = self.clipboard_history.get(if self.clipboard_history.len() > 0 { self.clipboard_history.len() - 1 } else { 0 }).unwrap_or(&("".to_string())).clone(); + println!("o,i: {}, {}", o_minus_2, i_minus_1); + let mut first_diff_position = i_minus_1.chars().zip(o_minus_2.chars()).position(|(a, b)| a != b); + println!("diff_pos: {:?}", first_diff_position); + if o_minus_2 != i_minus_1 && first_diff_position.is_none() { + first_diff_position = Some(o_minus_2.chars().count()); + } + let diff = i_minus_1.chars().skip(first_diff_position.unwrap_or(0)).collect::(); + println!("diff: {}", diff); + diff_hiragana = HiraganaConverter.convert(&diff)?; + let prefix = i_minus_1.chars().zip(o_minus_2.chars()).take_while(|(a, b)| a == b).map(|(a, _)| a).collect::(); + self.reconversion_prefix = Some(prefix.clone()); + } + println!("diff_hiragana: {}", diff_hiragana); + + if self.reconversion_index.is_none() { + self.reconversion_candidates = Some(self.search_candidate_provider.get_candidates(&diff_hiragana, 10)?); + self.reconversion_index = Some(0); + if self.reconversion_prefix.clone().unwrap() + &self.reconversion_candidates.as_ref().unwrap()[self.reconversion_index.unwrap()].clone() == text { + self.reconversion_index = Some(self.reconversion_index.unwrap() + 1); + } + } else if self.reconversion_index.unwrap() + 1 < self.reconversion_candidates.as_ref().unwrap().len() { + self.reconversion_index = Some(self.reconversion_index.unwrap() + 1); + } else { + self.reconversion_index = Some(0); + } + + if self.reconversion_candidates.is_some() { + println!("Candidates: {:?}", self.reconversion_candidates.as_ref().unwrap()); + } + + self.conversion_history.push(self.reconversion_prefix.clone().unwrap() + &self.reconversion_candidates.as_ref().unwrap()[self.reconversion_index.unwrap()].clone()); + self.clipboard_history.push(text.to_string()); + + while self.conversion_history.len() > 3 { + self.conversion_history.remove(0); + } + while self.clipboard_history.len() > 3 { + self.clipboard_history.remove(0); + } + + return Ok(self.conversion_history.last().unwrap().clone()); + } + + Err(anyhow::anyhow!("Failed to convert")) } }