public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixLongDisplayTime;
            int noOfLongDisplayTimes = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                double maxDisplayTime = Utilities.GetOptimalDisplayMilliseconds(p.Text) * 8.0;
                if (maxDisplayTime > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
                    maxDisplayTime = Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds;
                double displayTime = p.Duration.TotalMilliseconds;

                bool allowFix = callbacks.AllowFix(p, fixAction);
                if (allowFix && displayTime > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds)
                {
                    string oldCurrent = p.ToString();
                    p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds;
                    noOfLongDisplayTimes++;
                    callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                }
                else if (allowFix && maxDisplayTime < displayTime)
                {
                    string oldCurrent = p.ToString();
                    displayTime = Utilities.GetOptimalDisplayMilliseconds(p.Text);
                    p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + displayTime;
                    noOfLongDisplayTimes++;
                    callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                }
            }

            callbacks.UpdateFixStatus(noOfLongDisplayTimes, language.FixLongDisplayTimes, string.Format(language.XDisplayTimesShortned, noOfLongDisplayTimes));
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            const string beginTagUpper = "<I>";
            const string endTagUpper = "</I>";
            const string beginTag = "<i>";
            const string endTag = "</i>";
            string fixAction = language.FixInvalidItalicTag;
            int noOfInvalidHtmlTags = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                if (callbacks.AllowFix(subtitle.Paragraphs[i], fixAction))
                {
                    var text = subtitle.Paragraphs[i].Text;
                    if (text.Contains('<'))
                    {
                        text = text.Replace(beginTagUpper, beginTag).Replace(endTagUpper, endTag);
                        string oldText = text;

                        text = HtmlUtil.FixInvalidItalicTags(text);
                        if (text != oldText)
                        {
                            subtitle.Paragraphs[i].Text = text;
                            noOfInvalidHtmlTags++;
                            callbacks.AddFixToListView(subtitle.Paragraphs[i], fixAction, oldText, text);
                        }
                    }
                }
            }

            callbacks.UpdateFixStatus(noOfInvalidHtmlTags, language.FixInvalidItalicTags, string.Format(language.XInvalidHtmlTagsFixed, noOfInvalidHtmlTags));
        }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.MergeShortLineAll;
     int noOfShortLines = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         if (callbacks.AllowFix(p, fixAction))
         {
             string s = HtmlUtil.RemoveHtmlTags(p.Text, true);
             if (s.Replace(Environment.NewLine, " ").Replace("  ", " ").Length < Configuration.Settings.Tools.MergeLinesShorterThan && p.Text.Contains(Environment.NewLine))
             {
                 s = Utilities.AutoBreakLine(p.Text, callbacks.Language);
                 if (s != p.Text)
                 {
                     string oldCurrent = p.Text;
                     p.Text = s;
                     noOfShortLines++;
                     callbacks.AddFixToListView(p, fixAction, oldCurrent, p.Text);
                 }
             }
         }
     }
     callbacks.UpdateFixStatus(noOfShortLines, language.RemoveLineBreaks, string.Format(language.XLinesUnbreaked, noOfShortLines));
 }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.FixTurkishAnsi;
     int noOfFixes = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         string text = p.Text;
         string oldText = text;
         text = text.Replace('Ý', 'İ');
         text = text.Replace('Ð', 'Ğ');
         text = text.Replace('Þ', 'Ş');
         text = text.Replace('ý', 'ı');
         text = text.Replace('ð', 'ğ');
         text = text.Replace('þ', 'ş');
         if (oldText != text && callbacks.AllowFix(p, fixAction))
         {
             p.Text = text;
             noOfFixes++;
             callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
         }
     }
     callbacks.UpdateFixStatus(noOfFixes, language.FixCommonOcrErrors, language.FixTurkishAnsi);
 }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixSpanishInvertedQuestionAndExclamationMarks;
            int fixCount = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                Paragraph last = subtitle.GetParagraphOrDefault(i - 1);

                bool wasLastLineClosed = last == null || last.Text.EndsWith('?') || last.Text.EndsWith('!') || last.Text.EndsWith('.') ||
                                         last.Text.EndsWith(':') || last.Text.EndsWith(')') || last.Text.EndsWith(']');
                string trimmedStart = p.Text.TrimStart('-', ' ');
                if (last != null && last.Text.EndsWith("...", StringComparison.Ordinal) && trimmedStart.Length > 0 && char.IsLower(trimmedStart[0]))
                    wasLastLineClosed = false;
                if (!wasLastLineClosed && last.Text == last.Text.ToUpper())
                    wasLastLineClosed = true;

                string oldText = p.Text;

                FixSpanishInvertedLetter('?', "¿", p, last, ref wasLastLineClosed, fixAction, ref fixCount, callbacks);
                FixSpanishInvertedLetter('!', "¡", p, last, ref wasLastLineClosed, fixAction, ref fixCount, callbacks);

                if (p.Text != oldText)
                {
                    fixCount++;
                    callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                }
            }
            callbacks.UpdateFixStatus(fixCount, language.FixSpanishInvertedQuestionAndExclamationMarks, fixCount.ToString(CultureInfo.InvariantCulture));
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixMusicNotation;
            int fixCount = 0;
            string[] musicSymbols = Configuration.Settings.Tools.MusicSymbolToReplace.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                if (callbacks.AllowFix(p, fixAction))
                {
                    var oldText = p.Text;
                    var newText = oldText;

                    foreach (string musicSymbol in musicSymbols)
                    {
                        newText = newText.Replace(musicSymbol, Configuration.Settings.Tools.MusicSymbol);
                        newText = newText.Replace(musicSymbol.ToUpper(), Configuration.Settings.Tools.MusicSymbol);
                    }
                    var noTagsText = HtmlUtil.RemoveHtmlTags(newText);
                    if (newText != oldText && noTagsText != HtmlUtil.RemoveHtmlTags(oldText))
                    {
                        p.Text = newText;
                        fixCount++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(fixCount, language.FixMusicNotation, language.XFixMusicNotation);
        }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.FixEllipsesStart;
     int fixCount = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         var text = p.Text;
         if (text.Contains("..") && callbacks.AllowFix(p, fixAction))
         {
             var oldText = text;
             string[] lines = text.SplitToLines();
             for (int k = 0; k < lines.Length; k++)
             {
                 lines[k] = Helper.FixEllipsesStartHelper(lines[k]);
             }
             text = string.Join(Environment.NewLine, lines);
             if (oldText.Length > text.Length)
             {
                 p.Text = text;
                 fixCount++;
                 callbacks.AddFixToListView(p, fixAction, oldText, text);
             }
         }
     }
     callbacks.UpdateFixStatus(fixCount, language.FixEllipsesStart, language.XFixEllipsesStart);
 }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixEllipsesStart;
            int fixCount = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                var text = p.Text;
                if (text.Contains("..") && callbacks.AllowFix(p, fixAction))
                {
                    var oldText = text;
                    if (!text.Contains(Environment.NewLine))
                    {
                        text = Helper.FixEllipsesStartHelper(text);
                        if (oldText != text)
                        {
                            p.Text = text;
                            fixCount++;
                            callbacks.AddFixToListView(p, fixAction, oldText, text);
                        }
                    }
                    else
                    {
                        var lines = text.SplitToLines();
                        var fixedParagraph = string.Empty;
                        for (int k = 0; k < lines.Length; k++)
                        {
                            var line = lines[k];
                            fixedParagraph += Environment.NewLine + Helper.FixEllipsesStartHelper(line);
                            fixedParagraph = fixedParagraph.Trim();
                        }

                        if (fixedParagraph != text)
                        {
                            p.Text = fixedParagraph;
                            fixCount++;
                            callbacks.AddFixToListView(p, fixAction, oldText, fixedParagraph);
                        }
                    }
                }
            }
            callbacks.UpdateFixStatus(fixCount, language.FixEllipsesStart, language.XFixEllipsesStart);
        }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.FixDoubleGreaterThan;
     int fixCount = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         if (callbacks.AllowFix(p, fixAction))
         {
             if (!p.Text.Contains(">>", StringComparison.Ordinal))
                 continue;
             var text = p.Text;
             var oldText = text;
             if (!text.Contains(Environment.NewLine))
             {
                 text = Helper.FixDoubleGreaterThanHelper(text);
                 if (oldText != text)
                 {
                     fixCount++;
                     p.Text = text;
                     callbacks.AddFixToListView(p, fixAction, oldText, text);
                 }
             }
             else
             {
                 var lines = text.SplitToLines();
                 for (int k = 0; k < lines.Length; k++)
                 {
                     lines[k] = Helper.FixDoubleGreaterThanHelper(lines[k]);
                 }
                 text = string.Join(Environment.NewLine, lines);
                 if (oldText != text)
                 {
                     fixCount++;
                     p.Text = text;
                     callbacks.AddFixToListView(p, fixAction, oldText, text);
                 }
             }
         }
     }
     callbacks.UpdateFixStatus(fixCount, language.FixDoubleGreaterThan, language.XFixDoubleGreaterThan);
 }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.StartWithUppercaseLetterAfterPeriodInsideParagraph;
     int noOfFixes = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         string oldText = p.Text;
         if (p.Text.Length > 3 && callbacks.AllowFix(p, fixAction))
         {
             var st = new StrippableText(p.Text);
             string text = st.StrippedText;
             int start = text.IndexOfAny(ExpectedChars);
             while (start > 0 && start < text.Length)
             {
                 char charAtPosition = text[start];
                 // Allow fixing lowercase letter after recursive ??? or !!!.
                 if (charAtPosition != '.') // Dot is not include 'cause I don't capitalize word after the ellipses (...), right?
                 {
                     while (start + 1 < text.Length && text[start + 1] == charAtPosition)
                     {
                         start++;
                     }
                 }
                 if ((start + 3 < text.Length) && (text[start + 1] == ' ') && !IsAbbreviation(text, start, callbacks))
                 {
                     var subText = new StrippableText(text.Substring(start + 2));
                     text = text.Substring(0, start + 2) + subText.CombineWithPrePost(ToUpperFirstLetter(subText.StrippedText, callbacks));
                 }
                 // Try to reach the last dot if char at *start is '.'.
                 if (charAtPosition == '.')
                 {
                     while (start + 1 < text.Length && text[start + 1] == '.')
                     {
                         start++;
                     }
                 }
                 start += 3;
                 if (start < text.Length)
                     start = text.IndexOfAny(ExpectedChars, start);
             }
             text = st.CombineWithPrePost(text);
             if (oldText != text)
             {
                 p.Text = text;
                 noOfFixes++;
                 callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
             }
         }
     }
     callbacks.UpdateFixStatus(noOfFixes, language.StartWithUppercaseLetterAfterPeriodInsideParagraph, noOfFixes.ToString(CultureInfo.InvariantCulture));
 }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.UnneededPeriod;
            int unneededPeriodsFixed = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                var oldText = p.Text;
                if (callbacks.AllowFix(p, fixAction))
                {
                    if (p.Text.Contains("!." + Environment.NewLine))
                    {
                        p.Text = p.Text.Replace("!." + Environment.NewLine, "!" + Environment.NewLine);
                        unneededPeriodsFixed++;
                    }
                    if (p.Text.Contains("?." + Environment.NewLine))
                    {
                        p.Text = p.Text.Replace("?." + Environment.NewLine, "?" + Environment.NewLine);
                        unneededPeriodsFixed++;
                    }
                    if (p.Text.EndsWith("!.", StringComparison.Ordinal))
                    {
                        p.Text = p.Text.TrimEnd('.');
                        unneededPeriodsFixed++;
                    }
                    if (p.Text.EndsWith("?.", StringComparison.Ordinal))
                    {
                        p.Text = p.Text.TrimEnd('.');
                        unneededPeriodsFixed++;
                    }

                    var len = p.Text.Length;
                    if (p.Text.Contains("!. "))
                    {
                        p.Text = p.Text.Replace("!. ", "! ");
                        unneededPeriodsFixed += len - p.Text.Length;
                        len = p.Text.Length;
                    }
                    if (p.Text.Contains("?. "))
                    {
                        p.Text = p.Text.Replace("?. ", "? ");
                        unneededPeriodsFixed += len - p.Text.Length;
                    }

                    if (p.Text != oldText)
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                }
            }
            callbacks.UpdateFixStatus(unneededPeriodsFixed, language.RemoveUnneededPeriods, string.Format(language.XUnneededPeriodsRemoved, unneededPeriodsFixed));
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixMusicNotation;
            int fixCount = 0;
            string[] musicSymbols = Configuration.Settings.Tools.MusicSymbolToReplace.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                if (callbacks.AllowFix(p, fixAction))
                {
                    var oldText = p.Text;
                    var newText = oldText;
                    bool containsFontTag = oldText.Contains("<font ", StringComparison.OrdinalIgnoreCase);
                    foreach (string musicSymbol in musicSymbols)
                    {
                        if (containsFontTag && musicSymbol == "#")
                        {
                            var idx = newText.IndexOf('#');
                            while (idx >= 0)
                            {
                                // <font color="#808080">NATIVE HAWAIIAN CHANTING</font>
                                var isInsideFontTag = (idx < 13) ? false : (newText[idx - 1] == '"' && (newText.Length > idx + 2 && Uri.IsHexDigit(newText[idx + 1]) && Uri.IsHexDigit(newText[idx + 2])));
                                if (!isInsideFontTag)
                                {
                                    newText = newText.Remove(idx, 1);
                                    newText = newText.Insert(idx, Configuration.Settings.Tools.MusicSymbol);
                                }

                                idx = newText.IndexOf('#', idx + 1);
                            }
                        }
                        else
                        {
                            newText = newText.Replace(musicSymbol, Configuration.Settings.Tools.MusicSymbol);
                            newText = newText.Replace(musicSymbol.ToUpper(), Configuration.Settings.Tools.MusicSymbol);
                        }
                    }
                    var noTagsText = HtmlUtil.RemoveHtmlTags(newText);
                    if (newText != oldText && noTagsText != HtmlUtil.RemoveHtmlTags(oldText))
                    {
                        p.Text = newText;
                        fixCount++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(fixCount, language.FixMusicNotation, language.XFixMusicNotation);
        }
Example #13
0
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.Fix3PlusLine;
     int iFixes = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         if (Utilities.GetNumberOfLines(p.Text) > 2 && callbacks.AllowFix(p, fixAction))
         {
             string oldText = p.Text;
             p.Text = Utilities.AutoBreakLine(p.Text);
             iFixes++;
             callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
         }
     }
     callbacks.UpdateFixStatus(iFixes, language.Fix3PlusLines, language.X3PlusLinesFixed);
 }
Example #14
0
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.MergeShortLine;
     int noOfShortLines = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         string oldText = p.Text;
         var text = Helper.FixShortLines(p.Text);
         if (callbacks.AllowFix(p, fixAction) && oldText != text)
         {
             p.Text = text;
             noOfShortLines++;
             callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
         }
     }
     callbacks.UpdateFixStatus(noOfShortLines, language.RemoveLineBreaks, string.Format(language.XLinesUnbreaked, noOfShortLines));
 }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.FixDialogsOnOneLine;
     int noOfFixes = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         string oldText = p.Text;
         var text = Helper.FixDialogsOnOneLine(oldText, callbacks.Language);
         if (oldText != text && callbacks.AllowFix(p, fixAction))
         {
             p.Text = text;
             noOfFixes++;
             callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
         }
     }
     callbacks.UpdateFixStatus(noOfFixes, language.FixCommonOcrErrors, language.FixDialogsOneLineExample);
 }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.FixHyphen;
     int iFixes = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         var p = subtitle.Paragraphs[i];
         if (callbacks.AllowFix(p, fixAction))
         {
             string oldText = p.Text;
             string text = Helper.FixHyphensRemove(subtitle, i);
             if (text != oldText)
             {
                 p.Text = text;
                 iFixes++;
                 callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
             }
         }
     }
     callbacks.UpdateFixStatus(iFixes, language.FixHyphens, language.XHyphensFixed);
 }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     var fixAction = language.RemoveSpaceBetweenNumber;
     int noOfFixes = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         var p = subtitle.Paragraphs[i];
         if (callbacks.AllowFix(p, fixAction))
         {
             var text = Utilities.RemoveSpaceBetweenNumbers(p.Text);
             if (text != p.Text)
             {
                 var oldText = p.Text;
                 p.Text = text;
                 noOfFixes++;
                 callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
             }
         }
     }
     callbacks.UpdateFixStatus(noOfFixes, language.FixCommonOcrErrors, string.Format(language.RemoveSpaceBetweenNumbersFixed, noOfFixes));
 }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixDoubleApostrophes;
            int fixCount = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];

                if (p.Text.Contains("''"))
                {
                    if (callbacks.AllowFix(p, fixAction))
                    {
                        string oldText = p.Text;
                        p.Text = p.Text.Replace("''", "\"");
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                        fixCount++;
                    }
                }
            }
            callbacks.UpdateFixStatus(fixCount, language.FixDoubleApostrophes, language.XDoubleApostrophesFixed);
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixFirstLetterToUppercaseAfterParagraph;
            int fixedStartWithUppercaseLetterAfterParagraphTicked = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                Paragraph prev = subtitle.GetParagraphOrDefault(i - 1);

                string oldText = p.Text;
                string fixedText = DoFix(new Paragraph(p), prev, callbacks.Encoding, callbacks.Language);

                if (oldText != fixedText && callbacks.AllowFix(p, fixAction))
                {
                    p.Text = fixedText;
                    fixedStartWithUppercaseLetterAfterParagraphTicked++;
                    callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                }
            }
            callbacks.UpdateFixStatus(fixedStartWithUppercaseLetterAfterParagraphTicked, language.StartWithUppercaseLetterAfterParagraph, fixedStartWithUppercaseLetterAfterParagraphTicked.ToString(CultureInfo.InvariantCulture));
        }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.UnneededSpace;
     int doubleSpaces = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         if (callbacks.AllowFix(p, fixAction))
         {
             var oldText = p.Text;
             var text = Utilities.RemoveUnneededSpaces(p.Text, callbacks.Language);
             if (text.Length != oldText.Length && (Utilities.CountTagInText(text, ' ') + Utilities.CountTagInText(text, '\t') + Utilities.CountTagInText(text, Environment.NewLine)) < (Utilities.CountTagInText(oldText, ' ') + Utilities.CountTagInText(oldText, '\u00A0') + Utilities.CountTagInText(oldText, '\t') + Utilities.CountTagInText(oldText, Environment.NewLine)))
             {
                 doubleSpaces++;
                 p.Text = text;
                 callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
             }
         }
     }
     callbacks.UpdateFixStatus(doubleSpaces, language.RemoveUnneededSpaces, string.Format(language.XUnneededSpacesRemoved, doubleSpaces));
 }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixMissingOpenBracket;
            int fixCount = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                var p = subtitle.Paragraphs[i];

                if (callbacks.AllowFix(p, fixAction))
                {
                    var hit = false;
                    string oldText = p.Text;
                    var openIdx = p.Text.IndexOf('(');
                    var closeIdx = p.Text.IndexOf(')');
                    if (closeIdx >= 0 && (closeIdx < openIdx || openIdx < 0))
                    {
                        p.Text = Fix(p.Text, "(");
                        hit = true;
                    }

                    openIdx = p.Text.IndexOf('[');
                    closeIdx = p.Text.IndexOf(']');
                    if (closeIdx >= 0 && (closeIdx < openIdx || openIdx < 0))
                    {
                        p.Text = Fix(p.Text, "[");
                        hit = true;
                    }

                    if (hit)
                    {
                        fixCount++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(fixCount, language.FixMissingOpenBracket, language.XFixMissingOpenBracket);
        }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.FixLowercaseIToUppercaseI;
     int iFixes = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         string oldText = p.Text;
         string s = p.Text;
         if (s.Contains('i'))
         {
             s = FixAloneLowercaseIToUppercaseLine(SubtitleEditRegex.LittleIRegex, oldText, s, 'i');
             if (s != oldText && callbacks.AllowFix(p, fixAction))
             {
                 p.Text = s;
                 iFixes++;
                 callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
             }
         }
     }
     callbacks.UpdateFixStatus(iFixes, language.FixLowercaseIToUppercaseI, language.XIsChangedToUppercase);
 }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.RemoveSpaceBetweenNumber;
     int noOfFixes = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         string text = p.Text;
         Match match = RemoveSpaceBetweenNumbersRegEx.Match(text);
         int counter = 0;
         while (match.Success && counter < 100 && text.Length > match.Index + 1)
         {
             string temp = text.Substring(match.Index + 2);
             if (temp != "1/2" &&
                 !temp.StartsWith("1/2 ", StringComparison.Ordinal) &&
                 !temp.StartsWith("1/2.", StringComparison.Ordinal) &&
                 !temp.StartsWith("1/2!", StringComparison.Ordinal) &&
                 !temp.StartsWith("1/2?", StringComparison.Ordinal) &&
                 !temp.StartsWith("1/2<", StringComparison.Ordinal))
             {
                 text = text.Remove(match.Index + 1, 1);
             }
             if (text.Length > match.Index + 1)
                 match = RemoveSpaceBetweenNumbersRegEx.Match(text, match.Index + 2);
             counter++;
         }
         if (callbacks.AllowFix(p, fixAction) && p.Text != text)
         {
             string oldText = p.Text;
             p.Text = text;
             noOfFixes++;
             callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
         }
     }
     callbacks.UpdateFixStatus(noOfFixes, language.FixCommonOcrErrors, string.Format(language.RemoveSpaceBetweenNumbersFixed, noOfFixes));
 }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language  = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixSpanishInvertedQuestionAndExclamationMarks;
            int    fixCount  = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p    = subtitle.Paragraphs[i];
                Paragraph last = subtitle.GetParagraphOrDefault(i - 1);

                bool wasLastLineClosed = last == null || last.Text.EndsWith('?') || last.Text.EndsWith('!') || last.Text.EndsWith('.') ||
                                         last.Text.EndsWith(':') || last.Text.EndsWith(')') || last.Text.EndsWith(']');
                string trimmedStart = p.Text.TrimStart('-', ' ');
                if (last != null && last.Text.EndsWith("...", StringComparison.Ordinal) && trimmedStart.Length > 0 && char.IsLower(trimmedStart[0]))
                {
                    wasLastLineClosed = false;
                }

                if (!wasLastLineClosed && last.Text == last.Text.ToUpperInvariant())
                {
                    wasLastLineClosed = true;
                }

                string oldText = p.Text;

                FixSpanishInvertedLetter('?', "¿", p, last, ref wasLastLineClosed, fixAction, ref fixCount, callbacks);
                FixSpanishInvertedLetter('!', "¡", p, last, ref wasLastLineClosed, fixAction, ref fixCount, callbacks);

                if (p.Text != oldText)
                {
                    fixCount++;
                    callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                }
            }
            callbacks.UpdateFixStatus(fixCount, language.FixSpanishInvertedQuestionAndExclamationMarks, fixCount.ToString(CultureInfo.InvariantCulture));
        }
Example #25
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var          language            = Configuration.Settings.Language.FixCommonErrors;
            const string beginTagUpper       = "<I>";
            const string endTagUpper         = "</I>";
            const string beginTag            = "<i>";
            const string endTag              = "</i>";
            string       fixAction           = language.FixInvalidItalicTag;
            int          noOfInvalidHtmlTags = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                if (callbacks.AllowFix(subtitle.Paragraphs[i], fixAction))
                {
                    var text = subtitle.Paragraphs[i].Text;
                    if (text.Contains('<'))
                    {
                        if (!text.Contains("i>") && !text.Contains("<i"))
                        {
                            text = text.Replace(beginTagUpper, beginTag).Replace(endTagUpper, endTag);
                        }

                        string oldText = text;

                        text = HtmlUtil.FixInvalidItalicTags(text);
                        if (text != oldText)
                        {
                            subtitle.Paragraphs[i].Text = text;
                            noOfInvalidHtmlTags++;
                            callbacks.AddFixToListView(subtitle.Paragraphs[i], fixAction, oldText, text);
                        }
                    }
                }
            }

            callbacks.UpdateFixStatus(noOfInvalidHtmlTags, language.FixInvalidItalicTags, string.Format(language.XInvalidHtmlTagsFixed, noOfInvalidHtmlTags));
        }
Example #26
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.BreakLongLine;
            int noOfLongLines = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                var lines = p.Text.SplitToLines();
                bool tooLong = false;
                foreach (string line in lines)
                {
                    if (HtmlUtil.RemoveHtmlTags(line, true).Length > Configuration.Settings.General.SubtitleLineMaximumLength)
                    {
                        tooLong = true;
                        break;
                    }
                }
                if (callbacks.AllowFix(p, fixAction) && tooLong)
                {
                    string oldText = p.Text;
                    p.Text = Utilities.AutoBreakLine(p.Text, callbacks.Language);
                    if (oldText != p.Text)
                    {
                        noOfLongLines++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                    else
                    {
                        callbacks.LogStatus(fixAction, string.Format(language.UnableToFixTextXY, i + 1, p));
                        callbacks.AddToTotalErrors(1);
                    }
                }
            }

            callbacks.UpdateFixStatus(noOfLongLines, language.BreakLongLines, string.Format(language.XLineBreaksAdded, noOfLongLines));
        }
Example #27
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var fixAction     = Language.BreakLongLine;
            var noOfLongLines = 0;

            for (var i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                var p       = subtitle.Paragraphs[i];
                var lines   = p.Text.SplitToLines();
                var tooLong = false;
                foreach (var line in lines)
                {
                    if (line.CountCharacters() > Configuration.Settings.General.SubtitleLineMaximumLength)
                    {
                        tooLong = true;
                        break;
                    }
                }
                if (callbacks.AllowFix(p, fixAction) && tooLong)
                {
                    string oldText = p.Text;
                    p.Text = Utilities.AutoBreakLine(p.Text, callbacks.Language);
                    if (oldText != p.Text)
                    {
                        noOfLongLines++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                    else
                    {
                        callbacks.LogStatus(fixAction, string.Format(Language.UnableToFixTextXY, i + 1, p));
                        callbacks.AddToTotalErrors(1);
                    }
                }
            }

            callbacks.UpdateFixStatus(noOfLongLines, Language.BreakLongLines);
        }
Example #28
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            int noOfFixes = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p       = subtitle.Paragraphs[i];
                string    text    = p.Text;
                string    oldText = text;
                text = text.Replace('Ý', 'İ');
                text = text.Replace('Ð', 'Ğ');
                text = text.Replace('Þ', 'Ş');
                text = text.Replace('ý', 'ı');
                text = text.Replace('ð', 'ğ');
                text = text.Replace('þ', 'ş');
                if (oldText != text && callbacks.AllowFix(p, Language.FixTurkishAnsi))
                {
                    p.Text = text;
                    noOfFixes++;
                    callbacks.AddFixToListView(p, Language.FixTurkishAnsi, oldText, p.Text);
                }
            }
            callbacks.UpdateFixStatus(noOfFixes, Language.FixTurkishAnsi);
        }
 public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
 {
     var language = Configuration.Settings.Language.FixCommonErrors;
     string fixAction = language.UnneededPeriod;
     int removedCount = 0;
     for (int i = 0; i < subtitle.Paragraphs.Count; i++)
     {
         Paragraph p = subtitle.Paragraphs[i];
         if (callbacks.AllowFix(p, fixAction))
         {
             // Returns processed text.
             string procText = RemoveDotAfterPunctuation(p.Text);
             int diff = p.Text.Length - procText.Length;
             if (diff > 0)
             {
                 // Calculate total removed dots.
                 removedCount += diff;
                 callbacks.AddFixToListView(p, fixAction, p.Text, procText);
                 p.Text = procText;
             }
         }
     }
     callbacks.UpdateFixStatus(removedCount, language.RemoveUnneededPeriods, string.Format(language.XUnneededPeriodsRemoved, removedCount));
 }
