/// <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);
        }
Esempio n. 6
0
        /// <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);
        }