using System; using System.Collections.Generic; using System.Text; using System.Xml; namespace Nikse.SubtitleEdit.Core.SubtitleFormats { public class OresmeDocXDocument : SubtitleFormat { public override string Extension { get { return ".xml"; } } public override string Name { get { return "Oresme Docx document"; } } public override bool IsTimeBased { get { return true; } } public override bool IsMine(List lines, string fileName) { var sb = new StringBuilder(); lines.ForEach(line => sb.AppendLine(line)); string xmlAsString = sb.ToString().Trim(); if ((xmlAsString.Contains(""))) { var subtitle = new Subtitle(); LoadSubtitle(subtitle, lines, fileName); return subtitle.Paragraphs.Count > _errorCount; } return false; } private const string Layout = @" "; public override string ToText(Subtitle subtitle, string title) { string xmlStructure = Layout.Replace("'", "\""); var xml = new XmlDocument(); xml.LoadXml(xmlStructure); var nsmgr = new XmlNamespaceManager(xml.NameTable); nsmgr.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); XmlNode div = xml.DocumentElement.SelectSingleNode("w:body/w:tbl", nsmgr); for (int i = 0; i < subtitle.Paragraphs.Count; i++) { Paragraph p = subtitle.Paragraphs[i]; div.AppendChild(CreateXmlParagraph(xml, p)); if (i < subtitle.Paragraphs.Count - 1 && Math.Abs(p.EndTime.TotalMilliseconds - subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds) > 100) { var endP = new Paragraph(string.Empty, p.EndTime.TotalMilliseconds, 0); div.AppendChild(CreateXmlParagraph(xml, endP)); } } string s = ToUtf8XmlString(xml); return s; } private static XmlNode CreateXmlParagraph(XmlDocument xml, Paragraph p) { XmlNode paragraph = xml.CreateElement("w:tr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); var tc1 = xml.CreateElement("w:tc", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); paragraph.AppendChild(tc1); // // // var n1 = xml.CreateElement("w:tcPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); var n1sub = xml.CreateElement("w:tcW", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); // n1.AppendChild(n1sub); var n1suba1 = xml.CreateAttribute("w:w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n1suba1.InnerText = "1240"; n1sub.Attributes.Append(n1suba1); var n1suba2 = xml.CreateAttribute("w:type", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n1suba2.InnerText = "dxa"; n1sub.Attributes.Append(n1suba2); tc1.AppendChild(n1); // // // // // // [TIMECODE] // // var n2 = xml.CreateElement("w:p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); var n1a1 = xml.CreateAttribute("w:rsidR", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n1a1.InnerText = "00D56C9E"; n2.Attributes.Append(n1a1); var n1a2 = xml.CreateAttribute("w:rsidRDefault", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n1a2.InnerText = "00D56C9E"; n2.Attributes.Append(n1a2); var n2sub1 = xml.CreateElement("w:pPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); var n2sub1sub = xml.CreateElement("w:pStyle", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n2sub1.AppendChild(n2sub1sub); var n2sub1Suba1 = xml.CreateAttribute("w:val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n2sub1Suba1.InnerText = "TimeCode"; n2sub1sub.Attributes.Append(n2sub1Suba1); n2.AppendChild(n2sub1); var n2sub2 = xml.CreateElement("w:r", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); var n2sub2sub = xml.CreateElement("w:t", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n2sub2sub.InnerText = ToTimeCode(p.StartTime); n2sub2.AppendChild(n2sub2sub); n2.AppendChild(n2sub2); tc1.AppendChild(n2); // // // // // // // // // // // // var tc2 = xml.CreateElement("w:tc", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); paragraph.AppendChild(tc2); var n3sub1 = xml.CreateElement("w:tcPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); tc2.AppendChild(n3sub1); var n3sub1sub1 = xml.CreateElement("w:tcW", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); var n3suba1 = xml.CreateAttribute("w:w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n3suba1.InnerText = "5560"; n3sub1sub1.Attributes.Append(n3suba1); var n3suba2 = xml.CreateAttribute("w:type", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n3suba2.InnerText = "dxa"; n3sub1sub1.Attributes.Append(n3suba2); n3sub1.AppendChild(n3sub1sub1); var n3sub1sub2 = xml.CreateElement("w:vAlign", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); var n3sub1sub2a1 = xml.CreateAttribute("w:val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n3sub1sub2a1.InnerText = "bottom"; n3sub1sub2.Attributes.Append(n3sub1sub2a1); n3sub1.AppendChild(n3sub1sub2); var n3sub1sub3 = xml.CreateElement("w:p", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); var n3sub1sub3a1 = xml.CreateAttribute("w:rsidR", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n3sub1sub3a1.InnerText = "00D56C9E"; n3sub1sub3.Attributes.Append(n3sub1sub3a1); var n3sub1sub3a2 = xml.CreateAttribute("w:rsidRDefault", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n3sub1sub3a2.InnerText = "00D56C9E"; n3sub1sub3.Attributes.Append(n3sub1sub3a2); var n3sub1sub3sub1 = xml.CreateElement("w:pPr", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n3sub1sub3.AppendChild(n3sub1sub3sub1); var n3sub1sub3sub1sub = xml.CreateElement("w:pStyle", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); var n3sub1sub3sub1suba1 = xml.CreateAttribute("w:val", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n3sub1sub3sub1suba1.InnerText = "PopOn"; n3sub1sub3sub1sub.Attributes.Append(n3sub1sub3sub1suba1); n3sub1sub3sub1.AppendChild(n3sub1sub3sub1sub); var lines = HtmlUtil.RemoveHtmlTags(p.Text, true).Replace(Environment.NewLine, "\n").Split('\n'); for (int i = 0; i < lines.Length; i++) { var n3sub1sub3sub2 = xml.CreateElement("w:r", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n3sub1sub3.AppendChild(n3sub1sub3sub2); if (i > 0) { var lineBreak = xml.CreateElement("w:br", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); n3sub1sub3sub2.AppendChild(lineBreak); } var text = xml.CreateElement("w:t", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); text.InnerText = lines[i]; n3sub1sub3sub2.AppendChild(text); } tc2.AppendChild(n3sub1sub3); return paragraph; } private static string ToTimeCode(TimeCode timeCode) { return timeCode.ToHHMMSSFF(); //10:00:07:27 } public override void LoadSubtitle(Subtitle subtitle, List lines, string fileName) { _errorCount = 0; var sb = new StringBuilder(); lines.ForEach(line => sb.AppendLine(line)); var xml = new XmlDocument { XmlResolver = null }; xml.LoadXml(sb.ToString().Trim()); var nsmgr = new XmlNamespaceManager(xml.NameTable); nsmgr.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"); foreach (XmlNode node in xml.DocumentElement.SelectNodes("//w:tr", nsmgr)) { try { Paragraph p = new Paragraph(); XmlNode t = node.SelectSingleNode("w:tc/w:p/w:r/w:t", nsmgr); if (t != null) { p.StartTime = DecodeTimeCodeFrames(t.InnerText.Trim(), SplitCharColon); sb = new StringBuilder(); foreach (XmlNode wrNode in node.SelectNodes("w:tc/w:p/w:r", nsmgr)) { foreach (XmlNode child in wrNode.ChildNodes) { if (child.Name == "w:t") { bool isTimeCode = child.InnerText.Length == 11 && child.InnerText.Replace(":", string.Empty).Length == 8; if (!isTimeCode) sb.Append(child.InnerText); } else if (child.Name == "w:br") { sb.AppendLine(); } } } p.Text = sb.ToString(); subtitle.Paragraphs.Add(p); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); _errorCount++; } } for (int i = 0; i < subtitle.Paragraphs.Count - 1; i++) { subtitle.Paragraphs[i].EndTime.TotalMilliseconds = subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds; } subtitle.Paragraphs[subtitle.Paragraphs.Count - 1].EndTime.TotalMilliseconds = 2500; subtitle.RemoveEmptyLines(); for (int i = 0; i < subtitle.Paragraphs.Count - 1; i++) { if (subtitle.Paragraphs[i].EndTime.TotalMilliseconds == subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds) subtitle.Paragraphs[i].EndTime.TotalMilliseconds = subtitle.Paragraphs[i + 1].StartTime.TotalMilliseconds - 1; } subtitle.Renumber(); } } }