From 3cda76cffc4711b392cc81f3168013692372ec05 Mon Sep 17 00:00:00 2001 From: Ivandro Ismael Date: Sat, 24 Sep 2016 21:56:49 +0100 Subject: [PATCH] [MacSub] - Implement read/writing for MacSub --- libse/LibSE.csproj | 1 + libse/SubtitleFormats/MacSub.cs | 120 ++++++++++++++++++ libse/SubtitleFormats/SubtitleFormat.cs | 1 + .../SubtitleFormats/SubtitleFormatsTest.cs | 29 +++++ 4 files changed, 151 insertions(+) create mode 100644 libse/SubtitleFormats/MacSub.cs diff --git a/libse/LibSE.csproj b/libse/LibSE.csproj index 5550a9e75..0feeff93d 100644 --- a/libse/LibSE.csproj +++ b/libse/LibSE.csproj @@ -195,6 +195,7 @@ + diff --git a/libse/SubtitleFormats/MacSub.cs b/libse/SubtitleFormats/MacSub.cs new file mode 100644 index 000000000..898a3474a --- /dev/null +++ b/libse/SubtitleFormats/MacSub.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Nikse.SubtitleEdit.Core.SubtitleFormats +{ + /// + /// Implements MacSub (reading/writing). + /// http://devel.aegisub.org/wiki/SubtitleFormats/Macsub + /// + public class MacSub : SubtitleFormat + { + /// + /// Enum expecting line. + /// + private enum Expecting + { + StartFrame, + Text, + EndFrame + } + + public override string Extension + { + get + { + return ".txt"; + } + } + + public override bool IsTimeBased + { + get + { + return false; + } + } + + public override string Name + { + get + { + return "MacSub"; + } + } + + public override bool IsMine(List lines, string fileName) + { + var macSub = new Subtitle(); + LoadSubtitle(macSub, lines, fileName); + return macSub.Paragraphs.Count > _errorCount; + } + + public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName) + { + var expecting = Expecting.StartFrame; + subtitle.Paragraphs.Clear(); + _errorCount = 0; + var p = new Paragraph(); + for (int i = 0; i < lines.Count; i++) + { + string line = lines[i].Trim(); + string nextLine = null; + if (i + 1 < lines.Count) + { + nextLine = lines[i + 1].Trim(); + } + try + { + switch (expecting) + { + case Expecting.StartFrame: + p.StartFrame = int.Parse(line.TrimStart('/')); + expecting = Expecting.Text; + break; + + case Expecting.Text: + line = HtmlUtil.RemoveHtmlTags(line, true); + p.Text += string.IsNullOrEmpty(p.Text) ? line : Environment.NewLine + line; + // Next reading is going to be endframe if next line starts with (/) delimeter which indicates frame start. + if ((nextLine == null) || (nextLine.Length > 0 && nextLine[0] == '/')) + { + expecting = Expecting.EndFrame; + p.Number = i; + } + break; + + case Expecting.EndFrame: + p.EndFrame = int.Parse(line.TrimStart('/')); + subtitle.Paragraphs.Add(p); + // Prepare for next reading. + p = new Paragraph(); + expecting = Expecting.StartFrame; + break; + } + } + catch + { + _errorCount++; + } + } + + } + + public override string ToText(Subtitle subtitle, string title) + { + // Startframe + // Text + // Endframe. + const string writeFormat = "/{0}{3}{1}{3}/{2}{3}"; + var sb = new StringBuilder(); + foreach (var p in subtitle.Paragraphs) + { + sb.AppendFormat(writeFormat, MillisecondsToFrames(p.StartTime.TotalMilliseconds), HtmlUtil.RemoveHtmlTags(p.Text, true), + MillisecondsToFrames(p.EndTime.TotalMilliseconds), Environment.NewLine); + } + return sb.ToString(); + } + } +} diff --git a/libse/SubtitleFormats/SubtitleFormat.cs b/libse/SubtitleFormats/SubtitleFormat.cs index 84835e051..edc646a5d 100644 --- a/libse/SubtitleFormats/SubtitleFormat.cs +++ b/libse/SubtitleFormats/SubtitleFormat.cs @@ -87,6 +87,7 @@ namespace Nikse.SubtitleEdit.Core.SubtitleFormats new JsonType6(), new JsonType7(), new Lrc(), + new MacSub(), new MediaTransData(), new MicroDvd(), new MidwayInscriberCGX(), diff --git a/src/Test/Logic/SubtitleFormats/SubtitleFormatsTest.cs b/src/Test/Logic/SubtitleFormats/SubtitleFormatsTest.cs index db5e327aa..86e6874c4 100644 --- a/src/Test/Logic/SubtitleFormats/SubtitleFormatsTest.cs +++ b/src/Test/Logic/SubtitleFormats/SubtitleFormatsTest.cs @@ -899,5 +899,34 @@ Dialogue: Marked=0,0:00:01.00,0:00:03.00,Default,NTP,0000,0000,0000,!Effect," + #endregion + #region MacSub + + [TestMethod] + public void MacSubTest() + { + const string input = @"/3035 +Every satellite... +/3077 +/3082 +every constellation... +/3133 +/3138 +""souvenirs of space walks +and astronauts.“..."" +/3205"; + var macSub = new MacSub(); + var subtitle = new Subtitle(); + macSub.LoadSubtitle(subtitle, new List(input.SplitToLines()), null); + + // Test text. + Assert.AreEqual("Every satellite...", subtitle.Paragraphs[0].Text); + // Test line count. + Assert.AreEqual(2, subtitle.Paragraphs[2].NumberOfLines); + // Test frame. + Assert.AreEqual(3082, subtitle.Paragraphs[1].StartFrame); + } + + #endregion + } }