protected virtual void OnConvertionFailed(ConvertionFailedEventArgs args) { // 將無效字元記錄於內部變數。 m_InvalidChars.Add(args.InvalidChar); if (m_SuppressEvents) { return; } if (m_ConvertionFailedEvent != null) { m_ConvertionFailedEvent(this, args); } }
/// <summary> /// 把一行明眼字串轉換成點字串列。 /// 此時不考慮一行幾方和斷行的問題,只進行單純的轉換。 /// 斷行由其他函式負責處理,因為有些點字規則必須在斷行時才能處理。 /// </summary> /// <param name="lineNumber">字串的行號。此參數只是用來當轉換失敗時,傳給轉換失敗事件處理常式的資訊。</param> /// <param name="line">輸入的明眼字串。</param> /// <param name="isTitle">輸出參數,是否為標題。</param> /// <returns>點字串列。若則傳回 null,表示該列不需要轉成點字。</returns> public BrailleLine ConvertLine(int lineNumber, string line) { if (line == null) { return(null); } BrailleLine brLine = new BrailleLine(); string orgLine = line; // 保存原始的字串。 // 把換行符號之後的字串去掉 int i = line.IndexOfAny(new char[] { '\r', '\n' }); if (i >= 0) { line = line.Substring(0, i); } // 若去掉換行字元之後變成空字串,則傳回只包含一個空方的列。 if (String.IsNullOrEmpty(line)) { brLine.Words.Add(BrailleWord.NewBlank()); return(brLine); } // 預先處理特殊標籤的字元替換。 line = PreprocessTagsForLine(line); if (line == null) { return(null); } // 如果是原書頁碼,先檢查格式是否正確。 try { GetOrgPageNumber(line); } catch (Exception ex) { m_ErrorMsg.Append(String.Format("第 {0} 列 : ", lineNumber)); m_ErrorMsg.Append(ex.Message); m_ErrorMsg.Append("\r\n"); return(null); } line = StrHelper.Reverse(line); Stack <char> charStack = new Stack <char>(line); char ch; List <BrailleWord> brWordList; StringBuilder text = new StringBuilder(); ConvertionFailedEventArgs cvtFailedArgs = new ConvertionFailedEventArgs(); TextConvertedEventArgs textCvtArgs = new TextConvertedEventArgs(); while (charStack.Count > 0) { brWordList = ConvertWord(charStack); if (brWordList != null && brWordList.Count > 0) { // 成功轉換成點字,有 n 個字元會從串流中取出 brLine.Words.AddRange(brWordList); text.Length = 0; foreach (BrailleWord brWord in brWordList) { text.Append(brWord.Text); } textCvtArgs.SetArgValues(lineNumber, text.ToString()); OnTextConverted(textCvtArgs); } else { // 無法判斷和處理的字元應該會留存在串流中,將之取出。 ch = charStack.Pop(); int charIndex = line.Length - charStack.Count; // 引發事件。 cvtFailedArgs.SetArgs(lineNumber, charIndex, orgLine, ch); OnConvertionFailed(cvtFailedArgs); if (cvtFailedArgs.Stop) { break; } } // 如果進入分數情境,就把整個分數處理完。 if (m_ContextTagManager.IsActive(ContextTagNames.Fraction)) { try { brWordList = ConvertFraction(lineNumber, charStack); if (brWordList != null && brWordList.Count > 0) { // 成功轉換成點字,有 n 個字元會從串流中取出 brLine.Words.AddRange(brWordList); } } catch (Exception ex) { m_ErrorMsg.Append(String.Format("第 {0} 列 : ", lineNumber)); m_ErrorMsg.Append(ex.Message); m_ErrorMsg.Append("\r\n"); } } } ChineseBrailleRule.ApplyPunctuationRules(brLine); // 套用中文標點符號規則。 // 不刪除多餘空白,因為原本輸入時可能就希望縮排。 //ChineseBrailleRule.ShrinkSpaces(brLine); // 把連續全形空白刪到只剩一個。 // 將編號的數字修正成上位點。 if (m_EnglishConverter != null) { EnglishBrailleRule.FixNumbers(brLine, m_EnglishConverter.BrailleTable as EnglishBrailleTable); } EnglishBrailleRule.ApplyCapitalRule(brLine); // 套用大寫規則。 EnglishBrailleRule.ApplyDigitRule(brLine); // 套用數字規則。 EnglishBrailleRule.AddSpaces(brLine); // 補加必要的空白。 ChineseBrailleRule.ApplyBracketRule(brLine); // 套用括弧規則。 // 不刪除多於空白,因為原本輸入時可能就希望縮排。 //EnglishBrailleRule.ShrinkSpaces(brLine); // 把連續空白刪到只剩一個。 return(brLine); }