From d4faf96d0485823e1920db1f1e8627f69d800f8f Mon Sep 17 00:00:00 2001 From: niksedk Date: Tue, 12 Feb 2013 19:19:35 +0000 Subject: [PATCH] Added format SMIL Timesheet (data-* version) - Issue 121 git-svn-id: https://subtitleedit.googlecode.com/svn/trunk@1623 99eadd0c-20b8-1223-b5c4-2a2b2df33de2 --- .../SubtitleFormats/SmilTimesheetData.cs | 214 ++++++++++++++++++ src/Logic/SubtitleFormats/SubtitleFormat.cs | 1 + .../SubtitleFormats/UnknownSubtitle47.cs | 2 +- src/SubtitleEdit.csproj | 1 + 4 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 src/Logic/SubtitleFormats/SmilTimesheetData.cs diff --git a/src/Logic/SubtitleFormats/SmilTimesheetData.cs b/src/Logic/SubtitleFormats/SmilTimesheetData.cs new file mode 100644 index 000000000..d6edd9c09 --- /dev/null +++ b/src/Logic/SubtitleFormats/SmilTimesheetData.cs @@ -0,0 +1,214 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Nikse.SubtitleEdit.Logic.SubtitleFormats +{ + /// + /// http://wam.inrialpes.fr/timesheets/annotations/video.html + /// + public class SmilTimesheetData : SubtitleFormat + { + public override string Extension + { + get { return ".html"; } + } + + public override string Name + { + get { return "SMIL Timesheet"; } + } + + public override bool IsTimeBased + { + get { return true; } + } + + public override bool IsMine(List lines, string fileName) + { + var sb = new StringBuilder(); + foreach (string l in lines) + sb.AppendLine(l); + if (!sb.ToString().Contains(" data-begin")) + return false; + + var subtitle = new Subtitle(); + LoadSubtitle(subtitle, lines, fileName); + return subtitle.Paragraphs.Count > _errorCount; + } + + public override string ToText(Subtitle subtitle, string title) + { + string header = +@" + +" + Environment.NewLine + +"\t" + Environment.NewLine + +"\tSMIL Timesheet" + @" + +" + Environment.NewLine + +"\t
" + Environment.NewLine + +"\t\t" + Environment.NewLine; + + string paragraphWriteFormatOpen = "\t\t

\r\n{1}\r\n

"; + string paragraphWriteFormat = "\t\t

\r\n{2}\r\n

"; + int count = 1; + var sb = new StringBuilder(); + sb.AppendLine(header.Replace("_TITLE_", title)); + foreach (Paragraph p in subtitle.Paragraphs) + { + Paragraph next = subtitle.GetParagraphOrDefault(count); + string text = p.Text; + if (next != null && Math.Abs(next.StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds) < 100) + sb.AppendLine(string.Format(paragraphWriteFormatOpen, EncodeTime(p.StartTime), text)); + else + sb.AppendLine(string.Format(paragraphWriteFormat, EncodeTime(p.StartTime), EncodeTime(p.EndTime), text)); + count++; + } + sb.AppendLine("\t
"); + sb.AppendLine(""); + sb.AppendLine(""); + return sb.ToString().Trim(); + } + + private string EncodeTime(TimeCode time) + { + //3:15:22 + if (time.Hours > 0) + return string.Format("{0:00}:{1:00}:{2:00}.{3:00}", time.Hours, time.Minutes, time.Seconds, time.Milliseconds / 10); + if (time.Minutes > 9) + return string.Format("{0:00}:{1:00}.{2:00}", time.Minutes, time.Seconds, time.Milliseconds / 10); + return string.Format("{0}:{1:00}.{2:00}", time.Minutes, time.Seconds, time.Milliseconds / 10); + } + + private TimeCode DecodeTimeCode(string[] s) + { + if (s.Length == 3) + return new TimeCode(0, int.Parse(s[0]), int.Parse(s[1]), int.Parse(s[2]) * 10); + return new TimeCode(int.Parse(s[0]), int.Parse(s[1]), int.Parse(s[2]), int.Parse(s[3]) * 10); + } + + public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName) + { + _errorCount = 0; + var sb = new StringBuilder(); + foreach (string l in lines) + sb.AppendLine(l); + string allInput = sb.ToString(); + string allInputLower = allInput.ToLower(); + const string syncTag = "

