コード例 #1
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Given a TS string and an index, find the closest start of a word before that
        /// position (or after that position if at a word boundary already or in the last word
        /// of the string. If in a run marked using one of the special styles, always returns
        /// the position at the end of that run. Runs having these special styles are also
        /// always regarded as word boundaries.
        /// </summary>
        /// <param name="tss">the structured string of the paragraph or translation</param>
        /// <param name="ich">the given index</param>
        /// <param name="specialStyles">The special styles.</param>
        /// <returns>adjusted character index</returns>
        /// ------------------------------------------------------------------------------------
        public static int FindWordBoundary(this ITsString tss, int ich, params string[] specialStyles)
        {
            if (ich < 0 || ich > tss.Length)
            {
                throw new ArgumentOutOfRangeException("ich");
            }

            if (ich == 0 || ich == tss.Length)
            {
                return(ich);
            }

            string text          = tss.Text;
            string startingStyle = tss.StyleAt(ich);
            string prevStyle     = ich > 0 ? tss.StyleAt(ich - 1) : startingStyle;

            if (!specialStyles.Contains(startingStyle) || prevStyle == null)
            {
                startingStyle = null;
            }
            else if (startingStyle != null)
            {
                startingStyle = prevStyle;
            }

            // Advance to the next word boundary if appropriate)
            while (ich < text.Length)
            {
                // if the current character is space...
                if (Icu.IsSeparator(text[ich]))
                {
                    ich++;
                }
                else if (Icu.IsPunct(text[ich]) && ich > 0 && !Icu.IsSeparator(text[ich - 1]))
                {
                    // if word-final punctuation advance
                    ich++;
                }
                else if (startingStyle != null && tss.StyleAt(ich) == startingStyle)
                {
                    ich++;
                }
                else
                {
                    break;
                }
            }

            // NEVER move backward if at the end of the paragraph.
            if (ich < text.Length)
            {
                // While the insertion point is in the middle of a word then back up to the
                // start of the word or the start of a paragraph.
                while (ich > 0 && !Icu.IsSeparator(text[ich - 1]) && !specialStyles.Contains(tss.StyleAt(ich - 1)))
                {
                    ich--;
                }
            }

            return(ich);
        }