public void ConvertTest()
        {
            string msg = "EnglishWordConverter.Convert 測試失敗: ";

            EnglishWordConverter target = new EnglishWordConverter();

            ContextTagManager context = new ContextTagManager();

            // 測試刪節號。
            string             text      = "...";
            Stack <char>       charStack = new Stack <char>(text);
            List <BrailleWord> expected  = new List <BrailleWord>();
            BrailleWord        brWord    = new BrailleWord(text, "040404");

            expected.Add(brWord);
            List <BrailleWord> actual = target.Convert(charStack, context);

            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試左單引號。
            text      = "‘";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "2026");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試左雙引號。
            text      = "“";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "26");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試大寫字母(不用加大寫記號,因為延後到整行調整時才處理)。
            text      = "A";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "01");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試數字
            text      = "6";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "16");    // 下位點。
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();
        }
Beispiel #2
0
        /// <summary>
        /// 從堆疊中讀取字元,並轉成點字。
        /// </summary>
        /// <param name="charStack">字元堆疊。</param>
        /// <returns>傳回轉換後的點字物件串列,若串列為空串列,表示沒有成功轉換的字元。</returns>
        public override List <BrailleWord> Convert(Stack <char> charStack, ContextTagManager context)
        {
            if (charStack.Count < 1)
            {
                throw new ArgumentException("傳入空的字元堆疊!");
            }

            // 注意: 此函式只能一次處理一個字元,不可取多個字元!
            //       因為可能會碰到 "</數學>" 標籤,這些必須在 BrailleProcessor 中事先處理掉。

            char               ch;
            string             text;
            bool               isExtracted;     // 目前處理的字元是否已從堆疊中移出。
            BrailleWord        brWord;
            List <BrailleWord> brWordList = null;

            ch          = charStack.Peek();      // 只讀取但不從堆疊移走。
            isExtracted = false;

            // 小於跟大於符號交由 ContextTagConverter 或 EnglishWordConverter 處理)。
            if (ch == '<' || ch == '>')
            {
                return(null);
            }

            text = ch.ToString();

            brWord = base.ConvertToBrailleWord(text);

            if (brWord != null)
            {
                if (brWordList == null)
                {
                    brWordList = new List <BrailleWord>();
                }

                brWord.IsEngPhonetic = true;                    // 註記此為英文音標,以便後續處理時可以判斷.
                brWordList.Add(brWord);

                if (!isExtracted)
                {
                    charStack.Pop();
                }
            }
            return(brWordList);
        }
        /// <summary>
        /// 從堆疊中讀取字元,並轉成點字。
        /// </summary>
        /// <param name="charStack">字元堆疊。</param>
        /// <returns>傳回轉換後的點字物件串列,若串列為空串列,表示沒有成功轉換的字元。</returns>
        public override List <BrailleWord> Convert(Stack <char> charStack, ContextTagManager context)
        {
            if (charStack.Count < 1)
            {
                throw new ArgumentException("傳入空的字元堆疊!");
            }

            char               ch;
            string             text;
            bool               isExtracted; // 目前處理的字元是否已從堆疊中移出。
            BrailleWord        brWord;
            List <BrailleWord> brWordList = null;

            ch          = charStack.Peek(); // 只讀取但不從堆疊移走。
            isExtracted = false;

            // 小於跟大於符號交由 ContextTagConverter 或 EnglishWordConverter 處理)。
            if (ch == '<' || ch == '>')
            {
                return(null);
            }

            text = ch.ToString();

            brWord = base.ConvertToBrailleWord(text);

            if (brWord != null)
            {
                // 不加數字點位。
                brWord.NoDigitCell = true;

                if (brWordList == null)
                {
                    brWordList = new List <BrailleWord>();
                }
                brWordList.Add(brWord);

                if (!isExtracted)
                {
                    charStack.Pop();
                }
            }
            return(brWordList);
        }
        public override List<BrailleWord> Convert(Stack<char> charStack, ContextTagManager context)
        {
            if (charStack.Count < 1)
                throw new ArgumentException("傳入空的字元堆疊!");

            char ch = charStack.Peek();

            if (ch != '<')
                return null;

            List<BrailleWord> brWordList = null; 

            char[] charBuf = charStack.ToArray();
            string s = new string(charBuf);
            bool isBeginTag;

			// 剖析字串是否為情境標籤,是則"進入"該情境標籤。
            ContextTag ctag = context.Parse(s, out isBeginTag);	

            if (ctag != null)
            {
                string tagName = ctag.TagName;
                if (isBeginTag == false)
                {
                    tagName = ctag.EndTagName;
                }

                // 轉換成控制字
                brWordList = new List<BrailleWord>();
                brWordList.Add(BrailleWord.CreateAsContextTag(tagName));

                // 將此標籤從堆疊中移除。
                for (int i = 0; i < tagName.Length; i++)
                {
                    charStack.Pop();
                }
            }
            return brWordList;
        }
