public static void PopulateTreeFromIndexFile (string indexFilePath, Tree tree, IDocStorage storage, Dictionary<string, XElement> nsSummaries, Func<XElement, string> indexGenerator = null) { var root = tree.RootNode; int resID = 0; var asm = Path.GetDirectoryName (indexFilePath); storage = storage ?? new Storage.NullStorage (); // nsSummaries is allowed to be null if the user doesn't care about it nsSummaries = nsSummaries ?? new Dictionary<string, XElement> (); // default index generator uses a counter indexGenerator = indexGenerator ?? (_ => resID++.ToString ()); using (var reader = XmlReader.Create (File.OpenRead (indexFilePath))) { reader.ReadToFollowing ("Types"); var types = XElement.Load (reader.ReadSubtree ()); foreach (var ns in types.Elements ("Namespace")) { var nsName = (string)ns.Attribute ("Name"); nsName = !string.IsNullOrEmpty (nsName) ? nsName : "global"; var nsNode = root.GetOrCreateNode (nsName, "N:" + nsName); XElement nsElements; if (!nsSummaries.TryGetValue (nsName, out nsElements)) nsSummaries[nsName] = nsElements = new XElement ("elements", new XElement ("summary"), new XElement ("remarks")); foreach (var type in ns.Elements ("Type")) { // Add the XML file corresponding to the type to our storage var id = indexGenerator (type); string typeFilePath; var typeDocument = EcmaDoc.LoadTypeDocument (asm, nsName, type.Attribute ("Name").Value, out typeFilePath); using (var file = File.OpenRead (typeFilePath)) storage.Store (id, file); nsElements.Add (ExtractClassSummary (typeFilePath)); var typeCaption = EcmaDoc.GetTypeCaptionFromIndex (type); var url = "ecma:" + id + '#' + typeCaption + '/'; typeCaption = EcmaDoc.GetTypeCaptionFromIndex (type, true); var typeNode = nsNode.CreateNode (typeCaption, url); // Add meta "Members" node typeNode.CreateNode ("Members", "*"); var membersNode = typeDocument.Root.Element ("Members"); if (membersNode == null || !membersNode.Elements ().Any ()) continue; var members = membersNode .Elements ("Member") .ToLookup (EcmaDoc.GetMemberType); foreach (var memberType in members) { // We pluralize the member type to get the caption and take the first letter as URL var node = typeNode.CreateNode (EcmaDoc.PluralizeMemberType (memberType.Key), memberType.Key[0].ToString ()); var memberIndex = 0; var isCtors = memberType.Key[0] == 'C'; // We do not escape much member name here foreach (var memberGroup in memberType.GroupBy (m => MakeMemberCaption (m, isCtors))) { if (memberGroup.Count () > 1) { // Generate overload var overloadCaption = MakeMemberCaption (memberGroup.First (), false); var overloadNode = node.CreateNode (overloadCaption, overloadCaption); foreach (var member in memberGroup) overloadNode.CreateNode (MakeMemberCaption (member, true), (memberIndex++).ToString ()); overloadNode.Sort (); } else { // We treat constructor differently by showing their argument list in all cases node.CreateNode (MakeMemberCaption (memberGroup.First (), isCtors), (memberIndex++).ToString ()); } } node.Sort (); } } nsNode.Sort (); } root.Sort (); } }
public static void PopulateTreeFromIndexFile(string indexFilePath, string idPrefix, Tree tree, IDocStorage storage, Dictionary <string, XElement> nsSummaries, Func <XElement, string> indexGenerator = null) { var root = tree.RootNode; int resID = 0; var asm = Path.GetDirectoryName(indexFilePath); storage = storage ?? new Storage.NullStorage(); // nsSummaries is allowed to be null if the user doesn't care about it nsSummaries = nsSummaries ?? new Dictionary <string, XElement> (); // default index generator uses a counter indexGenerator = indexGenerator ?? (_ => resID++.ToString()); using (var reader = XmlReader.Create(File.OpenRead(indexFilePath))) { reader.ReadToFollowing("Types"); var types = XElement.Load(reader.ReadSubtree()); foreach (var ns in types.Elements("Namespace")) { var nsName = (string)ns.Attribute("Name"); nsName = !string.IsNullOrEmpty(nsName) ? nsName : "global"; var nsNode = root.GetOrCreateNode(nsName, "N:" + nsName); XElement nsElements; if (!nsSummaries.TryGetValue(nsName, out nsElements)) { nsSummaries[nsName] = nsElements = new XElement("elements", new XElement("summary"), new XElement("remarks")); } foreach (var type in ns.Elements("Type")) { // Add the XML file corresponding to the type to our storage var id = indexGenerator(type); string typeFilePath; var typeDocument = EcmaDoc.LoadTypeDocument(asm, nsName, type.Attribute("Name").Value, out typeFilePath); if (typeDocument == null) { continue; } using (var file = File.OpenRead(typeFilePath)) storage.Store(id, file); nsElements.Add(ExtractClassSummary(typeFilePath)); var typeCaption = EcmaDoc.GetTypeCaptionFromIndex(type); var url = idPrefix + id + '#' + typeCaption + '/'; typeCaption = EcmaDoc.GetTypeCaptionFromIndex(type, true); var typeNode = nsNode.CreateNode(typeCaption, url); // Add meta "Members" node typeNode.CreateNode("Members", "*"); var membersNode = typeDocument.Root.Element("Members"); if (membersNode == null || !membersNode.Elements().Any()) { continue; } var members = membersNode .Elements("Member") .ToLookup(EcmaDoc.GetMemberType); foreach (var memberType in members) { // We pluralize the member type to get the caption and take the first letter as URL var node = typeNode.CreateNode(EcmaDoc.PluralizeMemberType(memberType.Key), memberType.Key[0].ToString()); var memberIndex = 0; var isCtors = memberType.Key[0] == 'C'; // We do not escape much member name here foreach (var memberGroup in memberType.GroupBy(m => MakeMemberCaption(m, isCtors))) { if (memberGroup.Count() > 1) { // Generate overload var overloadCaption = MakeMemberCaption(memberGroup.First(), false); var overloadNode = node.CreateNode(overloadCaption, overloadCaption); foreach (var member in memberGroup) { overloadNode.CreateNode(MakeMemberCaption(member, true), (memberIndex++).ToString()); } overloadNode.Sort(); } else { // We treat constructor differently by showing their argument list in all cases node.CreateNode(MakeMemberCaption(memberGroup.First(), isCtors), (memberIndex++).ToString()); } } node.Sort(); } } nsNode.Sort(); } root.Sort(); } }
public static void PopulateTreeFromIndexFile(string indexFilePath, string idPrefix, Tree tree, IDocStorage storage, Dictionary <string, XElement> nsSummaries, Func <XElement, string> indexGenerator = null, IEcmaProviderFileSource fileSource = null) { fileSource = fileSource ?? DefaultEcmaProviderFileSource.Default; var root = tree.RootNode; int resID = 0; var asm = Path.GetDirectoryName(indexFilePath); storage = storage ?? new Storage.NullStorage(); // nsSummaries is allowed to be null if the user doesn't care about it nsSummaries = nsSummaries ?? new Dictionary <string, XElement> (); // default index generator uses a counter indexGenerator = indexGenerator ?? (_ => resID++.ToString()); using (var reader = fileSource.GetIndexReader(indexFilePath)) { reader.ReadToFollowing("Types"); var types = XElement.Load(reader.ReadSubtree()); foreach (var ns in types.Elements("Namespace")) { var nsName = (string)ns.Attribute("Name"); nsName = !string.IsNullOrEmpty(nsName) ? nsName : "global"; var nsNode = root.GetOrCreateNode(nsName, "N:" + nsName); XElement nsElements; if (!nsSummaries.TryGetValue(nsName, out nsElements)) { nsSummaries[nsName] = nsElements = new XElement("elements", new XElement("summary"), new XElement("remarks")); } //Add namespace summary and remarks data from file, if available var nsFileName = fileSource.GetNamespaceXmlPath(asm, nsName); if (File.Exists(nsFileName)) { var nsEl = fileSource.GetNamespaceElement(nsFileName); nsElements.Element("summary").ReplaceWith(nsEl.Descendants("summary").First()); nsElements.Element("remarks").ReplaceWith(nsEl.Descendants("remarks").First()); } else { Console.WriteLine("Error reading namespace XML for {0} at {1}", nsName, nsFileName); } foreach (var type in ns.Elements("Type")) { // Add the XML file corresponding to the type to our storage var id = indexGenerator(type); string typeFilePath; var typeDocument = EcmaDoc.LoadTypeDocument(asm, nsName, type.Attribute("Name").Value, out typeFilePath, fileSource); if (typeDocument == null) { continue; } // write the document (which may have been modified by the fileSource) to the storage MemoryStream io = new MemoryStream(); using (var writer = XmlWriter.Create(io)) { typeDocument.WriteTo(writer); } io.Seek(0, SeekOrigin.Begin); storage.Store(id, io); nsElements.Add(ExtractClassSummary(typeDocument)); var typeCaption = EcmaDoc.GetTypeCaptionFromIndex(type); var url = idPrefix + id + '#' + typeCaption + '/'; typeCaption = EcmaDoc.GetTypeCaptionFromIndex(type, true); var typeNode = nsNode.CreateNode(typeCaption, url); // Add meta "Members" node typeNode.CreateNode("Members", "*"); var membersNode = typeDocument.Root.Element("Members"); if (membersNode == null || !membersNode.Elements().Any()) { continue; } var members = membersNode .Elements("Member") .ToLookup(EcmaDoc.GetMemberType); foreach (var memberType in members) { // We pluralize the member type to get the caption and take the first letter as URL var node = typeNode.CreateNode(EcmaDoc.PluralizeMemberType(memberType.Key), memberType.Key[0].ToString()); var memberIndex = 0; var isCtors = memberType.Key[0] == 'C'; // We do not escape much member name here foreach (var memberGroup in memberType.GroupBy(m => MakeMemberCaption(m, isCtors))) { if (memberGroup.Count() > 1) { // Generate overload var overloadCaption = MakeMemberCaption(memberGroup.First(), false); var overloadNode = node.CreateNode(overloadCaption, overloadCaption); foreach (var member in memberGroup) { overloadNode.CreateNode(MakeMemberCaption(member, true), (memberIndex++).ToString()); } overloadNode.Sort(); } else { // We treat constructor differently by showing their argument list in all cases node.CreateNode(MakeMemberCaption(memberGroup.First(), isCtors), (memberIndex++).ToString()); } } node.Sort(); } } nsNode.Sort(); } root.Sort(); } }