Example #30
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language  = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixLowercaseIToUppercaseI;
            int    iFixes    = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p       = subtitle.Paragraphs[i];
                string    oldText = p.Text;
                string    s       = p.Text;
                if (s.Contains('i'))
                {
                    s = FixAloneLowercaseIToUppercaseLine(RegexUtils.LittleIRegex, oldText, s, 'i');
                    if (s != oldText && callbacks.AllowFix(p, fixAction))
                    {
                        p.Text = s;
                        iFixes++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(iFixes, language.FixLowercaseIToUppercaseI, language.XIsChangedToUppercase);
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language  = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.AddMissingQuote;
            int    noOfFixes = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];

                if (Utilities.CountTagInText(p.Text, '"') == 1)
                {
                    Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
                    if (next != null)
                    {
                        double betweenMilliseconds = next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds;
                        if (betweenMilliseconds > 1500)
                        {
                            next = null; // cannot be quote spanning several lines of more than 1.5 seconds between lines!
                        }
                        else if (next.Text.Replace("<i>", string.Empty).TrimStart().TrimStart('-').TrimStart().StartsWith('"') &&
                                 next.Text.Replace("</i>", string.Empty).TrimEnd().EndsWith('"') &&
                                 Utilities.CountTagInText(next.Text, '"') == 2)
                        {
                            next = null; // seems to have valid quotes, so no spanning
                        }
                    }

                    Paragraph prev = subtitle.GetParagraphOrDefault(i - 1);
                    if (prev != null)
                    {
                        double betweenMilliseconds = p.StartTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds;
                        if (betweenMilliseconds > 1500)
                        {
                            prev = null; // cannot be quote spanning several lines of more than 1.5 seconds between lines!
                        }
                        else if (prev.Text.Replace("<i>", string.Empty).TrimStart().TrimStart('-').TrimStart().StartsWith('"') &&
                                 prev.Text.Replace("</i>", string.Empty).TrimEnd().EndsWith('"') &&
                                 Utilities.CountTagInText(prev.Text, '"') == 2)
                        {
                            prev = null; // seems to have valid quotes, so no spanning
                        }
                    }

                    string oldText = p.Text;
                    var    lines   = HtmlUtil.RemoveHtmlTags(p.Text).SplitToLines();
                    if (lines.Count == 2 && lines[0].TrimStart().StartsWith('-') && lines[1].TrimStart().StartsWith('-'))
                    { // dialog
                        lines = p.Text.SplitToLines();
                        string line = lines[0].Trim();

                        if (line.Length > 5 && line.TrimStart().StartsWith("- \"", StringComparison.Ordinal) && (line.EndsWith('.') || line.EndsWith('!') || line.EndsWith('?')))
                        {
                            p.Text = p.Text.Trim().Replace(" " + Environment.NewLine, Environment.NewLine);
                            p.Text = p.Text.Replace(Environment.NewLine, "\"" + Environment.NewLine);
                        }
                        else if (line.Length > 5 && line.EndsWith('"') && line.Contains("- ") && line.IndexOf("- ", StringComparison.Ordinal) < 4)
                        {
                            p.Text = p.Text.Insert(line.IndexOf("- ", StringComparison.Ordinal) + 2, "\"");
                        }
                        else if (line.Contains('"') && line.IndexOf('"') > 2 && line.IndexOf('"') < line.Length - 3)
                        {
                            int index = line.IndexOf('"');
                            if (line[index - 1] == ' ')
                            {
                                p.Text = p.Text.Trim().Replace(" " + Environment.NewLine, Environment.NewLine);
                                p.Text = p.Text.Replace(Environment.NewLine, "\"" + Environment.NewLine);
                            }
                            else if (line[index + 1] == ' ')
                            {
                                if (line.Length > 5 && line.Contains("- ") && line.IndexOf("- ", StringComparison.Ordinal) < 4)
                                {
                                    p.Text = p.Text.Insert(line.IndexOf("- ", StringComparison.Ordinal) + 2, "\"");
                                }
                            }
                        }
                        else if (lines[1].Contains('"'))
                        {
                            line = lines[1].Trim();
                            if (line.Length > 5 && line.TrimStart().StartsWith("- \"", StringComparison.Ordinal) && (line.EndsWith('.') || line.EndsWith('!') || line.EndsWith('?')))
                            {
                                p.Text = p.Text.Trim() + "\"";
                            }
                            else if (line.Length > 5 && line.EndsWith('"') && p.Text.Contains(Environment.NewLine + "- "))
                            {
                                p.Text = p.Text.Insert(p.Text.IndexOf(Environment.NewLine + "- ", StringComparison.Ordinal) + Environment.NewLine.Length + 2, "\"");
                            }
                            else if (line.Contains('"') && line.IndexOf('"') > 2 && line.IndexOf('"') < line.Length - 3)
                            {
                                int index = line.IndexOf('"');
                                if (line[index - 1] == ' ')
                                {
                                    p.Text = p.Text.Trim() + "\"";
                                }
                                else if (line[index + 1] == ' ')
                                {
                                    if (line.Length > 5 && p.Text.Contains(Environment.NewLine + "- "))
                                    {
                                        p.Text = p.Text.Insert(p.Text.IndexOf(Environment.NewLine + "- ", StringComparison.Ordinal) + Environment.NewLine.Length + 2, "\"");
                                    }
                                }
                            }
                        }
                    }
                    else
                    { // not dialog
                        if (p.Text.StartsWith('"'))
                        {
                            if (next == null || !next.Text.Contains('"'))
                            {
                                p.Text += "\"";
                            }
                        }
                        else if (p.Text.StartsWith("<i>\"", StringComparison.Ordinal) && p.Text.EndsWith("</i>", StringComparison.Ordinal) && Utilities.CountTagInText(p.Text, "</i>") == 1)
                        {
                            if (next == null || !next.Text.Contains('"'))
                            {
                                p.Text = p.Text.Replace("</i>", "\"</i>");
                            }
                        }
                        else if (p.Text.EndsWith('"'))
                        {
                            if (prev == null || !prev.Text.Contains('"'))
                            {
                                p.Text = "\"" + p.Text;
                            }
                        }
                        else if (p.Text.Contains(Environment.NewLine + "\"") && Utilities.GetNumberOfLines(p.Text) == 2)
                        {
                            if (next == null || !next.Text.Contains('"'))
                            {
                                p.Text = p.Text + "\"";
                            }
                        }
                        else if ((p.Text.Contains(Environment.NewLine + "\"") || p.Text.Contains(Environment.NewLine + "-\"") || p.Text.Contains(Environment.NewLine + "- \"")) &&
                                 Utilities.GetNumberOfLines(p.Text) == 2 && p.Text.Length > 3)
                        {
                            if (next == null || !next.Text.Contains('"'))
                            {
                                if (p.Text.StartsWith("<i>", StringComparison.Ordinal) && p.Text.EndsWith("</i>", StringComparison.Ordinal) && Utilities.CountTagInText(p.Text, "</i>") == 1)
                                {
                                    p.Text = p.Text.Replace("</i>", "\"</i>");
                                }
                                else
                                {
                                    p.Text = p.Text + "\"";
                                }
                            }
                        }
                        else if (p.Text.StartsWith("<i>", StringComparison.Ordinal) && p.Text.EndsWith("</i>", StringComparison.Ordinal) && Utilities.CountTagInText(p.Text, "<i>") == 1)
                        {
                            if (prev == null || !prev.Text.Contains('"'))
                            {
                                p.Text = p.Text.Replace("<i>", "<i>\"");
                            }
                        }
                        else if (p.Text.Contains('"'))
                        {
                            string text         = p.Text;
                            int    indexOfQuote = p.Text.IndexOf('"');
                            if (text.Contains('"') && indexOfQuote > 2 && indexOfQuote < text.Length - 3)
                            {
                                int index = text.IndexOf('"');
                                if (text[index - 1] == ' ')
                                {
                                    if (p.Text.EndsWith(','))
                                    {
                                        p.Text = p.Text.Insert(p.Text.Length - 1, "\"").Trim();
                                    }
                                    else
                                    {
                                        p.Text = p.Text.Trim() + "\"";
                                    }
                                }
                                else if (text[index + 1] == ' ')
                                {
                                    p.Text = "\"" + p.Text;
                                }
                            }
                        }
                    }

                    if (oldText != p.Text)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            noOfFixes++;
                            callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                        }
                        else
                        {
                            p.Text = oldText;
                        }
                    }
                }
            }
            callbacks.UpdateFixStatus(noOfFixes, fixAction, language.XMissingQuotesAdded);
        }
Example #32
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var commaDouble            = new Regex(@"([\p{L}\d\s])(,,)([\p{L}\d\s])");
            var commaTriple            = new Regex(@"([\p{L}\d\s])( *, *, *,)([\p{L}\d\s])");
            var commaTripleEndOfLine   = new Regex(@"([\p{L}\d\s])(, *, *,)$");
            var commaWhiteSpaceBetween = new Regex(@"([\p{L}\d\s])(,\s+,)([\p{L}\d\s])");
            var commaFollowedByLetter  = new Regex(@",(\p{L})");

            string fixAction = Configuration.Settings.Language.FixCommonErrors.FixCommas;
            int    fixCount  = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                var p = subtitle.Paragraphs[i];
                if ((p.Text.IndexOf(',') >= 0 || p.Text.IndexOf('،') >= 0) && callbacks.AllowFix(p, fixAction))
                {
                    var s       = p.Text;
                    var oldText = s;

                    if (p.Text.IndexOf(',') >= 0)
                    {
                        s = commaDouble.Replace(s, "$1,$3");
                        s = commaTriple.Replace(s, "$1...$3");
                        s = commaTripleEndOfLine.Replace(s, "$1...");
                        s = commaWhiteSpaceBetween.Replace(s, "$1,$3");
                        s = commaFollowedByLetter.Replace(s, ", $1");

                        while (s.Contains(",."))
                        {
                            s = s.Replace(",.", ".");
                        }

                        while (s.Contains(",!"))
                        {
                            s = s.Replace(",!", "!");
                        }

                        while (s.Contains(",?"))
                        {
                            s = s.Replace(",?", "?");
                        }
                    }

                    if (p.Text.IndexOf('،') >= 0)
                    {
                        var commaDoubleAr            = new Regex(@"([\p{L}\d\s])( *،،)([\p{L}\d\s])");
                        var commaTripleAr            = new Regex(@"([\p{L}\d\s])( *، *، *،)([\p{L}\d\s])");
                        var commaTripleEndOfLineAr   = new Regex(@"([\p{L}\d\s])( *، *، *،)$");
                        var commaWhiteSpaceBetweenAr = new Regex(@"([\p{L}\d\s])( *،\s+،)([\p{L}\d\s])");
                        var commaFollowedByLetterAr  = new Regex(@"،(\p{L})");
                        s = commaDoubleAr.Replace(s, "$1،$3");
                        s = commaTripleAr.Replace(s, "$1...$3");
                        s = commaTripleEndOfLineAr.Replace(s, "$1...");
                        s = commaWhiteSpaceBetweenAr.Replace(s, "$1،$3");
                        s = commaFollowedByLetterAr.Replace(s, "، $1");

                        while (s.Contains("،."))
                        {
                            s = s.Replace("،.", ".");
                        }

                        while (s.Contains("،!"))
                        {
                            s = s.Replace("،!", "!");
                        }

                        while (s.Contains("،?"))
                        {
                            s = s.Replace("،?", "?");
                        }
                    }

                    if (oldText != s)
                    {
                        fixCount++;
                        callbacks.AddFixToListView(p, fixAction, oldText, s);
                        p.Text = s;
                    }
                }
            }
            callbacks.UpdateFixStatus(fixCount, Configuration.Settings.Language.FixCommonErrors.FixCommas, fixCount.ToString());
        }
Example #33
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            string fixAction0 = Language.RemovedEmptyLine;
            string fixAction1 = Language.RemovedEmptyLineAtTop;
            string fixAction2 = Language.RemovedEmptyLineAtBottom;
            string fixAction3 = Language.RemovedEmptyLineInMiddle;

            if (subtitle.Paragraphs.Count == 0)
            {
                return;
            }

            int emptyLinesRemoved = 0;

            for (int i = subtitle.Paragraphs.Count - 1; i >= 0; i--)
            {
                var p = subtitle.Paragraphs[i];
                if (!string.IsNullOrEmpty(p.Text))
                {
                    string text    = p.Text.Trim(' ');
                    var    oldText = text;
                    var    pre     = string.Empty;
                    var    post    = string.Empty;

                    // Ssa Tags
                    if (text.StartsWith("{\\", StringComparison.Ordinal))
                    {
                        var endIdx = text.IndexOf('}', 2);
                        if (endIdx > 2)
                        {
                            pre  = text.Substring(0, endIdx + 1);
                            text = text.Remove(0, endIdx + 1);
                        }
                    }

                    while (text.LineStartsWithHtmlTag(true, true))
                    {
                        // Three length tag
                        if (text[2] == '>')
                        {
                            pre += text.Substring(0, 3);
                            text = text.Remove(0, 3);
                        }
                        else // <font ...>
                        {
                            var closeIdx = text.IndexOf('>');
                            if (closeIdx <= 2)
                            {
                                break;
                            }

                            pre += text.Substring(0, closeIdx + 1);
                            text = text.Remove(0, closeIdx + 1);
                        }
                    }
                    while (text.LineEndsWithHtmlTag(true, true))
                    {
                        var len = text.Length;

                        // Three length tag
                        if (text[len - 4] == '<')
                        {
                            post = text.Substring(text.Length - 4) + post;
                            text = text.Remove(text.Length - 4);
                        }
                        else // </font>
                        {
                            post = text.Substring(text.Length - 7) + post;
                            text = text.Remove(text.Length - 7);
                        }
                    }

                    if (callbacks.AllowFix(p, fixAction1) && text.TrimStart(StringExtensions.UnicodeControlChars).StartsWith(Environment.NewLine, StringComparison.Ordinal))
                    {
                        if (pre.Length > 0)
                        {
                            text = pre + text.TrimStart(StringExtensions.UnicodeControlChars).TrimStart(Utilities.NewLineChars);
                        }
                        else
                        {
                            text = text.TrimStart(StringExtensions.UnicodeControlChars).TrimStart(Utilities.NewLineChars);
                        }

                        p.Text = text;
                        emptyLinesRemoved++;
                        callbacks.AddFixToListView(p, fixAction1, oldText, p.Text);
                    }
                    else
                    {
                        text = pre + text;
                    }

                    if (callbacks.AllowFix(p, fixAction2) && text.TrimEnd(StringExtensions.UnicodeControlChars).EndsWith(Environment.NewLine, StringComparison.Ordinal))
                    {
                        if (post.Length > 0)
                        {
                            text = text.TrimEnd(StringExtensions.UnicodeControlChars).TrimEnd(Utilities.NewLineChars) + post;
                        }
                        else
                        {
                            text = text.TrimEnd(StringExtensions.UnicodeControlChars).TrimEnd(Utilities.NewLineChars);
                        }

                        p.Text = text;
                        emptyLinesRemoved++;
                        callbacks.AddFixToListView(p, fixAction2, oldText, p.Text);
                    }

                    if (Configuration.Settings.Tools.RemoveEmptyLinesBetweenText &&
                        callbacks.AllowFix(p, fixAction3) && text.Contains(Environment.NewLine + Environment.NewLine))
                    {
                        int beforeLength = text.Length;
                        while (text.Contains(Environment.NewLine + Environment.NewLine))
                        {
                            text = text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine);
                        }
                        p.Text             = text;
                        emptyLinesRemoved += (beforeLength - text.Length) / Environment.NewLine.Length;
                        callbacks.AddFixToListView(p, fixAction3, oldText, p.Text);
                    }
                }
            }

            // this must be the very last action done, or line numbers will be messed up!!!
            for (int i = subtitle.Paragraphs.Count - 1; i >= 0; i--)
            {
                var p    = subtitle.Paragraphs[i];
                var text = HtmlUtil.RemoveHtmlTags(p.Text, true).Trim();
                if (callbacks.AllowFix(p, fixAction0) && string.IsNullOrEmpty(text.RemoveControlCharacters().RemoveChar(StringExtensions.UnicodeControlChars)))
                {
                    subtitle.Paragraphs.RemoveAt(i);
                    emptyLinesRemoved++;
                    callbacks.AddFixToListView(p, fixAction0, p.Text, $"[{Language.RemovedEmptyLine}]");
                    callbacks.AddToDeleteIndices(i);
                }
            }

            if (emptyLinesRemoved > 0)
            {
                callbacks.UpdateFixStatus(emptyLinesRemoved, Language.RemovedEmptyLinesUnsedLineBreaks);
                subtitle.Renumber();
            }
        }
Example #34
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language  = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixMusicNotation;
            int    fixCount  = 0;

            string[] musicSymbols = Configuration.Settings.Tools.MusicSymbolReplace.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                if (callbacks.AllowFix(p, fixAction))
                {
                    var  oldText         = p.Text;
                    var  newText         = oldText;
                    bool containsFontTag = oldText.Contains("<font ", StringComparison.OrdinalIgnoreCase);
                    foreach (string musicSymbol in musicSymbols)
                    {
                        var ms = musicSymbol.Trim();
                        if (containsFontTag && ms == "#")
                        {
                            var idx = newText.IndexOf('#');
                            while (idx >= 0)
                            {
                                // <font color="#808080">NATIVE HAWAIIAN CHANTING</font>
                                var isInsideFontTag = idx >= 13 && (newText[idx - 1] == '"' && newText.Length > idx + 2 && Uri.IsHexDigit(newText[idx + 1]) && Uri.IsHexDigit(newText[idx + 2]));
                                if (!isInsideFontTag)
                                {
                                    newText = newText.Remove(idx, 1);
                                    newText = newText.Insert(idx, Configuration.Settings.Tools.MusicSymbol);
                                }

                                idx = newText.IndexOf('#', idx + 1);
                            }
                        }
                        else
                        {
                            var fix = true;
                            if (ms == "#" && newText.Contains("#") && !newText.Contains("# "))
                            {
                                int count = Utilities.CountTagInText(newText, '#');
                                if (count == 1)
                                {
                                    var idx = newText.IndexOf('#');
                                    if (idx < newText.Length - 2)
                                    {
                                        if (char.IsLetterOrDigit(newText[idx + 1]))
                                        {
                                            fix = false;
                                        }
                                    }
                                }
                                else if (!newText.EndsWith('#'))
                                {
                                    var idx          = newText.IndexOf('#');
                                    int hashTagCount = 0;
                                    while (idx >= 0)
                                    {
                                        if (char.IsLetterOrDigit(newText[idx + 1]))
                                        {
                                            hashTagCount++;
                                        }
                                        idx = newText.IndexOf('#', idx + 1);
                                    }
                                    fix = hashTagCount == 0;
                                }
                            }

                            if (fix)
                            {
                                newText = newText.Replace(ms, Configuration.Settings.Tools.MusicSymbol);
                                newText = newText.Replace(ms.ToUpperInvariant(), Configuration.Settings.Tools.MusicSymbol);
                            }
                        }
                    }
                    var noTagsText = HtmlUtil.RemoveHtmlTags(newText);
                    if (newText != oldText && noTagsText != HtmlUtil.RemoveHtmlTags(oldText))
                    {
                        p.Text = newText;
                        fixCount++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(fixCount, language.FixMusicNotation, language.XFixMusicNotation);
        }
Example #35
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            int fixCount = 0;

            var isLanguageWithoutCaseDistinction = ContinuationUtilities.IsLanguageWithoutCaseDistinction(callbacks.Language);

            // Check continuation profile
            if (_continuationProfile == null)
            {
                SetContinuationProfile(Configuration.Settings.General.ContinuationStyle);
            }

            // Quick fix for Portuguese
            if (callbacks.Language == "pt")
            {
                _continuationProfile.SuffixApplyIfComma    = false;
                _continuationProfile.GapSuffixApplyIfComma = false;

                if (_continuationProfile.Prefix == "..." || _continuationProfile.Prefix == "…")
                {
                    _continuationProfile.PrefixAddSpace = true;
                }

                if (_continuationProfile.GapPrefix == "..." || _continuationProfile.GapPrefix == "…")
                {
                    _continuationProfile.GapPrefixAddSpace = true;
                }
            }

            var minGapMs = ContinuationUtilities.GetMinimumGapMs();

            var  inSentence       = false;
            bool?inItalicSentence = null;

            for (var i = 0; i < subtitle.Paragraphs.Count - 1; i++)
            {
                var p             = subtitle.Paragraphs[i];
                var pNext         = subtitle.Paragraphs[i + 1];
                var oldText       = p.Text;
                var oldTextNext   = pNext.Text;
                var text          = ContinuationUtilities.SanitizeString(p.Text);
                var textNext      = ContinuationUtilities.SanitizeString(pNext.Text);
                var isChecked     = true;
                var shouldProcess = true;

                // Detect gap
                var gap = pNext.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds >= minGapMs;

                // Convert for Arabic
                if (callbacks.Language == "ar")
                {
                    oldText     = ContinuationUtilities.ConvertToForArabic(oldText);
                    oldTextNext = ContinuationUtilities.ConvertToForArabic(oldTextNext);
                    text        = ContinuationUtilities.ConvertToForArabic(text);
                    textNext    = ContinuationUtilities.ConvertToForArabic(textNext);
                }

                // Check if we should fix this paragraph
                if (ShouldFixParagraph(text, gap))
                {
                    // If ends with nothing...
                    if (!ContinuationUtilities.IsEndOfSentence(text))
                    {
                        if (!isLanguageWithoutCaseDistinction)
                        {
                            // ...ignore inserts
                            if (Configuration.Settings.General.FixContinuationStyleUncheckInsertsAllCaps)
                            {
                                if (ContinuationUtilities.IsAllCaps(text) || ContinuationUtilities.IsAllCaps(textNext))
                                {
                                    isChecked = false;
                                }
                            }

                            // ...and italic lyrics
                            if (Configuration.Settings.General.FixContinuationStyleUncheckInsertsItalic)
                            {
                                if (ContinuationUtilities.IsItalic(oldText) && !ContinuationUtilities.IsNewSentence(text, true) && inItalicSentence == false)
                                {
                                    isChecked = false;
                                }
                            }

                            // ...and small caps inserts or non-italic lyrics
                            if (Configuration.Settings.General.FixContinuationStyleUncheckInsertsLowercase)
                            {
                                if (!ContinuationUtilities.IsNewSentence(text, true) && !inSentence)
                                {
                                    isChecked = false;
                                }
                            }

                            // ...ignore bold tags for Portuguese
                            if (callbacks.Language == "pt")
                            {
                                if (ContinuationUtilities.IsBold(oldText) || ContinuationUtilities.IsBold(oldTextNext))
                                {
                                    isChecked = false;
                                }
                            }
                        }

                        // ...ignore Arabic inserts
                        if (callbacks.Language == "ar")
                        {
                            if (ContinuationUtilities.IsArabicInsert(oldText, text) || ContinuationUtilities.IsArabicInsert(oldTextNext, textNext))
                            {
                                isChecked = false;
                            }
                        }
                    }

                    // Remove any suffixes and prefixes
                    var oldTextWithoutSuffix = ContinuationUtilities.RemoveSuffix(oldText, _continuationProfile, new List <string> {
                        ","
                    }, false).Trim();
                    var oldTextNextWithoutPrefix = ContinuationUtilities.RemovePrefix(oldTextNext, _continuationProfile, true, gap);
                    var textNextWithoutPrefix    = ContinuationUtilities.SanitizeString(oldTextNextWithoutPrefix, true);

                    // Get last word of this paragraph
                    var lastWord = ContinuationUtilities.GetLastWord(text);


                    // If ends with dots (possible interruptions), or nothing, check if next sentence is new sentence, otherwise don't check by default
                    if (text.EndsWith("..") || text.EndsWith("…") || ContinuationUtilities.EndsWithNothing(text, _continuationProfile))
                    {
                        if (!HasPrefix(textNext) && ((!isLanguageWithoutCaseDistinction && ContinuationUtilities.IsNewSentence(textNext, true)) || string.IsNullOrEmpty(textNext)))
                        {
                            isChecked = false;

                            // If set, we'll hide interruption continuation candidates that don't start with a name,
                            // to prevent clogging up the window with a lot of unchecked items.
                            // For example, a candidate we DO want to list:  But wait...   Marty is still there!
                            //                                          or:  This is something   Marty can do.
                            // If both sentences are all caps, DO show them.
                            if (Configuration.Settings.General.FixContinuationStyleHideContinuationCandidatesWithoutName &&
                                !(textNextWithoutPrefix.StartsWith("I ") || textNextWithoutPrefix.StartsWith("I'")) &&
                                !StartsWithName(textNextWithoutPrefix, callbacks.Language) &&
                                !(ContinuationUtilities.IsAllCaps(text) && ContinuationUtilities.IsAllCaps(textNext)))
                            {
                                shouldProcess = false;
                            }
                        }
                    }

                    if (shouldProcess)
                    {
                        // First paragraph...

                        // If first paragraphs ends with a suffix,
                        // and profile states to NOT replace comma,
                        // and next sentence starts with conjunction,
                        // try to re-add comma
                        var addComma = lastWord.EndsWith(",") || HasSuffix(text) &&
                                       (gap ? !_continuationProfile.GapSuffixReplaceComma : !_continuationProfile.SuffixReplaceComma) &&
                                       ContinuationUtilities.StartsWithConjunction(textNextWithoutPrefix, callbacks.Language);

                        // Make new last word
                        var newText = ContinuationUtilities.AddSuffixIfNeeded(oldTextWithoutSuffix, _continuationProfile, gap, addComma);

                        // Commit if changed
                        if (oldText != newText && callbacks.AllowFix(p, FixAction))
                        {
                            // Convert back for Arabic
                            if (callbacks.Language == "ar")
                            {
                                newText = ContinuationUtilities.ConvertBackForArabic(newText);
                            }

                            // Don't apply fix when it's checked in step 1
                            if (IsPreviewStep(callbacks) && isChecked || !IsPreviewStep(callbacks))
                            {
                                p.Text = newText;
                            }
                            fixCount++;
                            callbacks.AddFixToListView(p, FixAction, oldText, newText, isChecked);
                        }


                        // Second paragraph...

                        // Make new first word
                        var newTextNext = ContinuationUtilities.AddPrefixIfNeeded(oldTextNextWithoutPrefix, _continuationProfile, gap);

                        // Commit if changed
                        if (oldTextNext != newTextNext && callbacks.AllowFix(pNext, FixAction + " "))
                        {
                            // Convert back for Arabic
                            if (callbacks.Language == "ar")
                            {
                                newTextNext = ContinuationUtilities.ConvertBackForArabic(newTextNext);
                            }

                            // Don't apply fix when it's checked in step 1
                            if (IsPreviewStep(callbacks) && isChecked || !IsPreviewStep(callbacks))
                            {
                                pNext.Text = newTextNext;
                            }
                            fixCount++;
                            callbacks.AddFixToListView(pNext, FixAction + " ", oldTextNext, newTextNext, isChecked);
                        }
                    }
                }

                // Detect new sentence
                if (ContinuationUtilities.IsNewSentence(text, true))
                {
                    inSentence = true;

                    if (ContinuationUtilities.IsItalic(oldText))
                    {
                        inItalicSentence = true;
                    }
                    else
                    {
                        inItalicSentence = null;
                    }
                }

                // Detect end of sentence
                if (ContinuationUtilities.IsEndOfSentence(text))
                {
                    inSentence = false;

                    if (ContinuationUtilities.IsItalic(oldText))
                    {
                        inItalicSentence = false;
                    }
                    else
                    {
                        inItalicSentence = null;
                    }
                }
            }

            callbacks.UpdateFixStatus(fixCount, Language.FixUnnecessaryLeadingDots);
        }