Beispiel #5
0
 public abstract List <BrailleWord> Convert(Stack <char> charStack, ContextTagManager context);
Beispiel #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="charStack"></param>
        /// <param name="context"></param>
        /// <remarks>由於上、中、下的橫線在明眼字都是以相同的符號表示,可是點字卻不同,因此程式要特別處理:
        /// 每當碰到表格左邊的特定符號時,就設定橫線類型的旗號。</remarks>
        /// <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;

            BarType barType = BarType.Middle;                   // 橫線的種類

            while (!done && charStack.Count > 0)
            {
                ch          = charStack.Peek();          // 只讀取但不從堆疊移走。
                isExtracted = false;

                switch (ch)
                {
                case '┌':
                    barType = BarType.Top;
                    break;

                case '└':
                    barType = BarType.Bottom;
                    break;

                case '├':
                case '│':                               // 左直線
                    barType = BarType.Middle;
                    break;

                default:
                    break;
                }

                text = ch.ToString();

                brWord = base.ConvertToBrailleWord(text);

                if (brWord == null)
                {
                    break;
                }

                // 調整橫線的點字
                if ("─".Equals(brWord.Text))
                {
                    string cellCode;

                    if (barType == BarType.Top)
                    {
                        cellCode        = m_Table["‾"];
                        brWord.Cells[0] = BrailleCell.GetInstance(cellCode);
                    }
                    else if (barType == BarType.Bottom)
                    {
                        cellCode        = m_Table["ˍ"];
                        brWord.Cells[0] = BrailleCell.GetInstance(cellCode);
                    }
                }

                if (!isExtracted)
                {
                    charStack.Pop();
                }

                if (brWordList == null)
                {
                    brWordList = new List <BrailleWord>();
                }
                brWordList.Add(brWord);
            }
            return(brWordList);
        }
        public void ConvertTest()
        {
            string msg = "ChineseWordConverter.Convert 測試失敗: ";

            var target = new ChineseWordConverter(
                new ZhuyinReverseConverter(new ZhuyinReverseConversionProvider()));

            ContextTagManager context = new ContextTagManager();

            // 測試結合韻。
            string             text      = "我";
            Stack <char>       charStack = new Stack <char>(text);
            List <BrailleWord> expected  = new List <BrailleWord>();
            BrailleWord        brWord    = new BrailleWord(text, " ㄨㄛˇ", "1208");

            expected.Add(brWord);
            List <BrailleWord> actual = target.Convert(charStack, context);

            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試單音字:要在音調記號前加一個空方。
            text      = "智";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "ㄓ  ˋ", "013110");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試無特殊規則的注音。
            text      = "你";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "ㄋㄧ ˇ", "1D2108");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試標點符號。
            text      = ":";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "   ˉ", "1212");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試全形空白
            text      = " ";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "   ˉ", "00");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試簡體字。
            text      = "实";
            charStack = new Stack <char>(text);
            brWord    = new BrailleWord(text, "ㄕ  ˊ", "0A3102");
            expected.Clear();
            expected.Add(brWord);
            actual = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();

            // 測試無法轉換的字元:/
            text      = "/";
            charStack = new Stack <char>(text);
            expected  = null;
            actual    = target.Convert(charStack, context);
            CollectionAssert.AreEqual(expected, actual, msg + text);
            charStack.Clear();
        }
        /// <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);
        }
