示例#1
0
        public static string AutoBreakLine(string text, int maximumLength, int mergeLinesShorterThan, string language)
        {
            if (text == null || text.Length < 3)
            {
                return(text);
            }

            // do not autobreak dialogs
            if (Contains(text, '-') && text.Contains(Environment.NewLine))
            {
                var noTagLines = HtmlUtil.RemoveHtmlTags(text, true).SplitToLines();
                if (noTagLines.Length == 2)
                {
                    var arr0 = noTagLines[0].Trim().TrimEnd('"', '\'').TrimEnd();
                    if (arr0.StartsWith('-') && noTagLines[1].TrimStart().StartsWith('-') && arr0.Length > 1 && (Contains(".?!)]", arr0[arr0.Length - 1]) || arr0.EndsWith("--", StringComparison.Ordinal) || arr0.EndsWith('–')))
                    {
                        return(text);
                    }
                }
            }

            string s = RemoveLineBreaks(text);

            if (HtmlUtil.RemoveHtmlTags(s, true).Length < mergeLinesShorterThan)
            {
                return(s);
            }

            var htmlTags = new Dictionary <int, string>();
            var sb       = new StringBuilder();
            int six      = 0;

            while (six < s.Length)
            {
                var  letter   = s[six];
                bool tagFound = false;
                if (letter == '<')
                {
                    string tagString = s.Substring(six);
                    tagFound = tagString.StartsWith("<font", StringComparison.OrdinalIgnoreCase) ||
                               tagString.StartsWith("</font", StringComparison.OrdinalIgnoreCase) ||
                               tagString.StartsWith("<u", StringComparison.OrdinalIgnoreCase) ||
                               tagString.StartsWith("</u", StringComparison.OrdinalIgnoreCase) ||
                               tagString.StartsWith("<b", StringComparison.OrdinalIgnoreCase) ||
                               tagString.StartsWith("</b", StringComparison.OrdinalIgnoreCase) ||
                               tagString.StartsWith("<i", StringComparison.OrdinalIgnoreCase) ||
                               tagString.StartsWith("</i", StringComparison.OrdinalIgnoreCase);
                }

                int endIndex = -1;
                if (tagFound)
                {
                    endIndex = s.IndexOf('>', six + 1);
                }

                if (tagFound && endIndex > 0)
                {
                    string tag = s.Substring(six, endIndex - six + 1);
                    s = s.Remove(six, tag.Length);
                    if (htmlTags.ContainsKey(six))
                    {
                        htmlTags[six] = htmlTags[six] + tag;
                    }
                    else
                    {
                        htmlTags.Add(six, tag);
                    }
                }
                else
                {
                    sb.Append(letter);
                    six++;
                }
            }
            s = sb.ToString();

            int splitPos = -1;
            int mid      = s.Length / 2;

            // try to find " - " with uppercase letter after (dialog)
            if (s.Contains(" - "))
            {
                for (int j = 0; j <= (maximumLength / 2) + 5; j++)
                {
                    if (mid + j + 4 < s.Length)
                    {
                        if (s[mid + j] == '-' && s[mid + j + 1] == ' ' && s[mid + j - 1] == ' ')
                        {
                            string rest = s.Substring(mid + j + 1).TrimStart();
                            if (rest.Length > 0 && char.IsUpper(rest[0]))
                            {
                                splitPos = mid + j;
                                break;
                            }
                        }
                    }
                    if (mid - (j + 1) > 4)
                    {
                        if (s[mid - j] == '-' && s[mid - j + 1] == ' ' && s[mid - j - 1] == ' ')
                        {
                            string rest = s.Substring(mid - j + 1).TrimStart();
                            if (rest.Length > 0 && char.IsUpper(rest[0]))
                            {
                                if (mid - j > 5 && s[mid - j - 1] == ' ')
                                {
                                    if (Contains("!?.", s[mid - j - 2]))
                                    {
                                        splitPos = mid - j;
                                        break;
                                    }
                                    var first = s.Substring(0, mid - j - 1);
                                    if (first.EndsWith(".\"", StringComparison.Ordinal) || first.EndsWith("!\"", StringComparison.Ordinal) || first.EndsWith("?\"", StringComparison.Ordinal))
                                    {
                                        splitPos = mid - j;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (splitPos == maximumLength + 1 && s[maximumLength] != ' ') // only allow space for last char (as it does not count)
            {
                splitPos = -1;
            }

            if (splitPos < 0)
            {
                const string expectedChars1 = ".!?0123456789";
                const string expectedChars2 = ".!?";
                for (int j = 0; j < 15; j++)
                {
                    if (mid + j + 1 < s.Length && mid + j > 0)
                    {
                        if (Contains(expectedChars2, s[mid + j]) && !IsPartOfNumber(s, mid + j) && CanBreak(s, mid + j + 1, language))
                        {
                            splitPos = mid + j + 1;
                            if (Contains(expectedChars1, s[splitPos]))
                            { // do not break double/tripple end lines like "!!!" or "..."
                                splitPos++;
                                if (Contains(expectedChars1, s[mid + j + 1]))
                                {
                                    splitPos++;
                                }
                            }
                            break;
                        }
                        if (Contains(expectedChars2, s[mid - j]) && !IsPartOfNumber(s, mid - j) && CanBreak(s, mid - j, language))
                        {
                            splitPos = mid - j;
                            splitPos++;
                            break;
                        }
                    }
                }
            }

            if (splitPos > maximumLength)                                     // too long first line
            {
                if (splitPos != maximumLength + 1 || s[maximumLength] != ' ') // allow for maxlength+1 char to be space (does not count)
                {
                    splitPos = -1;
                }
            }
            else if (splitPos >= 0 && s.Length - splitPos > maximumLength) // too long second line
            {
                splitPos = -1;
            }

            if (splitPos < 0)
            {
                const string expectedChars1 = ".!?, ";
                const string expectedChars2 = " .!?";
                const string expectedChars3 = ".!?";
                for (int j = 0; j < 25; j++)
                {
                    if (mid + j + 1 < s.Length && mid + j > 0)
                    {
                        if (Contains(expectedChars1, s[mid + j]) && !IsPartOfNumber(s, mid + j) && s.Length > mid + j + 2 && CanBreak(s, mid + j, language))
                        {
                            splitPos = mid + j;
                            if (Contains(expectedChars2, s[mid + j + 1]))
                            {
                                splitPos++;
                                if (Contains(expectedChars2, s[mid + j + 2]))
                                {
                                    splitPos++;
                                }
                            }
                            break;
                        }
                        if (Contains(expectedChars1, s[mid - j]) && !IsPartOfNumber(s, mid - j) && s.Length > mid + j + 2 && CanBreak(s, mid - j, language))
                        {
                            splitPos = mid - j;
                            if (Contains(expectedChars3, s[splitPos]))
                            {
                                splitPos--;
                            }
                            if (Contains(expectedChars3, s[splitPos]))
                            {
                                splitPos--;
                            }
                            if (Contains(expectedChars3, s[splitPos]))
                            {
                                splitPos--;
                            }
                            break;
                        }
                    }
                }
            }

            if (splitPos < 0)
            {
                splitPos = mid;
                s        = s.Insert(mid - 1, Environment.NewLine);
                s        = ReInsertHtmlTags(s, htmlTags);
                htmlTags = new Dictionary <int, string>();
                s        = s.Replace(Environment.NewLine, "-");
            }
            if (splitPos < s.Length - 2)
            {
                s = s.Substring(0, splitPos) + Environment.NewLine + s.Substring(splitPos);
            }

            s = ReInsertHtmlTags(s, htmlTags);
            var idx = s.IndexOf(Environment.NewLine + "</", StringComparison.Ordinal);

            if (idx > 2)
            {
                var endIdx = s.IndexOf('>', idx + 2);
                if (endIdx > idx)
                {
                    var tag = s.Substring(idx + Environment.NewLine.Length, endIdx - (idx + Environment.NewLine.Length) + 1);
                    s = s.Insert(idx, tag);
                    s = s.Remove(idx + tag.Length + Environment.NewLine.Length, tag.Length);
                }
            }
            s = s.Replace(" " + Environment.NewLine, Environment.NewLine);
            s = s.Replace(Environment.NewLine + " ", Environment.NewLine);
            return(s.TrimEnd());
        }
示例#2
0
 public static int CountWords(this string source)
 {
     return(HtmlUtil.RemoveHtmlTags(source, true).Split(new[] { ' ', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Length);
 }