Example #36
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var          language  = Configuration.Settings.Language.FixCommonErrors;
            const string fixAction = "Fix Danish letter 'i'";
            int          fixCount  = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p       = subtitle.Paragraphs[i];
                string    text    = p.Text;
                string    oldText = text;

                // Make sure text contains lower: 'i'.
                if (RegexUtils.LittleIRegex.IsMatch(text))
                {
                    foreach (var regex in RegexUtils.DanishLetterI.DanishCompiledRegexList)
                    {
                        Match match = regex.Match(text);
                        while (match.Success)
                        {
                            // Get lower 'i' index from matched value.
                            int iIdx = RegexUtils.LittleIRegex.Match(match.Value).Index;
                            // Remove 'i' from given index and insert new uppwercase 'I'.
                            string temp = match.Value.Remove(iIdx, 1).Insert(iIdx, "I");

                            int index = match.Index;
                            if (index + match.Value.Length >= text.Length)
                            {
                                text = text.Substring(0, index) + temp;
                            }
                            else
                            {
                                text = text.Substring(0, index) + temp + text.Substring(index + match.Value.Length);
                            }

                            match = match.NextMatch();
                        }
                    }
                }

                if (RegexUtils.DanishLetterI.RegExIDag.IsMatch(text))
                {
                    text = RegexUtils.DanishLetterI.RegExIDag.Replace(text, "i dag");
                }

                if (RegexUtils.DanishLetterI.RegExIGaar.IsMatch(text))
                {
                    text = RegexUtils.DanishLetterI.RegExIGaar.Replace(text, "i går");
                }

                if (RegexUtils.DanishLetterI.RegExIMorgen.IsMatch(text))
                {
                    text = RegexUtils.DanishLetterI.RegExIMorgen.Replace(text, "i morgen");
                }

                if (RegexUtils.DanishLetterI.RegExIAlt.IsMatch(text))
                {
                    text = RegexUtils.DanishLetterI.RegExIAlt.Replace(text, "i alt");
                }

                if (RegexUtils.DanishLetterI.RegExIGang.IsMatch(text))
                {
                    text = RegexUtils.DanishLetterI.RegExIGang.Replace(text, "i gang");
                }

                if (RegexUtils.DanishLetterI.RegExIStand.IsMatch(text))
                {
                    text = RegexUtils.DanishLetterI.RegExIStand.Replace(text, "i stand");
                }

                if (RegexUtils.DanishLetterI.RegExIOevrigt.IsMatch(text))
                {
                    text = RegexUtils.DanishLetterI.RegExIOevrigt.Replace(text, "i øvrigt");
                }

                if (text != oldText && callbacks.AllowFix(p, fixAction))
                {
                    p.Text = text;
                    fixCount++;
                    callbacks.AddFixToListView(subtitle.Paragraphs[i], fixAction, oldText, text);
                }
            }

            callbacks.UpdateFixStatus(fixCount, language.FixDanishLetterI, string.Format(language.XIsChangedToUppercase, fixCount));
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            _callbacks = callbacks;

            string fixAction = language.FixShortDisplayTime;
            int noOfShortDisplayTimes = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                var skip = p.StartTime.IsMaxTime || p.EndTime.IsMaxTime;
                double displayTime = p.Duration.TotalMilliseconds;
                if (!skip && displayTime < Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds)
                {
                    Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
                    Paragraph prev = subtitle.GetParagraphOrDefault(i - 1);
                    if (next == null || (p.StartTime.TotalMilliseconds + Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines) < next.StartTime.TotalMilliseconds)
                    {
                        var temp = new Paragraph(p) { EndTime = { TotalMilliseconds = p.StartTime.TotalMilliseconds + Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds } };
                        if (Utilities.GetCharactersPerSecond(temp) <= Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
                        {
                            if (callbacks.AllowFix(p, fixAction))
                            {
                                string oldCurrent = p.ToString();
                                p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds;
                                noOfShortDisplayTimes++;
                                callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                            }
                        }
                    }
                    else if (Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime && p.StartTime.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds &&
                             (prev == null || prev.EndTime.TotalMilliseconds < p.EndTime.TotalMilliseconds - Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines))
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            string oldCurrent = p.ToString();
                            if (next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines > p.EndTime.TotalMilliseconds)
                                p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
                            p.StartTime.TotalMilliseconds = p.EndTime.TotalMilliseconds - Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds;
                            noOfShortDisplayTimes++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else
                    {
                        callbacks.LogStatus(language.FixShortDisplayTimes, string.Format(language.UnableToFixTextXY, i + 1, p));
                        callbacks.AddToTotalErrors(1);
                        skip = true;
                    }
                }

                double charactersPerSecond = Utilities.GetCharactersPerSecond(p);
                if (!skip && charactersPerSecond > Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
                {
                    var temp = new Paragraph(p);
                    while (Utilities.GetCharactersPerSecond(temp) > Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
                    {
                        temp.EndTime.TotalMilliseconds++;
                    }
                    Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
                    Paragraph nextNext = subtitle.GetParagraphOrDefault(i + 2);
                    Paragraph prev = subtitle.GetParagraphOrDefault(i - 1);
                    double diffMs = temp.Duration.TotalMilliseconds - p.Duration.TotalMilliseconds;

                    // Normal - just make current subtitle duration longer
                    if (next == null || temp.EndTime.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines < next.StartTime.TotalMilliseconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            string oldCurrent = p.ToString();
                            p.EndTime.TotalMilliseconds = temp.EndTime.TotalMilliseconds;
                            noOfShortDisplayTimes++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    // Start current subtitle earlier (max 50 ms)
                    else if (Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime && p.StartTime.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds &&
                             diffMs < 50 && (prev == null || prev.EndTime.TotalMilliseconds < p.EndTime.TotalMilliseconds - temp.Duration.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines))
                    {
                        noOfShortDisplayTimes = MoveStartTime(fixAction, noOfShortDisplayTimes, p, temp, next);
                    }
                    // Make current subtitle duration longer + move next subtitle
                    else if (diffMs < 1000 &&
                             Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime &&
                             p.StartTime.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds &&
                             (nextNext == null || next.EndTime.TotalMilliseconds + diffMs + Configuration.Settings.General.MinimumMillisecondsBetweenLines * 2 < nextNext.StartTime.TotalMilliseconds))
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            string oldCurrent = p.ToString();
                            p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + temp.Duration.TotalMilliseconds;
                            var nextDurationMs = next.Duration.TotalMilliseconds;
                            next.StartTime.TotalMilliseconds = p.EndTime.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines;
                            next.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds + nextDurationMs;
                            noOfShortDisplayTimes++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    // Make next subtitle duration shorter + make current subtitle duration longer
                    else if (diffMs < 1000 &&
                             Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime && Utilities.GetCharactersPerSecond(new Paragraph(next.Text, p.StartTime.TotalMilliseconds + temp.Duration.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines, next.EndTime.TotalMilliseconds)) < Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            string oldCurrent = p.ToString();
                            next.StartTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + temp.Duration.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines;
                            p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
                            noOfShortDisplayTimes++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    // Make next-next subtitle duration shorter + move next + make current subtitle duration longer
                    else if (diffMs < 500 &&
                             Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime && nextNext != null &&
                             Utilities.GetCharactersPerSecond(new Paragraph(nextNext.Text, nextNext.StartTime.TotalMilliseconds + diffMs + Configuration.Settings.General.MinimumMillisecondsBetweenLines, nextNext.EndTime.TotalMilliseconds - (diffMs))) < Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            string oldCurrent = p.ToString();
                            p.EndTime.TotalMilliseconds += diffMs;
                            next.StartTime.TotalMilliseconds += diffMs;
                            next.EndTime.TotalMilliseconds += diffMs;
                            nextNext.StartTime.TotalMilliseconds += diffMs;
                            noOfShortDisplayTimes++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    // Start current subtitle earlier (max 200 ms)
                    else if (Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime && p.StartTime.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds &&
                             diffMs < 200 && (prev == null || prev.EndTime.TotalMilliseconds < p.EndTime.TotalMilliseconds - temp.Duration.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines))
                    {
                        noOfShortDisplayTimes = MoveStartTime(fixAction, noOfShortDisplayTimes, p, temp, next);
                    }
                    else
                    {
                        // move some... though not enough
                        var improvedEndtime = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
                        if (improvedEndtime > p.EndTime.TotalMilliseconds)
                        {
                            if (callbacks.AllowFix(p, fixAction))
                            {
                                string oldCurrent = p.ToString();
                                p.EndTime.TotalMilliseconds = improvedEndtime;
                                noOfShortDisplayTimes++;
                                callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                            }
                        }

                        callbacks.LogStatus(language.FixShortDisplayTimes, string.Format(language.UnableToFixTextXY, i + 1, p));
                        callbacks.AddToTotalErrors(1);
                    }
                }
            }
            callbacks.UpdateFixStatus(noOfShortDisplayTimes, fixAction, string.Format(language.XDisplayTimesProlonged, noOfShortDisplayTimes));
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixMissingPeriodAtEndOfLine;
            int missigPeriodsAtEndOfLine = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
                string nextText = string.Empty;
                if (next != null)
                {
                    nextText = HtmlUtil.RemoveHtmlTags(next.Text, true).TrimStart('-', '"', '„').TrimStart();
                }
                bool isNextClose = next != null && next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds < 400;
                string tempNoHtml = HtmlUtil.RemoveHtmlTags(p.Text).TrimEnd();

                if (IsOneLineUrl(p.Text) || p.Text.Contains(ExpectedChars) || p.Text.EndsWith('\''))
                {
                    // ignore urls
                }
                else if (!string.IsNullOrEmpty(nextText) && next != null &&
                    next.Text.Length > 0 &&
                    Utilities.UppercaseLetters.Contains(nextText[0]) &&
                    tempNoHtml.Length > 0 &&
                    !ExpectedString1.Contains(tempNoHtml[tempNoHtml.Length - 1]))
                {
                    string tempTrimmed = tempNoHtml.TrimEnd().TrimEnd('\'', '"', '“', '”').TrimEnd();
                    if (tempTrimmed.Length > 0 && !ExpectedString2.Contains(tempTrimmed[tempTrimmed.Length - 1]) && p.Text != p.Text.ToUpper())
                    {
                        //don't end the sentence if the next word is an I word as they're always capped.
                        bool isNextCloseAndStartsWithI = isNextClose && (nextText.StartsWith("I ", StringComparison.Ordinal) ||
                                                                         nextText.StartsWith("I'", StringComparison.Ordinal));

                        if (!isNextCloseAndStartsWithI)
                        {
                            //test to see if the first word of the next line is a name
                            if (!callbacks.IsName(next.Text.Split(WordSplitChars)[0]) && callbacks.AllowFix(p, fixAction))
                            {
                                string oldText = p.Text;
                                if (p.Text.EndsWith('>'))
                                {
                                    int lastLessThan = p.Text.LastIndexOf('<');
                                    if (lastLessThan > 0)
                                        p.Text = p.Text.Insert(lastLessThan, ".");
                                }
                                else
                                {
                                    if (p.Text.EndsWith('“') && tempNoHtml.StartsWith('„'))
                                        p.Text = p.Text.TrimEnd('“') + ".“";
                                    else if (p.Text.EndsWith('"') && tempNoHtml.StartsWith('"'))
                                        p.Text = p.Text.TrimEnd('"') + ".\"";
                                    else
                                        p.Text += ".";
                                }
                                if (p.Text != oldText)
                                {
                                    missigPeriodsAtEndOfLine++;
                                    callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                                }
                            }
                        }
                    }
                }
                else if (next != null && !string.IsNullOrEmpty(p.Text) && Utilities.AllLettersAndNumbers.Contains(p.Text[p.Text.Length - 1]))
                {
                    if (p.Text != p.Text.ToUpper())
                    {
                        var st = new StripableText(next.Text);
                        if (st.StrippedText.Length > 0 && st.StrippedText != st.StrippedText.ToUpper() &&
                            Utilities.UppercaseLetters.Contains(st.StrippedText[0]))
                        {
                            if (callbacks.AllowFix(p, fixAction))
                            {
                                int j = p.Text.Length - 1;
                                while (j >= 0 && !@".!?¿¡".Contains(p.Text[j]))
                                    j--;
                                string endSign = ".";
                                if (j >= 0 && p.Text[j] == '¿')
                                    endSign = "?";
                                if (j >= 0 && p.Text[j] == '¡')
                                    endSign = "!";

                                string oldText = p.Text;
                                missigPeriodsAtEndOfLine++;
                                p.Text += endSign;
                                callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                            }
                        }
                    }
                }

                if (p.Text.Length > 4)
                {
                    int indexOfNewLine = p.Text.IndexOf(Environment.NewLine + " -", 3, StringComparison.Ordinal);
                    if (indexOfNewLine < 0)
                        indexOfNewLine = p.Text.IndexOf(Environment.NewLine + "-", 3, StringComparison.Ordinal);
                    if (indexOfNewLine < 0)
                        indexOfNewLine = p.Text.IndexOf(Environment.NewLine + "<i>-", 3, StringComparison.Ordinal);
                    if (indexOfNewLine < 0)
                        indexOfNewLine = p.Text.IndexOf(Environment.NewLine + "<i> -", 3, StringComparison.Ordinal);
                    if (indexOfNewLine > 0 && Configuration.Settings.General.UppercaseLetters.Contains(char.ToUpper(p.Text[indexOfNewLine - 1])) && callbacks.AllowFix(p, fixAction))
                    {
                        string oldText = p.Text;

                        string text = p.Text.Substring(0, indexOfNewLine);
                        var st = new StripableText(text);
                        if (st.Pre.TrimEnd().EndsWith('¿')) // Spanish ¿
                            p.Text = p.Text.Insert(indexOfNewLine, "?");
                        else if (st.Pre.TrimEnd().EndsWith('¡')) // Spanish ¡
                            p.Text = p.Text.Insert(indexOfNewLine, "!");
                        else
                            p.Text = p.Text.Insert(indexOfNewLine, ".");

                        missigPeriodsAtEndOfLine++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(missigPeriodsAtEndOfLine, language.AddPeriods, language.XPeriodsAdded);
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.StartWithUppercaseLetterAfterPeriodInsideParagraph;
            int noOfFixes = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                string oldText = p.Text;
                var st = new StripableText(p.Text);
                if (p.Text.Length > 3)
                {
                    string text = st.StrippedText.Replace("  ", " ");
                    int start = text.IndexOfAny(ExpectedChars);
                    while (start >= 0 && start < text.Length)
                    {
                        if (start > 0 && char.IsDigit(text[start - 1]))
                        {
                            // ignore periods after a number
                        }
                        else if (start + 4 < text.Length && text[start + 1] == ' ')
                        {
                            if (!IsAbbreviation(text, start, callbacks))
                            {
                                var subText = new StripableText(text.Substring(start + 2));
                                if (subText.StrippedText.Length > 0 && Helper.IsTurkishLittleI(subText.StrippedText[0], callbacks.Encoding, callbacks.Language))
                                {
                                    if (subText.StrippedText.Length > 1 && !(subText.Pre.Contains('\'') && subText.StrippedText.StartsWith('s')))
                                    {
                                        text = text.Substring(0, start + 2) + subText.Pre + Helper.GetTurkishUppercaseLetter(subText.StrippedText[0], callbacks.Encoding) + subText.StrippedText.Substring(1) + subText.Post;
                                        if (callbacks.AllowFix(p, fixAction))
                                        {
                                            p.Text = st.Pre + text + st.Post;
                                        }
                                    }
                                }
                                else if (subText.StrippedText.Length > 0 && Configuration.Settings.General.UppercaseLetters.Contains(char.ToUpper(subText.StrippedText[0])))
                                {
                                    if (subText.StrippedText.Length > 1 && !(subText.Pre.Contains('\'') && subText.StrippedText.StartsWith('s')))
                                    {
                                        text = text.Substring(0, start + 2) + subText.Pre + char.ToUpper(subText.StrippedText[0]) + subText.StrippedText.Substring(1) + subText.Post;
                                        if (callbacks.AllowFix(p, fixAction))
                                        {
                                            p.Text = st.Pre + text + st.Post;
                                        }
                                    }
                                }
                            }
                        }
                        start += 4;
                        if (start < text.Length)
                            start = text.IndexOfAny(ExpectedChars, start);
                    }
                }

                if (oldText != p.Text)
                {
                    noOfFixes++;
                    callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                }
            }
            callbacks.UpdateFixStatus(noOfFixes, language.StartWithUppercaseLetterAfterPeriodInsideParagraph, noOfFixes.ToString(CultureInfo.InvariantCulture));
        }
Example #40
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var twoLetterLanguageCode = callbacks.Language;
            var noOfFixes             = 0;

            foreach (var p in subtitle.Paragraphs)
            {
                var oldText = p.Text;
                var text    = p.Text
                              .Normalize()

                              .Replace('\u00a0', ' ')          // replace non-break-space (160 decimal) ascii char with normal space
                              .Replace("\u200B", string.Empty) // Zero Width Space
                              .Replace("\uFEFF", string.Empty) // Zero Width No-Break Space

                              .Replace('\u02F8', ':')          // ˸ Modifier Letter Raised Colon (\u02F8)
                              .Replace('\uFF1A', ':')          // : Fullwidth Colon (\uFF1A)
                              .Replace('\uFE13', ':')          // ︓ Presentation Form for Vertical Colon (\uFE13)

                              .Replace('\u2043', '-')          // ⁃ Hyphen bullet (\u2043)
                              .Replace('\u2010', '-')          // ‐ Hyphen (\u2010)
                              .Replace('\u2012', '-')          // ‒ Figure dash (\u2012)
                              .Replace('\u2013', '-')          // – En dash (\u2013)
                                                               //.Replace('\u2014', '-') // — Em dash (\u2014) - we keep em dash
                              .Replace('\u2015', '\u2014')     // ― Horizontal bar (\u2015)
                ;

                var cyrillicLanguages = new[] { "ru" };
                if (!cyrillicLanguages.Contains(twoLetterLanguageCode))
                {
                    text = text
                           .Replace('\u0435', 'e')  // Cyrillic Small Letter Ie: "е"
                    ;
                }

                if (twoLetterLanguageCode != "el")
                {
                    text = text
                           .Replace("\u03a4", "T")  // Greek Capital Letter Tau
                           .Replace("\u03a5", "Y")  // Greek Capital Letter Upsilon
                           .Replace("\u03b3", "Y")  // Greek Small Letter Gamma
                           .Replace("\u03a7", "X")  // Greek Capital Letter Chi
                           .Replace("\u03ba", "k")  // Greek Small Letter Kappa
                           .Replace("\u03bd", "v")  // Greek Small Letter Nu
                           .Replace("\u03c1", "p")  // Greek Small Letter Rho
                           .Replace("\u03c5", "u")  // Greek Small Letter Upsilon
                           .Replace("\u039c", "M")  // Greek Capital Letter Mu
                           .Replace("\u039a", "K")  // Greek Capital Letter Kappa
                           .Replace("\u039d", "N")  // Greek Capital Letter Nu
                           .Replace("\u039f", "O")  // Greek Capital Letter Omicron
                           .Replace("\u03a1", "P")  // Greek Capital Letter Rho
                           .Replace("\u0395", "E")  // Greek Capital Letter Epsilon
                           .Replace("\u0396", "Z")  // Greek Capital Letter Zeta
                           .Replace("\u0397", "H")  // Greek Capital Letter Eta
                           .Replace("\u0384", "'")  // Greek Tonos
                           .Replace("\u0392", "B")  // Greek Capital Letter Beta
                           .Replace("\u0391", "A")  // Greek Capital Letter Alpha
                           .Replace("\u03bf", "o")  // Greek small letter Omicron
                    ;
                }

                if (oldText != text && callbacks.AllowFix(p, Language.NormalizeStrings))
                {
                    p.Text = text;
                    noOfFixes++;
                    callbacks.AddFixToListView(p, Language.NormalizeStrings, oldText, p.Text);
                }
            }
            callbacks.UpdateFixStatus(noOfFixes, Language.NormalizeStrings);
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    l         = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = l.FixUppercaseIInsideLowercaseWord;
            var    language  = callbacks.Language;
            int    uppercaseIsInsideLowercaseWords = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p       = subtitle.Paragraphs[i];
                string    oldText = p.Text;
                var       st      = new StrippableText(p.Text);

                Match match = ReAfterLowercaseLetter.Match(st.StrippedText);
                while (match.Success)
                {
                    if (!(match.Index > 1 && st.StrippedText.Substring(match.Index - 1, 2) == "Mc") && // irish names, McDonalds etc.
                        st.StrippedText[match.Index + 1] == 'I' &&
                        callbacks.AllowFix(p, fixAction))
                    {
                        string word = GetWholeWord(st.StrippedText, match.Index);
                        if (!callbacks.IsName(word))
                        {
                            var old = st.StrippedText;
                            st.StrippedText = st.StrippedText.Substring(0, match.Index + 1) + "l";
                            if (match.Index + 2 < old.Length)
                            {
                                st.StrippedText += old.Substring(match.Index + 2);
                            }

                            p.Text = st.MergedString;

                            st = new StrippableText(p.Text);
                            uppercaseIsInsideLowercaseWords++;
                            callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                            match = ReAfterLowercaseLetter.Match(st.StrippedText, match.Index);
                        }
                        else
                        {
                            match = match.NextMatch();
                        }
                    }
                    else
                    {
                        match = match.NextMatch();
                    }
                }

                match = ReBeforeLowercaseLetter.Match(st.StrippedText);
                while (match.Success)
                {
                    string word = GetWholeWord(st.StrippedText, match.Index);
                    if (!callbacks.IsName(word))
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            if (language == "en" && word.EndsWith('s') &&
                                p.Text.Length > match.Index + 1 &&
                                word.TrimEnd('s') == word.TrimEnd('s').ToUpperInvariant())
                            {
                                // skip words like "MRIs" where the last 's' indicates plural
                            }
                            else
                            {
                                var before = st.StrippedText[match.Index];
                                var after  = '\0';
                                if (match.Index < st.StrippedText.Length - 3)
                                {
                                    after = st.StrippedText[match.Index + 2];
                                }

                                if (before != '\0' && char.IsUpper(before) && after != '\0' && char.IsLower(after) &&
                                    !Utilities.LowercaseVowels.Contains(char.ToLower(before)) && !Utilities.LowercaseVowels.Contains(after))
                                {
                                    st.StrippedText = st.StrippedText.Remove(match.Index + 1, 1).Insert(match.Index + 1, "i");
                                    p.Text          = st.MergedString;
                                    uppercaseIsInsideLowercaseWords++;
                                    callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                                }
                                else if (@"‘’¡¿„“()[]♪'. @".Contains(before) && !Utilities.LowercaseVowels.Contains(char.ToLower(after)))
                                {
                                }
                                else
                                {
                                    bool ok = !(match.Index >= 1 && st.StrippedText.Substring(match.Index - 1, 2) == "Mc");

                                    if (ok)
                                    {
                                        st.StrippedText = st.StrippedText.Remove(match.Index + 1, 1).Insert(match.Index + 1, "l");
                                        p.Text          = st.MergedString;
                                        uppercaseIsInsideLowercaseWords++;
                                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                                    }
                                }
                            }
                        }
                    }
                    match = match.NextMatch();
                }
            }
            callbacks.UpdateFixStatus(uppercaseIsInsideLowercaseWords, l.FixUppercaseIInsindeLowercaseWords, l.XUppercaseIsFoundInsideLowercaseWords);
        }
Example #42
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var          language  = Configuration.Settings.Language.FixCommonErrors;
            const string fixAction = "Fix Danish letter 'i'";
            int          fixCount  = 0;

            var littleIRegex = new Regex(@"\bi\b", RegexOptions.Compiled);

            var iList = new List <Regex>
            {                  // not a complete list, more phrases will come
                MyRegEx(@", i ved nok\b"),
                MyRegEx(@", i ved, "),
                MyRegEx(@", i ved."),
                MyRegEx(@", i ikke blev\b"),
                MyRegEx(@"\b i føler at\b"),
                MyRegEx(@"\badvarede i os\b"),
                MyRegEx(@"\badvarede i dem\b"),
                MyRegEx(@"\bat i aldrig\b"),
                MyRegEx(@"\bat i alle bliver\b"),
                MyRegEx(@"\bat i alle er\b"),
                MyRegEx(@"\bat i alle forventer\b"),
                MyRegEx(@"\bat i alle gør\b"),
                MyRegEx(@"\bat i alle har\b"),
                MyRegEx(@"\bat i alle ved\b"),
                MyRegEx(@"\bat i alle vil\b"),
                MyRegEx(@"\bat i bare\b"),
                MyRegEx(@"\bat i bager\b"),
                MyRegEx(@"\bat i bruger\b"),
                MyRegEx(@"\bat i dræber\b"),
                MyRegEx(@"\bat i dræbte\b"),
                MyRegEx(@"\bat i fandt\b"),
                MyRegEx(@"\bat i fik\b"),
                MyRegEx(@"\bat i finder\b"),
                MyRegEx(@"\bat i forstår\b"),
                MyRegEx(@"\bat i får\b"),
                MyRegEx(@"\b[Aa]t i hver især\b"),
                MyRegEx(@"\bAt i ikke\b"),
                MyRegEx(@"\bat i ikke\b"),
                MyRegEx(@"\bat i kom\b"),
                MyRegEx(@"\bat i kommer\b"),
                MyRegEx(@"\bat i næsten er\b"),
                MyRegEx(@"\bat i næsten fik\b"),
                MyRegEx(@"\bat i næsten har\b"),
                MyRegEx(@"\bat i næsten skulle\b"),
                MyRegEx(@"\bat i næsten var\b"),
                MyRegEx(@"\bat i også får\b"),
                MyRegEx(@"\bat i også gør\b"),
                MyRegEx(@"\bat i også mener\b"),
                MyRegEx(@"\bat i også siger\b"),
                MyRegEx(@"\bat i også tror\b"),
                MyRegEx(@"\bat i rev\b"),
                MyRegEx(@"\bat i river\b"),
                MyRegEx(@"\bat i samarbejder\b"),
                MyRegEx(@"\bat i snakkede\b"),
                MyRegEx(@"\bat i scorer\b"),
                MyRegEx(@"\bat i siger\b"),
                MyRegEx(@"\bat i skal\b"),
                MyRegEx(@"\bat i skulle\b"),
                MyRegEx(@"\bat i to ikke\b"),
                MyRegEx(@"\bat i to siger\b"),
                MyRegEx(@"\bat i to har\b"),
                MyRegEx(@"\bat i to er\b"),
                MyRegEx(@"\bat i to bager\b"),
                MyRegEx(@"\bat i to skal\b"),
                MyRegEx(@"\bat i to gør\b"),
                MyRegEx(@"\bat i to får\b"),
                MyRegEx(@"\bat i udnyttede\b"),
                MyRegEx(@"\bat i udnytter\b"),
                MyRegEx(@"\bat i vil\b"),
                MyRegEx(@"\bat i ville\b"),
                MyRegEx(@"\bBehandler i mig\b"),
                MyRegEx(@"\bbehandler i mig\b"),
                MyRegEx(@"\bbliver i rige\b"),
                MyRegEx(@"\bbliver i ikke\b"),
                MyRegEx(@"\bbliver i indkvarteret\b"),
                MyRegEx(@"\bbliver i indlogeret\b"),
                MyRegEx(@"\bburde i gøre\b"),
                MyRegEx(@"\bburde i ikke\b"),
                MyRegEx(@"\bburde i købe\b"),
                MyRegEx(@"\bburde i løbe\b"),
                MyRegEx(@"\bburde i se\b"),
                MyRegEx(@"\bburde i sige\b"),
                MyRegEx(@"\bburde i tage\b"),
                MyRegEx(@"\bDa i ankom\b"),
                MyRegEx(@"\bda i ankom\b"),
                MyRegEx(@"\bda i forlod\b"),
                MyRegEx(@"\bDa i forlod\b"),
                MyRegEx(@"\bda i fik\b"),
                MyRegEx(@"\bDa i fik\b"),
                MyRegEx(@"\bDa i gik\b"),
                MyRegEx(@"\bda i gik\b"),
                MyRegEx(@"\bda i kom\b"),
                MyRegEx(@"\bDa i kom\b"),
                MyRegEx(@"\bda i så "),
                MyRegEx(@"\bDa i så "),
                MyRegEx(@"\bdet får i\b"),
                MyRegEx(@"\bDet får i\b"),
                MyRegEx(@"\bDet har i\b"),
                MyRegEx(@"\bdet har i\b"),
                MyRegEx(@"\bDet må i "),
                MyRegEx(@"\bdet må i "),
                MyRegEx(@"\b[Dd]et Det kan i sgu"),
                MyRegEx(@"\bend i aner\b"),
                MyRegEx(@"\bend i tror\b"),
                MyRegEx(@"\bend i ved\b"),
                MyRegEx(@"\b, er i alle\b"),
                MyRegEx(@"\bellers får i "),
                MyRegEx(@"\bEr i alle\b"),
                MyRegEx(@"\ber i allerede\b"),
                MyRegEx(@"\bEr i allerede\b"),
                MyRegEx(@"\ber i allesammen\b"),
                MyRegEx(@"\bEr i allesammen\b"),
                MyRegEx(@"\ber i der\b"),
                MyRegEx(@"\bEr i der\b"),
                MyRegEx(@"\bEr i fra\b"),
                MyRegEx(@"\bEr i gennem\b"),
                MyRegEx(@"\ber i gennem\b"),
                MyRegEx(@"\ber i glade\b"),
                MyRegEx(@"\bEr i glade\b"),
                MyRegEx(@"\bEr i gået\b"),
                MyRegEx(@"\ber i gået\b"),
                MyRegEx(@"\ber i her\b"),
                MyRegEx(@"\bEr i her\b"),
                MyRegEx(@"\ber i imod\b"),
                MyRegEx(@"\bEr i imod\b"),
                MyRegEx(@"\ber i klar\b"),
                MyRegEx(@"\bEr i klar\b"),
                MyRegEx(@"\bEr i mætte\b"),
                MyRegEx(@"\ber i mætte\b"),
                MyRegEx(@"\bEr i med\b"),
                MyRegEx(@"\ber i med\b"),
                MyRegEx(@"\ber i mod\b"),
                MyRegEx(@"\bEr i mod\b"),
                MyRegEx(@"\ber i okay\b"),
                MyRegEx(@"\bEr i okay\b"),
                MyRegEx(@"\ber i på\b"),
                MyRegEx(@"\bEr i på\b"),
                MyRegEx(@"\bEr i parate\b"),
                MyRegEx(@"\ber i parate\b"),
                MyRegEx(@"\ber i sikker\b"),
                MyRegEx(@"\bEr i sikker\b"),
                MyRegEx(@"\bEr i sikre\b"),
                MyRegEx(@"\ber i sikre\b"),
                MyRegEx(@"\ber i skøre\b"),
                MyRegEx(@"\bEr i skøre\b"),
                MyRegEx(@"\ber i stadig\b"),
                MyRegEx(@"\bEr i stadig\b"),
                MyRegEx(@"\bEr i sultne\b"),
                MyRegEx(@"\ber i sultne\b"),
                MyRegEx(@"\bEr i tilfredse\b"),
                MyRegEx(@"\ber i tilfredse\b"),
                MyRegEx(@"\bEr i to\b"),
                MyRegEx(@"\ber i ved at\b"),
                MyRegEx(@"\ber i virkelig\b"),
                MyRegEx(@"\bEr i virkelig\b"),
                MyRegEx(@"\bEr i vågne\b"),
                MyRegEx(@"\ber i vågne\b"),
                MyRegEx(@"\bfanden vil i?"),
                MyRegEx(@"\bfor ser i\b"),
                MyRegEx(@"\bFor ser i\b"),
                MyRegEx(@"\bFordi i ventede\b"),
                MyRegEx(@"\bfordi i ventede\b"),
                MyRegEx(@"\bFordi i deltog\b"),
                MyRegEx(@"\bfordi i deltog\b"),
                MyRegEx(@"\bforhandler i stadig\b"),
                MyRegEx(@"\bForhandler i stadig\b"),
                MyRegEx(@"\bforstår i\b"),
                MyRegEx(@"\bForstår i\b"),
                MyRegEx(@"\bFør i får\b"),
                MyRegEx(@"\bfør i får\b"),
                MyRegEx(@"\bFør i kommer\b"),
                MyRegEx(@"\bfør i kommer\b"),
                MyRegEx(@"\bFør i tager\b"),
                MyRegEx(@"\bfør i tager\b"),
                MyRegEx(@"\bfår i alle\b"),
                MyRegEx(@"\bfår i fratrukket\b"),
                MyRegEx(@"\bfår i ikke\b"),
                MyRegEx(@"\bfår i klø\b"),
                MyRegEx(@"\bfår i point\b"),
                MyRegEx(@"\bgider i at\b"),
                MyRegEx(@"\bGider i at\b"),
                MyRegEx(@"\bGider i ikke\b"),
                MyRegEx(@"\bgider i ikke\b"),
                MyRegEx(@"\bgider i lige\b"),
                MyRegEx(@"\bGider i lige\b"),
                MyRegEx(@"\b[Gg]ik i lige\b"),
                MyRegEx(@"\b[Gg]ik i hjem\b"),
                MyRegEx(@"\b[Gg]ik i over\b"),
                MyRegEx(@"\b[Gg]ik i forbi\b"),
                MyRegEx(@"\b[Gg]ik i ind\b"),
                MyRegEx(@"\b[Gg]ik i uden\b"),
                MyRegEx(@"\bGjorde i det\b"),
                MyRegEx(@"\bGjorde i det\b"),
                MyRegEx(@"\bgjorde i ikke\b"),
                MyRegEx(@"\bGider i godt\b"),
                MyRegEx(@"\bgider i godt\b"),
                MyRegEx(@"\bGider i ikke\b"),
                MyRegEx(@"\bgider i ikke\b"),
                MyRegEx(@"\b[Gg]iver i mig\b"),
                MyRegEx(@"\bglor i på\b"),
                MyRegEx(@"\bGlor i på\b"),
                MyRegEx(@"\b[Gg]lor i allesammen på\b"),
                MyRegEx(@"\b[Gg]lor i alle på\b"),
                MyRegEx(@"\bGår i ind\b"),
                MyRegEx(@"\bgår i ind\b"),
                MyRegEx(@"\b[Gg]å i bare\b"),
                MyRegEx(@"\bHørte i det\b"),
                MyRegEx(@"\bhørte i det\b"),
                MyRegEx(@"\bHar i \b"),
                MyRegEx(@"\bhar i ødelagt\b"),
                MyRegEx(@"\bhar i fået\b"),
                MyRegEx(@"\bHar i fået\b"),
                MyRegEx(@"\bHar i det\b"),
                MyRegEx(@"\bhar i det\b"),
                MyRegEx(@"\bhar i gjort\b"),
                MyRegEx(@"\bhar i ikke\b"),
                MyRegEx(@"\bHar i nogen\b"),
                MyRegEx(@"\bhar i nogen\b"),
                MyRegEx(@"\bHar i nok\b"),
                MyRegEx(@"\bhar i nok\b"),
                MyRegEx(@"\bhar i ordnet\b"),
                MyRegEx(@"\bHar i ordnet\b"),
                MyRegEx(@"\bhar i spist\b"),
                MyRegEx(@"\bHar i spist\b"),
                MyRegEx(@"\bhar i tænkt\b"),
                MyRegEx(@"\bhar i tabt\b"),
                MyRegEx(@"\bhelvede vil i?"),
                MyRegEx(@"\bHer har i\b"),
                MyRegEx(@"\bher har i\b"),
                MyRegEx(@"\b[Hh]older i fast\b"),
                MyRegEx(@"\b[Hh]older i godt fast\b"),
                MyRegEx(@"\bHvad fanden har i\b"),
                MyRegEx(@"\bhvad fanden har i\b"),
                MyRegEx(@"\bHvad fanden tror i\b"),
                MyRegEx(@"\bhvad fanden tror i\b"),
                MyRegEx(@"\bhvad fanden vil i\b"),
                MyRegEx(@"\bHvad fanden vil i\b"),
                MyRegEx(@"\bHvad gør i\b"),
                MyRegEx(@"\bhvad gør i\b"),
                MyRegEx(@"\bhvad har i\b"),
                MyRegEx(@"\bHvad har i\b"),
                MyRegEx(@"\bHvad i ikke\b"),
                MyRegEx(@"\bhvad i ikke\b"),
                MyRegEx(@"\b[Hh]vad laver i\b"),
                MyRegEx(@"\b[Hh]vad lavede i\b"),
                MyRegEx(@"\b[Hh]vad mener i\b"),
                MyRegEx(@"\b[Hh]vad siger i\b"),
                MyRegEx(@"\b[Hh]vad skal i\b"),
                MyRegEx(@"\b[Hh]vad snakker i\b"),
                MyRegEx(@"\b[Hh]vad sløver i\b"),
                MyRegEx(@"\b[Hh]vad synes i\b"),
                MyRegEx(@"\b[Hh]vad vil i\b"),
                MyRegEx(@"\b[Hh]vem er i\b"),
                MyRegEx(@"\b[Hh]vem fanden tror i\b"),
                MyRegEx(@"\b[Hh]vem tror i\b"),
                MyRegEx(@"\b[Hh]vilken slags mennesker er i?"),
                MyRegEx(@"\b[Hh]vilken slags folk er i?"),
                MyRegEx(@"\b[Hh]vis i altså\b"),
                MyRegEx(@"\b[Hh]vis i bare\b"),
                MyRegEx(@"\b[Hh]vis i forstår\b"),
                MyRegEx(@"\b[Hh]vis i får\b"),
                MyRegEx(@"\b[Hh]vis i går\b"),
                MyRegEx(@"\b[Hh]vis i ikke\b"),
                MyRegEx(@"\b[Hh]vis i lovede\b"),
                MyRegEx(@"\b[Hh]vis i lover\b"),
                MyRegEx(@"\b[Hh]vis i overholder\b"),
                MyRegEx(@"\b[Hh]vis i overtræder\b"),
                MyRegEx(@"\b[Hh]vis i slipper\b"),
                MyRegEx(@"\b[Hh]vis i taber\b"),
                MyRegEx(@"\b[Hh]vis i vandt\b"),
                MyRegEx(@"\b[Hh]vis i vinder\b"),
                MyRegEx(@"\b[Hh]vor er i\b"),
                MyRegEx(@"\b[Hh]vor får i\b"),
                MyRegEx(@"\b[Hh]vor gamle er i\b"),
                MyRegEx(@"\b[Hh]vor i begyndte\b"),
                MyRegEx(@"\b[Hh]vor i startede\b"),
                MyRegEx(@"\b[Hh]vor skal i\b"),
                MyRegEx(@"\b[Hh]vor var i\b"),
                MyRegEx(@"\b[Hh]vordan har i\b"),
                MyRegEx(@"\b[Hh]vordan hørte i\b"),
                MyRegEx(@"\b[Hh]vordan i når\b"),
                MyRegEx(@"\b[Hh]vordan i nåede\b"),
                MyRegEx(@"\b[Hh]vordan kunne i\b"),
                MyRegEx(@"\b[Hh]vorfor afleverer i det\b"),
                MyRegEx(@"\b[Hh]vorfor gør i "),
                MyRegEx(@"\b[Hh]vorfor gjorde i "),
                MyRegEx(@"\b[Hh]vorfor græder i "),
                MyRegEx(@"\b[Hh]vorfor har i "),
                MyRegEx(@"\b[Hh]vorfor kom i "),
                MyRegEx(@"\b[Hh]vorfor kommer i "),
                MyRegEx(@"\b[Hh]vorfor løb i "),
                MyRegEx(@"\b[Hh]vorfor lover i "),
                MyRegEx(@"\b[Hh]vorfor lovede i "),
                MyRegEx(@"\b[Hh]vorfor skal i\b"),
                MyRegEx(@"\b[Hh]vorfor skulle i\b"),
                MyRegEx(@"\b[Hh]vorfor sagde i\b"),
                MyRegEx(@"\b[Hh]vorfor synes i\b"),
                MyRegEx(@"\b[Hh]vornår gør i "),
                MyRegEx(@"\bHvornår kom i\b"),
                MyRegEx(@"\b[Hh]vornår ville i "),
                MyRegEx(@"\b[Hh]vornår giver i "),
                MyRegEx(@"\b[Hh]vornår gav i "),
                MyRegEx(@"\b[Hh]vornår rejser i\b"),
                MyRegEx(@"\b[Hh]vornår rejste i\b"),
                MyRegEx(@"\b[Hh]vornår skal i "),
                MyRegEx(@"\b[Hh]vornår skulle i "),
                MyRegEx(@"\b[Hh]ører i på\b"),
                MyRegEx(@"\b[Hh]ørte i på\b"),
                MyRegEx(@"\b[Hh]ører i,\b"),
                MyRegEx(@"\b[Hh]ører i ikke\b"),
                MyRegEx(@"\bi altid\b"),
                MyRegEx(@"\bi ankomme\b"),
                MyRegEx(@"\bi ankommer\b"),
                MyRegEx(@"\bi bare kunne\b"),
                MyRegEx(@"\bi bare havde\b"),
                MyRegEx(@"\bi bare gjorde\b"),
                MyRegEx(@"\bi begge er\b"),
                MyRegEx(@"\bi begge gør\b"),
                MyRegEx(@"\bi begge har\b"),
                MyRegEx(@"\bi begge var\b"),
                MyRegEx(@"\bi begge vil\b"),
                MyRegEx(@"\bi behøver ikke gemme\b"),
                MyRegEx(@"\bi behøver ikke prøve\b"),
                MyRegEx(@"\bi behøver ikke skjule\b"),
                MyRegEx(@"\bi behandlede\b"),
                MyRegEx(@"\bi behandler\b"),
                MyRegEx(@"\bi beskidte dyr\b"),
                MyRegEx(@"\bi blev\b"),
                MyRegEx(@"\bi blive\b"),
                MyRegEx(@"\bi bliver\b"),
                MyRegEx(@"\bi burde\b"),
                MyRegEx(@"\bi er\b"),
                MyRegEx(@"\bi fyrer af\b"),
                MyRegEx(@"\bi gør\b"),
                MyRegEx(@"\bi gav\b"),
                MyRegEx(@"\bi gerne "),
                MyRegEx(@"\bi giver\b"),
                MyRegEx(@"\bi gjorde\b"),
                MyRegEx(@"\bi hører\b"),
                MyRegEx(@"\bi hørte\b"),
                MyRegEx(@"\bi har\b"),
                MyRegEx(@"\bi havde\b"),
                MyRegEx(@"\bi igen bliver\b"),
                MyRegEx(@"\bi igen burde\b"),
                MyRegEx(@"\bi igen finder\b"),
                MyRegEx(@"\bi igen gør\b"),
                MyRegEx(@"\bi igen kommer\b"),
                MyRegEx(@"\bi igen prøver\b"),
                MyRegEx(@"\bi igen siger\b"),
                MyRegEx(@"\bi igen skal\b"),
                MyRegEx(@"\bi igen vil\b"),
                MyRegEx(@"\bi ikke gerne\b"),
                MyRegEx(@"\bi ikke kan\b"),
                MyRegEx(@"\bi ikke kommer\b"),
                MyRegEx(@"\bi ikke vil\b"),
                MyRegEx(@"\bi kan\b"),
                MyRegEx(@"\bi kender\b"),
                MyRegEx(@"\bi kom\b"),
                MyRegEx(@"\bi komme\b"),
                MyRegEx(@"\bi kommer\b"),
                MyRegEx(@"\bi kunne\b"),
                MyRegEx(@"\bi morer jer\b"),
                MyRegEx(@"\bi må gerne\b"),
                MyRegEx(@"\bi må give\b"),
                MyRegEx(@"\bi må da\b"),
                MyRegEx(@"\bi nåede\b"),
                MyRegEx(@"\bi når\b"),
                MyRegEx(@"\bi prøve\b"),
                MyRegEx(@"\bi prøvede\b"),
                MyRegEx(@"\bi prøver\b"),
                MyRegEx(@"\bi sagde\b"),
                MyRegEx(@"\bi scorede\b"),
                MyRegEx(@"\bi ser\b"),
                MyRegEx(@"\bi set\b"),
                MyRegEx(@"\bi siger\b"),
                MyRegEx(@"\bi sikkert alle\b"),
                MyRegEx(@"\bi sikkert ikke gør\b"),
                MyRegEx(@"\bi sikkert ikke kan\b"),
                MyRegEx(@"\bi sikkert ikke vil\b"),
                MyRegEx(@"\bi skal\b"),
                MyRegEx(@"\bi skulle\b"),
                MyRegEx(@"\bi små stakler\b"),
                MyRegEx(@"\bi stopper\b"),
                MyRegEx(@"\bi synes\b"),
                MyRegEx(@"\bi troede\b"),
                MyRegEx(@"\bi tror\b"),
                MyRegEx(@"\bi var\b"),
                MyRegEx(@"\bi vel ikke\b"),
                MyRegEx(@"\bi vil\b"),
                MyRegEx(@"\bi ville\b"),
                MyRegEx(@"\b[Kk]an i lugte\b"),
                MyRegEx(@"\b[Kk]an i overleve\b"),
                MyRegEx(@"\b[Kk]an i spise\b"),
                MyRegEx(@"\b[Kk]an i se\b"),
                MyRegEx(@"\b[Kk]an i smage\b"),
                MyRegEx(@"\b[Kk]an i forstå\b"),
                MyRegEx(@"\b[Kk]ørte i hele\b"),
                MyRegEx(@"\b[Kk]ørte i ikke\b"),
                MyRegEx(@"\b[Kk]an i godt\b"),
                MyRegEx(@"\b[Kk]an i gøre\b"),
                MyRegEx(@"\b[Kk]an i huske\b"),
                MyRegEx(@"\b[Kk]an i ikke\b"),
                MyRegEx(@"\b[Kk]an i lide\b"),
                MyRegEx(@"\b[Kk]an i leve\b"),
                MyRegEx(@"\b[Kk]an i love\b"),
                MyRegEx(@"\b[Kk]an i måske\b"),
                MyRegEx(@"\b[Kk]an i nok\b"),
                MyRegEx(@"\b[Kk]an i se\b"),
                MyRegEx(@"\b[Kk]an i sige\b"),
                MyRegEx(@"\b[Kk]an i tilgive\b"),
                MyRegEx(@"\b[Kk]an i tygge\b"),
                MyRegEx(@"\b[Kk]an i to ikke\b"),
                MyRegEx(@"\b[Kk]an i tro\b"),
                MyRegEx(@"\bKender i "),
                MyRegEx(@"\b[Kk]ender i hinanden\b"),
                MyRegEx(@"\b[Kk]ender i to hinanden\b"),
                MyRegEx(@"\bKendte i \b"),
                MyRegEx(@"\b[Kk]endte i hinanden\b"),
                MyRegEx(@"\b[Kk]iggede i på\b"),
                MyRegEx(@"\b[Kk]igger i på\b"),
                MyRegEx(@"\b[Kk]ommer i her\b"),
                MyRegEx(@"\b[Kk]ommer i ofte\b"),
                MyRegEx(@"\b[Kk]ommer i sammen\b"),
                MyRegEx(@"\b[Kk]ommer i tit\b"),
                MyRegEx(@"\b[Kk]unne i fortælle\b"),
                MyRegEx(@"\b[Kk]unne i give\b"),
                MyRegEx(@"\b[Kk]unne i gøre\b"),
                MyRegEx(@"\b[Kk]unne i ikke\b"),
                MyRegEx(@"\b[Kk]unne i lide\b"),
                MyRegEx(@"\b[Kk]unne i mødes\b"),
                MyRegEx(@"\b[Kk]unne i se\b"),
                MyRegEx(@"\b[Ll]eder i efter\b"),
                MyRegEx(@"\b[Ll]aver i ikke\b"),
                MyRegEx(@"\blaver i her\b"),
                MyRegEx(@"\b[Ll]igner i far\b"),
                MyRegEx(@"\b[Ll]igner i hinanden\b"),
                MyRegEx(@"\b[Ll]igner i mor\b"),
                MyRegEx(@"\bLover i\b"),
                MyRegEx(@"\b[Ll]ykkes i med\b"),
                MyRegEx(@"\b[Ll]ykkedes i med\b"),
                MyRegEx(@"\b[Ll]øb i hellere\b"),
                MyRegEx(@"\b[Mm]ødte i "),
                MyRegEx(@"\b[Mm]angler i en\b"),
                MyRegEx(@"\b[Mm]en i gutter\b"),
                MyRegEx(@"\b[Mm]en i drenge\b"),
                MyRegEx(@"\b[Mm]en i fyre\b"),
                MyRegEx(@"\b[Mm]en i står\b"),
                MyRegEx(@"\b[Mm]ener i at\b"),
                MyRegEx(@"\b[Mm]ener i det\b"),
                MyRegEx(@"\b[Mm]ener i virkelig\b"),
                MyRegEx(@"\b[Mm]ens i sov\b"),
                MyRegEx(@"\b[Mm]ens i stadig\b"),
                MyRegEx(@"\b[Mm]ens i lå\b"),
                MyRegEx(@"\b[Mm]ister i point\b"),
                MyRegEx(@"\b[Mm]orer i jer\b"),
                MyRegEx(@"\b[Mm]å i alle"),
                MyRegEx(@"\b[Mm]å i gerne"),
                MyRegEx(@"\b[Mm]å i godt\b"),
                MyRegEx(@"\b[Mm]å i vide\b"),
                MyRegEx(@"\b[Mm]å i ikke"),
                MyRegEx(@"\b[Nn]u løber i\b"),
                MyRegEx(@"\b[Nn]u siger i\b"),
                MyRegEx(@"\b[Nn]u skal i\b"),
                MyRegEx(@"\b[Nn]år i\b"),
                MyRegEx(@"\b[Oo]m i ikke\b"),
                MyRegEx(@"\b[Oo]pgiver i\b"),
                MyRegEx(@"\b[Oo]vergiver i jer\b"),
                MyRegEx(@"\bpersoner i lukker\b"),
                MyRegEx(@"\b[Pp]as på i ikke\b"),
                MyRegEx(@"\b[Pp]as på i ikke\b"),
                MyRegEx(@"\b[Pp]å i ikke\b"),
                MyRegEx(@"\b[Pp]å at i ikke\b"),
                MyRegEx(@"\b[Ss]agde i ikke\b"),
                MyRegEx(@"\b[Ss]amlede i ham\b"),
                MyRegEx(@"\bSer i\b"),
                MyRegEx(@"\bSiger i\b"),
                MyRegEx(@"\b[Ss]ikker på i ikke\b"),
                MyRegEx(@"\b[Ss]ikre på i ikke\b"),
                MyRegEx(@"\b[Ss]kal i alle\b"),
                MyRegEx(@"\b[Ss]kal i allesammen\b"),
                MyRegEx(@"\b[Ss]kal i begge dø\b"),
                MyRegEx(@"\b[Ss]kal i bare\b"),
                MyRegEx(@"\b[Ss]kal i dele\b"),
                MyRegEx(@"\b[Ss]kal i dø\b"),
                MyRegEx(@"\b[Ss]kal i fordele\b"),
                MyRegEx(@"\b[Ss]kal i fordeles\b"),
                MyRegEx(@"\b[Ss]kal i fortælle\b"),
                MyRegEx(@"\b[Ss]kal i gøre\b"),
                MyRegEx(@"\b[Ss]kal i have\b"),
                MyRegEx(@"\b[Ss]kal i ikke\b"),
                MyRegEx(@"\b[Ss]kal i klare\b"),
                MyRegEx(@"\b[Ss]kal i klatre\b"),
                MyRegEx(@"\b[Ss]kal i larme\b"),
                MyRegEx(@"\b[Ss]kal i lave\b"),
                MyRegEx(@"\b[Ss]kal i løfte\b"),
                MyRegEx(@"\b[Ss]kal i med\b"),
                MyRegEx(@"\b[Ss]kal i på\b"),
                MyRegEx(@"\b[Ss]kal i til\b"),
                MyRegEx(@"\b[Ss]kal i ud\b"),
                MyRegEx(@"\b[Ss]lap i ud\b"),
                MyRegEx(@"\b[Ss]lap i væk\b"),
                MyRegEx(@"\b[Ss]nart er i\b"),
                MyRegEx(@"\b[Ss]om i måske\b"),
                MyRegEx(@"\b[Ss]om i nok\b"),
                MyRegEx(@"\b[Ss]om i ved\b"),
                MyRegEx(@"\b[Ss]pis i bare\b"),
                MyRegEx(@"\b[Ss]pis i dem\b"),
                MyRegEx(@"\b[Ss]ynes i at\b"),
                MyRegEx(@"\b[Ss]ynes i det\b"),
                MyRegEx(@"\b[Ss]ynes i,"),
                MyRegEx(@"\b[Ss]ætter i en\b"),
                MyRegEx(@"\bSå i at\b"),
                MyRegEx(@"\bSå i det\b"),
                MyRegEx(@"\bSå i noget\b"),
                MyRegEx(@"\b[Ss]å tager i\b"),
                MyRegEx(@"\bTænder i på\b"),
                MyRegEx(@"\btænder i på\b"),
                MyRegEx(@"\btog i bilen\b"),
                MyRegEx(@"\bTog i bilen\b"),
                MyRegEx(@"\btog i liften\b"),
                MyRegEx(@"\bTog i liften\b"),
                MyRegEx(@"\btog i toget\b"),
                MyRegEx(@"\bTog i toget\b"),
                MyRegEx(@"\btræder i frem\b"),
                MyRegEx(@"\bTræder i frem\b"),
                MyRegEx(@"\bTror i at\b"),
                MyRegEx(@"\btror i at\b"),
                MyRegEx(@"\btror i det\b"),
                MyRegEx(@"\bTror i det\b"),
                MyRegEx(@"\bTror i jeg\b"),
                MyRegEx(@"\btror i jeg\b"),
                MyRegEx(@"\bTror i på\b"),
                MyRegEx(@"\b[Tr]ror i på\b"),
                MyRegEx(@"\b[Tr]ror i, "),
                MyRegEx(@"\b[Vv]ar i blevet\b"),
                MyRegEx(@"\b[Vv]ed i alle\b"),
                MyRegEx(@"\b[Vv]ed i allesammen\b"),
                MyRegEx(@"\b[Vv]ed i er\b"),
                MyRegEx(@"\b[Vv]ed i ikke\b"),
                MyRegEx(@"\b[Vv]ed i hvad\b"),
                MyRegEx(@"\b[Vv]ed i hvem\b"),
                MyRegEx(@"\b[Vv]ed i hvor\b"),
                MyRegEx(@"\b[Vv]ed i hvorfor\b"),
                MyRegEx(@"\b[Vv]ed i hvordan\b"),
                MyRegEx(@"\b[Vv]ed i var\b"),
                MyRegEx(@"\b[Vv]ed i ville\b"),
                MyRegEx(@"\b[Vv]ed i har\b"),
                MyRegEx(@"\b[Vv]ed i havde\b"),
                MyRegEx(@"\b[Vv]ed i hvem\b"),
                MyRegEx(@"\b[Vv]ed i hvad\b"),
                MyRegEx(@"\b[Vv]ed i hvor\b"),
                MyRegEx(@"\b[Vv]ed i mente\b"),
                MyRegEx(@"\b[Vv]ed i tror\b"),
                MyRegEx(@"\b[Vv]enter i på\b"),
                MyRegEx(@"\b[Vv]il i besegle\b"),
                MyRegEx(@"\b[Vv]il i dræbe\b"),
                MyRegEx(@"\b[Vv]il i fjerne\b"),
                MyRegEx(@"\b[Vv]il i fortryde\b"),
                MyRegEx(@"\b[Vv]il i gerne\b"),
                MyRegEx(@"\b[Vv]il i godt\b"),
                MyRegEx(@"\b[Vv]il i have\b"),
                MyRegEx(@"\b[Vv]il i høre\b"),
                MyRegEx(@"\b[Vv]il i ikke\b"),
                MyRegEx(@"\b[Vv]il i købe\b"),
                MyRegEx(@"\b[Vv]il i kaste\b"),
                MyRegEx(@"\b[Vv]il i møde\b"),
                MyRegEx(@"\b[Vv]il i måske\b"),
                MyRegEx(@"\bvil i savne\b"),
                MyRegEx(@"\bVil i savne\b"),
                MyRegEx(@"\bvil i se\b"),
                MyRegEx(@"\bVil i se\b"),
                MyRegEx(@"\bvil i sikkert\b"),
                MyRegEx(@"\bvil i smage\b"),
                MyRegEx(@"\bVil i smage\b"),
                MyRegEx(@"\b[Vv]il i virkelig\b"),
                MyRegEx(@"\b[Vv]il i virkeligt\b"),
                MyRegEx(@"\bVil i være\b"),
                MyRegEx(@"\bvil i være\b"),
                MyRegEx(@"\bVille i blive\b"),
                MyRegEx(@"\bville i blive\b"),
                MyRegEx(@"\bville i dræbe\b"),
                MyRegEx(@"\bville i få\b"),
                MyRegEx(@"\bville i få\b"),
                MyRegEx(@"\bville i gøre\b"),
                MyRegEx(@"\bville i høre\b"),
                MyRegEx(@"\bville i ikke\b"),
                MyRegEx(@"\bville i kaste\b"),
                MyRegEx(@"\bville i komme\b"),
                MyRegEx(@"\bville i mene\b"),
                MyRegEx(@"\bville i nå\b"),
                MyRegEx(@"\bville i savne\b"),
                MyRegEx(@"\bVille i se\b"),
                MyRegEx(@"\bville i se\b"),
                MyRegEx(@"\bville i sikkert\b"),
                MyRegEx(@"\bville i synes\b"),
                MyRegEx(@"\bville i tage\b"),
                MyRegEx(@"\bville i tro\b"),
                MyRegEx(@"\bville i være\b"),
                MyRegEx(@"\bville i være\b"),
                MyRegEx(@"\b[Vv]iste i, at\b"),
                MyRegEx(@"\b[Vv]iste i at\b"),
                MyRegEx(@"\bvover i\b"),
            };

            var regExIDag     = new Regex(@"\bidag\b", RegexOptions.Compiled);
            var regExIGaar    = new Regex(@"\bigår\b", RegexOptions.Compiled);
            var regExIMorgen  = new Regex(@"\bimorgen\b", RegexOptions.Compiled);
            var regExIAlt     = new Regex(@"\bialt\b", RegexOptions.Compiled);
            var regExIGang    = new Regex(@"\bigang\b", RegexOptions.Compiled);
            var regExIStand   = new Regex(@"\bistand\b", RegexOptions.Compiled);
            var regExIOevrigt = new Regex(@"\biøvrigt\b", RegexOptions.Compiled);

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                string text    = subtitle.Paragraphs[i].Text;
                string oldText = text;

                if (littleIRegex.IsMatch(text))
                {
                    foreach (var regex in iList)
                    {
                        var match = regex.Match(text);
                        while (match.Success)
                        {
                            var iMatch = littleIRegex.Match(match.Value);
                            if (iMatch.Success)
                            {
                                string temp = match.Value.Remove(iMatch.Index, 1).Insert(iMatch.Index, "I");

                                int index = match.Index;
                                if (index + match.Value.Length >= text.Length)
                                {
                                    text = text.Substring(0, index) + temp;
                                }
                                else
                                {
                                    text = text.Substring(0, index) + temp + text.Substring(index + match.Value.Length);
                                }
                            }
                            match = match.NextMatch();
                        }
                    }
                }

                if (regExIDag.IsMatch(text))
                {
                    text = regExIDag.Replace(text, "i dag");
                }

                if (regExIGaar.IsMatch(text))
                {
                    text = regExIGaar.Replace(text, "i går");
                }

                if (regExIMorgen.IsMatch(text))
                {
                    text = regExIMorgen.Replace(text, "i morgen");
                }

                if (regExIAlt.IsMatch(text))
                {
                    text = regExIAlt.Replace(text, "i alt");
                }

                if (regExIGang.IsMatch(text))
                {
                    text = regExIGang.Replace(text, "i gang");
                }

                if (regExIStand.IsMatch(text))
                {
                    text = regExIStand.Replace(text, "i stand");
                }

                if (regExIOevrigt.IsMatch(text))
                {
                    text = regExIOevrigt.Replace(text, "i øvrigt");
                }

                if (text != oldText)
                {
                    subtitle.Paragraphs[i].Text = text;
                    fixCount++;
                    callbacks.AddFixToListView(subtitle.Paragraphs[i], fixAction, oldText, text);
                }
            }

            callbacks.UpdateFixStatus(fixCount, language.FixDanishLetterI, string.Format(language.XIsChangedToUppercase, fixCount));
        }
