From f70fa274e53be473a64748923e99a82bf5e6c5d8 Mon Sep 17 00:00:00 2001 From: niksedk Date: Tue, 25 Aug 2015 16:15:08 +0200 Subject: [PATCH] Added new subtitle format - thx Sebastian :) --- src/Logic/SubtitleFormats/SubtitleFormat.cs | 4 +- src/Logic/SubtitleFormats/Xif.cs | 241 ++++++++++++++++++++ src/SubtitleEdit.csproj | 1 + 3 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 src/Logic/SubtitleFormats/Xif.cs diff --git a/src/Logic/SubtitleFormats/SubtitleFormat.cs b/src/Logic/SubtitleFormats/SubtitleFormat.cs index cc73a1c4d..2d63269cc 100644 --- a/src/Logic/SubtitleFormats/SubtitleFormat.cs +++ b/src/Logic/SubtitleFormats/SubtitleFormat.cs @@ -1,4 +1,5 @@ -using Nikse.SubtitleEdit.Core; +using System.IO.Compression; +using Nikse.SubtitleEdit.Core; using System; using System.Collections.Generic; using System.IO; @@ -145,6 +146,7 @@ namespace Nikse.SubtitleEdit.Logic.SubtitleFormats new VocapiaSplit(), new WebVTT(), new WebVTTFileWithLineNumber(), + new Xif(), new YouTubeAnnotations(), new YouTubeSbv(), new YouTubeTranscript(), diff --git a/src/Logic/SubtitleFormats/Xif.cs b/src/Logic/SubtitleFormats/Xif.cs new file mode 100644 index 000000000..c02ea72b6 --- /dev/null +++ b/src/Logic/SubtitleFormats/Xif.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using System.Xml; +using Nikse.SubtitleEdit.Core; + +namespace Nikse.SubtitleEdit.Logic.SubtitleFormats +{ + class Xif : SubtitleFormat + { + public override string Extension + { + get { return ".xif"; } + } + + public override string Name + { + get { return "XIF"; } + } + + public override bool IsTimeBased + { + get { return true; } + } + + public override bool IsMine(List lines, string fileName) + { + var subtitle = new Subtitle(); + LoadSubtitle(subtitle, lines, fileName); + return subtitle.Paragraphs.Count > _errorCount; + } + + public override string ToText(Subtitle subtitle, string title) + { + const string xmpTemplate = @" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + + const string paragraphTemplate = @" + + + + + + + + + + + + + + + + text1 + + + + + "; + + var xml = new XmlDocument(); + var lastTimeCode = new TimeCode(0); + if (subtitle.Paragraphs.Count > 0) + { + lastTimeCode = subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].StartTime; + } + if (string.IsNullOrWhiteSpace(title)) + title = "Unknown"; + xml.LoadXml(xmpTemplate.Replace('\'', '"')); + var globalFileInfoNode = xml.DocumentElement.SelectSingleNode("FileHeader/GlobalFileInfo"); + globalFileInfoNode.Attributes["ProgrammeName"].InnerText = title; + globalFileInfoNode.Attributes["ProgrammeTitle"].InnerText = title; + globalFileInfoNode.Attributes["StopTime"].InnerText = lastTimeCode.ToHHMMSSFF(); + globalFileInfoNode.Attributes["NumberOfCaptions"].InnerText = subtitle.Paragraphs.Count.ToString(CultureInfo.InvariantCulture); + + + var fileBodyNode = xml.DocumentElement.SelectSingleNode("FileBody"); + foreach (Paragraph p in subtitle.Paragraphs) + { + XmlNode content = xml.CreateElement("ContentBlock"); + content.InnerXml = paragraphTemplate; + content.SelectSingleNode("ContentBlock/ThreadedObject/TimingObject/TimeIn").InnerText = p.StartTime.ToHHMMSSFF(); + content.SelectSingleNode("ContentBlock/ThreadedObject/TimingObject/TimeOut").InnerText = p.EndTime.ToHHMMSSFF(); + + var paragraphNode = content.SelectSingleNode("ContentBlock/ThreadedObject/Content/SubtitleText/Paragraph"); + var lines = HtmlUtil.RemoveHtmlTags(p.Text, true).SplitToLines(); + for (int i = 1; i < lines.Length + 1; i++) + { + var rowNode = xml.CreateElement("Row"); + + var attrNumber = xml.CreateAttribute("Number"); + attrNumber.InnerText = i.ToString(CultureInfo.InvariantCulture); + rowNode.Attributes.Append(attrNumber); + + var attrJust = xml.CreateAttribute("JustificationOverride"); + attrJust.InnerText = "Centre"; + rowNode.Attributes.Append(attrJust); + + var attrHighlight = xml.CreateAttribute("Highlight"); + attrHighlight.InnerText = "0"; + rowNode.Attributes.Append(attrHighlight); + + paragraphNode.AppendChild(rowNode); + } + for (int index = 0; index < lines.Length; index++) + { + var line = lines[index]; + + if (index > 0) + { + var hardReturnNode = xml.CreateElement("HardReturn"); + paragraphNode.AppendChild(hardReturnNode); + } + + var foregroundColorNode = xml.CreateElement("ForegroundColour"); + var attrColor = xml.CreateAttribute("Colour"); + attrColor.InnerText = "7"; + foregroundColorNode.Attributes.Append(attrColor); + paragraphNode.AppendChild(foregroundColorNode); + + var textNode = xml.CreateElement("Text"); + textNode.InnerText = line; + paragraphNode.AppendChild(textNode); + + } + fileBodyNode.AppendChild(content); + } + return ToUtf8XmlString(xml).Replace(" xmlns=\"\"", string.Empty); + } + + public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName) + { + _errorCount = 0; + var sb = new StringBuilder(); + lines.ForEach(line => sb.AppendLine(line)); + var xmlAsText = sb.ToString().Trim(); + if (!xmlAsText.Contains(" +