using System; using System.Linq; using System.Text; namespace Nikse.SubtitleEdit.Core.Forms { public class MoveWordUpDown { public string S1 { get; private set; } public string S2 { get; private set; } public MoveWordUpDown(string s1, string s2) { S1 = s1 ?? string.Empty; S2 = s2 ?? string.Empty; } /// /// Move first word in S2 to up as last word in S1 /// public void MoveWordUp() { if (string.IsNullOrEmpty(S2)) { return; } var assTagOn = false; var htmlTagOn = false; var sbWord = new StringBuilder(); var done = false; var sbS2 = new StringBuilder(); for (int i = 0; i < S2.Length; i++) { var ch = S2[i]; if (done) { sbS2.Append(ch); } else if (assTagOn) { if (ch == '}') { assTagOn = false; } sbS2.Append(ch); } else if (htmlTagOn) { if (ch == '>') { htmlTagOn = false; } sbS2.Append(ch); } else if (ch == '{' && S2.Substring(i).StartsWith("{\\", StringComparison.Ordinal)) { assTagOn = true; sbS2.Append(ch); } else if (S2.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S2.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S2.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S2.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S2.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S2.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase)) { htmlTagOn = true; sbS2.Append(ch); } else if (sbWord.ToString().Trim().Length > 0 && (ch == ' ' || ch == '\r' || ch == '\n')) { done = true; } else { sbWord.Append(ch); } } S1 = AddWordAfter(sbWord.ToString().Trim(), S1); S1 = AutoBreakIfNeeded(S1); S2 = sbS2.ToString().Trim(); S2 = RemoveEmptyTags(S2); } /// /// Move last word from S1 down as first word in S2 /// public void MoveWordDown() { if (string.IsNullOrEmpty(S1)) { return; } var assTagOn = false; var htmlTagOn = false; var sbWord = new StringBuilder(); var done = false; var sbS1 = new StringBuilder(); for (int i = S1.Length - 1; i >= 0; i--) { var ch = S1[i]; if (done) { sbS1.Append(ch); } else if (assTagOn) { if (ch == '{' && S2.Substring(i).StartsWith("{\\", StringComparison.Ordinal)) { assTagOn = false; } sbS1.Append(ch); } else if (htmlTagOn) { if (S1.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(i).StartsWith("", StringComparison.OrdinalIgnoreCase)) { htmlTagOn = false; } sbS1.Append(ch); } else if (ch == '}' && S1.StartsWith("{\\", StringComparison.Ordinal)) { assTagOn = true; sbS1.Append(ch); } else if (ch == '>' && S1.Substring(0, i + 1).Contains("", StringComparison.OrdinalIgnoreCase) || S1.Substring(0, i + 1).EndsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(0, i + 1).EndsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(0, i + 1).EndsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(0, i + 1).EndsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(0, i + 1).EndsWith("", StringComparison.OrdinalIgnoreCase) || S1.Substring(0, i + 1).EndsWith("", StringComparison.OrdinalIgnoreCase)) { htmlTagOn = true; sbS1.Append(ch); } else if (sbWord.ToString().Trim().Length > 0 && (ch == ' ' || ch == '\r' || ch == '\n')) { done = true; } else { sbWord.Append(ch); } } S1 = string.Join(string.Empty, sbS1.ToString().Trim().ToCharArray().Reverse()); S1 = RemoveEmptyTags(S1); S2 = AddWordBefore(string.Join(string.Empty, sbWord.ToString().Trim().ToCharArray().Reverse()), S2); S2 = AutoBreakIfNeeded(S2); } private static bool IsPartOfFontTag(string s, int i) { var indexOfFontTag = s.Substring(0, i).LastIndexOf("", indexOfFontTag, StringComparison.Ordinal); if (indexOfEndFontTag < 0) { return false; } return i >= indexOfFontTag && i <= indexOfEndFontTag; } private static string RemoveEmptyTags(string s) { var noTags = HtmlUtil.RemoveHtmlTags(s, true); if (noTags.Length == 0) { return string.Empty; } return s .Replace("", string.Empty) .Replace("", string.Empty) .Replace("", string.Empty); } private static string AddWordBefore(string word, string input) { var pre = string.Empty; var s = input; if (s.StartsWith("{\\") && s.Contains("}")) { var idx = s.IndexOf('}'); pre = s.Substring(0, idx + 1); s = s.Remove(0, idx + 1); } var arr = s.SplitToLines(); if (s.StartsWith("", StringComparison.OrdinalIgnoreCase) && (s.EndsWith("", StringComparison.OrdinalIgnoreCase) || arr[0].EndsWith("", StringComparison.OrdinalIgnoreCase))) { return pre + s.Insert(3, word.Trim() + " ").Trim(); } return pre + (word.Trim() + " " + s.Trim()).Trim(); } private static string AddWordAfter(string word, string s) { var arr = s.SplitToLines(); if (s.EndsWith("", StringComparison.OrdinalIgnoreCase) && (s.StartsWith("", StringComparison.OrdinalIgnoreCase) || arr[arr.Count - 1].StartsWith("", StringComparison.OrdinalIgnoreCase))) { return s.Insert(s.Length - 4, " " + word.Trim()).Trim(); } return (s.Trim() + " " + word.Trim()).Trim(); } private static string AutoBreakIfNeeded(string s) { bool doBreak = false; foreach (var line in s.SplitToLines()) { if (HtmlUtil.RemoveHtmlTags(line, true).Length > Configuration.Settings.General.SubtitleLineMaximumLength) { doBreak = true; break; } } return doBreak ? Utilities.AutoBreakLine(s) : s; } } }