Example #43
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language              = Configuration.Settings.Language.FixCommonErrors;
            string fixAction             = language.NormalizeStrings;
            var    twoLetterLanguageCode = callbacks.Language;
            int    noOfFixes             = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                var p       = subtitle.Paragraphs[i];
                var oldText = p.Text;
                var text    = p.Text
                              .Normalize()

                              .Replace('\u00a0', ' ')          // replace non-break-space (160 decimal) ascii char with normal space
                              .Replace("\u200B", string.Empty) // Zero Width Space
                              .Replace("\uFEFF", string.Empty) // Zero Width No-Break Space

                              .Replace('\u02F8', ':')          // ˸ Modifier Letter Raised Colon (\u02F8)
                              .Replace('\uFF1A', ':')          // : Fullwidth Colon (\uFF1A)
                              .Replace('\uFE13', ':')          // ︓ Presentation Form for Vertical Colon (\uFE13)

                              .Replace('\u2043', '-')          // ⁃ Hyphen bullet (\u2043)
                              .Replace('\u2010', '-')          // ‐ Hyphen (\u2010)
                              .Replace('\u2012', '-')          // ‒ Figure dash (\u2012)
                              .Replace('\u2013', '-')          // – En dash (\u2013)
                              .Replace('\u2014', '-')          // — Em dash (\u2014)
                              .Replace('\u2015', '-')          // ― Horizontal bar (\u2015)
                ;

                if (twoLetterLanguageCode != "el")
                {
                    text = text
                           .Replace("\u03a4", "T") // Greek Capital Letter Tau
                           .Replace("\u03a5", "Y") // Greek Capital Letter Upsilon
                           .Replace("\u03b3", "Y") // Greek Small Letter Gamma
                           .Replace("\u03a7", "X") // Greek Capital Letter Chi
                           .Replace("\u03ba", "k") // Greek Small Letter Kappa
                           .Replace("\u03bd", "v") // Greek Small Letter Nu
                           .Replace("\u03c1", "p") // Greek Small Letter Rho
                           .Replace("\u03c5", "u") // Greek Small Letter Upsilon
                           .Replace("\u039c", "M") // Greek Capital Letter Mu
                           .Replace("\u039a", "K") // Greek Capital Letter Kappa
                           .Replace("\u039d", "N") // Greek Capital Letter Nu
                           .Replace("\u039f", "O") // Greek Capital Letter Omicron
                           .Replace("\u03a1", "P") // Greek Capital Letter Rho
                           .Replace("\u0395", "E") // Greek Capital Letter Epsilon
                           .Replace("\u0396", "Z") // Greek Capital Letter Zeta
                           .Replace("\u0397", "H") // Greek Capital Letter Eta
                           .Replace("\u0384", "'") // Greek Tonos
                           .Replace("\u0392", "B") // Greek Capital Letter Beta
                           .Replace("\u0391", "A") // Greek Capital Letter Alpha
                           .Replace("\u03bf", "o") // Greek small letter Omicron
                    ;
                }

                if (oldText != text && callbacks.AllowFix(p, fixAction))
                {
                    p.Text = text;
                    noOfFixes++;
                    callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                }
            }
            callbacks.UpdateFixStatus(noOfFixes, language.FixCommonOcrErrors, language.FixDialogsOneLineExample);
        }
