using System; using System.Collections.Generic; using System.Globalization; using System.Text; using System.Xml; namespace Nikse.SubtitleEdit.Core.SubtitleFormats { public 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 = @" "; var xml = new XmlDocument(); var lastTimeCode = new TimeCode(); 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.SelectSingleNode("ContentBlock")); } return ToUtf8XmlString(xml, true).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("