示例#1
0
        //
        // Titlecasing:
        // -----------
        // Titlecasing refers to a casing practice wherein the first letter of a word is an uppercase letter
        // and the rest of the letters are lowercase.  The choice of which words to titlecase in headings
        // and titles is dependent on language and local conventions.  For example, "The Merry Wives of Windor"
        // is the appropriate titlecasing of that play's name in English, with the word "of" not titlecased.
        // In German, however, the title is "Die lustigen Weiber von Windsor," and both "lustigen" and "von"
        // are not titlecased.  In French even fewer words are titlecased: "Les joyeuses commeres de Windsor."
        //
        // Moreover, the determination of what actually constitutes a word is language dependent, and this can
        // influence which letter or letters of a "word" are uppercased when titlecasing strings.  For example
        // "l'arbre" is considered two words in French, whereas "can't" is considered one word in English.
        //
        public unsafe string ToTitleCase(string str)
        {
            if (str == null)
            {
                throw new ArgumentNullException(nameof(str));
            }
            if (str.Length == 0)
            {
                return(str);
            }

            StringBuilder result        = new StringBuilder();
            string        lowercaseData = null;
            // Store if the current culture is Dutch (special case)
            bool isDutchCulture = CultureName.StartsWith("nl-", StringComparison.OrdinalIgnoreCase);

            for (int i = 0; i < str.Length; i++)
            {
                UnicodeCategory charType;
                int             charLen;

                charType = CharUnicodeInfo.InternalGetUnicodeCategory(str, i, out charLen);
                if (char.CheckLetter(charType))
                {
                    // Special case to check for Dutch specific titlecasing with "IJ" characters
                    // at the beginning of a word
                    if (isDutchCulture && i < str.Length - 1 && (str[i] == 'i' || str[i] == 'I') && (str[i + 1] == 'j' || str[i + 1] == 'J'))
                    {
                        result.Append("IJ");
                        i += 2;
                    }
                    else
                    {
                        // Do the titlecasing for the first character of the word.
                        i = AddTitlecaseLetter(ref result, ref str, i, charLen) + 1;
                    }

                    //
                    // Convert the characters until the end of the this word
                    // to lowercase.
                    //
                    int lowercaseStart = i;

                    //
                    // Use hasLowerCase flag to prevent from lowercasing acronyms (like "URT", "USA", etc)
                    // This is in line with Word 2000 behavior of titlecasing.
                    //
                    bool hasLowerCase = (charType == UnicodeCategory.LowercaseLetter);
                    // Use a loop to find all of the other letters following this letter.
                    while (i < str.Length)
                    {
                        charType = CharUnicodeInfo.InternalGetUnicodeCategory(str, i, out charLen);
                        if (IsLetterCategory(charType))
                        {
                            if (charType == UnicodeCategory.LowercaseLetter)
                            {
                                hasLowerCase = true;
                            }
                            i += charLen;
                        }
                        else if (str[i] == '\'')
                        {
                            i++;
                            if (hasLowerCase)
                            {
                                if (lowercaseData == null)
                                {
                                    lowercaseData = ToLower(str);
                                }
                                result.Append(lowercaseData, lowercaseStart, i - lowercaseStart);
                            }
                            else
                            {
                                result.Append(str, lowercaseStart, i - lowercaseStart);
                            }
                            lowercaseStart = i;
                            hasLowerCase   = true;
                        }
                        else if (!IsWordSeparator(charType))
                        {
                            // This category is considered to be part of the word.
                            // This is any category that is marked as false in wordSeprator array.
                            i += charLen;
                        }
                        else
                        {
                            // A word separator. Break out of the loop.
                            break;
                        }
                    }

                    int count = i - lowercaseStart;

                    if (count > 0)
                    {
                        if (hasLowerCase)
                        {
                            if (lowercaseData == null)
                            {
                                lowercaseData = ToLower(str);
                            }
                            result.Append(lowercaseData, lowercaseStart, count);
                        }
                        else
                        {
                            result.Append(str, lowercaseStart, count);
                        }
                    }

                    if (i < str.Length)
                    {
                        // not a letter, just append it
                        i = AddNonLetter(ref result, ref str, i, charLen);
                    }
                }
                else
                {
                    // not a letter, just append it
                    i = AddNonLetter(ref result, ref str, i, charLen);
                }
            }
            return(result.ToString());
        }
        /// <summary>
        /// Compares this CultureTextViewModel instance with another instance to determine the sort
        /// order in the editor view.
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(CultureTextViewModel other)
        {
            string otherName = other.CultureName;

            if (string.Compare(CultureName, otherName, StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                //System.Diagnostics.Debug.WriteLine(CultureName + " = " + otherName + " (1)");
                return(0);                  // Exact match
            }

            if (CultureName.Length >= 2 && otherName.Length >= 2)
            {
                // Prefer primary culture (with or without region; if set)
                if (!string.IsNullOrEmpty(TextKeyVM.MainWindowVM.PrimaryCulture))
                {
                    // tP:  thisPrimary
                    // oP:  otherPrimary
                    // oPR: otherPrimaryRelated
                    //
                    //             !tPR         tPR
                    //             !tP    tP    !tP   tP
                    //           --------------------------
                    // !oPR  !oP | cont.  xxx | -1    -1  |
                    //       oP  |  xxx   xxx | xxx   xxx |
                    //           --------------------------
                    // oPR   !oP |   1    xxx | cont. -1  |
                    //       oP  |   1    xxx |  1    xxx |
                    //           --------------------------

                    bool thisPrimary         = string.Compare(CultureName, TextKeyVM.MainWindowVM.PrimaryCulture, StringComparison.InvariantCultureIgnoreCase) == 0;
                    bool thisPrimaryRelated  = CultureName.StartsWith(TextKeyVM.MainWindowVM.PrimaryCulture.Substring(0, 2));
                    bool otherPrimary        = string.Compare(otherName, TextKeyVM.MainWindowVM.PrimaryCulture, StringComparison.InvariantCultureIgnoreCase) == 0;
                    bool otherPrimaryRelated = otherName.StartsWith(TextKeyVM.MainWindowVM.PrimaryCulture.Substring(0, 2));

                    if (thisPrimary || thisPrimaryRelated && !otherPrimaryRelated)
                    {
                        //System.Diagnostics.Debug.WriteLine(CultureName + " < " + otherName + " (2)");
                        return(-1);
                    }
                    if (otherPrimary || otherPrimaryRelated && !thisPrimaryRelated)
                    {
                        //System.Diagnostics.Debug.WriteLine(CultureName + " > " + otherName + " (2)");
                        return(1);
                    }
                }

                if (string.Compare(CultureName.Substring(0, 2), otherName.Substring(0, 2), StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    // Same language, prefer shorter names (without region)
                    if (CultureName.Length != otherName.Length)
                    {
                        int i = CultureName.Length - otherName.Length;
                        //if (i < 0)
                        //    System.Diagnostics.Debug.WriteLine(CultureName + " < " + otherName + " (3)");
                        //else if (i > 0)
                        //    System.Diagnostics.Debug.WriteLine(CultureName + " > " + otherName + " (3)");
                        //else
                        //    System.Diagnostics.Debug.WriteLine(CultureName + " = " + otherName + " (3)");
                        return(i);
                        // If this.length < other.length, then the result is negative and this comes before other
                    }
                }
            }
            return(string.Compare(CultureName, otherName, StringComparison.InvariantCultureIgnoreCase));
        }