Example #44
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;

            string fixAction0 = language.RemovedEmptyLine;
            string fixAction1 = language.RemovedEmptyLineAtTop;
            string fixAction2 = language.RemovedEmptyLineAtBottom;

            if (subtitle.Paragraphs.Count == 0)
            {
                return;
            }

            int emptyLinesRemoved = 0;

            for (int i = subtitle.Paragraphs.Count - 1; i >= 0; i--)
            {
                Paragraph p = subtitle.Paragraphs[i];
                if (!string.IsNullOrEmpty(p.Text))
                {
                    string text    = p.Text.Trim(' ');
                    var    oldText = text;
                    var    pre     = string.Empty;
                    var    post    = string.Empty;

                    // Ssa Tags
                    if (text.StartsWith("{\\", StringComparison.Ordinal))
                    {
                        var endIDx = text.IndexOf('}', 2);
                        if (endIDx > 2)
                        {
                            pre  = text.Substring(0, endIDx + 1);
                            text = text.Remove(0, endIDx + 1);
                        }
                    }

                    while (text.LineStartsWithHtmlTag(true, true))
                    {
                        // Three length tag
                        if (text[2] == '>')
                        {
                            pre += text.Substring(0, 3);
                            text = text.Remove(0, 3);
                        }
                        else // <font ...>
                        {
                            var closeIdx = text.IndexOf('>');
                            if (closeIdx <= 2)
                            {
                                break;
                            }

                            pre += text.Substring(0, closeIdx + 1);
                            text = text.Remove(0, closeIdx + 1);
                        }
                    }
                    while (text.LineEndsWithHtmlTag(true, true))
                    {
                        var len = text.Length;

                        // Three length tag
                        if (text[len - 4] == '<')
                        {
                            post = text.Substring(text.Length - 4) + post;
                            text = text.Remove(text.Length - 4);
                        }
                        else // </font>
                        {
                            post = text.Substring(text.Length - 7) + post;
                            text = text.Remove(text.Length - 7);
                        }
                    }

                    if (callbacks.AllowFix(p, fixAction1) && text.StartsWith(Environment.NewLine, StringComparison.Ordinal))
                    {
                        if (pre.Length > 0)
                        {
                            text = pre + text.TrimStart(Utilities.NewLineChars);
                        }
                        else
                        {
                            text = text.TrimStart(Utilities.NewLineChars);
                        }
                        p.Text = text;
                        emptyLinesRemoved++;
                        callbacks.AddFixToListView(p, fixAction1, oldText, p.Text);
                    }
                    else
                    {
                        text = pre + text;
                    }

                    if (callbacks.AllowFix(p, fixAction2) && text.EndsWith(Environment.NewLine, StringComparison.Ordinal))
                    {
                        if (post.Length > 0)
                        {
                            text = text.TrimEnd(Utilities.NewLineChars) + post;
                        }
                        else
                        {
                            text = text.TrimEnd(Utilities.NewLineChars);
                        }
                        p.Text = text;
                        emptyLinesRemoved++;
                        callbacks.AddFixToListView(p, fixAction2, oldText, p.Text);
                    }
                }
            }

            // this must be the very last action done, or line numbers will be messed up!!!
            for (int i = subtitle.Paragraphs.Count - 1; i >= 0; i--)
            {
                Paragraph p    = subtitle.Paragraphs[i];
                var       text = HtmlUtil.RemoveHtmlTags(p.Text, true).Trim();
                if (callbacks.AllowFix(p, fixAction0) && string.IsNullOrEmpty(text))
                {
                    subtitle.Paragraphs.RemoveAt(i);
                    emptyLinesRemoved++;
                    callbacks.AddFixToListView(p, fixAction0, p.Text, string.Format("[{0}]", language.RemovedEmptyLine));
                    callbacks.AddToDeleteIndices(i);
                }
            }

            if (emptyLinesRemoved > 0)
            {
                callbacks.UpdateFixStatus(emptyLinesRemoved, language.RemovedEmptyLinesUnsedLineBreaks, string.Format(language.EmptyLinesRemovedX, emptyLinesRemoved));
                subtitle.Renumber();
            }
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language  = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixMissingPeriodAtEndOfLine;
            int    missingPeriodsAtEndOfLine = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                var    p        = subtitle.Paragraphs[i];
                var    next     = subtitle.GetParagraphOrDefault(i + 1);
                string nextText = string.Empty;
                if (next != null)
                {
                    nextText = HtmlUtil.RemoveHtmlTags(next.Text, true).TrimStart('-', '"', '„').TrimStart();
                }
                bool   isNextClose = next != null && next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds < 400;
                string tempNoHtml  = HtmlUtil.RemoveHtmlTags(p.Text).TrimEnd();

                if (IsOneLineUrl(p.Text) || p.Text.Contains(ExpectedChars) || p.Text.EndsWith('\''))
                {
                    // ignore urls
                }
                else if (!string.IsNullOrEmpty(nextText) && next != null &&
                         next.Text.Length > 0 &&
                         char.IsUpper(nextText[0]) &&
                         tempNoHtml.Length > 0 &&
                         !ExpectedString1.Contains(tempNoHtml[tempNoHtml.Length - 1]))
                {
                    string tempTrimmed = tempNoHtml.TrimEnd().TrimEnd('\'', '"', '“', '”').TrimEnd();
                    if (tempTrimmed.Length > 0 && !ExpectedString2.Contains(tempTrimmed[tempTrimmed.Length - 1]) && p.Text != p.Text.ToUpperInvariant())
                    {
                        //don't end the sentence if the next word is an I word as they're always capped.
                        bool isNextCloseAndStartsWithI = isNextClose && (nextText.StartsWith("I ", StringComparison.Ordinal) ||
                                                                         nextText.StartsWith("I'", StringComparison.Ordinal));

                        if (!isNextCloseAndStartsWithI)
                        {
                            //test to see if the first word of the next line is a name
                            if (callbacks.AllowFix(p, fixAction))
                            {
                                string oldText = p.Text;
                                if (callbacks.IsName(next.Text.Split(WordSplitChars)[0]))
                                {
                                    if (next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds > 2000)
                                    {
                                        AddPeriod(p, tempNoHtml);
                                    }
                                }
                                else
                                {
                                    AddPeriod(p, tempNoHtml);
                                }

                                if (p.Text != oldText)
                                {
                                    missingPeriodsAtEndOfLine++;
                                    callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                                }
                            }
                        }
                    }
                }
                else if (next != null && !string.IsNullOrEmpty(p.Text) && Utilities.AllLettersAndNumbers.Contains(p.Text[p.Text.Length - 1]))
                {
                    if (p.Text != p.Text.ToUpperInvariant())
                    {
                        var st = new StrippableText(next.Text);
                        if (st.StrippedText.Length > 0 && st.StrippedText != st.StrippedText.ToUpperInvariant() &&
                            char.IsUpper(st.StrippedText[0]))
                        {
                            if (callbacks.AllowFix(p, fixAction))
                            {
                                int j = p.Text.Length - 1;
                                while (j >= 0 && !@".!?¿¡".Contains(p.Text[j]))
                                {
                                    j--;
                                }

                                string endSign = ".";
                                if (j >= 0 && p.Text[j] == '¿')
                                {
                                    endSign = "?";
                                }

                                if (j >= 0 && p.Text[j] == '¡')
                                {
                                    endSign = "!";
                                }

                                string oldText = p.Text;
                                missingPeriodsAtEndOfLine++;
                                p.Text += endSign;
                                callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                            }
                        }
                    }
                }

                if (p.Text.Length > 4)
                {
                    int indexOfNewLine = p.Text.IndexOf(Environment.NewLine + " -", 3, StringComparison.Ordinal);
                    if (indexOfNewLine < 0)
                    {
                        indexOfNewLine = p.Text.IndexOf(Environment.NewLine + "-", 3, StringComparison.Ordinal);
                    }

                    if (indexOfNewLine < 0)
                    {
                        indexOfNewLine = p.Text.IndexOf(Environment.NewLine + "<i>-", 3, StringComparison.Ordinal);
                    }

                    if (indexOfNewLine < 0)
                    {
                        indexOfNewLine = p.Text.IndexOf(Environment.NewLine + "<i> -", 3, StringComparison.Ordinal);
                    }

                    if (indexOfNewLine > 0 && char.IsUpper(char.ToUpper(p.Text[indexOfNewLine - 1])) && callbacks.AllowFix(p, fixAction))
                    {
                        string oldText = p.Text;

                        string text = p.Text.Substring(0, indexOfNewLine);
                        var    st   = new StrippableText(text);
                        if (st.Pre.TrimEnd().EndsWith('¿')) // Spanish ¿
                        {
                            p.Text = p.Text.Insert(indexOfNewLine, "?");
                        }
                        else if (st.Pre.TrimEnd().EndsWith('¡')) // Spanish ¡
                        {
                            p.Text = p.Text.Insert(indexOfNewLine, "!");
                        }
                        else
                        {
                            p.Text = p.Text.Insert(indexOfNewLine, ".");
                        }

                        missingPeriodsAtEndOfLine++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(missingPeriodsAtEndOfLine, language.AddPeriods, language.XPeriodsAdded);
        }
Example #46
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var          language      = Configuration.Settings.Language.FixCommonErrors;
            string       languageCode  = callbacks.Language;
            string       fixAction     = language.FixMissingSpace;
            int          missingSpaces = 0;
            const string expectedChars = @"""”<.";

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];

                // missing space after comma ","
                Match match = FixMissingSpacesReComma.Match(p.Text);
                while (match.Success)
                {
                    bool doFix = !expectedChars.Contains(p.Text[match.Index + 2]);

                    if (doFix && languageCode == "el" && (p.Text.Substring(match.Index).StartsWith("ό,τι", StringComparison.Ordinal) || p.Text.Substring(match.Index).StartsWith("ο,τι", StringComparison.Ordinal)))
                    {
                        doFix = false;
                    }

                    if (doFix && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = p.Text.Replace(match.Value, match.Value[0] + ", " + match.Value[match.Value.Length - 1]);
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                    match = match.NextMatch();
                }

                bool allowFix = callbacks.AllowFix(p, fixAction);

                // missing space after "?"
                match = FixMissingSpacesReQuestionMark.Match(p.Text);
                while (match.Success)
                {
                    if (allowFix && !@"""<".Contains(p.Text[match.Index + 2]))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = p.Text.Replace(match.Value, match.Value[0] + "? " + match.Value[match.Value.Length - 1]);
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                    match = FixMissingSpacesReQuestionMark.Match(p.Text, match.Index + 1);
                }

                // missing space after "!"
                match = FixMissingSpacesReExclamation.Match(p.Text);
                while (match.Success)
                {
                    if (allowFix && !@"""<".Contains(p.Text[match.Index + 2]))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = p.Text.Replace(match.Value, match.Value[0] + "! " + match.Value[match.Value.Length - 1]);
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                    match = FixMissingSpacesReExclamation.Match(p.Text, match.Index + 1);
                }

                // missing space after ":"
                match = FixMissingSpacesReColon.Match(p.Text);
                while (match.Success)
                {
                    int start = match.Index;
                    start -= 4;
                    if (start < 0)
                    {
                        start = 0;
                    }
                    int indexOfStartCodeTag = p.Text.IndexOf('{', start);
                    int indexOfEndCodeTag   = p.Text.IndexOf('}', start);
                    if (indexOfStartCodeTag >= 0 && indexOfEndCodeTag >= 0 && indexOfStartCodeTag < match.Index)
                    {
                        // we are inside a tag: like indexOfEndCodeTag "{y:i}Is this italic?"
                    }
                    else if (allowFix && !@"""<".Contains(p.Text[match.Index + 2]))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = p.Text.Replace(match.Value, match.Value[0] + ": " + match.Value[match.Value.Length - 1]);
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                    match = FixMissingSpacesReColon.Match(p.Text, match.Index + 1);
                }

                // missing space after period "."
                match = FixMissingSpacesRePeriod.Match(p.Text);
                while (match.Success)
                {
                    if (!p.Text.Contains("www.", StringComparison.OrdinalIgnoreCase) &&
                        !p.Text.Contains("http://", StringComparison.OrdinalIgnoreCase) &&
                        !UrlCom.IsMatch(p.Text) &&
                        !UrlNet.IsMatch(p.Text) &&
                        !UrlOrg.IsMatch(p.Text)) // urls are skipped
                    {
                        bool isMatchAbbreviation = false;

                        string word = GetWordFromIndex(p.Text, match.Index);
                        if (Utilities.CountTagInText(word, '.') > 1)
                        {
                            isMatchAbbreviation = true;
                        }

                        if (!isMatchAbbreviation && word.Contains('@')) // skip emails
                        {
                            isMatchAbbreviation = true;
                        }

                        if (match.Value.Equals("h.d", StringComparison.OrdinalIgnoreCase) && match.Index > 0 && p.Text.Substring(match.Index - 1, 4).Equals("ph.d", StringComparison.OrdinalIgnoreCase))
                        {
                            isMatchAbbreviation = true;
                        }

                        if (!isMatchAbbreviation && callbacks.AllowFix(p, fixAction))
                        {
                            missingSpaces++;
                            string oldText = p.Text;
                            p.Text = p.Text.Replace(match.Value, match.Value.Replace(".", ". "));
                            callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                        }
                    }
                    match = match.NextMatch();
                }

                if (!p.Text.StartsWith("--", StringComparison.Ordinal))
                {
                    var arr = p.Text.SplitToLines();
                    if (arr.Length == 2 && arr[0].Length > 1 && arr[1].Length > 1)
                    {
                        if (arr[0][0] == '-' && arr[0][1] != ' ')
                        {
                            arr[0] = arr[0].Insert(1, " ");
                        }
                        if (arr[0].Length > 6 && arr[0].StartsWith("<i>-", StringComparison.OrdinalIgnoreCase) && arr[0][4] != ' ')
                        {
                            arr[0] = arr[0].Insert(4, " ");
                        }
                        if (arr[1][0] == '-' && arr[1][1] != ' ' && arr[1][1] != '-')
                        {
                            arr[1] = arr[1].Insert(1, " ");
                        }
                        if (arr[1].Length > 6 && arr[1].StartsWith("<i>-", StringComparison.OrdinalIgnoreCase) && arr[1][4] != ' ')
                        {
                            arr[1] = arr[1].Insert(4, " ");
                        }
                        string newText = arr[0] + Environment.NewLine + arr[1];
                        if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                        {
                            missingSpaces++;
                            string oldText = p.Text;
                            p.Text = newText;
                            callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                        }
                    }
                }

                //fix missing spaces before/after quotes - Get a"get out of jail free"card. -> Get a "get out of jail free" card.
                if (Utilities.CountTagInText(p.Text, '"') == 2)
                {
                    int    start = p.Text.IndexOf('"');
                    int    end   = p.Text.LastIndexOf('"');
                    string quote = p.Text.Substring(start, end - start + 1);
                    if (!quote.Contains(Environment.NewLine))
                    {
                        string newText        = p.Text;
                        int    indexOfFontTag = newText.IndexOf("<font ", StringComparison.OrdinalIgnoreCase);
                        bool   isAfterAssTag  = newText.Contains("{\\") && start > 0 && newText[start - 1] == '}';
                        if (!isAfterAssTag && start > 0 && !(Environment.NewLine + @" >[(♪♫¿").Contains(p.Text[start - 1]))
                        {
                            if (indexOfFontTag < 0 || start > newText.IndexOf('>', indexOfFontTag)) // font tags can contain "
                            {
                                newText = newText.Insert(start, " ");
                                end++;
                            }
                        }
                        if (end < newText.Length - 2 && !(Environment.NewLine + @" <,.!?:;])♪♫¿").Contains(p.Text[end + 1]))
                        {
                            if (indexOfFontTag < 0 || end > newText.IndexOf('>', indexOfFontTag)) // font tags can contain "
                            {
                                newText = newText.Insert(end + 1, " ");
                            }
                        }
                        if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                        {
                            missingSpaces++;
                            string oldText = p.Text;
                            p.Text = newText;
                            callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                        }
                    }
                }

                //fix missing spaces before/after music quotes - #He's so happy# -> #He's so happy#
                if (p.Text.Length > 5 && p.Text.Contains(new[] { '#', '♪', '♫' }))
                {
                    string newText = p.Text;
                    if (@"#♪♫".Contains(newText[0]) && !@" <".Contains(newText[1]) && !newText.Substring(1).StartsWith(Environment.NewLine) &&
                        !newText.Substring(1).StartsWith('♪') && !newText.Substring(1).StartsWith('♫'))
                    {
                        newText = newText.Insert(1, " ");
                    }
                    if (@"#♪♫".Contains(newText[newText.Length - 1]) && !@" >".Contains(newText[newText.Length - 2]) &&
                        !newText.Substring(0, newText.Length - 1).EndsWith(Environment.NewLine, StringComparison.Ordinal) && !newText.Substring(0, newText.Length - 1).EndsWith('♪') &&
                        !newText.Substring(0, newText.Length - 1).EndsWith('♫'))
                    {
                        newText = newText.Insert(newText.Length - 1, " ");
                    }
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }

                //fix missing spaces in "Hey...move it!" to "Hey... move it!"
                int index = p.Text.IndexOf("...", StringComparison.Ordinal);
                if (index >= 0 && p.Text.Length > 5)
                {
                    string newText = p.Text;
                    while (index != -1)
                    {
                        if (newText.Length > index + 4 && index > 1)
                        {
                            if (Utilities.AllLettersAndNumbers.Contains(newText[index + 3]) &&
                                Utilities.AllLettersAndNumbers.Contains(newText[index - 1]))
                            {
                                newText = newText.Insert(index + 3, " ");
                            }
                        }
                        index = newText.IndexOf("...", index + 2, StringComparison.Ordinal);
                    }
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }

                //fix missing spaces in "The<i>Bombshell</i> will gone." to "The <i>Bombshell</i> will gone."
                index = p.Text.IndexOf("<i>", StringComparison.OrdinalIgnoreCase);
                if (index >= 0 && p.Text.Length > 5)
                {
                    string newText = p.Text;
                    while (index != -1)
                    {
                        if (newText.Length > index + 6 && index > 1)
                        {
                            if (Utilities.AllLettersAndNumbers.Contains(newText[index + 3]) &&
                                Utilities.AllLettersAndNumbers.Contains(newText[index - 1]))
                            {
                                newText = newText.Insert(index, " ");
                            }
                        }
                        index = newText.IndexOf("<i>", index + 3, StringComparison.OrdinalIgnoreCase);
                    }
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }

                //fix missing spaces in "The <i>Bombshell</i>will gone." to "The <i>Bombshell</i> will gone."
                index = p.Text.IndexOf("</i>", StringComparison.OrdinalIgnoreCase);
                if (index > 3 && p.Text.Length > 5)
                {
                    string newText = p.Text;
                    while (index != -1)
                    {
                        if (newText.Length > index + 6 && index > 1)
                        {
                            if (Utilities.AllLettersAndNumbers.Contains(newText[index + 4]) &&
                                Utilities.AllLettersAndNumbers.Contains(newText[index - 1]))
                            {
                                newText = newText.Insert(index + 4, " ");
                            }
                        }
                        index = newText.IndexOf("</i>", index + 4, StringComparison.OrdinalIgnoreCase);
                    }
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }

                if (callbacks.Language == "fr") // special rules for French
                {
                    string newText = p.Text;
                    int    j       = 1;
                    while (j < newText.Length)
                    {
                        if (@"!?:;".Contains(newText[j]))
                        {
                            if (Utilities.AllLetters.Contains(newText[j - 1]))
                            {
                                newText = newText.Insert(j, " ");
                                j++;
                            }
                        }
                        j++;
                    }
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(missingSpaces, language.FixMissingSpaces, string.Format(language.XMissingSpacesAdded, missingSpaces));
        }
Example #47
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language  = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixDoubleDash;
            int    fixCount  = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                if (callbacks.AllowFix(p, fixAction))
                {
                    string text    = p.Text;
                    string oldText = p.Text;

                    while (text.Contains("---", StringComparison.Ordinal))
                    {
                        text = text.Replace("---", "--");
                    }

                    if (text.Contains("--", StringComparison.Ordinal))
                    {
                        text = text.Replace("--", "... ");
                        text = text.Replace("...  ", "... ");
                        text = text.Replace(" ...", "...");
                        text = text.TrimEnd();
                        text = text.Replace("... " + Environment.NewLine, "..." + Environment.NewLine);
                        text = text.Replace("... </", "...</"); // </i>, </font>...
                        text = text.Replace("... ?", "...?");
                        text = text.Replace("... !", "...!");

                        if (text.IndexOf(Environment.NewLine, StringComparison.Ordinal) > 1)
                        {
                            var lines = text.SplitToLines();
                            for (int k = 0; k < lines.Count; k++)
                            {
                                lines[k] = Helper.RemoveSpacesBeginLineAfterEllipses(lines[k]);
                            }

                            text = string.Join(Environment.NewLine, lines);
                        }
                        else
                        {
                            text = Helper.RemoveSpacesBeginLineAfterEllipses(text);
                        }
                    }
                    //if (text.EndsWith('-'))
                    //{
                    //    text = text.Substring(0, text.Length - 1) + "...";
                    //    text = text.Replace(" ...", "...");
                    //}
                    //if (text.EndsWith("-</i>"))
                    //{
                    //    text = text.Replace("-</i>", "...</i>");
                    //    text = text.Replace(" ...", "...");
                    //}

                    if (text.StartsWith('—') && text.Length > 1)
                    {
                        text = text.Substring(1).Insert(0, "...");
                    }
                    if (text.EndsWith('—') && text.Length > 1)
                    {
                        text = text.Substring(0, text.Length - 1) + "...";
                        text = text.Replace(" ...", "...");
                    }

                    if (text != oldText)
                    {
                        p.Text = text;
                        fixCount++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(fixCount, language.FixDoubleDash, language.XFixDoubleDash);
        }
Example #48
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            string fixAction    = Language.UnneededPeriod;
            int    removedCount = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                var p = subtitle.Paragraphs[i];
                if (callbacks.AllowFix(p, fixAction))
                {
                    // Returns processed text.
                    string procText = RemoveDotAfterPunctuation(p.Text);

                    while (procText.Contains("....", StringComparison.Ordinal))
                    {
                        procText = procText.Replace("....", "...");
                    }

                    while (procText.Contains("……", StringComparison.Ordinal))
                    {
                        procText = procText.Replace("……", "…");
                    }

                    while (procText.Contains(".…", StringComparison.Ordinal))
                    {
                        procText = procText.Replace(".…", "…");
                    }

                    while (procText.Contains("….", StringComparison.Ordinal))
                    {
                        procText = procText.Replace("….", "…");
                    }

                    var l = callbacks.Language;
                    if (procText.Contains('.') && LanguageAutoDetect.IsLanguageWithoutPeriods(l))
                    {
                        var sb = new StringBuilder();
                        foreach (var line in procText.SplitToLines())
                        {
                            var s = line;
                            if (s.EndsWith('.') && !s.EndsWith("..", StringComparison.Ordinal))
                            {
                                s = s.TrimEnd('.');
                            }
                            else if (s.EndsWith(".</i>", StringComparison.Ordinal) && !s.EndsWith("..</i>", StringComparison.Ordinal))
                            {
                                s = s.Remove(s.Length - 5, 1);
                            }

                            sb.AppendLine(s);
                        }

                        procText = sb.ToString().TrimEnd();
                    }

                    int diff = p.Text.Length - procText.Length;
                    if (diff > 0)
                    {
                        // Calculate total removed dots.
                        removedCount += diff;
                        callbacks.AddFixToListView(p, fixAction, p.Text, procText);
                        p.Text = procText;
                    }
                }
            }
            callbacks.UpdateFixStatus(removedCount, Language.RemoveUnneededPeriods);
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;

            _callbacks = callbacks;

            string fixAction             = language.FixShortDisplayTime;
            int    noOfShortDisplayTimes = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p           = subtitle.Paragraphs[i];
                var       skip        = p.StartTime.IsMaxTime || p.EndTime.IsMaxTime;
                double    displayTime = p.Duration.TotalMilliseconds;
                if (!skip && displayTime < Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds)
                {
                    Paragraph next = subtitle.GetParagraphOrDefault(i + 1);
                    Paragraph prev = subtitle.GetParagraphOrDefault(i - 1);
                    if (next == null || (p.StartTime.TotalMilliseconds + Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines) < next.StartTime.TotalMilliseconds)
                    {
                        var temp = new Paragraph(p)
                        {
                            EndTime = { TotalMilliseconds = p.StartTime.TotalMilliseconds + Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds }
                        };
                        if (Utilities.GetCharactersPerSecond(temp) <= Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
                        {
                            if (callbacks.AllowFix(p, fixAction))
                            {
                                string oldCurrent = p.ToString();
                                p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds;
                                noOfShortDisplayTimes++;
                                callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                            }
                        }
                    }
                    else if (Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime && p.StartTime.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds &&
                             (prev == null || prev.EndTime.TotalMilliseconds < p.EndTime.TotalMilliseconds - Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines))
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            string oldCurrent = p.ToString();
                            if (next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines > p.EndTime.TotalMilliseconds)
                            {
                                p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
                            }

                            p.StartTime.TotalMilliseconds = p.EndTime.TotalMilliseconds - Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds;
                            noOfShortDisplayTimes++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else
                    {
                        callbacks.LogStatus(language.FixShortDisplayTimes, string.Format(language.UnableToFixTextXY, i + 1, p));
                        callbacks.AddToTotalErrors(1);
                        skip = true;
                    }
                }

                double charactersPerSecond = Utilities.GetCharactersPerSecond(p);
                if (!skip && charactersPerSecond > Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
                {
                    var temp = new Paragraph(p);
                    var numberOfCharacters = temp.Text.CountCharacters(Configuration.Settings.General.CharactersPerSecondsIgnoreWhiteSpace);
                    while (Utilities.GetCharactersPerSecond(temp, numberOfCharacters) > Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
                    {
                        temp.EndTime.TotalMilliseconds++;
                    }
                    Paragraph next     = subtitle.GetParagraphOrDefault(i + 1);
                    Paragraph nextNext = subtitle.GetParagraphOrDefault(i + 2);
                    Paragraph prev     = subtitle.GetParagraphOrDefault(i - 1);
                    double    diffMs   = temp.Duration.TotalMilliseconds - p.Duration.TotalMilliseconds;

                    // Normal - just make current subtitle duration longer
                    if (next == null || temp.EndTime.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines < next.StartTime.TotalMilliseconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            string oldCurrent = p.ToString();
                            p.EndTime.TotalMilliseconds = temp.EndTime.TotalMilliseconds;
                            noOfShortDisplayTimes++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    // Start current subtitle earlier (max 50 ms)
                    else if (Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime && p.StartTime.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds &&
                             diffMs < 50 && (prev == null || prev.EndTime.TotalMilliseconds < p.EndTime.TotalMilliseconds - temp.Duration.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines))
                    {
                        noOfShortDisplayTimes = MoveStartTime(fixAction, noOfShortDisplayTimes, p, temp, next);
                    }
                    // Make current subtitle duration longer + move next subtitle
                    else if (diffMs < 1000 &&
                             Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime &&
                             p.StartTime.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds &&
                             (nextNext == null || next.EndTime.TotalMilliseconds + diffMs + Configuration.Settings.General.MinimumMillisecondsBetweenLines * 2 < nextNext.StartTime.TotalMilliseconds))
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            string oldCurrent = p.ToString();
                            p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + temp.Duration.TotalMilliseconds;
                            var nextDurationMs = next.Duration.TotalMilliseconds;
                            next.StartTime.TotalMilliseconds = p.EndTime.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines;
                            next.EndTime.TotalMilliseconds   = next.StartTime.TotalMilliseconds + nextDurationMs;
                            noOfShortDisplayTimes++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    // Make next subtitle duration shorter + make current subtitle duration longer
                    else if (diffMs < 1000 &&
                             Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime && Utilities.GetCharactersPerSecond(new Paragraph(next.Text, p.StartTime.TotalMilliseconds + temp.Duration.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines, next.EndTime.TotalMilliseconds)) < Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            string oldCurrent = p.ToString();
                            next.StartTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + temp.Duration.TotalMilliseconds + Configuration.Settings.General.MinimumMillisecondsBetweenLines;
                            p.EndTime.TotalMilliseconds      = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
                            noOfShortDisplayTimes++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    // Make next-next subtitle duration shorter + move next + make current subtitle duration longer
                    else if (diffMs < 500 &&
                             Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime && nextNext != null &&
                             Utilities.GetCharactersPerSecond(new Paragraph(nextNext.Text, nextNext.StartTime.TotalMilliseconds + diffMs + Configuration.Settings.General.MinimumMillisecondsBetweenLines, nextNext.EndTime.TotalMilliseconds - (diffMs))) < Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            string oldCurrent = p.ToString();
                            p.EndTime.TotalMilliseconds          += diffMs;
                            next.StartTime.TotalMilliseconds     += diffMs;
                            next.EndTime.TotalMilliseconds       += diffMs;
                            nextNext.StartTime.TotalMilliseconds += diffMs;
                            noOfShortDisplayTimes++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    // Start current subtitle earlier (max 200 ms)
                    else if (Configuration.Settings.Tools.FixShortDisplayTimesAllowMoveStartTime && p.StartTime.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds &&
                             diffMs < 200 && (prev == null || prev.EndTime.TotalMilliseconds < p.EndTime.TotalMilliseconds - temp.Duration.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines))
                    {
                        noOfShortDisplayTimes = MoveStartTime(fixAction, noOfShortDisplayTimes, p, temp, next);
                    }
                    else
                    {
                        // move some... though not enough
                        var improvedEndtime = next.StartTime.TotalMilliseconds - Configuration.Settings.General.MinimumMillisecondsBetweenLines;
                        if (improvedEndtime > p.EndTime.TotalMilliseconds)
                        {
                            if (callbacks.AllowFix(p, fixAction))
                            {
                                string oldCurrent = p.ToString();
                                p.EndTime.TotalMilliseconds = improvedEndtime;
                                noOfShortDisplayTimes++;
                                callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                            }
                        }

                        callbacks.LogStatus(language.FixShortDisplayTimes, string.Format(language.UnableToFixTextXY, i + 1, p));
                        callbacks.AddToTotalErrors(1);
                    }
                }
            }
            callbacks.UpdateFixStatus(noOfShortDisplayTimes, fixAction, string.Format(language.XDisplayTimesProlonged, noOfShortDisplayTimes));
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            string fixAction = Language.StartWithUppercaseLetterAfterColon;
            int    noOfFixes = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                var       p         = new Paragraph(subtitle.Paragraphs[i]);
                Paragraph last      = subtitle.GetParagraphOrDefault(i - 1);
                string    oldText   = p.Text;
                int       skipCount = 0;

                if (last != null)
                {
                    string lastText = HtmlUtil.RemoveHtmlTags(last.Text);
                    if (lastText.EndsWith(':') || lastText.EndsWith(';'))
                    {
                        var st = new StrippableText(p.Text);
                        if (st.StrippedText.Length > 0 && st.StrippedText[0] != char.ToUpper(st.StrippedText[0]))
                        {
                            p.Text = st.Pre + char.ToUpper(st.StrippedText[0]) + st.StrippedText.Substring(1) + st.Post;
                        }
                    }
                }

                if (oldText.Contains(ExpectedChars))
                {
                    bool lastWasColon = false;
                    for (int j = 0; j < p.Text.Length; j++)
                    {
                        var s = p.Text[j];
                        if (s == ':' || s == ';')
                        {
                            lastWasColon = true;
                        }
                        else if (lastWasColon)
                        {
                            // skip whitespace index
                            if (j + 2 < p.Text.Length && p.Text[j] == ' ')
                            {
                                s = p.Text[++j];
                            }

                            var startFromJ = p.Text.Substring(j);
                            if (startFromJ.Length > 3 && startFromJ[0] == '<' && startFromJ[2] == '>' && (startFromJ[1] == 'i' || startFromJ[1] == 'b' || startFromJ[1] == 'u'))
                            {
                                skipCount = 2;
                            }
                            else if (startFromJ.StartsWith("<font ", StringComparison.OrdinalIgnoreCase) && p.Text.Substring(j).Contains('>'))
                            {
                                skipCount = (j + startFromJ.IndexOf('>', 6)) - j;
                            }
                            else if (Helper.IsTurkishLittleI(s, callbacks.Encoding, callbacks.Language))
                            {
                                p.Text       = p.Text.Remove(j, 1).Insert(j, Helper.GetTurkishUppercaseLetter(s, callbacks.Encoding).ToString(CultureInfo.InvariantCulture));
                                lastWasColon = false;
                            }
                            else if (char.IsLower(s))
                            {
                                // iPhone
                                bool change = true;
                                if (s == 'i' && p.Text.Length > j + 1)
                                {
                                    if (p.Text[j + 1] == char.ToUpper(p.Text[j + 1]))
                                    {
                                        change = false;
                                    }
                                }
                                if (change)
                                {
                                    p.Text = p.Text.Remove(j, 1).Insert(j, char.ToUpper(s).ToString(CultureInfo.InvariantCulture));
                                }

                                lastWasColon = false;
                            }
                            else if (!(" " + Environment.NewLine).Contains(s))
                            {
                                lastWasColon = false;
                            }

                            // move the: 'j' pointer and reset skipCount to 0
                            if (skipCount > 0)
                            {
                                j        += skipCount;
                                skipCount = 0;
                            }
                        }
                    }
                }

                if (oldText != p.Text && callbacks.AllowFix(p, fixAction))
                {
                    noOfFixes++;
                    subtitle.Paragraphs[i].Text = p.Text;
                    callbacks.AddFixToListView(subtitle.Paragraphs[i], fixAction, oldText, p.Text);
                }
            }
            callbacks.UpdateFixStatus(noOfFixes, Language.StartWithUppercaseLetterAfterColon);
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language  = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.StartWithUppercaseLetterAfterPeriodInsideParagraph;
            int    noOfFixes = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p       = subtitle.Paragraphs[i];
                string    oldText = p.Text;
                if (p.Text.Length > 3 && callbacks.AllowFix(p, fixAction))
                {
                    var    st    = new StrippableText(p.Text);
                    string text  = st.StrippedText;
                    int    start = text.IndexOfAny(ExpectedChars);
                    while (start > 0 && start < text.Length)
                    {
                        char charAtPosition = text[start];
                        // Allow fixing lowercase letter after recursive ??? or !!!.
                        if (charAtPosition != '.') // Dot is not include 'cause I don't capitalize word after the ellipses (...), right?
                        {
                            while (start + 1 < text.Length && text[start + 1] == charAtPosition)
                            {
                                start++;
                            }
                        }

                        // Try to reach the last dot if char at *start is '.'.
                        if (charAtPosition == '.')
                        {
                            while (start + 1 < text.Length && text[start + 1] == '.')
                            {
                                start++;
                            }
                        }

                        if (start + 3 < text.Length && (text[start + 1] == ' ') && !IsAbbreviation(text, start, callbacks))
                        {
                            var textBefore = text.Substring(0, start + 1);
                            var subText    = new StrippableText(text.Substring(start + 2));
                            text = text.Substring(0, start + 2) + subText.CombineWithPrePost(ToUpperFirstLetter(textBefore, subText.StrippedText, callbacks));
                        }

                        start += 3;
                        if (start < text.Length)
                        {
                            start = text.IndexOfAny(ExpectedChars, start);
                        }
                    }
                    text = st.CombineWithPrePost(text);
                    if (oldText != text)
                    {
                        p.Text = text;
                        noOfFixes++;
                        var isChecked = true;
                        if (callbacks.Language == "bg" && text.Contains("г. "))
                        {
                            // Bulgarian have "г." after years but the sentence continues with lowercase
                            var regex = new Regex(@"\d г\. \p{L}");
                            var t1    = regex.Replace(oldText, string.Empty);
                            var t2    = regex.Replace(text, string.Empty);
                            isChecked = t1 != t2;
                        }
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text, isChecked);
                    }
                }
            }
            callbacks.UpdateFixStatus(noOfFixes, language.StartWithUppercaseLetterAfterPeriodInsideParagraph, noOfFixes.ToString(CultureInfo.InvariantCulture));
        }
Example #52
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;

            string fixAction0 = language.RemovedEmptyLine;
            string fixAction1 = language.RemovedEmptyLineAtTop;
            string fixAction2 = language.RemovedEmptyLineAtBottom;

            if (subtitle.Paragraphs.Count == 0)
                return;

            int emptyLinesRemoved = 0;

            for (int i = subtitle.Paragraphs.Count - 1; i >= 0; i--)
            {
                Paragraph p = subtitle.Paragraphs[i];
                if (!string.IsNullOrEmpty(p.Text))
                {
                    string text = p.Text.Trim(' ');
                    var oldText = text;
                    var pre = string.Empty;
                    var post = string.Empty;

                    // Ssa Tags
                    if (text.StartsWith("{\\", StringComparison.Ordinal))
                    {
                        var endIDx = text.IndexOf('}', 2);
                        if (endIDx > 2)
                        {
                            pre = text.Substring(0, endIDx + 1);
                            text = text.Remove(0, endIDx + 1);
                        }
                    }

                    while (text.LineStartsWithHtmlTag(true, true))
                    {
                        // Three length tag
                        if (text[2] == '>')
                        {
                            pre += text.Substring(0, 3);
                            text = text.Remove(0, 3);
                        }
                        else // <font ...>
                        {
                            var closeIdx = text.IndexOf('>');
                            if (closeIdx <= 2)
                                break;

                            pre += text.Substring(0, closeIdx + 1);
                            text = text.Remove(0, closeIdx + 1);
                        }
                    }
                    while (text.LineEndsWithHtmlTag(true, true))
                    {
                        var len = text.Length;

                        // Three length tag
                        if (text[len - 4] == '<')
                        {
                            post = text.Substring(text.Length - 4) + post;
                            text = text.Remove(text.Length - 4);
                        }
                        else // </font>
                        {
                            post = text.Substring(text.Length - 7) + post;
                            text = text.Remove(text.Length - 7);
                        }
                    }

                    if (callbacks.AllowFix(p, fixAction1) && text.StartsWith(Environment.NewLine, StringComparison.Ordinal))
                    {
                        if (pre.Length > 0)
                            text = pre + text.TrimStart(Utilities.NewLineChars);
                        else
                            text = text.TrimStart(Utilities.NewLineChars);
                        p.Text = text;
                        emptyLinesRemoved++;
                        callbacks.AddFixToListView(p, fixAction1, oldText, p.Text);
                    }
                    else
                    {
                        text = pre + text;
                    }

                    if (callbacks.AllowFix(p, fixAction2) && text.EndsWith(Environment.NewLine, StringComparison.Ordinal))
                    {
                        if (post.Length > 0)
                            text = text.TrimEnd(Utilities.NewLineChars) + post;
                        else
                            text = text.TrimEnd(Utilities.NewLineChars);
                        p.Text = text;
                        emptyLinesRemoved++;
                        callbacks.AddFixToListView(p, fixAction2, oldText, p.Text);
                    }
                }
            }

            // this must be the very last action done, or line numbers will be messed up!!!
            for (int i = subtitle.Paragraphs.Count - 1; i >= 0; i--)
            {
                Paragraph p = subtitle.Paragraphs[i];
                var text = HtmlUtil.RemoveHtmlTags(p.Text, true).Trim();
                if (callbacks.AllowFix(p, fixAction0) && string.IsNullOrEmpty(text))
                {
                    subtitle.Paragraphs.RemoveAt(i);
                    emptyLinesRemoved++;
                    callbacks.AddFixToListView(p, fixAction0, p.Text, string.Format("[{0}]", language.RemovedEmptyLine));
                    callbacks.AddToDeleteIndices(i);
                }
            }

            if (emptyLinesRemoved > 0)
            {
                callbacks.UpdateFixStatus(emptyLinesRemoved, language.RemovedEmptyLinesUnsedLineBreaks, string.Format(language.EmptyLinesRemovedX, emptyLinesRemoved));
                subtitle.Renumber();
            }
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            string fixAction = Language.AddMissingQuote;
            int    noOfFixes = 0;
            var    skipTo    = -1;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                if (i < skipTo)
                {
                    continue;
                }

                var    p       = subtitle.Paragraphs[i];
                string oldText = p.Text;
                p.Text = FixDifferentQuotes(p.Text); //TODO: extract to own rule

                if (Utilities.CountTagInText(p.Text, '"') == 1)
                {
                    var next = subtitle.GetParagraphOrDefault(i + 1);
                    if (next != null)
                    {
                        double betweenMilliseconds = next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds;
                        if (betweenMilliseconds > 1500)
                        {
                            next = null; // cannot be quote spanning several lines of more than 1.5 seconds between lines!
                        }
                        else if (next.Text.Replace("<i>", string.Empty).TrimStart().TrimStart('-').TrimStart().StartsWith('"') &&
                                 next.Text.Replace("</i>", string.Empty).TrimEnd().EndsWith('"') &&
                                 Utilities.CountTagInText(next.Text, '"') == 2)
                        {
                            next = null; // seems to have valid quotes, so no spanning
                        }
                    }
                    if (next != null && !HtmlUtil.RemoveHtmlTags(p.Text).EndsWith('"') && next.Text.TrimEnd('.', '!', '?').EndsWith('"'))
                    {
                        skipTo = i + 2;
                        continue;
                    }

                    if (next != null && next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds < 500 && !HtmlUtil.RemoveHtmlTags(p.Text).TrimEnd('.', '!', '?').EndsWith('"') && next.Text.IndexOf('"') < 0)
                    {
                        var next2 = subtitle.GetParagraphOrDefault(i + 2);
                        if (next2 != null && next2.StartTime.TotalMilliseconds - next.EndTime.TotalMilliseconds < 500 && Utilities.CountTagInText(next2.Text, '"') == 1 && next2.Text.TrimEnd('.', '!', '?').EndsWith('"'))
                        {
                            skipTo = i + 3;
                            continue;
                        }
                        var next3 = subtitle.GetParagraphOrDefault(i + 3);
                        if (next2 != null && next3 != null && next2.StartTime.TotalMilliseconds - next.EndTime.TotalMilliseconds < 500 && next3.StartTime.TotalMilliseconds - next2.EndTime.TotalMilliseconds < 500 &&
                            next2.Text.IndexOf('"') < 0 && Utilities.CountTagInText(next3.Text, '"') == 1 && next3.Text.TrimEnd('.', '!', '?').EndsWith('"'))
                        {
                            skipTo = i + 4;
                            continue;
                        }
                    }

                    var prev = subtitle.GetParagraphOrDefault(i - 1);
                    if (prev != null)
                    {
                        double betweenMilliseconds = p.StartTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds;
                        if (betweenMilliseconds > 1500 || // cannot be quote spanning several lines of more than 1.5 seconds between lines!

                            // seems to have valid quotes, so no spanning
                            prev.Text.Replace("<i>", string.Empty).TrimStart().TrimStart('-').TrimStart().StartsWith('"') &&
                            prev.Text.Replace("</i>", string.Empty).TrimEnd().EndsWith('"') &&
                            Utilities.CountTagInText(prev.Text, '"') == 2)
                        {
                            prev = null;
                        }
                    }

                    var lines = HtmlUtil.RemoveHtmlTags(p.Text).SplitToLines();
                    if (lines.Count == 2 && lines[0].TrimStart().StartsWith('-') && lines[1].TrimStart().StartsWith('-'))
                    { // dialog
                        lines = p.Text.SplitToLines();
                        string line = lines[0].Trim();

                        if (line.Length > 5 && line.TrimStart().StartsWith("- \"", StringComparison.Ordinal) && (line.EndsWith('.') || line.EndsWith('!') || line.EndsWith('?')))
                        {
                            p.Text = p.Text.Trim().Replace(" " + Environment.NewLine, Environment.NewLine);
                            p.Text = p.Text.Replace(Environment.NewLine, "\"" + Environment.NewLine);
                        }
                        else if (line.Length > 5 && line.EndsWith('"') && line.Contains("- ") && line.IndexOf("- ", StringComparison.Ordinal) < 4)
                        {
                            p.Text = p.Text.Insert(line.IndexOf("- ", StringComparison.Ordinal) + 2, "\"");
                        }
                        else if (line.Contains('"') && line.IndexOf('"') > 2 && line.IndexOf('"') < line.Length - 3)
                        {
                            int index = line.IndexOf('"');
                            if (line[index - 1] == ' ')
                            {
                                p.Text = p.Text.Trim().Replace(" " + Environment.NewLine, Environment.NewLine);
                                p.Text = p.Text.Replace(Environment.NewLine, "\"" + Environment.NewLine);
                            }
                            else if (line[index + 1] == ' ')
                            {
                                if (line.Length > 5 && line.Contains("- ") && line.IndexOf("- ", StringComparison.Ordinal) < 4)
                                {
                                    p.Text = p.Text.Insert(line.IndexOf("- ", StringComparison.Ordinal) + 2, "\"");
                                }
                            }
                        }
                        else if (lines[1].Contains('"'))
                        {
                            line = lines[1].Trim();
                            if (line.Length > 5 && line.TrimStart().StartsWith("- \"", StringComparison.Ordinal) && (line.EndsWith('.') || line.EndsWith('!') || line.EndsWith('?')))
                            {
                                p.Text = p.Text.Trim() + "\"";
                            }
                            else if (line.Length > 5 && line.EndsWith('"') && p.Text.Contains(Environment.NewLine + "- "))
                            {
                                p.Text = p.Text.Insert(p.Text.IndexOf(Environment.NewLine + "- ", StringComparison.Ordinal) + Environment.NewLine.Length + 2, "\"");
                            }
                            else if (line.Contains('"') && line.IndexOf('"') > 2 && line.IndexOf('"') < line.Length - 3)
                            {
                                int index = line.IndexOf('"');
                                if (line[index - 1] == ' ')
                                {
                                    p.Text = p.Text.Trim() + "\"";
                                }
                                else if (line[index + 1] == ' ')
                                {
                                    if (line.Length > 5 && p.Text.Contains(Environment.NewLine + "- "))
                                    {
                                        p.Text = p.Text.Insert(p.Text.IndexOf(Environment.NewLine + "- ", StringComparison.Ordinal) + Environment.NewLine.Length + 2, "\"");
                                    }
                                }
                            }
                        }
                    }
                    else
                    { // not dialog
                        if (p.Text.StartsWith('"'))
                        {
                            if (next == null || !next.Text.Contains('"') && p.Text.HasSentenceEnding(callbacks.Language))
                            {
                                p.Text += "\"";
                            }
                        }
                        else if (p.Text.StartsWith("<i>\"", StringComparison.Ordinal) && p.Text.EndsWith("</i>", StringComparison.Ordinal) && Utilities.CountTagInText(p.Text, "</i>") == 1)
                        {
                            if (next == null || !next.Text.Contains('"'))
                            {
                                p.Text = p.Text.Replace("</i>", "\"</i>");
                            }
                        }
                        else if (p.Text.EndsWith('"'))
                        {
                            if (prev == null || !prev.Text.Contains('"') || (prev.Text.TrimEnd('"').HasSentenceEnding() && prev.Text.TrimEnd('"').IndexOf('"') < 0))
                            {
                                p.Text = "\"" + p.Text;
                            }
                        }
                        else if (p.Text.Contains(Environment.NewLine + "\"") && Utilities.GetNumberOfLines(p.Text) == 2)
                        {
                            if (next == null || !next.Text.Contains('"'))
                            {
                                p.Text = p.Text + "\"";
                            }
                        }
                        else if ((p.Text.Contains(Environment.NewLine + "\"") || p.Text.Contains(Environment.NewLine + "-\"") || p.Text.Contains(Environment.NewLine + "- \"")) &&
                                 Utilities.GetNumberOfLines(p.Text) == 2 && p.Text.Length > 3)
                        {
                            if (next == null || !next.Text.Contains('"'))
                            {
                                if (p.Text.StartsWith("<i>", StringComparison.Ordinal) && p.Text.EndsWith("</i>", StringComparison.Ordinal) && Utilities.CountTagInText(p.Text, "</i>") == 1)
                                {
                                    p.Text = p.Text.Replace("</i>", "\"</i>");
                                }
                                else
                                {
                                    p.Text = p.Text + "\"";
                                }
                            }
                        }
                        else if (p.Text.StartsWith("<i>", StringComparison.Ordinal) && p.Text.EndsWith("</i>", StringComparison.Ordinal) && Utilities.CountTagInText(p.Text, "<i>") == 1)
                        {
                            if (prev == null || !prev.Text.Contains('"'))
                            {
                                p.Text = p.Text.Replace("<i>", "<i>\"");
                            }
                        }
                        else if (p.Text.Contains('"'))
                        {
                            string text         = p.Text;
                            int    indexOfQuote = p.Text.IndexOf('"');
                            if (text.Contains('"') && indexOfQuote > 2 && indexOfQuote < text.Length - 3)
                            {
                                int index = text.IndexOf('"');
                                if (text[index - 1] == ' ')
                                {
                                    if (p.Text.EndsWith(','))
                                    {
                                        p.Text = p.Text.Insert(p.Text.Length - 1, "\"").Trim();
                                    }
                                    else
                                    {
                                        p.Text = p.Text.Trim() + "\"";
                                    }
                                }
                                else if (text[index + 1] == ' ')
                                {
                                    p.Text = "\"" + p.Text;
                                }
                            }
                        }
                    }
                }

                if (oldText != p.Text)
                {
                    if (callbacks.AllowFix(p, fixAction))
                    {
                        noOfFixes++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                    else
                    {
                        p.Text = oldText;
                    }
                }
            }
            callbacks.UpdateFixStatus(noOfFixes, fixAction);
        }
Example #54
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language  = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.StartWithUppercaseLetterAfterPeriodInsideParagraph;
            int    noOfFixes = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p       = subtitle.Paragraphs[i];
                string    oldText = p.Text;
                var       st      = new StripableText(p.Text);
                if (p.Text.Length > 3)
                {
                    string text  = st.StrippedText.Replace("  ", " ");
                    int    start = text.IndexOfAny(ExpectedChars);
                    while (start >= 0 && start < text.Length)
                    {
                        if (start > 0 && char.IsDigit(text[start - 1]))
                        {
                            // ignore periods after a number
                        }
                        else if (start + 4 < text.Length && text[start + 1] == ' ')
                        {
                            if (!IsAbbreviation(text, start, callbacks))
                            {
                                var subText = new StripableText(text.Substring(start + 2));
                                if (subText.StrippedText.Length > 0 && Helper.IsTurkishLittleI(subText.StrippedText[0], callbacks.Encoding, callbacks.Language))
                                {
                                    if (subText.StrippedText.Length > 1 && !(subText.Pre.Contains('\'') && subText.StrippedText.StartsWith('s')))
                                    {
                                        text = text.Substring(0, start + 2) + subText.Pre + Helper.GetTurkishUppercaseLetter(subText.StrippedText[0], callbacks.Encoding) + subText.StrippedText.Substring(1) + subText.Post;
                                        if (callbacks.AllowFix(p, fixAction))
                                        {
                                            p.Text = st.Pre + text + st.Post;
                                        }
                                    }
                                }
                                else if (subText.StrippedText.Length > 0 && Configuration.Settings.General.UppercaseLetters.Contains(char.ToUpper(subText.StrippedText[0])))
                                {
                                    if (subText.StrippedText.Length > 1 && !(subText.Pre.Contains('\'') && subText.StrippedText.StartsWith('s')))
                                    {
                                        text = text.Substring(0, start + 2) + subText.Pre + char.ToUpper(subText.StrippedText[0]) + subText.StrippedText.Substring(1) + subText.Post;
                                        if (callbacks.AllowFix(p, fixAction))
                                        {
                                            p.Text = st.Pre + text + st.Post;
                                        }
                                    }
                                }
                            }
                        }
                        start += 4;
                        if (start < text.Length)
                        {
                            start = text.IndexOfAny(ExpectedChars, start);
                        }
                    }
                }

                if (oldText != p.Text)
                {
                    noOfFixes++;
                    callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                }
            }
            callbacks.UpdateFixStatus(noOfFixes, language.StartWithUppercaseLetterAfterPeriodInsideParagraph, noOfFixes.ToString(CultureInfo.InvariantCulture));
        }
