static BrailleCell() { // 建立好 256 個 BraillCell 物件。 // NOTE: 其實只用到前面 64 個,因為只有六點,用到的位元為 0..5,範圍是 // 00..3F。考慮到未來支援八點的點字,故使用 256。 m_AllCells = new BrailleCell[256]; for (int i = 0; i < m_AllCells.Length; i++) { m_AllCells[i] = new BrailleCell((byte)i); } }
public void AddCellsFromPositionNumbers(string positionNumberString) { if (String.IsNullOrEmpty(positionNumberString)) { return; } var numbers = positionNumberString.Split(' '); foreach (string num in numbers) { var cell = BrailleCell.GetInstanceFromPositionNumberString(num); CellList.Add(cell); } }
public override bool Equals(object obj) { if (base.Equals(obj)) { return(true); } BrailleCell brCell = (BrailleCell)obj; if (m_Value != brCell.Value) { return(false); } return(true); }
/// <summary> /// 把指定的點字字串(16進位)轉成 BrailleCell 物件,並加入點字串列中。 /// </summary> /// <param name="brCode">欲加入串列的點字碼 16 進位字串。</param> public void AddCell(string brCode) { if (String.IsNullOrEmpty(brCode)) { return; } for (int i = 0; i < brCode.Length; i += 2) { string s = brCode.Substring(i, 2); byte aByte = StrHelper.HexStrToByte(s); BrailleCell cell = BrailleCell.GetInstance(aByte); m_CellList.Add(cell); } }
/// <summary> /// 將十六進位的點字碼字串轉成對應的點字物件,並加入點字串列。 /// </summary> /// <param name="brCodes">十六進位的點字碼字串。此字串的長度應為 2 的倍數。</param> /// <returns></returns> public void Add(string brCodes) { if (String.IsNullOrEmpty(brCodes)) { return; // 忽略空的點字碼(因為呼叫端可能常常會傳入空的點字碼) } for (int i = 0; i < brCodes.Length; i += 2) { string s = brCodes.Substring(i, 2); byte aByte = StrHelper.HexStrToByte(s); BrailleCell cell = BrailleCell.GetInstance(aByte); m_Cells.Add(cell); } }
/// <summary> /// 把編號的數字修正成上位點。 /// 注意:此函式會把點字串列中的 # 點字物件刪除。 /// </summary> /// <param name="brLine"></param> public static void FixNumbers(BrailleLine brLine, EnglishBrailleTable brTable) { BrailleWord brWord; bool isNumberMode = false; string brCode; int index = 0; while (index < brLine.WordCount) { brWord = brLine[index]; if (brWord.Text == "#") { isNumberMode = true; brLine.Words.RemoveAt(index); continue; } if (Char.IsDigit(brWord.Text[0])) { if (isNumberMode) { // 把編號的數字改成上位點。 brCode = brTable.FindDigit(brWord.Text, true); if (brWord.Cells.Count > 1) // 第 0 個 cell 可能是數字記號。 { brWord.Cells[1] = BrailleCell.GetInstance(brCode); } else { brWord.Cells[0] = BrailleCell.GetInstance(brCode); } } } else { if (isNumberMode && brWord.Text != "." && brWord.Text != "-" && brWord.Text != ",") { isNumberMode = false; } } index++; } }
/// <summary> /// 加入大寫點。 /// </summary> /// <param name="brWord">點字物件</param> /// <param name="count">要加幾個大寫點。</param> private static void AddCapitalCell(BrailleWord brWord, int count) { int capCnt = 0; foreach (BrailleCell brCell in brWord.Cells) { if (brCell.Equals(BrailleCell.GetInstance(BrailleCellCode.Capital))) { capCnt++; } } int neededCapCnt = count - capCnt; while (neededCapCnt > 0) { brWord.Cells.Insert(0, BrailleCell.Capital); neededCapCnt--; } }
/// <summary> /// 在指定的索引處的 BrailleWord 物件中加入數符。 /// 此函式會自動判斷是否有不需加入數符的例外狀況,例如:次方。 /// </summary> /// <param name="brLine"></param> /// <param name="index"></param> private static void AddDigitSymbol(BrailleLine brLine, int index) { BrailleCell digitCell = BrailleCell.GetInstance(BrailleCellCode.Digit); bool needDigitSymbol = true; if (index > 0) // 先檢查前一個字元,是否為不需加數符的特例。 { if (brLine.Words[index - 1].Text.Equals("^")) // 次方。 { needDigitSymbol = false; } } if (needDigitSymbol) { BrailleWord firstDigitWord = brLine.Words[index]; // 如果已經有加上數字記號就不再重複加。 if (!firstDigitWord.Cells[0].Equals(digitCell)) { firstDigitWord.Cells.Insert(0, digitCell); } } }
public BrailleWord(string aWord, byte brCode) : this() { m_Text = aWord; m_CellList.Add(BrailleCell.GetInstance(brCode)); }
/// <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="brLine"></param> public static void ApplyPunctuationRules(BrailleLine brLine) { int wordIdx = 0; BrailleWord brWord; string text; while (wordIdx < brLine.WordCount) { brWord = brLine[wordIdx]; if (brWord.Language != BrailleLanguage.Chinese) { wordIdx++; continue; } text = brWord.Text; if (text.Length == 3) { // 判斷是否為特殊的編號(選擇題的答案編號) if (text[0] == '【' && Char.IsDigit(text[1]) && text[2] == '】') { // 前後需各加一空方。 //wordIdx += EncloseBlankCells(brLine, wordIdx) + 1; continue; } } // 處理緊鄰的"()",在中間加一空方,使其變成"( )"。 if ("(".Equals(text) && ((wordIdx + 1) < brLine.WordCount)) { BrailleWord brWord2 = brLine[wordIdx + 1]; if (")".Equals(brWord2.Text)) { // 兩個緊鄰的點字:"()",要在左括弧前面加一空方,且括弧中間要加一空方, // 否則組成的點字會跟 '○' 的點字一樣。 int offset = EncloseBlankCells(brLine, wordIdx); // 設定 '(' 後面跟著的空方和 ')' 為不可斷行。 brLine[wordIdx + 1].DontBreakLineHere = true; brLine[wordIdx + 2].DontBreakLineHere = true; wordIdx += offset + 1; continue; } if (BrailleWord.IsBlank(brWord2) && ((wordIdx + 2) < brLine.WordCount)) { BrailleWord brWord3 = brLine[wordIdx + 2]; if (")".Equals(brWord3.Text)) { // 原本輸入的文字就已經在 '(' 和 ')' 中間加了空方。 // 設定 '(' 後面跟著的空方和 ')' 為不可斷行。 brLine[wordIdx + 1].DontBreakLineHere = true; brLine[wordIdx + 2].DontBreakLineHere = true; int offset = PrefixBlankCell(brLine, wordIdx); wordIdx += offset + 2; continue; } } // 註:左括弧後面跟著的既不是空白也不是右括弧,視為括弧中有文字, // 規則為:左括弧前方不空方,括弧中間不空方,右括弧後面要空方。 // 由於無論什麼情況,右括弧後面一定要加空方,因此由下面的程式碼處理, // 這裡無須搜尋對應的右括弧並加空方。 } switch (text) { case "。": case "」": // 下引號的規則同句號。 wordIdx += ApplyPeriodRule(brLine, wordIdx); break; case ",": wordIdx += ApplyCommaRule(brLine, wordIdx); break; case ":": wordIdx += ApplyColonRule(brLine, wordIdx); break; case "!": // 驚嘆號、問號的規則相同。 case "?": wordIdx += ApplyQuestionRule(brLine, wordIdx); break; case ")": // 後面要加一空方。 case "∘": // 溫度符號 case "℃": wordIdx += PostfixBlankCell(brLine, wordIdx); break; case "※": // 前後要加一空方。 case "◎": case "○": case "╳": case "←": case "→": case "↑": case "↓": case "∴": case "∵": case "=": case "≠": case "<": case ">": case "≦": case "≧": case "∠": case "⊥": wordIdx += EncloseBlankCells(brLine, wordIdx); break; case "√": // 打勾符號,前後須加空方,後面接逗號時需特殊處理。 if ((wordIdx + 1) < brLine.WordCount) { string text2 = brLine[wordIdx + 1].Text; if (text2.Equals(",") || text2.Equals(",")) { // 打勾符號後面若跟著逗號,則可連書,且該逗號需用第 6 點。 brLine[wordIdx + 1].CellList.Clear(); brLine[wordIdx + 1].CellList.Add(BrailleCell.GetInstance(new int[] { 6 })); wordIdx += PrefixBlankCell(brLine, wordIdx); } else { // 否則打勾符號前後 wordIdx += EncloseBlankCells(brLine, wordIdx); } } else { wordIdx += EncloseBlankCells(brLine, wordIdx); } break; case "▲": // 刪除符號起始 wordIdx += PrefixBlankCell(brLine, wordIdx); break; case "▼": // 刪除符號結束 wordIdx += PostfixBlankCell(brLine, wordIdx); break; default: break; } wordIdx++; } }
public void Insert(int index, BrailleCell cell) { m_Cells.Insert(index, cell); }
public void Add(BrailleCell cell) { m_Cells.Add(cell); }
public BrailleWord(string text, byte brCode) : this(text) { CellList.Add(BrailleCell.GetInstance(brCode)); }