/// <summary> /// 載入明眼字文件並轉換成點字。 /// </summary> public void LoadAndConvert() { if (StrHelper.IsEmpty(m_FileName)) { throw new Exception("檔案名稱尚未指定!"); } if (m_Processor == null) { throw new Exception("在呼叫 BrailleDocument.Load 之前,請先指定 BrailleProcessor。"); } Encoding enc = Encoding.Default; if (FileHelper.IsUTF8Encoded(m_FileName)) { enc = Encoding.UTF8; } using (StreamReader sr = new StreamReader(m_FileName, enc, true)) { try { LoadAndConvert(sr); } finally { sr.Close(); } } }
/// <summary> /// 檢查指定的 BrailleWord 物件是否沒有包含任何有意義的資料(空方算有意義的資料)。 /// </summary> /// <param name="brWord"></param> /// <returns></returns> public static bool IsEmpty(BrailleWord brWord) { if (StrHelper.IsEmpty(brWord.Text) && brWord.CellCount < 1) { // 文字為空字串,且沒有任何點字物件,即視為空的 BrailleWord 物件. return(true); } return(false); }
public void IsEmptyTest() { string input = " \t \r\n"; bool expected = true; bool actual = StrHelper.IsEmpty(input); Assert.AreEqual(expected, actual, "global::Huanlin.Text.StrHelper.IsEmpty did not return the expected value."); }
/// <summary> /// 將一個中文字的注音組字字根碼轉換成點字碼串列,並加入指定的 BrailleWord 物件。 /// 注意:若轉換成功,會同時加入注音碼和點字碼。 /// </summary> /// <param name="phcode">一個中文字的注音組字字根碼</param> /// <param name="brWord">欲加入點字的 BrailleWord 物件</param> /// <returns>成功傳回 true,失敗傳回 false。</returns> public BrailleCellList CreatePhoneticCellList(string phcode) { if (StrHelper.IsEmpty(phcode) || phcode.Length < 4) { return(null); // 不是中文字 } // 先取出注音符號各部份。 // TODO: 改成不用空白就能判斷結合韻,否則片語無法使用。 string firstPhCode = phcode.Substring(0, 1); // 第一個注音符號 string secondPhCode = phcode.Substring(1, 1); // 第二個注音符號 string thirdPhCode = phcode.Substring(2, 1); // 第三個注音符號 string joinedPhCode = phcode.Substring(1, 2); // 第二、三結合韻 string tonePhCode = phcode.Substring(3, 1); // 音調 // 取出注音符號各部份的點字碼。 string firstBrCode = _brailleTable.FindPhonetic(firstPhCode); string secondBrCode = _brailleTable.FindPhonetic(secondPhCode); string thirdBrCode = _brailleTable.FindPhonetic(thirdPhCode); string toneBrCode = _brailleTable.FindTone(tonePhCode); if (firstBrCode == null && secondBrCode == null && thirdBrCode == null) { return(null); } BrailleCellList cellList = new BrailleCellList(); // 處理特殊的單音字。 if (StrHelper.IsEmpty(secondPhCode) && StrHelper.IsEmpty(thirdPhCode)) { string monoBrCode = _brailleTable.FindMono(firstPhCode); if (String.IsNullOrEmpty(monoBrCode)) { throw new Exception("無效的注音符號: " + phcode); } cellList.Add(monoBrCode); // 特殊單音字要附加 'ㄦ' string erBrCode = _brailleTable.FindPhonetic("ㄦ"); if (String.IsNullOrEmpty(erBrCode)) { throw new Exception("點字對照表中無此符號: ㄦ"); } cellList.Add(erBrCode); // 再加上聲調 cellList.Add(toneBrCode); return(cellList); } // 處理結合韻。 string joinedBrCode = _brailleTable.FindJoined(joinedPhCode); if (!String.IsNullOrEmpty(joinedBrCode)) // 是結合韻? { cellList.Add(firstBrCode); // 加入第一個注音符號 cellList.Add(joinedBrCode); // 加入結合韻 cellList.Add(toneBrCode); // 加入聲調 return(cellList); } // 不是特殊單音字,也不是結合韻:其他注音符號拼法。例如:"ㄋㄧ ˇ"。 cellList.Add(firstBrCode); // 加入第一個注音符號 cellList.Add(secondBrCode); // 加入第二個注音符號 cellList.Add(thirdBrCode); // 加入第三個注音符號 cellList.Add(toneBrCode); // 加入聲調 return(cellList); }
/// <summary> /// 從堆疊中讀取字元,並轉成點字。只處理中文字和中文標點符號。 /// </summary> /// <param name="charStack">字元堆疊。</param> /// <param name="context">情境物件。</param> /// <returns>傳回轉換後的點字物件串列,若串列為空串列,表示沒有成功轉換的字元。</returns> public override List <BrailleWord> Convert(Stack <char> charStack, ContextTagManager context) { if (charStack.Count < 1) { throw new ArgumentException("傳入空的字元堆疊!"); } bool done = false; char ch; string text; bool isExtracted; // 目前處理的字元是否已從堆疊中移出。 BrailleWord brWord; List <BrailleWord> brWordList = null; int idx = 0; int chineseStartIdx = -1; int chineseEndIdx = -1; while (!done && charStack.Count > 0) { ch = charStack.Peek(); // 只讀取但不從堆疊移走。 isExtracted = false; // 小於跟大於符號是情境標籤,不處理(交由 ControlTagConverter 負責)。 if (ch == '<' || ch == '>') { break; } // 全形英文字母要轉成半形,並且由英文點字元件處理。 if (CharHelper.IsFullShapeLetter(ch)) { charStack.Pop(); ch = CharHelper.FullShapeToAsciiLetter(ch); charStack.Push(ch); break; } // 全形數字要轉成半形,並且由英文點字元件處理。 if (CharHelper.IsFullShapeDigit(ch)) { charStack.Pop(); ch = CharHelper.FullShapeToAsciiDigit(ch); charStack.Push(ch); break; } text = ch.ToString(); // 處理雙字元的標點符號。 if (ch == '…' || ch == '-' || ch == '─' || ch == '╴' || ch == '﹏') { // 讀下一個字元,若是相同符號,則可略過;若不同,則下次迴圈仍需處理。 if (charStack.Count >= 2) { charStack.Pop(); char ch2 = charStack.Pop(); if (ch2 == ch) // 如果是連續兩個刪節號或破折號。 { text = text + text; isExtracted = true; } else { // 不是連續符號,把之前取出的字元放回堆疊。 charStack.Push(ch2); charStack.Push(ch); isExtracted = false; } } } else if (ch == '[') // 處理以半形中括號包住的特殊符號. { if (charStack.Count >= 3) { charStack.Pop(); char ch2 = charStack.Pop(); char ch3 = charStack.Pop(); if (ch3 == ']' && (ch2 == '↗' || ch2 == '↘')) { text = text + ch2.ToString() + ch3.ToString(); isExtracted = true; } else { // 不是中括號包住的特殊符號,把之前取出的字元放回堆疊。 charStack.Push(ch3); charStack.Push(ch2); charStack.Push(ch); isExtracted = false; } } } /* 特殊數字編號【1】已經改成直接定義在 xml 檔案 (2009-6-22). * else if (ch == '【') * { // 特殊數字編號,用於選擇題的答案編號,例如: 【1】,見 ChineseBrailleTable.xml。 * if (charStack.Count >= 3) * { * charStack.Pop(); * char ch2 = charStack.Pop(); * char ch3 = charStack.Pop(); * if (Char.IsDigit(ch2) && ch3 == '】') // 無論是半形或全形數字,Char.IsDigit 都會傳回 true。 * { * isExtracted = true; * if (CharHelper.IsFullShapeDigit(ch2)) * { * ch2 = CharHelper.FullShapeToAsciiDigit(ch2); * } * text = ch.ToString() + ch2.ToString() + ch3.ToString(); * } * else * { * charStack.Push(ch3); * charStack.Push(ch2); * charStack.Push(ch); * isExtracted = false; * } * } * } */ brWord = InternalConvert(text); if (brWord == null) { break; } if (!isExtracted) { charStack.Pop(); } if (!StrHelper.IsEmpty(text)) // 避免將空白字元也列入 Chinese。 { brWord.Language = BrailleLanguage.Chinese; } ApplyBrailleConfig(brWord); // 根據組態檔的設定調整點字轉換結果。 if (brWordList == null) { brWordList = new List <BrailleWord>(); } brWordList.Add(brWord); // 記錄連續中文字元,以修正破音字的注音字根。 if (brWord.Text.IsCJK()) // 如果是中文字元,要記錄連續的中文字元區間 { if (chineseStartIdx < 0) { chineseStartIdx = idx; chineseEndIdx = idx; } else { chineseEndIdx = idx; } } else // 不是中文字,則把之前紀錄的連續中文字取出,並修正其注音字根 { FixPhoneticCodes(brWordList, chineseStartIdx, chineseEndIdx); chineseStartIdx = -1; chineseEndIdx = -1; } idx++; } // 處理這段中文字的最後一段連續中文字。 if (chineseStartIdx >= 0) { FixPhoneticCodes(brWordList, chineseStartIdx, chineseEndIdx); } return(brWordList); }