Example #55
0
        private void FixSpanishInvertedLetter(char mark, string inverseMark, Paragraph p, Paragraph last, ref bool wasLastLineClosed, string fixAction, ref int fixCount, IFixCallbacks callbacks)
        {
            if (p.Text.Contains(mark))
            {
                bool skip = last != null && !p.Text.Contains(inverseMark) && last.Text.Contains(inverseMark) && !last.Text.Contains(mark);

                if (!skip && Utilities.CountTagInText(p.Text, mark) == Utilities.CountTagInText(p.Text, inverseMark) &&
                    HtmlUtil.RemoveHtmlTags(p.Text).TrimStart(inverseMark[0]).Contains(inverseMark) == false &&
                    HtmlUtil.RemoveHtmlTags(p.Text).TrimEnd(mark).Contains(mark) == false)
                {
                    skip = true;
                }

                if (!skip)
                {
                    int startIndex = 0;
                    int markIndex  = p.Text.IndexOf(mark);
                    if (!wasLastLineClosed && ((p.Text.IndexOf('!') > 0 && p.Text.IndexOf('!') < markIndex) ||
                                               (p.Text.IndexOf('?') > 0 && p.Text.IndexOf('?') < markIndex) ||
                                               (p.Text.IndexOf('.') > 0 && p.Text.IndexOf('.') < markIndex)))
                    {
                        wasLastLineClosed = true;
                    }

                    while (markIndex > 0 && startIndex < p.Text.Length)
                    {
                        int inverseMarkIndex = p.Text.IndexOf(inverseMark, startIndex, StringComparison.Ordinal);
                        if (wasLastLineClosed && (inverseMarkIndex < 0 || inverseMarkIndex > markIndex))
                        {
                            if (callbacks.AllowFix(p, fixAction))
                            {
                                int j = markIndex - 1;

                                while (j > startIndex && (p.Text[j] == '.' || p.Text[j] == '!' || p.Text[j] == '?'))
                                {
                                    j--;
                                }

                                while (j > startIndex &&
                                       (p.Text[j] != '.' || IsSpanishAbbreviation(p.Text, j, callbacks)) &&
                                       p.Text[j] != '!' &&
                                       p.Text[j] != '?' &&
                                       !(j > 3 && p.Text.Substring(j - 3, 3) == Environment.NewLine + "-") &&
                                       !(j > 4 && p.Text.Substring(j - 4, 4) == Environment.NewLine + " -") &&
                                       !(j > 6 && p.Text.Substring(j - 6, 6) == Environment.NewLine + "<i>-"))
                                {
                                    j--;
                                }

                                if (@".!?".Contains(p.Text[j]))
                                {
                                    j++;
                                }
                                if (j + 3 < p.Text.Length && p.Text.Substring(j + 1, 2) == Environment.NewLine)
                                {
                                    j += 3;
                                }
                                else if (j + 2 < p.Text.Length && p.Text.Substring(j, 2) == Environment.NewLine)
                                {
                                    j += 2;
                                }
                                if (j >= startIndex)
                                {
                                    string part = p.Text.Substring(j, markIndex - j + 1);

                                    string speaker    = string.Empty;
                                    int    speakerEnd = part.IndexOf(')');
                                    if (part.StartsWith('(') && speakerEnd > 0 && speakerEnd < part.IndexOf(mark))
                                    {
                                        while (Environment.NewLine.Contains(part[speakerEnd + 1]))
                                        {
                                            speakerEnd++;
                                        }

                                        speaker = part.Substring(0, speakerEnd + 1);
                                        part    = part.Substring(speakerEnd + 1);
                                    }
                                    speakerEnd = part.IndexOf(']');
                                    if (part.StartsWith('[') && speakerEnd > 0 && speakerEnd < part.IndexOf(mark))
                                    {
                                        while (Environment.NewLine.Contains(part[speakerEnd + 1]))
                                        {
                                            speakerEnd++;
                                        }

                                        speaker = part.Substring(0, speakerEnd + 1);
                                        part    = part.Substring(speakerEnd + 1);
                                    }

                                    var st = new StrippableText(part);
                                    if (j == 0 && mark == '!' && st.Pre == "¿" && Utilities.CountTagInText(p.Text, mark) == 1 && HtmlUtil.RemoveHtmlTags(p.Text).EndsWith(mark))
                                    {
                                        p.Text = inverseMark + p.Text;
                                    }
                                    else if (j == 0 && mark == '?' && st.Pre == "¡" && Utilities.CountTagInText(p.Text, mark) == 1 && HtmlUtil.RemoveHtmlTags(p.Text).EndsWith(mark))
                                    {
                                        p.Text = inverseMark + p.Text;
                                    }
                                    else
                                    {
                                        string temp       = inverseMark;
                                        int    addToIndex = 0;
                                        while (p.Text.Length > markIndex + 1 && p.Text[markIndex + 1] == mark &&
                                               Utilities.CountTagInText(p.Text, mark) > Utilities.CountTagInText(p.Text + temp, inverseMark))
                                        {
                                            temp    += inverseMark;
                                            st.Post += mark;
                                            markIndex++;
                                            addToIndex++;
                                        }

                                        p.Text     = p.Text.Remove(j, markIndex - j + 1).Insert(j, speaker + st.Pre + temp + st.StrippedText + st.Post);
                                        markIndex += addToIndex;
                                    }
                                }
                            }
                        }
                        else if (last != null && !wasLastLineClosed && inverseMarkIndex == p.Text.IndexOf(mark) && !last.Text.Contains(inverseMark))
                        {
                            string lastOldtext = last.Text;
                            int    idx         = last.Text.Length - 2;
                            while (idx > 0 && (last.Text.Substring(idx, 2) != ". ") && (last.Text.Substring(idx, 2) != "! ") && (last.Text.Substring(idx, 2) != "? "))
                            {
                                idx--;
                            }

                            last.Text = last.Text.Insert(idx, inverseMark);
                            fixCount++;
                            callbacks.AddFixToListView(last, fixAction, lastOldtext, last.Text);
                        }

                        startIndex = markIndex + 2;
                        if (startIndex < p.Text.Length)
                        {
                            markIndex = p.Text.IndexOf(mark, startIndex);
                        }
                        else
                        {
                            markIndex = -1;
                        }

                        wasLastLineClosed = true;
                    }
                }
                if (p.Text.EndsWith(mark + "...", StringComparison.Ordinal) && p.Text.Length > 4)
                {
                    p.Text = p.Text.Remove(p.Text.Length - 4, 4) + "..." + mark;
                }
            }
            else if (Utilities.CountTagInText(p.Text, inverseMark) == 1)
            {
                int idx = p.Text.IndexOf(inverseMark, StringComparison.Ordinal);
                while (idx < p.Text.Length && !@".!?".Contains(p.Text[idx]))
                {
                    idx++;
                }
                if (idx < p.Text.Length)
                {
                    p.Text = p.Text.Insert(idx, mark.ToString(CultureInfo.InvariantCulture));
                    if (p.Text.Contains("¡¿") && p.Text.Contains("!?"))
                    {
                        p.Text = p.Text.Replace("!?", "?!");
                    }

                    if (p.Text.Contains("¿¡") && p.Text.Contains("?!"))
                    {
                        p.Text = p.Text.Replace("?!", "!?");
                    }
                }
            }
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var language = Configuration.Settings.Language.FixCommonErrors;

            // negative display time
            string fixAction = language.FixOverlappingDisplayTime;
            int noOfOverlappingDisplayTimesFixed = 0;
            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                var p = subtitle.Paragraphs[i];
                var oldP = new Paragraph(p);
                if (p.Duration.TotalMilliseconds < 0) // negative display time...
                {
                    bool isFixed = false;
                    string status = string.Format(language.StartTimeLaterThanEndTime,
                                                    i + 1, p.StartTime, p.EndTime, p.Text, Environment.NewLine);

                    var prev = subtitle.GetParagraphOrDefault(i - 1);
                    var next = subtitle.GetParagraphOrDefault(i + 1);

                    double wantedDisplayTime = Utilities.GetOptimalDisplayMilliseconds(p.Text) * 0.9;

                    if (next == null || next.StartTime.TotalMilliseconds > p.StartTime.TotalMilliseconds + wantedDisplayTime)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + wantedDisplayTime;
                            isFixed = true;
                        }
                    }
                    else if (next.StartTime.TotalMilliseconds > p.StartTime.TotalMilliseconds + 500.0)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + 500.0;
                            isFixed = true;
                        }
                    }
                    else if (prev == null || next.StartTime.TotalMilliseconds - wantedDisplayTime > prev.EndTime.TotalMilliseconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            p.StartTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - wantedDisplayTime;
                            p.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - 1;
                            isFixed = true;
                        }
                    }
                    else
                    {
                        callbacks.LogStatus(language.FixOverlappingDisplayTimes, string.Format(language.UnableToFixStartTimeLaterThanEndTime, i + 1, p), true);
                        callbacks.AddToTotalErrors(1);
                    }

                    if (isFixed)
                    {
                        noOfOverlappingDisplayTimesFixed++;
                        status = string.Format(language.XFixedToYZ, status, Environment.NewLine, p);
                        callbacks.LogStatus(language.FixOverlappingDisplayTimes, status);
                        callbacks.AddFixToListView(p, fixAction, oldP.ToString(), p.ToString());
                    }
                }
            }

            // overlapping display time
            for (int i = 1; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p = subtitle.Paragraphs[i];
                Paragraph prev = subtitle.GetParagraphOrDefault(i - 1);
                Paragraph target = prev;
                string oldCurrent = p.ToString();
                string oldPrevious = prev.ToString();
                double prevWantedDisplayTime = Utilities.GetOptimalDisplayMilliseconds(prev.Text, Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds);
                double currentWantedDisplayTime = Utilities.GetOptimalDisplayMilliseconds(p.Text, Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds);
                double prevOptimalDisplayTime = Utilities.GetOptimalDisplayMilliseconds(prev.Text);
                double currentOptimalDisplayTime = Utilities.GetOptimalDisplayMilliseconds(p.Text);
                bool canBeEqual = callbacks.Format != null && callbacks.Format.GetType() == typeof(AdvancedSubStationAlpha) || callbacks.Format.GetType() == typeof(SubStationAlpha);
                if (!canBeEqual)
                    canBeEqual = Configuration.Settings.Tools.FixCommonErrorsFixOverlapAllowEqualEndStart;

                double diff = prev.EndTime.TotalMilliseconds - p.StartTime.TotalMilliseconds;
                if (!prev.StartTime.IsMaxTime && !p.StartTime.IsMaxTime && diff >= 0 && !(canBeEqual && Math.Abs(diff) < 0.001))
                {
                    int diffHalf = (int)(diff / 2);
                    if (!Configuration.Settings.Tools.FixCommonErrorsFixOverlapAllowEqualEndStart && Math.Abs(p.StartTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds) < 0.001 &&
                        prev.Duration.TotalMilliseconds > 100)
                    {
                        if (callbacks.AllowFix(target, fixAction))
                        {
                            if (!canBeEqual)
                            {
                                bool okEqual = true;
                                if (prev.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds)
                                    prev.EndTime.TotalMilliseconds--;
                                else if (p.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds)
                                    p.StartTime.TotalMilliseconds++;
                                else
                                    okEqual = false;
                                if (okEqual)
                                {
                                    noOfOverlappingDisplayTimesFixed++;
                                    callbacks.AddFixToListView(target, fixAction, oldPrevious, prev.ToString());
                                }
                            }
                        }
                        //prev.EndTime.TotalMilliseconds--;
                    }
                    else if (prevOptimalDisplayTime <= (p.StartTime.TotalMilliseconds - prev.StartTime.TotalMilliseconds))
                    {
                        if (callbacks.AllowFix(target, fixAction))
                        {
                            prev.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds - 1;
                            if (canBeEqual)
                                prev.EndTime.TotalMilliseconds++;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(target, fixAction, oldPrevious, prev.ToString());
                        }
                    }
                    else if (diff > 0 && currentOptimalDisplayTime <= p.Duration.TotalMilliseconds - diffHalf &&
                             prevOptimalDisplayTime <= prev.Duration.TotalMilliseconds - diffHalf)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            prev.EndTime.TotalMilliseconds -= diffHalf;
                            p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds + 1;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else if (currentOptimalDisplayTime <= p.EndTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds + 1;
                            if (canBeEqual)
                                p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else if (diff > 0 && currentWantedDisplayTime <= p.Duration.TotalMilliseconds - diffHalf &&
                             prevWantedDisplayTime <= prev.Duration.TotalMilliseconds - diffHalf)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            prev.EndTime.TotalMilliseconds -= diffHalf;
                            p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds + 1;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else if (prevWantedDisplayTime <= (p.StartTime.TotalMilliseconds - prev.StartTime.TotalMilliseconds))
                    {
                        if (callbacks.AllowFix(target, fixAction))
                        {
                            prev.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds - 1;
                            if (canBeEqual)
                                prev.EndTime.TotalMilliseconds++;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(target, fixAction, oldPrevious, prev.ToString());
                        }
                    }
                    else if (currentWantedDisplayTime <= p.EndTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds + 1;
                            if (canBeEqual)
                                p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else if (Math.Abs(p.StartTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds) < 10 && p.Duration.TotalMilliseconds > 1)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            prev.EndTime.TotalMilliseconds -= 2;
                            p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds + 1;
                            if (canBeEqual)
                                p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else if (Math.Abs(p.StartTime.TotalMilliseconds - prev.StartTime.TotalMilliseconds) < 10 && Math.Abs(p.EndTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds) < 10)
                    { // merge lines with same time codes
                        if (callbacks.AllowFix(target, fixAction))
                        {
                            prev.Text = prev.Text.Replace(Environment.NewLine, " ");
                            p.Text = p.Text.Replace(Environment.NewLine, " ");

                            string stripped = HtmlUtil.RemoveHtmlTags(prev.Text).TrimStart();
                            if (!stripped.StartsWith("- ", StringComparison.Ordinal))
                                prev.Text = "- " + prev.Text.TrimStart();

                            stripped = HtmlUtil.RemoveHtmlTags(p.Text).TrimStart();
                            if (!stripped.StartsWith("- ", StringComparison.Ordinal))
                                p.Text = "- " + p.Text.TrimStart();

                            prev.Text = prev.Text.Trim() + Environment.NewLine + p.Text;
                            p.Text = string.Empty;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(target, fixAction, oldCurrent, p.ToString());

                            p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds + 1;
                            p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + 1;
                            if (canBeEqual)
                            {
                                p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds;
                                p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds;
                            }
                        }
                    }
                    else
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            callbacks.LogStatus(language.FixOverlappingDisplayTimes, string.Format(language.UnableToFixTextXY, i + 1, Environment.NewLine + prev.Number + "  " + prev + Environment.NewLine + p.Number + "  " + p), true);
                            callbacks.AddToTotalErrors(1);
                        }
                    }
                }
            }

            callbacks.UpdateFixStatus(noOfOverlappingDisplayTimesFixed, fixAction, string.Format(language.XOverlappingTimestampsFixed, noOfOverlappingDisplayTimesFixed));
        }
