/// <summary>
        ///     Is the letter at provided index a leading letter?
        /// </summary>
        /// <returns><see langword="true" /> if the letter is a leading letter</returns>
        private static bool IsLeadingLetter(FastStringBuilder letters, int index)
        {
            var currentIndexLetter = letters.Get(index);

            char previousIndexLetter = default;
            if (index != 0)
                previousIndexLetter = letters.Get(index - 1);

            char nextIndexLetter = default;
            if (index < letters.Length - 1)
                nextIndexLetter = letters.Get(index + 1);

            bool isPreviousLetterNonConnectable = index == 0 ||
                                                  !TextUtils.IsRTLCharacter(previousIndexLetter) ||
                                                  previousIndexLetter == (int)GeneralLetters.Alef ||
                                                  previousIndexLetter == (int)GeneralLetters.Dal ||
                                                  previousIndexLetter == (int)GeneralLetters.Thal ||
                                                  previousIndexLetter == (int)GeneralLetters.Ra2 ||
                                                  previousIndexLetter == (int)GeneralLetters.Zeen ||
                                                  previousIndexLetter == (int)GeneralLetters.PersianZe ||
                                                  previousIndexLetter == (int)GeneralLetters.Waw ||
                                                  previousIndexLetter == (int)GeneralLetters.AlefMad ||
                                                  previousIndexLetter ==
                                                  (int)GeneralLetters.AlefHamza ||
                                                  previousIndexLetter ==
                                                  (int)GeneralLetters.Hamza ||
                                                  previousIndexLetter ==
                                                  (int)GeneralLetters.AlefMaksoor ||
                                                  previousIndexLetter ==
                                                  (int)GeneralLetters.ZeroWidthNoJoiner ||
                                                  previousIndexLetter ==
                                                  (int)GeneralLetters.WawHamza ||
                                                  previousIndexLetter ==
                                                  (int)IsolatedLetters.Alef ||
                                                  previousIndexLetter == (int)IsolatedLetters.Dal ||
                                                  previousIndexLetter ==
                                                  (int)IsolatedLetters.Thal ||
                                                  previousIndexLetter == (int)IsolatedLetters.Ra2 ||
                                                  previousIndexLetter ==
                                                  (int)IsolatedLetters.Zeen ||
                                                  previousIndexLetter ==
                                                  (int)IsolatedLetters.PersianZe ||
                                                  previousIndexLetter == (int)IsolatedLetters.Waw ||
                                                  previousIndexLetter ==
                                                  (int)IsolatedLetters.AlefMad ||
                                                  previousIndexLetter ==
                                                  (int)IsolatedLetters.AlefHamza ||
                                                  previousIndexLetter ==
                                                  (int)IsolatedLetters.Hamza ||
                                                  previousIndexLetter ==
                                                  (int)IsolatedLetters.AlefMaksoor;


            bool canThisLetterBeLeading = currentIndexLetter != ' ' &&
                                          currentIndexLetter != (int)GeneralLetters.Dal &&
                                          currentIndexLetter != (int)GeneralLetters.Thal &&
                                          currentIndexLetter != (int)GeneralLetters.Ra2 &&
                                          currentIndexLetter != (int)GeneralLetters.Zeen &&
                                          currentIndexLetter != (int)GeneralLetters.PersianZe &&
                                          currentIndexLetter != (int)GeneralLetters.Alef &&
                                          currentIndexLetter != (int)GeneralLetters.AlefHamza &&
                                          currentIndexLetter != (int)GeneralLetters.AlefMaksoor &&
                                          currentIndexLetter != (int)GeneralLetters.AlefMad &&
                                          currentIndexLetter != (int)GeneralLetters.WawHamza &&
                                          currentIndexLetter != (int)GeneralLetters.Waw &&
                                          currentIndexLetter !=
                                          (int)GeneralLetters.ZeroWidthNoJoiner &&
                                          currentIndexLetter != (int)GeneralLetters.Hamza;

            bool isNextLetterConnectable = index < letters.Length - 1 &&
                                           TextUtils.IsRTLCharacter(nextIndexLetter) &&
                                           nextIndexLetter != (int)GeneralLetters.Hamza &&
                                           nextIndexLetter !=
                                           (int)GeneralLetters.ZeroWidthNoJoiner;

            return isPreviousLetterNonConnectable &&
                   canThisLetterBeLeading &&
                   isNextLetterConnectable;
        }
        /// <summary>
        ///     Is the letter at provided index a middle letter?
        /// </summary>
        /// <returns><see langword="true" /> if the letter is a middle letter</returns>
        private static bool IsMiddleLetter(FastStringBuilder letters, int index)
        {
            var currentIndexLetter = letters.Get(index);

            char previousIndexLetter = default;
            if (index != 0)
                previousIndexLetter = letters.Get(index - 1);

            char nextIndexLetter = default;
            if (index < letters.Length - 1)
                nextIndexLetter = letters.Get(index + 1);

            bool middleLetterCheck = index != 0 &&
                                     currentIndexLetter != (int)GeneralLetters.Alef &&
                                     currentIndexLetter != (int)GeneralLetters.Dal &&
                                     currentIndexLetter != (int)GeneralLetters.Thal &&
                                     currentIndexLetter != (int)GeneralLetters.Ra2 &&
                                     currentIndexLetter != (int)GeneralLetters.Zeen &&
                                     currentIndexLetter != (int)GeneralLetters.PersianZe &&
                                     currentIndexLetter != (int)GeneralLetters.Waw &&
                                     currentIndexLetter != (int)GeneralLetters.AlefMad &&
                                     currentIndexLetter != (int)GeneralLetters.AlefHamza &&
                                     currentIndexLetter != (int)GeneralLetters.AlefMaksoor &&
                                     currentIndexLetter != (int)GeneralLetters.WawHamza &&
                                     currentIndexLetter != (int)GeneralLetters.ZeroWidthNoJoiner &&
                                     currentIndexLetter != (int)GeneralLetters.Hamza;

            bool previousLetterCheck = index != 0 &&
                                       previousIndexLetter != (int)GeneralLetters.Alef &&
                                       previousIndexLetter != (int)GeneralLetters.Dal &&
                                       previousIndexLetter != (int)GeneralLetters.Thal &&
                                       previousIndexLetter != (int)GeneralLetters.Ra2 &&
                                       previousIndexLetter != (int)GeneralLetters.Zeen &&
                                       previousIndexLetter != (int)GeneralLetters.PersianZe &&
                                       previousIndexLetter != (int)GeneralLetters.Waw &&
                                       previousIndexLetter != (int)GeneralLetters.AlefMad &&
                                       previousIndexLetter != (int)GeneralLetters.AlefHamza &&
                                       previousIndexLetter != (int)GeneralLetters.AlefMaksoor &&
                                       previousIndexLetter != (int)GeneralLetters.WawHamza &&
                                       previousIndexLetter != (int)GeneralLetters.Hamza &&
                                       previousIndexLetter !=
                                       (int)GeneralLetters.ZeroWidthNoJoiner &&
                                       previousIndexLetter != (int)IsolatedLetters.Alef &&
                                       previousIndexLetter != (int)IsolatedLetters.Dal &&
                                       previousIndexLetter != (int)IsolatedLetters.Thal &&
                                       previousIndexLetter != (int)IsolatedLetters.Ra2 &&
                                       previousIndexLetter != (int)IsolatedLetters.Zeen &&
                                       previousIndexLetter != (int)IsolatedLetters.PersianZe &&
                                       previousIndexLetter != (int)IsolatedLetters.Waw &&
                                       previousIndexLetter != (int)IsolatedLetters.AlefMad &&
                                       previousIndexLetter != (int)IsolatedLetters.AlefHamza &&
                                       previousIndexLetter != (int)IsolatedLetters.AlefMaksoor &&
                                       previousIndexLetter != (int)IsolatedLetters.WawHamza &&
                                       previousIndexLetter != (int)IsolatedLetters.Hamza &&
                                       TextUtils.IsRTLCharacter(previousIndexLetter);

            bool nextLetterCheck = index < letters.Length - 1 &&
                                   TextUtils.IsRTLCharacter(nextIndexLetter) &&
                                   nextIndexLetter != (int)GeneralLetters.ZeroWidthNoJoiner &&
                                   nextIndexLetter != (int)GeneralLetters.Hamza &&
                                   nextIndexLetter != (int)IsolatedLetters.Hamza;

            return nextLetterCheck && previousLetterCheck && middleLetterCheck;
        }
