/// <summary> /// 剖析傳入的字串,如果是以指定的標籤開頭,就遞增或遞減 /// 該情境標籤的計數值(根據它是起始還是結束標籤而定)。 /// </summary> /// <param name="s">輸入字串。</param> /// <param name="tagName">指定的標籤。</param> /// <returns></returns> public ContextTag Parse(string s, string tagName) { ContextTag result = null; string beginTag; string endTag; foreach (ContextTag tag in m_Tags) { if (!tag.TagName.Equals(tagName)) { continue; } beginTag = tag.TagName; endTag = beginTag.Insert(1, "/"); if (s.StartsWith(beginTag)) { // 進入此情境 tag.Enter(); result = tag; break; } else if (s.StartsWith(endTag)) // 結束標籤 { // 離開此情境 tag.Leave(); result = tag; break; } } return(result); }
/// <summary> /// 剖析傳入的字串,如果是以情境標籤開頭,就遞增或遞減 /// 該情境標籤的計數值(根據它是起始還是結束標籤而定)。 /// </summary> /// <param name="s">傳入的字串。</param> /// <param name="isBeginTag">傳回的旗號,若為 true,表示找到起始標籤,若為 false,則為結束標籤。</param> /// <returns>若有找到情境標籤,則傳回 ContextTag 物件,並設定 isBeginTag 輸出參數。</returns> public ContextTag Parse(string s, out bool isBeginTag) { ContextTag result = null; string beginTag; string endTag; isBeginTag = false; foreach (ContextTag tag in m_Tags) { beginTag = tag.TagName; endTag = beginTag.Insert(1, "/"); if (s.StartsWith(beginTag)) { // 進入此情境 tag.Enter(); result = tag; isBeginTag = true; break; } else if (s.StartsWith(endTag)) // 結束標籤 { // 離開此情境 tag.Leave(); result = tag; isBeginTag = false; break; } } return(result); }
public ContextTagManager() { m_Tags = new List <ContextTag>(); foreach (string tagName in ContextTag.AllTagNames) { m_Tags.Add(ContextTag.CreateInstance(tagName)); } }
/// <summary> /// 移除所有情境標籤,除了標題標籤。 /// </summary> public void RemoveContextTagsButTitle(BrailleLine brLine) { BrailleWord brWord; for (int i = brLine.WordCount - 1; i >= 0; i--) { brWord = brLine.Words[i]; if (brWord.IsContextTag && !ContextTag.IsTitleTag(brWord.Text)) { brLine.Words.RemoveAt(i); } } }
/// <summary> /// 轉換分數。 /// </summary> /// <param name="lineNumber"></param> /// <param name="chars"></param> /// <returns></returns> private List <BrailleWord> ConvertFraction(int lineNumber, Stack <char> chars) { char[] charAry = chars.ToArray(); string s = new string(charAry); int idxEof = s.IndexOf(ContextTag.GetEndTagName(ContextTagNames.Fraction)); // end of fraction if (idxEof < 0) { throw new Exception("<分數> 標籤有起始但沒有結束標籤!"); } s = s.Substring(0, idxEof); // 從字串頭取到 </分數> 標籤之前。 string intPart; string numerator; string denumerator; ParseFraction(s, out intPart, out numerator, out denumerator); // Note: 整數部份、分子、分母都有可能是英文字母(代數)。 string temp; Stack <char> charStack; List <BrailleWord> brWordList = null; List <BrailleWord> brWordListIntPart = new List <BrailleWord>(); if (!String.IsNullOrEmpty(intPart)) { // 將整數部份轉換成點字串列。 temp = StrHelper.Reverse(intPart); charStack = new Stack <char>(temp); while (charStack.Count > 0) { brWordList = ConvertWord(charStack); if (brWordList == null) { throw new Exception("無法轉換分數的整數部份!"); } else { brWordListIntPart.AddRange(brWordList); } } } // 將分子部份轉換成點字串列。 temp = StrHelper.Reverse(numerator + "/"); charStack = new Stack <char>(temp); List <BrailleWord> brWordListNumerator = new List <BrailleWord>(); while (charStack.Count > 0) { brWordList = ConvertWord(charStack); if (brWordList == null) { throw new Exception("無法轉換分數的分子部份!"); } else { brWordListNumerator.AddRange(brWordList); } } // 分子的數字不要加數符 foreach (BrailleWord brWord in brWordListNumerator) { brWord.NoDigitCell = true; } // 補上分子的點字符號 brWordListNumerator[0].Cells.Insert(0, BrailleCell.GetInstance(new int[] { 1, 4, 5, 6 })); if (brWordListIntPart.Count > 0) { brWordListNumerator[0].Cells.Insert(0, BrailleCell.GetInstance(new int[] { 4, 5, 6 })); } // 將分母部份轉換成點字串列。 temp = StrHelper.Reverse(denumerator); charStack = new Stack <char>(temp); List <BrailleWord> brWordListDenumerator = new List <BrailleWord>(); while (charStack.Count > 0) { brWordList = ConvertWord(charStack); if (brWordList == null) { throw new Exception("無法轉換分數的分母部份!"); } else { brWordListDenumerator.AddRange(brWordList); } } // 分母的數字不要加數符 foreach (BrailleWord brWord in brWordListDenumerator) { brWord.NoDigitCell = true; } // 補上分母後面的點字符號 BrailleWord lastBrWord = brWordListDenumerator[brWordListDenumerator.Count - 1]; if (brWordListIntPart.Count > 0) { lastBrWord.Cells.Add(BrailleCell.GetInstance(new int[] { 4, 5, 6 })); } lastBrWord.Cells.Add(BrailleCell.GetInstance(new int[] { 3, 4, 5, 6 })); // 結合整數部份、分子、分母至同一個串列。 List <BrailleWord> brWordListFraction = new List <BrailleWord>(); brWordListFraction.AddRange(brWordListIntPart); brWordListFraction.AddRange(brWordListNumerator); brWordListFraction.AddRange(brWordListDenumerator); // 完成! 從傳入的字元堆疊中取出已經處理的字元。 while (idxEof > 0) { chars.Pop(); idxEof--; } return(brWordListFraction); }
/// <summary> /// 根據前後鄰近的字元判斷中間是否需要加一個空方。 /// </summary> /// <param name="lastWord">前一個字。</param> /// <param name="currWord">目前的字。</param> /// <returns></returns> private static bool NeedSpace(BrailleWord lastWord, BrailleWord currWord) { if (lastWord == null || currWord == null) { throw new ArgumentException("傳入 NeedSpace() 的參數為 null!"); } if (lastWord.IsEngPhonetic && currWord.IsEngPhonetic) { return(false); } if (String.IsNullOrEmpty(lastWord.Text) || String.IsNullOrEmpty(currWord.Text)) { return(false); } if (ContextTag.StartsWithContextTag(lastWord.Text)) // 如果前一個字是情境標籤,就不加空方 { return(false); } if (ContextTag.StartsWithContextTag(currWord.Text)) // 如果目前的字是情境標籤,就不加空方 { return(false); } char lastChar = lastWord.Text[0]; char currChar = currWord.Text[0]; // 若前一個字元已經是空白,就不用處理。 if (Char.IsWhiteSpace(lastChar)) { return(false); } if (lastChar == '★') // 「點譯者註」的後面不加空方。 { return(false); } if (lastChar == '□' || currChar == '□') // 「滿點」符號的左右均不加空方。 { return(false); } if (CharHelper.IsAscii(currChar) && !CharHelper.IsAscii(lastChar)) { // 目前的字元是 ASCII,但前一個字元不是(視為中文或其他雙位元組字元),需插入 // 一個空白,除了一些例外,如:全型+號前後若接數字,即視為數學式子,+號前後都不空方。 if (Char.IsDigit(currChar)) { switch (lastChar) { case '+': case '-': case '×': // 全型乘號 (VS2005 編輯器無法正確顯示) case '÷': // 全型除號 (VS2005 編輯器無法正確顯示) case '(': case '【': // // 用粗中刮弧把數字包起來時,代表題號,不用加空方. return(false); } } return(true); } if (!CharHelper.IsAscii(currChar) && CharHelper.IsAscii(lastChar)) { // 目前的字元不是 ASCII,但前一個字元是,需插入一個空白, // 除了一些例外,例如:12℃ 的溫度符號前面不加空方。 if (Char.IsDigit(lastChar)) { switch (currChar) { case '∘': // 溫度符號 case '℃': case '+': case '-': case '×': // 全型乘號 (VS2005 編輯器無法正確顯示) case '÷': // 全型除號 (VS2005 編輯器無法正確顯示) case ')': case '】': // 用粗中刮弧把數字包起來時,代表題號,不用加空方. return(false); } } return(true); } return(false); }