Example #57
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language  = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixUppercaseIInsideLowercaseWord;
            int    uppercaseIsInsideLowercaseWords = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p       = subtitle.Paragraphs[i];
                string    oldText = p.Text;
                var       st      = new StrippableText(p.Text);

                Match match = ReAfterLowercaseLetter.Match(st.StrippedText);
                while (match.Success)
                {
                    if (!(match.Index > 1 && st.StrippedText.Substring(match.Index - 1, 2) == "Mc") && // irish names, McDonalds etc.
                        st.StrippedText[match.Index + 1] == 'I' &&
                        callbacks.AllowFix(p, fixAction))
                    {
                        string word = GetWholeWord(st.StrippedText, match.Index);
                        if (!callbacks.IsName(word))
                        {
                            var old = st.StrippedText;
                            st.StrippedText = st.StrippedText.Substring(0, match.Index + 1) + "l";
                            if (match.Index + 2 < old.Length)
                            {
                                st.StrippedText += old.Substring(match.Index + 2);
                            }
                            p.Text = st.MergedString;

                            st = new StrippableText(p.Text);
                            uppercaseIsInsideLowercaseWords++;
                            callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                            match = ReAfterLowercaseLetter.Match(st.StrippedText, match.Index);
                        }
                        else
                        {
                            match = match.NextMatch();
                        }
                    }
                    else
                    {
                        match = match.NextMatch();
                    }
                }

                match = ReBeforeLowercaseLetter.Match(st.StrippedText);
                while (match.Success)
                {
                    string word = GetWholeWord(st.StrippedText, match.Index);
                    if (!callbacks.IsName(word))
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            if (word.Equals("internal", StringComparison.OrdinalIgnoreCase) ||
                                word.Equals("island", StringComparison.OrdinalIgnoreCase) ||
                                word.Equals("islands", StringComparison.OrdinalIgnoreCase))
                            {
                            }
                            else if (match.Index == 0)
                            {  // first letter in paragraph
                               //too risky! - perhaps if periods is fixed at the same time... or too complicated!?
                               //if (isLineContinuation)
                               //{
                               //    st.StrippedText = st.StrippedText.Remove(match.Index, 1).Insert(match.Index, "l");
                               //    p.Text = st.MergedString;
                               //    uppercaseIsInsideLowercaseWords++;
                               //    AddFixToListView(p, fixAction, oldText, p.Text);
                               //}
                            }
                            else
                            {
                                if (match.Index > 2 && st.StrippedText[match.Index - 1] == ' ')
                                {
                                    if ((Utilities.AllLettersAndNumbers + @",").Contains(st.StrippedText[match.Index - 2]) &&
                                        match.Length >= 2 && Utilities.LowercaseVowels.Contains(char.ToLower(match.Value[1])))
                                    {
                                        st.StrippedText = st.StrippedText.Remove(match.Index, 1).Insert(match.Index, "l");
                                        p.Text          = st.MergedString;
                                        uppercaseIsInsideLowercaseWords++;
                                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                                    }
                                }
                                else if (match.Index > Environment.NewLine.Length + 1 && Environment.NewLine.Contains(st.StrippedText[match.Index - 1]))
                                {
                                    if ((Utilities.AllLettersAndNumbers + @",").Contains(st.StrippedText[match.Index - Environment.NewLine.Length + 1]) &&
                                        match.Length >= 2 && Utilities.LowercaseVowels.Contains(match.Value[1]))
                                    {
                                        st.StrippedText = st.StrippedText.Remove(match.Index, 1).Insert(match.Index, "l");
                                        p.Text          = st.MergedString;
                                        uppercaseIsInsideLowercaseWords++;
                                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                                    }
                                }
                                else if (match.Index > 1 && "\"'<>()[]{}-—,.‘’¡¿„“()[]♪@".Contains(st.StrippedText[match.Index - 1]))
                                {
                                }
                                else
                                {
                                    var before = '\0';
                                    var after  = '\0';
                                    if (match.Index > 0)
                                    {
                                        before = st.StrippedText[match.Index - 1];
                                    }
                                    if (match.Index < st.StrippedText.Length - 2)
                                    {
                                        after = st.StrippedText[match.Index + 1];
                                    }
                                    if (before != '\0' && char.IsUpper(before) && after != '\0' && char.IsLower(after) &&
                                        !Utilities.LowercaseVowels.Contains(char.ToLower(before)) && !Utilities.LowercaseVowels.Contains(after))
                                    {
                                        st.StrippedText = st.StrippedText.Remove(match.Index, 1).Insert(match.Index, "i");
                                        p.Text          = st.MergedString;
                                        uppercaseIsInsideLowercaseWords++;
                                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                                    }
                                    else if (@"‘’¡¿„“()[]♪'. @".Contains(before) && !Utilities.LowercaseVowels.Contains(char.ToLower(after)))
                                    {
                                    }
                                    else
                                    {
                                        var ok = true;

                                        if (match.Index >= 2 && st.StrippedText.Substring(match.Index - 2, 2) == "Mc")
                                        {
                                            ok = false;
                                        }

                                        if (ok)
                                        {
                                            st.StrippedText = st.StrippedText.Remove(match.Index, 1).Insert(match.Index, "l");
                                            p.Text          = st.MergedString;
                                            uppercaseIsInsideLowercaseWords++;
                                            callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    match = match.NextMatch();
                }
            }
            callbacks.UpdateFixStatus(uppercaseIsInsideLowercaseWords, language.FixUppercaseIInsindeLowercaseWords, language.XUppercaseIsFoundInsideLowercaseWords);
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            // negative display time
            string fixAction = Language.FixOverlappingDisplayTime;
            int    noOfOverlappingDisplayTimesFixed = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                var p    = subtitle.Paragraphs[i];
                var oldP = new Paragraph(p);
                if (p.Duration.TotalMilliseconds < 0) // negative display time...
                {
                    bool   isFixed = false;
                    string status  = string.Format(Language.StartTimeLaterThanEndTime, i + 1, p.StartTime, p.EndTime, p.Text, Environment.NewLine);

                    var prev = subtitle.GetParagraphOrDefault(i - 1);
                    var next = subtitle.GetParagraphOrDefault(i + 1);

                    double wantedDisplayTime = Utilities.GetOptimalDisplayMilliseconds(p.Text) * 0.9;

                    if (next == null || next.StartTime.TotalMilliseconds > p.StartTime.TotalMilliseconds + wantedDisplayTime)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + wantedDisplayTime;
                            isFixed = true;
                        }
                    }
                    else if (next.StartTime.TotalMilliseconds > p.StartTime.TotalMilliseconds + 500.0)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            p.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds + 500.0;
                            isFixed = true;
                        }
                    }
                    else if (prev == null || next.StartTime.TotalMilliseconds - wantedDisplayTime > prev.EndTime.TotalMilliseconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            p.StartTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - wantedDisplayTime;
                            p.EndTime.TotalMilliseconds   = next.StartTime.TotalMilliseconds - 1;
                            isFixed = true;
                        }
                    }
                    else
                    {
                        callbacks.LogStatus(Language.FixOverlappingDisplayTimes, string.Format(Language.UnableToFixStartTimeLaterThanEndTime, i + 1, p), true);
                        callbacks.AddToTotalErrors(1);
                    }

                    if (isFixed)
                    {
                        noOfOverlappingDisplayTimesFixed++;
                        status = string.Format(Language.XFixedToYZ, status, Environment.NewLine, p);
                        callbacks.LogStatus(Language.FixOverlappingDisplayTimes, status);
                        callbacks.AddFixToListView(p, fixAction, oldP.ToString(), p.ToString());
                    }
                }
            }

            // overlapping display time
            for (int i = 1; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p                         = subtitle.Paragraphs[i];
                Paragraph prev                      = subtitle.GetParagraphOrDefault(i - 1);
                Paragraph target                    = prev;
                string    oldCurrent                = p.ToString();
                string    oldPrevious               = prev.ToString();
                double    prevWantedDisplayTime     = Utilities.GetOptimalDisplayMilliseconds(prev.Text, Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds);
                double    currentWantedDisplayTime  = Utilities.GetOptimalDisplayMilliseconds(p.Text, Configuration.Settings.General.SubtitleMaximumCharactersPerSeconds);
                double    prevOptimalDisplayTime    = Utilities.GetOptimalDisplayMilliseconds(prev.Text);
                double    currentOptimalDisplayTime = Utilities.GetOptimalDisplayMilliseconds(p.Text);
                bool      canBeEqual                = callbacks.Format != null && (callbacks.Format.GetType() == typeof(AdvancedSubStationAlpha) || callbacks.Format.GetType() == typeof(SubStationAlpha));
                if (!canBeEqual)
                {
                    canBeEqual = Configuration.Settings.Tools.FixCommonErrorsFixOverlapAllowEqualEndStart;
                }

                double diff = prev.EndTime.TotalMilliseconds - p.StartTime.TotalMilliseconds;
                if (!prev.StartTime.IsMaxTime && !p.StartTime.IsMaxTime && diff >= 0 && !(canBeEqual && Math.Abs(diff) < 0.001))
                {
                    int diffHalf = (int)(diff / 2);
                    if (!Configuration.Settings.Tools.FixCommonErrorsFixOverlapAllowEqualEndStart && Math.Abs(p.StartTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds) < 0.001 &&
                        prev.Duration.TotalMilliseconds > 100)
                    {
                        if (callbacks.AllowFix(target, fixAction))
                        {
                            if (!canBeEqual)
                            {
                                bool okEqual = true;
                                if (prev.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds)
                                {
                                    prev.EndTime.TotalMilliseconds--;
                                }
                                else if (p.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMinimumDisplayMilliseconds)
                                {
                                    p.StartTime.TotalMilliseconds++;
                                }
                                else
                                {
                                    okEqual = false;
                                }

                                if (okEqual)
                                {
                                    noOfOverlappingDisplayTimesFixed++;
                                    callbacks.AddFixToListView(target, fixAction, oldPrevious, prev.ToString());
                                }
                            }
                        }
                    }
                    else if (prevOptimalDisplayTime <= (p.StartTime.TotalMilliseconds - prev.StartTime.TotalMilliseconds))
                    {
                        if (callbacks.AllowFix(target, fixAction))
                        {
                            prev.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds - 1;
                            if (canBeEqual)
                            {
                                prev.EndTime.TotalMilliseconds++;
                            }

                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(target, fixAction, oldPrevious, prev.ToString());
                        }
                    }
                    else if (diff > 0 && currentOptimalDisplayTime <= p.Duration.TotalMilliseconds - diffHalf &&
                             prevOptimalDisplayTime <= prev.Duration.TotalMilliseconds - diffHalf)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            prev.EndTime.TotalMilliseconds -= diffHalf;
                            p.StartTime.TotalMilliseconds   = prev.EndTime.TotalMilliseconds + 1;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else if (currentOptimalDisplayTime <= p.EndTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds + 1;
                            if (canBeEqual)
                            {
                                p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds;
                            }

                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else if (diff > 0 && currentWantedDisplayTime <= p.Duration.TotalMilliseconds - diffHalf &&
                             prevWantedDisplayTime <= prev.Duration.TotalMilliseconds - diffHalf)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            prev.EndTime.TotalMilliseconds -= diffHalf;
                            p.StartTime.TotalMilliseconds   = prev.EndTime.TotalMilliseconds + 1;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else if (prevWantedDisplayTime <= (p.StartTime.TotalMilliseconds - prev.StartTime.TotalMilliseconds))
                    {
                        if (callbacks.AllowFix(target, fixAction))
                        {
                            prev.EndTime.TotalMilliseconds = p.StartTime.TotalMilliseconds - 1;
                            if (canBeEqual)
                            {
                                prev.EndTime.TotalMilliseconds++;
                            }

                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(target, fixAction, oldPrevious, prev.ToString());
                        }
                    }
                    else if (currentWantedDisplayTime <= p.EndTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds + 1;
                            if (canBeEqual)
                            {
                                p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds;
                            }

                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else if (Math.Abs(p.StartTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds) < 10 && p.Duration.TotalMilliseconds > 1)
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            prev.EndTime.TotalMilliseconds -= 2;
                            p.StartTime.TotalMilliseconds   = prev.EndTime.TotalMilliseconds + 1;
                            if (canBeEqual)
                            {
                                p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds;
                            }

                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(p, fixAction, oldCurrent, p.ToString());
                        }
                    }
                    else if (Math.Abs(p.StartTime.TotalMilliseconds - prev.StartTime.TotalMilliseconds) < 10 && Math.Abs(p.EndTime.TotalMilliseconds - prev.EndTime.TotalMilliseconds) < 10)
                    { // merge lines with same time codes
                        if (callbacks.AllowFix(target, fixAction))
                        {
                            prev.Text = prev.Text.Replace(Environment.NewLine, " ");
                            p.Text    = p.Text.Replace(Environment.NewLine, " ");

                            string stripped = HtmlUtil.RemoveHtmlTags(prev.Text).TrimStart();
                            if (!stripped.StartsWith("- ", StringComparison.Ordinal))
                            {
                                prev.Text = "- " + prev.Text.TrimStart();
                            }

                            stripped = HtmlUtil.RemoveHtmlTags(p.Text).TrimStart();
                            if (!stripped.StartsWith("- ", StringComparison.Ordinal))
                            {
                                p.Text = "- " + p.Text.TrimStart();
                            }

                            prev.Text = prev.Text.Trim() + Environment.NewLine + p.Text;
                            p.Text    = string.Empty;
                            noOfOverlappingDisplayTimesFixed++;
                            callbacks.AddFixToListView(target, fixAction, oldCurrent, p.ToString());

                            p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds + 1;
                            p.EndTime.TotalMilliseconds   = p.StartTime.TotalMilliseconds + 1;
                            if (canBeEqual)
                            {
                                p.StartTime.TotalMilliseconds = prev.EndTime.TotalMilliseconds;
                                p.EndTime.TotalMilliseconds   = p.StartTime.TotalMilliseconds;
                            }
                        }
                    }
                    else
                    {
                        if (callbacks.AllowFix(p, fixAction))
                        {
                            callbacks.LogStatus(Language.FixOverlappingDisplayTimes, string.Format(Language.UnableToFixTextXY, i + 1, Environment.NewLine + prev.Number + "  " + prev + Environment.NewLine + p.Number + "  " + p), true);
                            callbacks.AddToTotalErrors(1);
                        }
                    }
                }
            }

            callbacks.UpdateFixStatus(noOfOverlappingDisplayTimesFixed, fixAction);
        }
