This commit is contained in:
Ivandro Jao 2024-03-28 16:11:49 +00:00
parent de837282f6
commit ac4049414c
2 changed files with 114 additions and 13 deletions

View File

@ -438,6 +438,41 @@ namespace Test.Logic
string s2 = HtmlUtil.FixInvalidItalicTags(s1);
Assert.AreEqual(s2, "<i>Hallo!" + Environment.NewLine + "Hallo!" + Environment.NewLine + "Hallo!</i>");
}
[TestMethod]
public void FixInvalidItalicTags15()
{
var s1 = "Foo<b><i>bar</b>";
Assert.AreEqual("Foo<b><i>bar</i></b>", HtmlUtil.FixInvalidItalicTags(s1));
}
[TestMethod]
public void FixInvalidItalicTags16()
{
var s1 = "Foo <i>bar";
Assert.AreEqual( "Foo <i>bar</i>", HtmlUtil.FixInvalidItalicTags(s1));
}
[TestMethod]
public void FixInvalidItalicTags17()
{
var s1 = "Foobar<i>";
Assert.AreEqual("Foobar", HtmlUtil.FixInvalidItalicTags(s1));
}
[TestMethod]
public void FixInvalidItalicTags18()
{
var s1 = "<u><b><i>Foobar</b></u>";
Assert.AreEqual("<u><b><i>Foobar</i></b></u>", HtmlUtil.FixInvalidItalicTags(s1));
}
[TestMethod]
public void FixInvalidItalicTags19()
{
var s1 = "<i>Foobar";
Assert.AreEqual("<i>Foobar</i>", HtmlUtil.FixInvalidItalicTags(s1));
}
[TestMethod]
public void FixInvalidItalicTagsWithAssTag()

View File

@ -588,6 +588,49 @@ namespace Nikse.SubtitleEdit.Core.Common
return text;
}
public static bool IsTextFormattable(in string text)
{
if (string.IsNullOrEmpty(text))
{
return false;
}
var len = text.Length;
int index = 0;
while (index < len && text[index] == '<')
{
index = text.IndexOf('>', index + 1);
if (index < 0) break;
index += 1;
}
// buggy text of no closing present
index = Math.Max(0, index);
var fromLenIdx = len - 1;
while (fromLenIdx >= 0 && text[fromLenIdx] == '>')
{
fromLenIdx = text.LastIndexOf('<', fromLenIdx);
if (fromLenIdx < 0) break;
fromLenIdx--;
}
fromLenIdx = fromLenIdx > 0 ? fromLenIdx : len;
// no formattable text in between
if (fromLenIdx < index) return false;
for (int i = index; i <= fromLenIdx; i++)
{
if (char.IsLetterOrDigit(text[i]))
{
return true;
}
}
return false;
}
public static string FixInvalidItalicTags(string input)
{
var text = input;
@ -739,21 +782,44 @@ namespace Nikse.SubtitleEdit.Core.Common
if (italicBeginTagCount == 1 && italicEndTagCount == 0)
{
var lastIndexWithNewLine = text.LastIndexOf(Environment.NewLine + beginTag, StringComparison.Ordinal) + Environment.NewLine.Length;
var lastIndex = text.LastIndexOf(beginTag, StringComparison.Ordinal);
var lines = text.SplitToLines();
var sc = StringComparison.Ordinal;
for (int i = 0; i < lines.Count; i++)
{
var line = lines[i];
var italicIndex = line.LastIndexOf(beginTag, StringComparison.Ordinal);
// no italic in current 'i' line, try next
if (italicIndex < 0)
{
continue;
}
if (text.StartsWith(beginTag, StringComparison.Ordinal) || text.Contains(": <i>"))
{
text += endTag;
}
else if (noOfLines == 2 && lastIndex == lastIndexWithNewLine)
{
text += endTag;
}
else
{
text = text.Replace(beginTag, string.Empty);
// try earlier insert if possible e.g: <b><i>foobar</b> => <b><i>foobar</i></b>
lines[i] = IsTextFormattable(line.Substring(italicIndex + 3))
? line.Insert(CalculateEarlyInsertIndex(line), endTag)
: line.Replace(beginTag, string.Empty);
break; // break as soon as we reach here since italicBeginTagCount == 1
int CalculateEarlyInsertIndex(string s)
{
var len = s.Length;
var lastClosingTagIndex = s.LastIndexOf("</", len - 1, len - italicIndex - 3, sc);
while (lastClosingTagIndex > italicIndex + 3)
{
var tempClosingIdx = s.LastIndexOf("</", lastClosingTagIndex, lastClosingTagIndex - italicIndex - 3, sc);
if (tempClosingIdx < 0) break;
lastClosingTagIndex = tempClosingIdx;
}
// try finding first closing tag index and insert the new closing there
// to avoid having text with closed tags like <b><i>foo</b></i>
return lastClosingTagIndex > italicIndex ? lastClosingTagIndex : len;
}
}
// reconstruct the text from lines
text = string.Join(Environment.NewLine, lines);
}
if (italicBeginTagCount == 0 && italicEndTagCount == 1)