Example #3
0
        public static void FindTag(
            FastStringBuilder str,
            int start,
            out Tag tag)
        {
            for (int i = start; i < str.Length;)
            {
                if (str.Get(i) != '<')
                {
                    i++;
                    continue;
                }

                bool calculateHashCode = true;
                tag.HashCode = 0;
                for (int j = i + 1; j < str.Length; j++)
                {
                    int jChar = str.Get(j);

                    if (calculateHashCode)
                    {
                        if (Char32Utils.IsLetter(jChar))
                        {
                            unchecked
                            {
                                if (tag.HashCode == 0)
                                {
                                    tag.HashCode = jChar.GetHashCode();
                                }
                                else
                                {
                                    tag.HashCode = (tag.HashCode * 397) ^ jChar.GetHashCode();
                                }
                            }
                        }
                        else if (tag.HashCode != 0)
                        {
                            // We have computed the hash code. Now we reached a non letter character. We need to stop
                            calculateHashCode = false;
                        }
                    }

                    // Rich text tag cannot contain < or start with space
                    if ((j == i + 1 && jChar == ' ') || jChar == '<')
                    {
                        break;
                    }

                    if (jChar == '>')
                    {
                        // Check if the tag is closing, opening or self contained

                        tag.Start = i;
                        tag.End   = j;

                        if (str.Get(j - 1) == '/')
                        {
                            // This is self contained.
                            tag.Type = TagType.SelfContained;
                        }
                        else if (str.Get(i + 1) == '/')
                        {
                            // This is closing
                            tag.Type = TagType.Closing;
                        }
                        else
                        {
                            tag.Type = TagType.Opening;
                        }

                        return;
                    }
                }

                i++;
            }

            tag.Start    = 0;
            tag.End      = 0;
            tag.Type     = TagType.None;
            tag.HashCode = 0;
        }