Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 30 additions & 26 deletions libs/braillify/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ impl Encoder {
} else {
let word_chars = word.chars().collect::<Vec<char>>();
let word_len = word_chars.len();
// 단어 전체가 대문자인지 확인(타 언어인 경우 반드시 false)
let is_all_uppercase = word_chars.iter().all(|c| c.is_uppercase());
let has_korean_char = word_chars
.iter()
Expand Down Expand Up @@ -127,9 +128,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;
}
Expand Down Expand Up @@ -253,9 +257,11 @@ impl Encoder {
) {
result.push(code);
*skip_count = len;
} else if let Some((code, len)) = rule_en_10_4(
&word_chars[i..].iter().collect::<String>().to_lowercase(),
) {
} else if !is_all_uppercase
&& let Some((code, len)) = rule_en_10_4(
&word_chars[i..].iter().collect::<String>().to_lowercase(),
)
{
result.push(code);
*skip_count = len;
} else {
Expand Down Expand Up @@ -298,18 +304,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;
Expand Down Expand Up @@ -339,14 +341,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]
Expand Down Expand Up @@ -385,11 +387,10 @@ impl Encoder {

pub fn encode(text: &str) -> Result<Vec<u8>, 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();
Expand Down Expand Up @@ -540,7 +541,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")
Expand Down Expand Up @@ -587,7 +588,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(" ", "⠀");
Expand Down
4 changes: 4 additions & 0 deletions libs/braillify/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down
6 changes: 3 additions & 3 deletions test_cases/rule_33.csv
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"우리나라 기차에는 KTX, 새마을호, 무궁화호 등이 있다.","m""oc""<`@o;<ncz`0,,ktx""`,re<!`ju""`em@m7jvju`i{7o`o/i4",13162191635082148352995305232325304516032231735460263716017138135426392637010425421021121050,⠍⠐⠕⠉⠐⠣⠀⠈⠕⠰⠣⠝⠉⠵⠀⠴⠠⠠⠅⠞⠭⠐⠀⠠⠗⠑⠣⠮⠚⠥⠐⠀⠑⠍⠈⠍⠶⠚⠧⠚⠥⠀⠊⠪⠶⠕⠀⠕⠌⠊⠲
"우리나라 기차에는 KTX, 새마을호, 무궁화호 등이 있다.","M""OC""< @O;<NCZ 0,,KTX"" ,RE<!JU"" EM@M7JVJU I[7O O/I4",1316219163508214835299530523232530451603223173546263716017138135426392637010425421021121050,⠍⠐⠕⠉⠐⠣⠀⠈⠕⠰⠣⠝⠉⠵⠀⠴⠠⠠⠅⠞⠭⠐⠀⠠⠗⠑⠣⠮⠚⠥⠐⠀⠑⠍⠈⠍⠶⠚⠧⠚⠥⠀⠊⠪⠶⠕⠀⠕⠌⠊⠲

WHO: 세계 보건 기구,"0,,who""1`,n@/`~u@)`@o@m",52323258192116203229812024378620821813,⠴⠠⠠⠺⠓⠕⠐⠴⠠⠠⠺⠓⠕⠐⠂⠀⠠⠝⠈⠌⠀⠘⠥⠈⠾⠀⠈⠕⠈⠍
WHO: 세계 보건 기구,"0,,who""1`,n@/`~u@)`@o@m",52323258192116203229812024378620821813,⠴⠠⠠⠺⠓⠕⠐⠂⠀⠠⠝⠈⠌⠀⠘⠥⠈⠾⠀⠈⠕⠈⠍

"오동근, 1998a, 1998b; 이진영, 2001, p. 109","ui=@z"`#aiih0a1`#aiih;b;2`o.q`}"`#bjja"`0p4`#aji",3710638531606011010195212060110101948348602140310591606032626116052155006012610,⠥⠊⠿⠈⠵⠐⠀⠼⠁⠊⠊⠓⠴⠁⠂⠀⠼⠁⠊⠊⠓⠰⠃⠰⠆⠀⠕⠨⠟⠻⠐⠀⠼⠃⠚⠚⠁⠐⠀⠴⠏⠲⠀⠼⠁⠚⠊
"오동근, 1998a, 1998b; 이진영, 2001, p. 109","UI=@Z"" #AIIH0A1 #AIIH;B;2 O.Q]"" #BJJA" 0P4 #AJI",371063853160601101019521206011010194834860214031591606032626116052155006012610,⠥⠊⠿⠈⠵⠐⠀⠼⠁⠊⠊⠓⠴⠁⠂⠀⠼⠁⠊⠊⠓⠰⠃⠰⠆⠀⠕⠨⠟⠻⠐⠀⠼⠃⠚⠚⠁⠐⠀⠴⠏⠲⠀⠼⠁⠚⠊

Hedy Lamarr―미국의 여배우이자 와이파이 기술을 발명한 발명가,"0,h$y`,lam>r--eo@maw`:~rmo.`vo`d<o`@o,&!`~1e}j3`~1e}$",52321943610327113282336361721813158049242313214003921025352108213247460242175926180242175943,⠴⠠⠓⠫⠽⠀⠠⠇⠁⠍⠜⠗⠤⠤⠑⠕⠈⠍⠁⠺⠀⠱⠘⠗⠍⠕⠨⠀⠧⠕⠀⠙⠣⠕⠀⠈⠕⠠⠯⠮⠀⠘⠂⠑⠻⠚⠒⠀⠘⠂⠑⠻⠫
2 changes: 1 addition & 1 deletion test_cases/rule_48.csv
Original file line number Diff line number Diff line change
@@ -1 +1 @@
원주율은 약 3.14 이다.,^<mr,15184013412538281860950125211050,⠏⠒⠨⠍⠩⠂⠵⠈⠜⠁⠈⠼⠉⠲⠁⠙⠕⠊⠲
원주율은 약 3.14이다.,p3.m%1z >a #c4adoi4,15184013412530281060950125211050,⠏⠒⠨⠍⠩⠂⠵⠀⠜⠁⠀⠼⠉⠲⠁⠙⠕⠊⠲
2 changes: 1 addition & 1 deletion test_cases/rule_51.csv
Original file line number Diff line number Diff line change
@@ -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,⠕⠂⠠⠕⠐⠂⠼⠃⠚⠚⠋⠀⠉⠡⠀⠼⠃⠏⠂⠼⠃⠓⠕⠂⠼⠁⠉⠠⠕
4 changes: 2 additions & 2 deletions test_cases/rule_51_b2.csv
Original file line number Diff line number Diff line change
@@ -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,⠰⠻⠈⠛⠐⠂⠘⠗⠁⠈⠛
8 changes: 4 additions & 4 deletions test_cases/rule_52.csv
Original file line number Diff line number Diff line change
@@ -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,⠑⠹⠕⠊⠸⠌⠑⠹⠚⠕⠊

착한 사람 / 악한 사람,";<aj3`l""<5`_/`<aj3`l""<5",48351261887163534856128351261887163534,⠰⠣⠁⠚⠒⠇⠐⠣⠢⠈⠸⠌⠈⠣⠁⠚⠒⠇⠐⠣⠢
착한 사람 / 악한 사람,";<AJ3 L""<5 _/ <AJ3 L""<5",48351261807163534056120351261807163534,⠰⠣⠁⠚⠒⠇⠐⠣⠢⠀⠸⠌⠀⠣⠁⠚⠒⠇⠐⠣⠢

1,000원/개,"#a1jjjp3_/@r,601226262615185612823",⠼⠁⠂⠚⠚⠚⠏⠒⠸⠌⠈⠗
"1,000원/개",#A1JJJP3_/@R,601226262615185612823,⠼⠁⠂⠚⠚⠚⠏⠒⠸⠌⠈⠗
Loading