/// <summary> /// 計算折行之後的縮排格數。 /// </summary> /// <param name="brLine"></param> /// <returns>縮排格數。</returns> private static int CalcNewLineIndents(BrailleLine brLine) { if (AppGlobals.Config.Braille.AutoIndentNumberedLine) { int count = 0; bool foundOrderedItem = false; // 如果是以數字編號開頭(空白略過),自動計算折行的列要縮排幾格。 foreach (BrailleWord brWord in brLine.Words) { if (BrailleWord.IsBlank(brWord)) { count++; continue; } if (BrailleWord.IsOrderedListItem(brWord)) { count++; foundOrderedItem = true; break; } } if (foundOrderedItem) { return(count); } } return(0); }
/// <summary> /// 在指定的位置左邊附加一個空方,若該位置已經有空方,則不做任何處理。 /// </summary> /// <param name="brLine"></param> /// <param name="index"></param> /// <returns>這次調整一共增加或刪除了幾個 word。</returns> private static int PrefixBlankCell(BrailleLine brLine, int index) { int wordOffset = 0; if (index > 0 && !BrailleWord.IsBlank(brLine[index - 1])) { brLine.Words.Insert(index, BrailleWord.NewBlank()); wordOffset = 1; } return(wordOffset); }
public bool IsEmptyOrWhiteSpace() { foreach (var word in Words) { if (!BrailleWord.IsBlank(word) && !BrailleWord.IsEmpty(word)) { return(false); } } return(true); }
/// <summary> /// 去掉開頭的空白字元。 /// </summary> public void TrimStart() { int i = 0; while (i < m_Words.Count) { if (BrailleWord.IsBlank(m_Words[i]) || BrailleWord.IsEmpty(m_Words[i])) { m_Words.RemoveAt(i); continue; } break; } }
/// <summary> /// 去掉結尾的空白字元。 /// </summary> public void TrimEnd() { int i = m_Words.Count - 1; while (i >= 0) { if (BrailleWord.IsBlank(m_Words[i]) || BrailleWord.IsEmpty(m_Words[i])) { m_Words.RemoveAt(i); i--; continue; } break; } }
/// <summary> /// 在指定的位置右邊附加一個空方,若該位置已經有空方,則不做任何處理。 /// </summary> /// <param name="brLine"></param> /// <param name="index"></param> /// <returns>這次調整一共增加或刪除了幾個 word。</returns> private static int PostfixBlankCell(BrailleLine brLine, int index) { int wordOffset = 0; index++; if (index < brLine.WordCount) // 如果已經到結尾,就不加空方。 { if (!BrailleWord.IsBlank(brLine[index])) { brLine.Words.Insert(index, BrailleWord.NewBlank()); wordOffset = 1; } } return(wordOffset); }
/// <summary> /// 套用問號、驚嘆號的點字規則。 /// 規則:後面要加一空方,若後面跟著下引號('」'),則不加空方。 /// </summary> /// <param name="brLine"></param> /// <param name="index"></param> /// <returns></returns> private static int ApplyQuestionRule(BrailleLine brLine, int index) { index++; if (index >= brLine.WordCount) // 如果已經到結尾或超過,就不加空方。 { return(0); } int wordOffset = 0; BrailleWord brWord = brLine[index]; if (!BrailleWord.IsBlank(brWord)) // 若原本已有空方,就不再多加。 { if (!brWord.Text.Equals("」")) { brLine.Words.Insert(index, BrailleWord.NewBlank()); wordOffset = 1; } } return(wordOffset); }
/// <summary> /// 套用句號規則: /// 1.在同一點字行中,句號之後,須空一方,再點寫下文; /// 如在行末不夠點寫句號時,須將原句最末一字與句號移至次一行連書, /// 然後空方接寫下文;如句號恰在一行之最末一方,下文換行點寫時,次行之首無須空方。 /// 2.句號可與後引號(包括後單或雙引號)、刪節號、後括弧 /// (包括後圓括弧、後方括弧、後大括弧)、後夾註號連書,但不得單獨書於一行之首)。 /// </summary> /// <param name="brLine"></param> /// <param name="index"></param> /// <returns></returns> private static int ApplyPeriodRule(BrailleLine brLine, int index) { index++; if (index >= brLine.WordCount) // 如果已經到結尾或超過,就不加空方。 { return(0); } int wordOffset = 0; BrailleWord brWord = brLine[index]; if (!BrailleWord.IsBlank(brWord)) // 若原本已有空方,就不再多加。 { // 句號可與標點符號連書而無須加空方。 if (!BrailleWord.IsChinesePunctuation(brWord)) { brLine.Words.Insert(index, BrailleWord.NewBlank()); wordOffset = 1; } } return(wordOffset); }
/// <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++; } }