diff --git a/src/Logic/SubtitleFormats/SoftNiSub.cs b/src/Logic/SubtitleFormats/SoftNiSub.cs index ce71249eb..91c437a5b 100644 --- a/src/Logic/SubtitleFormats/SoftNiSub.cs +++ b/src/Logic/SubtitleFormats/SoftNiSub.cs @@ -42,28 +42,85 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats foreach (Paragraph p in subtitle.Paragraphs) { string text = p.Text; - if (text.StartsWith("") && text.EndsWith("")) - text = "[" + text; - text = Utilities.RemoveHtmlTags(text); + bool positionTop = false; + + // If text starts with {\an8}, subtitle appears at the top + if (text.StartsWith("{\\an8}")) + { + positionTop = true; + // Remove the tag {\an8}. + text = text.Remove(0, 6); + } + + // Split lines (split a subtitle into its lines) + var lines = text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + int count = 0; + var lineSb = new StringBuilder(); + string tempLine = string.Empty; + Boolean nextLineInItalics = false; + foreach (string line in lines) + { + // Append line break in every line except the first one + if (count > 0) + lineSb.Append(Environment.NewLine); + + tempLine = line; + + // This line should be in italics (it was detected in previous line) + if (nextLineInItalics) + { + tempLine = "" + tempLine; + nextLineInItalics = false; + } + + if (tempLine.StartsWith("") && tempLine.EndsWith("")) + { + // Whole line is in italics + // Remove from the beginning + tempLine = tempLine.Remove(0, 3); + // Remove from the end + tempLine = tempLine.Remove(tempLine.Length - 4, 4); + // Add new italics tag at the beginning + tempLine = "[" + tempLine; + } + else if (tempLine.StartsWith("") && Utilities.CountTagInText(tempLine, "") > Utilities.CountTagInText(tempLine, "")) + { + // Line starts with but italics are not closed. So the next line should be in italics + nextLineInItalics = true; + } + lineSb.Append(tempLine); + count++; + + text = lineSb.ToString(); + // Replace remaining italics tags + text = text.Replace("", @"["); + text = text.Replace("", @"]"); + text = Utilities.RemoveHtmlTags(text); + } + + // Add top-position SoftNI marker "{" at the beginning of first line. + if (positionTop) + text = "{" + text; + sb.AppendLine(string.Format("{0}{1}{2}\\{3}", text, Environment.NewLine, p.StartTime.ToHHMMSSPeriodFF(), p.EndTime.ToHHMMSSPeriodFF())); } - sb.AppendLine(@"*END* -...........\........... -*CODE* -0000000000000000 -*CAST* -*GENERATOR* -*FONTS* -*READ* -0,300 15,000 130,000 100,000 25,000 -*TIMING* -1 25 0 -*TIMED BACKUP NAME* -C:\ -*FORMAT SAMPLE ÅåÉéÌìÕõÛûÿ* -*READ ADVANCED* -< > 1 1 0,300 -*MARKERS*"); + sb.AppendLine(@"*END*"); + sb.AppendLine(@"...........\..........."); + sb.AppendLine(@"*CODE*"); + sb.AppendLine(@"0000000000000000"); + sb.AppendLine(@"*CAST*"); + sb.AppendLine(@"*GENERATOR*"); + sb.AppendLine(@"*FONTS*"); + sb.AppendLine(@"*READ*"); + sb.AppendLine(@"0,300 15,000 130,000 100,000 25,000"); + sb.AppendLine(@"*TIMING*"); + sb.AppendLine(@"1 25 0"); + sb.AppendLine(@"*TIMED BACKUP NAME*"); + sb.AppendLine(@"C:\"); + sb.AppendLine(@"*FORMAT SAMPLE ÅåÉéÌìÕõÛûÿ*"); + sb.AppendLine(@"*READ ADVANCED*"); + sb.AppendLine(@"< > 1 1 0,300"); + sb.AppendLine(@"*MARKERS*"); return sb.ToString(); } @@ -85,6 +142,7 @@ C:\ string s = line.Trim(); if (regexTimeCodes.IsMatch(s)) { + // Start and end time separated by "\" var temp = s.Split('\\'); if (temp.Length > 1) { @@ -101,8 +159,46 @@ C:\ p.StartTime = DecodeTimeCode(startParts); p.EndTime = DecodeTimeCode(endParts); string text = sb.ToString().Trim(); - if (text.StartsWith("[")) - text = "" + text.Remove(0, 1) + ""; + + Boolean positionTop = false; + // If text starts with "{", subtitle appears at the top + if (text.StartsWith("{")) + { + positionTop = true; + // Remove the tag "{" + text = text.Remove(0, 1); + } + // Replace tags + text = text.Replace("[", @""); + text = text.Replace("]", @""); + + // Split subtitle lines (one subtitle has one or more lines) + var subtitleLines = text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + int count = 0; + var lineSb = new StringBuilder(); + string tempLine = string.Empty; + foreach (string subtitleLine in subtitleLines) + { + // Append line break in every line except the first one + if (count > 0) + lineSb.Append(Environment.NewLine); + tempLine = subtitleLine; + // Close italics in every line (if next line is in italics, SoftNI will use "[" at the beginning) + if (Utilities.CountTagInText(tempLine,"") > Utilities.CountTagInText(tempLine,"")) + tempLine = tempLine + ""; + + lineSb.Append(tempLine); + count++; + } + text = lineSb.ToString(); + + // Replace "line break" with just a line break (Subrip does not need to close italics and open them again in the next line). + text = text.Replace("" + Environment.NewLine + "", Environment.NewLine); + + // Subtitle appears at the top (add tag) + if (positionTop) + text = "{\\an8}" + text; + p.Text = text; if (text.Length > 0) subtitle.Paragraphs.Add(p); diff --git a/src/Logic/SubtitleFormats/SubtitleFormat.cs b/src/Logic/SubtitleFormats/SubtitleFormat.cs index 69fdd161b..3c53c3dde 100644 --- a/src/Logic/SubtitleFormats/SubtitleFormat.cs +++ b/src/Logic/SubtitleFormats/SubtitleFormat.cs @@ -89,12 +89,12 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats new ScenaristClosedCaptions(), new ScenaristClosedCaptionsDropFrame(), new SmilTimesheetData(), + new SoftNiSub(), new SonyDVDArchitect(), new SonyDVDArchitectExplicitDuration(), new SonyDVDArchitectLineAndDuration(), new SonyDVDArchitectTabs(), new SonyDVDArchitectWithLineNumbers(), - new SoftNiSub(), new Spruce(), new SpruceWithSpace(), new StructuredTitles(),