= 0) + { + int syncEndPos = allInputLower.IndexOf("

", index); + if (syncEndPos > 0) + { + string s = allInput.Substring(syncStartPos+2, syncEndPos - syncStartPos -2); + int indexOfBegin = s.IndexOf(" data-begin="); + int indexOfAttributesEnd = s.IndexOf(">"); + if (indexOfBegin >= 0 && indexOfAttributesEnd > indexOfBegin) + { + string text = s.Substring(indexOfAttributesEnd).Remove(0, 1).Trim(); + text = text.Replace("
", Environment.NewLine); + text = text.Replace("
", Environment.NewLine); + text = text.Replace("
", Environment.NewLine); + text = text.Replace("\t", " "); + while (text.Contains(" ")) + text = text.Replace(" ", " "); + while (text.Contains(Environment.NewLine + " ")) + text = text.Replace(Environment.NewLine + " ", Environment.NewLine); + while (text.Contains(Environment.NewLine + Environment.NewLine)) + text = text.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine); + + string begin = s.Substring(indexOfBegin + " data-begin=".Length); + var tcBegin = new StringBuilder(); + for (int i = 0; i <= 10; i++) + { + if (begin.Length > i && "0123456789:.".Contains(begin[i].ToString())) + { + tcBegin.Append(begin[i].ToString()); + } + } + + var tcEnd = new StringBuilder(); + int indexOfEnd = s.IndexOf(" data-end="); + if (indexOfEnd >= 0) + { + string end = s.Substring(indexOfEnd + " data-end=".Length); + for (int i = 0; i <= 10; i++) + { + if (end.Length > i && "0123456789:.".Contains(end[i].ToString())) + { + tcEnd.Append(end[i].ToString()); + } + } + } + + var arr = tcBegin.ToString().Split(".:".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + if (arr.Length == 3 || arr.Length == 4) + { + var p = new Paragraph(); + p.Text = text; + try + { + p.StartTime = DecodeTimeCode(arr); + if (tcEnd.Length > 0) + { + arr = tcEnd.ToString().Split(".:".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + p.EndTime = DecodeTimeCode(arr); + } + subtitle.Paragraphs.Add(p); + } + catch + { + _errorCount++; + } + } + } + + } + if (syncEndPos <= 0) + { + syncStartPos = -1; + } + else + { + syncStartPos = allInputLower.IndexOf(syncTag, syncEndPos); + index = syncStartPos + syncTag.Length; + } + } + + index = 1; + foreach (Paragraph paragraph in subtitle.Paragraphs) + { + Paragraph next = subtitle.GetParagraphOrDefault(index); + if (next != null) + { + paragraph.EndTime.TotalMilliseconds = next.StartTime.TotalMilliseconds - 1; + } + else if (paragraph.EndTime.TotalMilliseconds < 50) + { + paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(paragraph.Text); + } + if (paragraph.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds) + { + paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(paragraph.Text); + } + index++; + } + + + foreach (Paragraph p2 in subtitle.Paragraphs) + p2.Text = Utilities.HtmlDecode(p2.Text); + + subtitle.Renumber(1); + } + + } +} diff --git a/src/Logic/SubtitleFormats/SubtitleFormat.cs b/src/Logic/SubtitleFormats/SubtitleFormat.cs index 2e29cd748..bc1975a8d 100644 --- a/src/Logic/SubtitleFormats/SubtitleFormat.cs +++ b/src/Logic/SubtitleFormats/SubtitleFormat.cs @@ -71,6 +71,7 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats new SamiModern(), new Scenarist(), new ScenaristClosedCaptions(), + new SmilTimesheetData(), new SonyDVDArchitect(), new SonyDVDArchitectExplicitDuration(), new SonyDVDArchitectLineAndDuration(), diff --git a/src/Logic/SubtitleFormats/UnknownSubtitle47.cs b/src/Logic/SubtitleFormats/UnknownSubtitle47.cs index 3fb3d0f80..a4dd37d87 100644 --- a/src/Logic/SubtitleFormats/UnknownSubtitle47.cs +++ b/src/Logic/SubtitleFormats/UnknownSubtitle47.cs @@ -90,7 +90,7 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats } if (paragraph.Duration.TotalMilliseconds > Configuration.Settings.General.SubtitleMaximumDisplayMilliseconds) { - paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(p.Text); + paragraph.EndTime.TotalMilliseconds = paragraph.StartTime.TotalMilliseconds + Utilities.GetOptimalDisplayMilliseconds(paragraph.Text); } index++; } diff --git a/src/SubtitleEdit.csproj b/src/SubtitleEdit.csproj index f3afe2b47..eacaeed56 100644 --- a/src/SubtitleEdit.csproj +++ b/src/SubtitleEdit.csproj @@ -804,6 +804,7 @@ +