Example #59
0
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language      = Configuration.Settings.Language.FixCommonErrors;
            string languageCode  = callbacks.Language;
            string fixAction     = language.FixMissingSpace;
            int    missingSpaces = 0;
            var    dialogHelper  = new DialogSplitMerge {
                DialogStyle = Configuration.Settings.General.DialogStyle
            };
            const string expectedChars = @"""”<.";

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                var p = subtitle.Paragraphs[i];

                // missing space after comma ","
                var match = FixMissingSpacesReComma.Match(p.Text);
                while (match.Success)
                {
                    bool doFix = !expectedChars.Contains(p.Text[match.Index + 2]);

                    if (doFix && languageCode == "el" &&
                        (p.Text.Substring(match.Index).StartsWith("ό,τι", StringComparison.Ordinal) ||
                         p.Text.Substring(match.Index).StartsWith("O,τι", StringComparison.Ordinal) ||
                         p.Text.Substring(match.Index).StartsWith("Ό,τι", StringComparison.Ordinal) ||
                         p.Text.Substring(match.Index).StartsWith("Ο,ΤΙ", StringComparison.Ordinal) ||
                         p.Text.Substring(match.Index).StartsWith("ο,τι", StringComparison.Ordinal)))
                    {
                        doFix = false;
                    }

                    if (doFix && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = p.Text.Replace(match.Value, match.Value[0] + ", " + match.Value[match.Value.Length - 1]);
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                    match = match.NextMatch();
                }

                bool allowFix = callbacks.AllowFix(p, fixAction);

                // missing space after "?"
                match = FixMissingSpacesReQuestionMark.Match(p.Text);
                while (match.Success)
                {
                    if (allowFix && !@"""<".Contains(p.Text[match.Index + 2]))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = p.Text.Replace(match.Value, match.Value[0] + "? " + match.Value[match.Value.Length - 1]);
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                    match = FixMissingSpacesReQuestionMark.Match(p.Text, match.Index + 1);
                }

                // missing space after "!"
                match = FixMissingSpacesReExclamation.Match(p.Text);
                while (match.Success)
                {
                    if (allowFix && !@"""<".Contains(p.Text[match.Index + 2]))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = p.Text.Replace(match.Value, match.Value[0] + "! " + match.Value[match.Value.Length - 1]);
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                    match = FixMissingSpacesReExclamation.Match(p.Text, match.Index + 1);
                }

                // missing space after ":"
                match = FixMissingSpacesReColon.Match(p.Text);
                while (match.Success)
                {
                    int start = match.Index;
                    start -= 4;
                    if (start < 0)
                    {
                        start = 0;
                    }

                    int indexOfStartCodeTag = p.Text.IndexOf('{', start);
                    int indexOfEndCodeTag   = p.Text.IndexOf('}', start);
                    if (indexOfStartCodeTag >= 0 && indexOfEndCodeTag >= 0 && indexOfStartCodeTag < match.Index)
                    {
                        // we are inside a tag: like indexOfEndCodeTag "{y:i}Is this italic?"
                    }
                    else if (allowFix && !@"""<".Contains(p.Text[match.Index + 2]))
                    {
                        bool skipSwedishOrFinish = false;
                        if (languageCode == "sv" || languageCode == "fi")
                        {
                            var m = FixMissingSpacesReColonWithAfter.Match(p.Text, match.Index);
                            skipSwedishOrFinish = IsSwedishSkipValue(languageCode, m) || IsFinnishSkipValue(languageCode, m);
                        }
                        if (!skipSwedishOrFinish)
                        {
                            missingSpaces++;
                            string oldText = p.Text;
                            p.Text = p.Text.Replace(match.Value, match.Value[0] + ": " + match.Value[match.Value.Length - 1]);
                            callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                        }
                    }
                    match = FixMissingSpacesReColon.Match(p.Text, match.Index + 1);
                }

                // missing space after period "."
                match = FixMissingSpacesRePeriod.Match(p.Text);
                while (match.Success)
                {
                    if (!p.Text.Contains("www.", StringComparison.OrdinalIgnoreCase) &&
                        !p.Text.Contains("http://", StringComparison.OrdinalIgnoreCase) &&
                        !Url.IsMatch(p.Text)) // Skip urls.
                    {
                        bool isMatchAbbreviation = false;

                        string word = GetWordFromIndex(p.Text, match.Index);
                        if (Utilities.CountTagInText(word, '.') > 1)
                        {
                            isMatchAbbreviation = true;
                        }

                        if (!isMatchAbbreviation && word.Contains('@')) // skip emails
                        {
                            isMatchAbbreviation = true;
                        }

                        if (match.Value.Equals("h.d", StringComparison.OrdinalIgnoreCase) && match.Index > 0 && p.Text.Substring(match.Index - 1, 4).Equals("ph.d", StringComparison.OrdinalIgnoreCase))
                        {
                            isMatchAbbreviation = true;
                        }

                        if (!isMatchAbbreviation && callbacks.AllowFix(p, fixAction))
                        {
                            missingSpaces++;
                            string oldText = p.Text;
                            p.Text = p.Text.Replace(match.Value, match.Value.Replace(".", ". "));
                            callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                        }
                    }
                    match = match.NextMatch();
                }

                if (!p.Text.StartsWith("--", StringComparison.Ordinal))
                {
                    var newText = dialogHelper.AddSpaces(p.Text);
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }

                //fix missing spaces before/after quotes - Get a"get out of jail free"card. -> Get a "get out of jail free" card.
                if (Utilities.CountTagInText(p.Text, '"') == 2)
                {
                    int    start = p.Text.IndexOf('"');
                    int    end   = p.Text.LastIndexOf('"');
                    string quote = p.Text.Substring(start, end - start + 1);
                    if (!quote.Contains(Environment.NewLine))
                    {
                        string newText         = p.Text;
                        int    indexOfFontTag  = newText.IndexOf("<font ", StringComparison.OrdinalIgnoreCase);
                        bool   isAfterAssTag   = newText.Contains("{\\") && start > 0 && newText[start - 1] == '}';
                        bool   isAfterEllipsis = start >= 3 && newText.Substring(start - 3, 3) == "...";
                        if (!isAfterAssTag && !isAfterEllipsis && start > 0 && !(Environment.NewLine + @" >[(♪♫¿").Contains(p.Text[start - 1]))
                        {
                            if (indexOfFontTag < 0 || start > newText.IndexOf('>', indexOfFontTag)) // font tags can contain "
                            {
                                newText = newText.Insert(start, " ");
                                end++;
                            }
                        }
                        if (end < newText.Length - 2 && !(Environment.NewLine + @" <,.!?:;])♪♫¿").Contains(p.Text[end + 1]))
                        {
                            if (indexOfFontTag < 0 || end > newText.IndexOf('>', indexOfFontTag)) // font tags can contain "
                            {
                                newText = newText.Insert(end + 1, " ");
                            }
                        }
                        if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                        {
                            missingSpaces++;
                            string oldText = p.Text;
                            p.Text = newText;
                            callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                        }
                    }
                }

                //fix missing spaces before/after music quotes - #He's so happy# -> #He's so happy#
                var musicSymbols = new[] { '#', '♪', '♫' };
                if (p.Text.Length > 5 && p.Text.Contains(musicSymbols))
                {
                    var lines = p.Text.SplitToLines();
                    for (var lineIndex = 0; lineIndex < lines.Count; lineIndex++)
                    {
                        var lineNoHtmlAndMusicTags = HtmlUtil.RemoveHtmlTags(lines[lineIndex], true)
                                                     .RemoveChar('#')
                                                     .RemoveChar('♪')
                                                     .RemoveChar('♫');
                        if (lineNoHtmlAndMusicTags.Length > 1)
                        {
                            foreach (var musicSymbol in musicSymbols)
                            {
                                var fix = !(musicSymbol == '#' && Utilities.CountTagInText(lines[lineIndex], musicSymbol) == 1 && !lines[lineIndex].EndsWith(musicSymbol));
                                if (fix)
                                {
                                    lines[lineIndex] = FixMissingSpaceBeforeAfterMusicQuotes(lines[lineIndex], musicSymbol);
                                }
                            }
                        }
                    }
                    string newText = string.Join(Environment.NewLine, lines);
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }

                //fix missing spaces in "Hey...move it!" to "Hey... move it!"
                int index = p.Text.IndexOf("...", StringComparison.Ordinal);
                if (index > 0 && p.Text.Length > 5)
                {
                    string newText = p.Text;
                    while (index != -1)
                    {
                        if (newText.Length > index + 4 && index >= 1)
                        {
                            if (Utilities.AllLettersAndNumbers.Contains(newText[index + 3]) &&
                                Utilities.AllLettersAndNumbers.Contains(newText[index - 1]))
                            {
                                newText = newText.Insert(index + 3, " ");
                            }
                        }
                        index = newText.IndexOf("...", index + 2, StringComparison.Ordinal);
                    }
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }

                //fix missing spaces in "The<i>Bombshell</i> will gone." to "The <i>Bombshell</i> will gone."
                index = p.Text.IndexOf("<i>", StringComparison.OrdinalIgnoreCase);
                if (index >= 0 && p.Text.Length > 5)
                {
                    string newText = p.Text;
                    while (index != -1)
                    {
                        if (newText.Length > index + 6 && index > 1)
                        {
                            if (Utilities.AllLettersAndNumbers.Contains(newText[index + 3]) &&
                                Utilities.AllLettersAndNumbers.Contains(newText[index - 1]))
                            {
                                newText = newText.Insert(index, " ");
                            }
                        }
                        index = newText.IndexOf("<i>", index + 3, StringComparison.OrdinalIgnoreCase);
                    }
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }

                //fix missing spaces in "The <i>Bombshell</i>will gone." to "The <i>Bombshell</i> will gone."
                index = p.Text.IndexOf("</i>", StringComparison.OrdinalIgnoreCase);
                if (index > 3 && p.Text.Length > 5)
                {
                    string newText = p.Text;
                    while (index != -1)
                    {
                        if (newText.Length > index + 6 && index > 1)
                        {
                            if (Utilities.AllLettersAndNumbers.Contains(newText[index + 4]) &&
                                Utilities.AllLettersAndNumbers.Contains(newText[index - 1]))
                            {
                                newText = newText.Insert(index + 4, " ");
                            }
                        }
                        index = newText.IndexOf("</i>", index + 4, StringComparison.OrdinalIgnoreCase);
                    }
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }

                if (callbacks.Language == "fr") // special rules for French
                {
                    string newText = p.Text;
                    int    j       = 1;
                    while (j < newText.Length)
                    {
                        if (@"!?:;".Contains(newText[j]) && char.IsLetter(newText[j - 1]))
                        {
                            newText = newText.Insert(j++, " ");
                        }
                        j++;
                    }
                    if (newText != p.Text && callbacks.AllowFix(p, fixAction))
                    {
                        missingSpaces++;
                        string oldText = p.Text;
                        p.Text = newText;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(missingSpaces, language.FixMissingSpaces, string.Format(language.XMissingSpacesAdded, missingSpaces));
        }
        public void Fix(Subtitle subtitle, IFixCallbacks callbacks)
        {
            var    language  = Configuration.Settings.Language.FixCommonErrors;
            string fixAction = language.FixMissingPeriodAtEndOfLine;
            int    missigPeriodsAtEndOfLine = 0;

            for (int i = 0; i < subtitle.Paragraphs.Count; i++)
            {
                Paragraph p        = subtitle.Paragraphs[i];
                Paragraph next     = subtitle.GetParagraphOrDefault(i + 1);
                string    nextText = string.Empty;
                if (next != null)
                {
                    nextText = HtmlUtil.RemoveHtmlTags(next.Text).TrimStart('-', '"', '„').TrimStart();
                }
                string tempNoHtml = HtmlUtil.RemoveHtmlTags(p.Text).TrimEnd();

                if (IsOneLineUrl(p.Text) || p.Text.Contains(new[] { '♪', '♫' }) || p.Text.EndsWith('\''))
                {
                    // ignore urls
                }
                else if (!string.IsNullOrEmpty(nextText) && next != null &&
                         next.Text.Length > 0 &&
                         Utilities.UppercaseLetters.Contains(nextText[0]) &&
                         tempNoHtml.Length > 0 &&
                         !@",.!?:;>-])♪♫…".Contains(tempNoHtml[tempNoHtml.Length - 1]))
                {
                    string tempTrimmed = tempNoHtml.TrimEnd().TrimEnd('\'', '"', '“', '”').TrimEnd();
                    if (tempTrimmed.Length > 0 && !@")]*#¶.!?".Contains(tempTrimmed[tempTrimmed.Length - 1]) && p.Text != p.Text.ToUpper())
                    {
                        //don't end the sentence if the next word is an I word as they're always capped.
                        if (!next.Text.StartsWith("I ", StringComparison.Ordinal) && !next.Text.StartsWith("I'", StringComparison.Ordinal))
                        {
                            //test to see if the first word of the next line is a name
                            if (!callbacks.IsName(next.Text.Split(WordSplitChars)[0]) && callbacks.AllowFix(p, fixAction))
                            {
                                string oldText = p.Text;
                                if (p.Text.EndsWith('>'))
                                {
                                    int lastLessThan = p.Text.LastIndexOf('<');
                                    if (lastLessThan > 0)
                                    {
                                        p.Text = p.Text.Insert(lastLessThan, ".");
                                    }
                                }
                                else
                                {
                                    if (p.Text.EndsWith('“') && tempNoHtml.StartsWith('„'))
                                    {
                                        p.Text = p.Text.TrimEnd('“') + ".“";
                                    }
                                    else if (p.Text.EndsWith('"') && tempNoHtml.StartsWith('"'))
                                    {
                                        p.Text = p.Text.TrimEnd('"') + ".\"";
                                    }
                                    else
                                    {
                                        p.Text += ".";
                                    }
                                }
                                if (p.Text != oldText)
                                {
                                    missigPeriodsAtEndOfLine++;
                                    callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                                }
                            }
                        }
                    }
                }
                else if (next != null && !string.IsNullOrEmpty(p.Text) && Utilities.AllLettersAndNumbers.Contains(p.Text[p.Text.Length - 1]))
                {
                    if (p.Text != p.Text.ToUpper())
                    {
                        var st = new StripableText(next.Text);
                        if (st.StrippedText.Length > 0 && st.StrippedText != st.StrippedText.ToUpper() &&
                            Utilities.UppercaseLetters.Contains(st.StrippedText[0]))
                        {
                            if (callbacks.AllowFix(p, fixAction))
                            {
                                int j = p.Text.Length - 1;
                                while (j >= 0 && !@".!?¿¡".Contains(p.Text[j]))
                                {
                                    j--;
                                }
                                string endSign = ".";
                                if (j >= 0 && p.Text[j] == '¿')
                                {
                                    endSign = "?";
                                }
                                if (j >= 0 && p.Text[j] == '¡')
                                {
                                    endSign = "!";
                                }

                                string oldText = p.Text;
                                missigPeriodsAtEndOfLine++;
                                p.Text += endSign;
                                callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                            }
                        }
                    }
                }

                if (p.Text.Length > 4)
                {
                    int indexOfNewLine = p.Text.IndexOf(Environment.NewLine + " -", 3, StringComparison.Ordinal);
                    if (indexOfNewLine < 0)
                    {
                        indexOfNewLine = p.Text.IndexOf(Environment.NewLine + "-", 3, StringComparison.Ordinal);
                    }
                    if (indexOfNewLine < 0)
                    {
                        indexOfNewLine = p.Text.IndexOf(Environment.NewLine + "<i>-", 3, StringComparison.Ordinal);
                    }
                    if (indexOfNewLine < 0)
                    {
                        indexOfNewLine = p.Text.IndexOf(Environment.NewLine + "<i> -", 3, StringComparison.Ordinal);
                    }
                    if (indexOfNewLine > 0 && Configuration.Settings.General.UppercaseLetters.Contains(char.ToUpper(p.Text[indexOfNewLine - 1])) && callbacks.AllowFix(p, fixAction))
                    {
                        string oldText = p.Text;

                        string text = p.Text.Substring(0, indexOfNewLine);
                        var    st   = new StripableText(text);
                        if (st.Pre.TrimEnd().EndsWith('¿')) // Spanish ¿
                        {
                            p.Text = p.Text.Insert(indexOfNewLine, "?");
                        }
                        else if (st.Pre.TrimEnd().EndsWith('¡')) // Spanish ¡
                        {
                            p.Text = p.Text.Insert(indexOfNewLine, "!");
                        }
                        else
                        {
                            p.Text = p.Text.Insert(indexOfNewLine, ".");
                        }

                        missigPeriodsAtEndOfLine++;
                        callbacks.AddFixToListView(p, fixAction, oldText, p.Text);
                    }
                }
            }
            callbacks.UpdateFixStatus(missigPeriodsAtEndOfLine, language.AddPeriods, language.XPeriodsAdded);
        }