From bf1a89eafd52e986feb5b80149d149dabd7cafb3 Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Thu, 21 Aug 2025 23:27:51 +0900 Subject: [PATCH 1/3] Fix test case and checking en --- libs/braillify/src/lib.rs | 64 +++++++++++++++++++++---------------- libs/braillify/src/utils.rs | 4 +++ test_cases/rule_33.csv | 6 ++-- test_cases/rule_48.csv | 2 +- test_cases/rule_51.csv | 2 +- test_cases/rule_51_b2.csv | 4 +-- test_cases/rule_52.csv | 8 ++--- 7 files changed, 52 insertions(+), 38 deletions(-) diff --git a/libs/braillify/src/lib.rs b/libs/braillify/src/lib.rs index 63a5358c..9b6285d7 100644 --- a/libs/braillify/src/lib.rs +++ b/libs/braillify/src/lib.rs @@ -81,7 +81,13 @@ impl Encoder { } else { let word_chars = word.chars().collect::>(); let word_len = word_chars.len(); - let is_all_uppercase = word_chars.iter().all(|c| c.is_uppercase()); + + let is_all_uppercase = word_chars + .iter() + .filter(|c| c.is_ascii_alphabetic()) + .collect::>(); + let is_all_uppercase = + !is_all_uppercase.is_empty() && is_all_uppercase.iter().all(|c| c.is_uppercase()); let has_korean_char = word_chars .iter() .any(|c| (0xAC00 <= *c as u32 && *c as u32 <= 0xD7A3)); @@ -127,9 +133,12 @@ impl Encoder { if self.english_indicator && i > 0 && !c.is_ascii_alphabetic() { // 제31항 국어 문장 안에 그리스 문자가 나올 때에는 그 앞에 로마자표 ⠴을 적고 그 뒤에 로마자 종료표 ⠲을 적는다 - if self.is_english && !['"', ')', '('].contains(c) { + if self.is_english { + // 제33항 「통일영어점자 규정」과 「한글 점자」의 점형이 다른 문장 부호(, : ; ―)가 로마자와 한글 사이에 나올 때에는 로마자 종료표를 적지 않고 문장 부호는 「한글 점자」에 따라 적는다. // 제34항 로마자가 따옴표나 괄호 등으로 묶일 때에는 로마자 종료표를 적지 않는다. - result.push(50); + if !['"', ')', '('].contains(c) && ![',', ':', ';', '―'].contains(c) { + result.push(50); + } } self.is_english = false; } @@ -253,9 +262,11 @@ impl Encoder { ) { result.push(code); *skip_count = len; - } else if let Some((code, len)) = rule_en_10_4( - &word_chars[i..].iter().collect::().to_lowercase(), - ) { + } else if !is_all_uppercase + && let Some((code, len)) = rule_en_10_4( + &word_chars[i..].iter().collect::().to_lowercase(), + ) + { result.push(code); *skip_count = len; } else { @@ -298,18 +309,14 @@ impl Encoder { result.push(if c == '\n' { 255 } else { 0 }); } CharType::MathSymbol(c) => { - if i > 0 - && word_chars[..i] - .iter() - .any(|c| (0xAC00 <= *c as u32 && *c as u32 <= 0xD7A3)) - { + if i > 0 && word_chars[..i].iter().any(|c| utils::is_korean_char(*c)) { result.push(0); } result.extend(math_symbol_shortcut::encode_char_math_symbol_shortcut(c)?); if i < word_len - 1 { let mut korean = vec![]; for wc in word_chars[i..].iter() { - if 0xAC00 <= *wc as u32 && *wc as u32 <= 0xD7A3 { + if utils::is_korean_char(*wc) { korean.push(*wc); } else if !korean.is_empty() { break; @@ -339,14 +346,14 @@ impl Encoder { && !(remaining_words .first() .is_some_and(|w| w.chars().all(|c| c.is_ascii_alphabetic()))) - { - // 28항 [붙임] 로마자가 한 글자만 대문자일 때에는 대문자 기호표 ⠠을 그 앞에 적고, 단어 전체가 대문자이거나 두 글자 이상 연속해서 대문자일 때에는 대문자 단어표 - // ⠠⠠을 그 앞에 적는다. 세 개 이상의 연속된 단어가 모두 대문자일 때에는 첫 단어 - // 앞에 대문자 구절표 ⠠⠠⠠을 적고, 마지막 단어 뒤에 대문자 종료표 ⠠⠄을 적는다. - result.push(32); - result.push(4); - self.triple_big_english = false; // Reset after adding terminator - } + { + // 28항 [붙임] 로마자가 한 글자만 대문자일 때에는 대문자 기호표 ⠠을 그 앞에 적고, 단어 전체가 대문자이거나 두 글자 이상 연속해서 대문자일 때에는 대문자 단어표 + // ⠠⠠을 그 앞에 적는다. 세 개 이상의 연속된 단어가 모두 대문자일 때에는 첫 단어 + // 앞에 대문자 구절표 ⠠⠠⠠을 적고, 마지막 단어 뒤에 대문자 종료표 ⠠⠄을 적는다. + result.push(32); + result.push(4); + self.triple_big_english = false; // Reset after adding terminator + } if !remaining_words.is_empty() { if self.english_indicator && !remaining_words[0] @@ -385,11 +392,10 @@ impl Encoder { pub fn encode(text: &str) -> Result, String> { // 한국어가 존재할 경우 english_indicator 가 true 가 됩니다. - let english_indicator = text.split(' ').filter(|word| !word.is_empty()).any(|word| { - word.chars().any(|c| { - (c as u32 >= 0x3131 && c as u32 <= 0x3163) || (0xAC00 <= c as u32 && c as u32 <= 0xD7A3) - }) - }); + let english_indicator = text + .split(' ') + .filter(|word| !word.is_empty()) + .any(|word| word.chars().any(utils::is_korean_char)); let mut encoder = Encoder::new(english_indicator); let mut result = Vec::new(); @@ -424,6 +430,7 @@ mod test { use super::*; #[test] pub fn test_encode() { + assert_eq!(encode_to_unicode("1998a,").unwrap(), "⠴⠠⠠⠺⠓⠕⠐⠂"); assert_eq!(encode_to_unicode("상상이상의 ").unwrap(), "⠇⠶⠇⠶⠕⠇⠶⠺"); assert_eq!(encode_to_unicode("안녕\n반가워").unwrap(), "⠣⠒⠉⠻\n⠘⠒⠫⠏"); assert_eq!(encode_to_unicode("BMI(지수)").unwrap(), "⠴⠠⠠⠃⠍⠊⠦⠄⠨⠕⠠⠍⠠⠴"); @@ -540,7 +547,7 @@ mod test { let mut total = 0; let mut failed = 0; let mut failed_cases = Vec::new(); - let mut file_stats = std::collections::HashMap::new(); + let mut file_stats = std::collections::BTreeMap::new(); let files = dir .map(|entry| entry.unwrap().path()) .filter(|path| path.extension().unwrap_or_default() == "csv") @@ -587,7 +594,10 @@ mod test { for (line_num, result) in reader.into_records().enumerate() { total += 1; file_total += 1; - let error = format!("CSV 레코드를 읽는 중 오류 발생: {:?} at {}", result, line_num); + let error = format!( + "CSV 레코드를 읽는 중 오류 발생: {:?} at {}", + result, line_num + ); let record = result.expect(&error); let input = &record[0]; let expected = record[2].replace(" ", "⠀"); diff --git a/libs/braillify/src/utils.rs b/libs/braillify/src/utils.rs index 84dc4b0d..ac9cc176 100644 --- a/libs/braillify/src/utils.rs +++ b/libs/braillify/src/utils.rs @@ -28,6 +28,10 @@ pub fn has_choseong_o(ch: char) -> bool { false } +pub fn is_korean_char(c: char) -> bool { + (c as u32 >= 0x3131 && c as u32 <= 0x3163) || (0xAC00 <= c as u32 && c as u32 <= 0xD7A3) +} + #[cfg(test)] mod test { use super::*; diff --git a/test_cases/rule_33.csv b/test_cases/rule_33.csv index 47cd4868..3be0b665 100644 --- a/test_cases/rule_33.csv +++ b/test_cases/rule_33.csv @@ -1,7 +1,7 @@ -"우리나라 기차에는 KTX, 새마을호, 무궁화호 등이 있다.","m""oc""<`@o;r--eo@maw`:~rmo.`vo`da #c4adoi4,15184013412530281060950125211050,⠏⠒⠨⠍⠩⠂⠵⠀⠜⠁⠀⠼⠉⠲⠁⠙⠕⠊⠲ \ No newline at end of file diff --git a/test_cases/rule_51.csv b/test_cases/rule_51.csv index 1743aa87..b45df100 100644 --- a/test_cases/rule_51.csv +++ b/test_cases/rule_51.csv @@ -1 +1 @@ -일시: 2006년 2월 28일 13시,"o1,o""1`#bjjf`c*`#bp1`#bho1`#ac,o",21232211628603262611893386031528603192128601903221,⠕⠂⠠⠕⠐⠂⠈⠼⠃⠚⠚⠋⠈⠉⠡⠈⠼⠃⠏⠂⠈⠼⠃⠓⠕⠂⠈⠼⠁⠉⠀⠠⠕ +일시: 2006년 2월 28일 13시,"o1,o""1 #bjjf c* #bp1 #bho1 #ac,o",2123221162060326261109330603152060319212060193221,⠕⠂⠠⠕⠐⠂⠀⠼⠃⠚⠚⠋⠀⠉⠡⠀⠼⠃⠏⠂⠀⠼⠃⠓⠕⠂⠀⠼⠁⠉⠠⠕ diff --git a/test_cases/rule_51_b2.csv b/test_cases/rule_51_b2.csv index 1359413e..1a5ca6ad 100644 --- a/test_cases/rule_51_b2.csv +++ b/test_cases/rule_51_b2.csv @@ -1,5 +1,5 @@ -오전 10:20,u.)`#aj"1#bj,37406286012616260326,⠥⠨⠾⠈⠼⠁⠚⠐⠂⠼⠃⠚ +오전 10:20,U.) #AJ"1#BJ,37406206012616260326,⠥⠨⠾⠀⠼⠁⠚⠐⠂⠼⠃⠚ -요한 3:16,+j3`#c"1#af,442618860916260111,⠬⠚⠒⠈⠼⠉⠐⠂⠼⠁⠋ +요한 3:16,+J3 #C"1#AF,442618060916260111,⠬⠚⠒⠀⠼⠉⠐⠂⠼⠁⠋ 청군:백군,;]@g"1^ra@g,485982716224231827,⠰⠻⠈⠛⠐⠂⠘⠗⠁⠈⠛ \ No newline at end of file diff --git a/test_cases/rule_52.csv b/test_cases/rule_52.csv index a55b0d1d..64cd3f82 100644 --- a/test_cases/rule_52.csv +++ b/test_cases/rule_52.csv @@ -1,7 +1,7 @@ -강 나루 건너서 / 밀밭길을 // 구름에 달 가듯이 / 가는 나그네,"$7`c""m`@)cs,s`_/`eo1~8@o1!````_/_/`@m""{5n`i1`$i{'o`_/`$cz`c@{`cn",435489161388629143214856128172122438821246888805612561288131642342981028431042421856128439538984280929,⠫⠶⠈⠉⠐⠍⠈⠈⠾⠉⠎⠠⠎⠈⠸⠌⠈⠑⠕⠂⠘⠦⠈⠕⠂⠮⠈⠈⠈⠈⠀⠸⠌⠸⠌⠈⠈⠍⠐⠪⠢⠝⠈⠊⠂⠈⠫⠊⠪⠄⠕⠈⠸⠌⠈⠫⠉⠵⠈⠉⠈⠪⠈⠀⠉⠝ +강 나루 건너서 / 밀밭길을 // 구름에 달 가듯이 / 가는 나그네,"$7`c""m`@)cs,s`_/`eo1~8@o1! _/_/`@m""{5n`i1`$i{'o`_/`$cz`c@{cn",435409161308629143214056120172122438821246056125612081316423429010204310424210561204395309842929,⠫⠶⠀⠉⠐⠍⠀⠈⠾⠉⠎⠠⠎⠀⠸⠌⠀⠑⠕⠂⠘⠦⠈⠕⠂⠮⠀⠸⠌⠸⠌⠀⠈⠍⠐⠪⠢⠝⠀⠊⠂⠀⠫⠊⠪⠄⠕⠀⠸⠌⠀⠫⠉⠵⠀⠉⠈⠪⠉⠝ -먹이다/먹히다,e?oi_/e?joi,1757211056121757262110,⠑⠹⠕⠊⠸⠌⠑⠹⠚⠕⠊ +먹이다/먹히다,E?OI_/E?JOI,1757211056121757262110,⠑⠹⠕⠊⠸⠌⠑⠹⠚⠕⠊ -착한 사람 / 악한 사람,"; Date: Thu, 21 Aug 2025 23:47:16 +0900 Subject: [PATCH 2/3] Checking en --- libs/braillify/src/lib.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libs/braillify/src/lib.rs b/libs/braillify/src/lib.rs index 9b6285d7..f3cbefcd 100644 --- a/libs/braillify/src/lib.rs +++ b/libs/braillify/src/lib.rs @@ -81,13 +81,8 @@ impl Encoder { } else { let word_chars = word.chars().collect::>(); let word_len = word_chars.len(); - - let is_all_uppercase = word_chars - .iter() - .filter(|c| c.is_ascii_alphabetic()) - .collect::>(); - let is_all_uppercase = - !is_all_uppercase.is_empty() && is_all_uppercase.iter().all(|c| c.is_uppercase()); + // 단어 전체가 대문자인지 확인(타 언어인 경우 반드시 false) + let is_all_uppercase = word_chars.iter().all(|c| c.is_uppercase()); let has_korean_char = word_chars .iter() .any(|c| (0xAC00 <= *c as u32 && *c as u32 <= 0xD7A3)); @@ -114,6 +109,7 @@ impl Encoder { // 어 전체가 대문자이거나 두 글자 이상 연속해서 대문자일 때에는 대문자 단어표 // ⠠을 그 앞에 적는다. 세 개 이상의 연속된 단어가 모두 대문자일 때에는 첫 단어 // 앞에 대문자 구절표 ⠠⠠⠠을 적고, 마지막 단어 뒤에 대문자 종료표 ⠠⠄을 적는다. + println!("가즈아ㅏㅏㅏㅏ"); result.push(32); result.push(32); } @@ -430,7 +426,6 @@ mod test { use super::*; #[test] pub fn test_encode() { - assert_eq!(encode_to_unicode("1998a,").unwrap(), "⠴⠠⠠⠺⠓⠕⠐⠂"); assert_eq!(encode_to_unicode("상상이상의 ").unwrap(), "⠇⠶⠇⠶⠕⠇⠶⠺"); assert_eq!(encode_to_unicode("안녕\n반가워").unwrap(), "⠣⠒⠉⠻\n⠘⠒⠫⠏"); assert_eq!(encode_to_unicode("BMI(지수)").unwrap(), "⠴⠠⠠⠃⠍⠊⠦⠄⠨⠕⠠⠍⠠⠴"); From 28f6aeae55cd9df54414f7dc82eed9fb2303fad2 Mon Sep 17 00:00:00 2001 From: owjs3901 Date: Thu, 21 Aug 2025 23:48:20 +0900 Subject: [PATCH 3/3] Rm print --- libs/braillify/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/braillify/src/lib.rs b/libs/braillify/src/lib.rs index f3cbefcd..0499355e 100644 --- a/libs/braillify/src/lib.rs +++ b/libs/braillify/src/lib.rs @@ -109,7 +109,6 @@ impl Encoder { // 어 전체가 대문자이거나 두 글자 이상 연속해서 대문자일 때에는 대문자 단어표 // ⠠을 그 앞에 적는다. 세 개 이상의 연속된 단어가 모두 대문자일 때에는 첫 단어 // 앞에 대문자 구절표 ⠠⠠⠠을 적고, 마지막 단어 뒤에 대문자 종료표 ⠠⠄을 적는다. - println!("가즈아ㅏㅏㅏㅏ"); result.push(32); result.push(32); }