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); }
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); }
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)); }
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)); }
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)); }
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); }
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)); }
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); }
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()); }
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(); } }
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); }
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); }
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)); }
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); }
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)); }
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); }
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); }
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)); }
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); }
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)); }
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); }
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)); }
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)); }
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); }
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); }