Beispiel #9
0
        /// <summary>
        /// 從堆疊中讀取字元,把 ASCII 字元(半形的英數字)轉換成點字。
        /// </summary>
        /// <param name="charStack">輸入的 ASCII 字元堆疊。</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;

            while (!done && charStack.Count > 0)
            {
                ch          = charStack.Peek(); // 只讀取但不從堆疊移走。
                isExtracted = false;

                // 如果在數學區塊中
                if (context.IsActive(ContextTagNames.Math))
                {
                    if (ch == '*' || ch == '.' || ch == ':')
                    {
                        break;                          // 以上符號須交給 MathConverter 處理。
                    }
                }

                // 如果在座標區塊中,'('、',' 和 ')' 必須交給 CoordinateConverter 處理。
                if (context.IsActive(ContextTagNames.Coordinate))
                {
                    if (ch == '(' || ch == ',' || ch == ')')
                    {
                        break;
                    }
                }

                // 如果是半形小於符號,先檢查是否為情境標籤。
                if (ch == '<')
                {
                    char[] charBuf = charStack.ToArray();
                    string s       = new string(charBuf);
                    if (ContextTag.StartsWithContextTag(s))
                    {
                        break;  // 情境標籤必須交給 ContextTagConverter 處理。
                    }
                }

                text = ch.ToString();

                // 處理特殊字元。
                isExtracted = ProcessSpecialEntity(charStack, ref text);

                if (!isExtracted)
                {
                    // 處理刪節號。
                    if (ch == '.' && charStack.Count >= 3)
                    {
                        charStack.Pop();
                        char ch2 = charStack.Pop();
                        char ch3 = charStack.Pop();
                        if (ch2 == '.' && ch3 == '.')   // 連續三個點: 刪節號
                        {
                            isExtracted = true;
                            text        = "...";
                        }
                        else
                        {
                            charStack.Push(ch3);
                            charStack.Push(ch2);
                            charStack.Push(ch);
                            isExtracted = false;
                        }
                    }
                    // Tab 字元視為一個空白。
                    if (ch == '\t')
                    {
                        text = " ";
                    }
                }

                brWord = InternalConvert(text);
                if (brWord == null)
                {
                    break;
                }

                if (!isExtracted)
                {
                    charStack.Pop();
                }

                brWord.Language = BrailleLanguage.English;

                if (context.IsActive(ContextTagNames.Coordinate))   // 若處於座標情境標籤內
                {
                    // 不加數字點位。
                    brWord.NoDigitCell = true;
                }
                else if (":".Equals(text) && context.IsActive(ContextTagNames.Time))                    // 處理時間的冒號。
                {
                    // 在冒號的點字前面加上 456 點。
                    BrailleCell cell = BrailleCell.GetInstance(new int[] { 4, 5, 6 });
                    brWord.Cells.Insert(0, cell);
                }

                if (brWordList == null)
                {
                    brWordList = new List <BrailleWord>();
                }
                brWordList.Add(brWord);
            }
            return(brWordList);
        }
Beispiel #10
0
        public void BreakLineTest()
        {
            string msg = "BrailleProcesser.BreakLine 測試失敗!";

            BrailleProcessor target = BrailleProcessor.GetInstance();

            ContextTagManager context = new ContextTagManager();

            // 測試斷行:冒號+我。
            string      line   = "一二三四:我";
            BrailleLine brLine = target.ConvertLine(line); // 冒號後面會加一個空方

            int cellsPerLine = 12;                         // 故意在空方之後斷行。

            string             expected = "一二三四:";
            List <BrailleLine> brLines  = target.BreakLine(brLine, cellsPerLine, context);
            string             actual   = brLines[0].ToString();

            Assert.AreEqual(expected, actual, msg);
            brLines.Clear();

            // 測試斷行:斷在句點。
            line   = "一二三四。";
            brLine = target.ConvertLine(line);

            cellsPerLine = 10;                  // 故意斷在句號處。

            string expected1 = "一二三";           // 應該把最後一個字連同句號斷至下一行。
            string expected2 = "四。";

            brLines = target.BreakLine(brLine, cellsPerLine, context);
            bool isOk = (brLines.Count == 2 &&
                         brLines[0].ToString() == expected1 && brLines[1].ToString() == expected2);

            Assert.IsTrue(isOk, msg);

            // 測試斷行:斷在英文字中間要加上連字號。
            line   = "this is a loooooong word.";
            brLine = target.ConvertLine(line);

            cellsPerLine = 12;                  // 故意斷在句號處。

            expected1 = "this is a";            // 應該把最後一個字連同句號斷至下一行。
            expected2 = "loooooong";
            brLines   = target.BreakLine(brLine, cellsPerLine, context);
            isOk      = (brLines.Count == 3 &&
                         brLines[0].ToString() == expected1 && brLines[1].ToString() == expected2);
            Assert.IsTrue(isOk, msg);

            // 測試斷行:連續的數字不可斷開。
            line   = "12345 6789";
            brLine = target.ConvertLine(line);

            cellsPerLine = 8;

            brLines = target.BreakLine(brLine, cellsPerLine, context);
            isOk    = (brLines.Count == 2 &&
                       brLines[0].ToString() == "12345" &&
                       brLines[1].ToString() == "6789" &&
                       brLines[0][0].Cells[0].Value == (byte)BrailleCellCode.Digit &&
                       brLines[1][0].Cells[0].Value == (byte)BrailleCellCode.Digit);
            Assert.IsTrue(isOk, msg);

            // 測試斷行:斷在數字中間的逗號。
            line   = "abc 123,456";
            brLine = target.ConvertLine(line);

            cellsPerLine = 8;                   // 故意斷在逗號處。

            expected1 = "abc";
            expected2 = "123,456";
            brLines   = target.BreakLine(brLine, cellsPerLine, context);
            isOk      = (brLines.Count == 2 &&
                         brLines[0].ToString() == expected1 &&
                         brLines[1].ToString() == expected2 &&
                         brLines[1][0].Cells[0].Value == (byte)BrailleCellCode.Digit);
            Assert.IsTrue(isOk, msg);
        }