using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace MKVTest { internal class SerializeMkvInfo { public List SerializeFile(string filePath) { var file = File.ReadAllLines(filePath); if (file.Length == 0) return new List(); var lastDepthLevel = 0; //var xml = new StringBuilder(); var stack = new Stack(); var xml = new List {""}; //Create a root node for the file. var rootNode = new XmlTag() { Name = "File" }; stack.Push(rootNode); for (var i = 0; i < file.Length; i++) { var depth = GetDepth(file[i]); var tag = CreateTagFromString(file[i], depth); var padding = new StringBuilder(); for (var j = tag.Depth - 1; j > 0; j--) { padding.Append(" "); } if (i == file.Length - 1) { var t = stack.Pop(); xml.Insert(xml.Count - 1, padding + "<" + t.Name + ">" + t.Value + ""); xml[xml.Count - 1] = padding + "<" + tag.Name + ">" + tag.Value + ""; //Unwind the stack. xml.AddRange(stack.Select(s => "")); continue; } if (depth == lastDepthLevel) { if (stack.Count != 0) { var t = stack.Pop(); xml[xml.Count - 1] = padding + "<" + t.Name + ">" + t.Value + ""; } } else if (depth < lastDepthLevel) { //Moving up if (stack.Count != 0) { var t = stack.Pop(); xml[xml.Count - 1] = padding + "<" + t.Name + ">" + t.Value + ""; var diff = lastDepthLevel - depth; var subPadding = new StringBuilder(); for (var j = 0; j < diff; j++) { subPadding.Clear(); var subTag = stack.Pop(); for (var k = subTag.Depth - 1; k != 0; k--) { subPadding.Append(" "); } if (stack.Count != 0) { xml.Add(subPadding + ""); } else { break; } } } } if(tag.Name != string.Empty) xml.Add(padding + "<" + tag.Name + ">"); stack.Push(tag); lastDepthLevel = depth; } //File.WriteAllLines(@"C:\Users\glmcc\Desktop\Test.info", xml); return xml; } private static XmlTag CreateTagFromString(string text, int tagDepth) { var tag = new XmlTag(); var clearingPadding = true; var foundDelimiter = false; var insideBraces = false; var name = new StringBuilder(); var value = new StringBuilder(); //var attributes = new List(); for (var i = 0; i < text.Length; i++) { if ((char.IsSymbol(text[i]) || char.IsPunctuation(text[i]) || char.IsWhiteSpace(text[i])) && clearingPadding) { continue; } if ((text[i].ToString() == ":" || text[i] == ',') && !foundDelimiter) { foundDelimiter = true; continue; } clearingPadding = false; if (foundDelimiter) { if (text[i] == '(') { insideBraces = true; continue; } if (insideBraces && text[i] == ')') { insideBraces = false; continue; } if(!insideBraces) value.Append(text[i]); } else { if (text[i] == '(') { insideBraces = true; continue; } if(text[i] == ')') { insideBraces = false; continue; } if(!insideBraces) name.Append(text[i]); } } tag.Name = FormatTagName(name.ToString()); tag.Value = value.ToString().Trim(); tag.Depth = tagDepth; return tag; } private static string FormatTagName(string text) { if (text.Length == 0) return string.Empty; var name = new StringBuilder(); var previousCharWasWhiteSpace = false; foreach (var c in text) { if (!char.IsWhiteSpace(c)) { name.Append(previousCharWasWhiteSpace ? char.ToUpper(c) : c); previousCharWasWhiteSpace = false; } if (char.IsWhiteSpace(c)) { previousCharWasWhiteSpace = true; } } return name.ToString(); } private static int GetDepth(string line) { if (line.Length == 0) return -1; var depth = 0; for (var i = 0; i < line.Length; i++) { if (char.IsPunctuation(line[i]) || char.IsWhiteSpace(line[i]) || char.IsSymbol(line[i])) { depth++; } else { break; } } return depth; } } }