private void WriteManifest() { BuildContext context = this.Context; ReferenceGroup group = this.Group; Debug.Assert(context != null); Debug.Assert(group != null); if (group == null || context == null) { return; } BuildGroupContext groupContext = context.GroupContexts[group.Id]; if (groupContext == null) { throw new BuildException( "The group context is not provided, and it is required by the build system."); } string manifestFile = Path.Combine( Path.GetDirectoryName(_tocFilePath), groupContext["$ManifestFile"]); if (!File.Exists(manifestFile)) { return; } XmlDocument document = new XmlDocument(); document.Load(manifestFile); XPathNavigator documentNavigator = document.CreateNavigator(); XPathNavigator rootNavigator = documentNavigator.SelectSingleNode("topics"); if (rootNavigator == null) { return; } XmlWriter manifestWriter = rootNavigator.AppendChild(); // We also save the additional namespaces introduced so that their // titles can be changed by changing the <include item="rootTopicTitle"/>, // to <include item="namespaceTopicTitle"/> using build components. XmlWriterSettings writerSettings = new XmlWriterSettings(); writerSettings.Indent = true; writerSettings.OmitXmlDeclaration = false; writerSettings.Encoding = Encoding.UTF8; string rootNamespaceFile = Path.Combine(context.WorkingDirectory, groupContext["$RootNamespaces"]); XmlWriter rootWriter = XmlWriter.Create(rootNamespaceFile, writerSettings); try { rootWriter.WriteStartDocument(); rootWriter.WriteStartElement("topics"); rootWriter.WriteAttributeString("contentsAfter", _contentsAfter.ToString()); for (int i = 0; i < _undocumentedNodes.Count; i++) { KeyValuePair <string, HierarchicalTocNode> keyValue = _undocumentedNodes[i]; HierarchicalTocNode node = keyValue.Value; string topicId = "N:" + node.FullText; manifestWriter.WriteStartElement("topic"); // start: topic manifestWriter.WriteAttributeString("id", topicId); manifestWriter.WriteEndElement(); // end: topic rootWriter.WriteStartElement("topic"); // start: topic rootWriter.WriteAttributeString("id", topicId); if (_dicTocExcludedNamespaces != null && _dicTocExcludedNamespaces.ContainsKey(topicId)) { rootWriter.WriteAttributeString("isTocExcluded", "true"); string tocExcludedTopic = GetTocExcludedTopic(topicId); string fileName = String.Empty; if (_namingMethod == ReferenceNamingMethod.Guid) { fileName = ReferenceDocument.GetGuildFileName( tocExcludedTopic); } else if (_namingMethod == ReferenceNamingMethod.MemberName) { fileName = ReferenceDocument.GetFriendlyFileName( tocExcludedTopic); } else { fileName = ReferenceDocument.GetGuildFileName( tocExcludedTopic); } rootWriter.WriteAttributeString("tocExcludedTopic", tocExcludedTopic); rootWriter.WriteAttributeString("topicFile", fileName); XPathNavigator currNode = rootNavigator.SelectSingleNode( "topic[@id='" + topicId + "']"); if (currNode != null && currNode.MoveToAttribute( "id", String.Empty)) { currNode.SetValue(tocExcludedTopic); _dicTocExcludedNamespaces[topicId] = fileName; } } rootWriter.WriteEndElement(); // end: topic } rootWriter.WriteEndElement(); rootWriter.WriteEndDocument(); manifestWriter.Close(); manifestWriter = null; rootWriter.Close(); rootWriter = null; document.Save(manifestFile); } finally { if (manifestWriter != null) { manifestWriter.Close(); manifestWriter = null; document.Save(manifestFile); } if (rootWriter != null) { rootWriter.Close(); rootWriter = null; } } }
private void WriteNode(XmlWriter writer, HierarchicalTocNode node) { if (node == null || String.IsNullOrEmpty(node.Text)) { return; } string nodeText = node.FullText; string topicId = "N:" + nodeText; writer.WriteStartElement("topic"); // start: topic writer.WriteAttributeString("id", topicId); HierarchicalTocItem tocItem = _tocContents[nodeText]; string fileName = String.Empty; string projectName = "_Namespaces"; if (tocItem != null) { fileName = tocItem.FileName; projectName = tocItem.ProjectName; } else { if (_namingMethod == ReferenceNamingMethod.Guid) { fileName = ReferenceDocument.GetGuildFileName(topicId); } else if (_namingMethod == ReferenceNamingMethod.MemberName) { fileName = ReferenceDocument.GetFriendlyFileName(topicId); } else { fileName = ReferenceDocument.GetGuildFileName(topicId); } _undocumentedNodes.Add(new KeyValuePair <string, HierarchicalTocNode>( fileName, node)); } writer.WriteAttributeString("project", projectName); writer.WriteAttributeString("file", fileName); if (!_contentsAfter && (tocItem != null)) { WriteTopics(writer, nodeText); } if (node.HasChildren) { IList <HierarchicalTocNode> nodes = node.Children; for (int i = 0; i < nodes.Count; i++) { this.WriteNode(writer, nodes[i]); } } if (_contentsAfter && (tocItem != null)) { WriteTopics(writer, nodeText); } writer.WriteEndElement(); // end: topic }
private void WriteReflections() { BuildGroupContext groupContext = this.Context.GroupContexts[this.Group.Id]; if (groupContext == null) { throw new BuildException( "The group context is not provided, and it is required by the build system."); } string reflectionFile = Path.Combine( Path.GetDirectoryName(_tocFilePath), groupContext["$ReflectionFile"]); if (!File.Exists(reflectionFile)) { return; } XmlDocument document = new XmlDocument(); document.Load(reflectionFile); XPathNavigator documentNavigator = document.CreateNavigator(); XPathNavigator rootNavigator = documentNavigator.SelectSingleNode( "reflection/apis"); if (rootNavigator == null) { return; } XmlWriter writer = rootNavigator.AppendChild(); for (int i = 0; i < _undocumentedNodes.Count; i++) { KeyValuePair <string, HierarchicalTocNode> keyValue = _undocumentedNodes[i]; string fileName = keyValue.Key; HierarchicalTocNode node = keyValue.Value; string nodeText = node.FullText; string topicId = "N:" + nodeText; // This simulates a root namespace group or container, allowing // the transformations to create a list of namespaces with syntax // section added. The only issue is that the title include tag is // set to <include item="rootTopicTitle"/>, which we can change // to <include item="namespaceTopicTitle"/> using build components. writer.WriteStartElement("api"); // start: api writer.WriteAttributeString("id", topicId); writer.WriteStartElement("topicdata"); // start: topicdata writer.WriteAttributeString("name", nodeText); writer.WriteAttributeString("group", "root"); writer.WriteEndElement(); // end: topicdata writer.WriteStartElement("apidata"); // start: apidata writer.WriteAttributeString("name", nodeText); writer.WriteAttributeString("group", "namespace"); writer.WriteEndElement(); // end: apidata writer.WriteStartElement("elements"); // start: elements XPathNavigator tocExcludedNode = null; if (_dicTocExcludedNamespaces != null && _dicTocExcludedNamespaces.ContainsKey(topicId)) { tocExcludedNode = rootNavigator.SelectSingleNode( "api[@id='" + topicId + "']"); if (tocExcludedNode != null) { string topicFile = _dicTocExcludedNamespaces[topicId]; if (!String.IsNullOrEmpty(topicFile)) { XPathNavigator fileNode = tocExcludedNode.SelectSingleNode("file"); if (fileNode != null && fileNode.MoveToAttribute( "name", String.Empty)) { fileNode.SetValue(topicFile); if (tocExcludedNode.MoveToAttribute("id", String.Empty)) { tocExcludedNode.SetValue(GetTocExcludedTopic(topicId)); } } } } } if (node.HasChildren) { IList <HierarchicalTocNode> children = node.Children; for (int j = 0; j < children.Count; j++) { HierarchicalTocNode child = children[j]; writer.WriteStartElement("element"); // start: element writer.WriteAttributeString("api", "N:" + child.FullText); writer.WriteEndElement(); // end: element } } writer.WriteEndElement(); // end: elements writer.WriteStartElement("file"); // start: file writer.WriteAttributeString("name", fileName); writer.WriteEndElement(); // end: file writer.WriteEndElement(); // end: api } writer.Close(); if (!String.IsNullOrEmpty(_projectName)) { XPathNavigator navigator = rootNavigator.SelectSingleNode( "api[starts-with(@id, 'R:')]"); if (navigator != null && navigator.MoveToChild("elements", String.Empty)) { writer = navigator.AppendChild(); for (int i = 0; i < _undocumentedNodes.Count; i++) { KeyValuePair <string, HierarchicalTocNode> keyValue = _undocumentedNodes[i]; HierarchicalTocNode node = keyValue.Value; string topicId = "N:" + node.FullText; if (_dicTocExcludedNamespaces != null && _dicTocExcludedNamespaces.ContainsKey(topicId)) { continue; } writer.WriteStartElement("element"); // start: element writer.WriteAttributeString("api", topicId); writer.WriteEndElement(); // end: element } writer.Close(); } } document.Save(reflectionFile); }
private bool Visit(string tocFilePath, BuildLogger logger) { _projectName = String.Empty; _projectFile = String.Empty; if (String.IsNullOrEmpty(tocFilePath)) { return(false); } ReferenceTocLayoutType layoutType = _tocLayout.LayoutType; if (layoutType == ReferenceTocLayoutType.None || layoutType == ReferenceTocLayoutType.Null || layoutType == ReferenceTocLayoutType.Flat) { return(false); } XPathDocument document = new XPathDocument(tocFilePath); XPathNavigator documentNavigator = document.CreateNavigator(); XPathNavigator projectNode = documentNavigator.SelectSingleNode( "topics/topic[starts-with(@id, 'R:')]"); if (projectNode != null) { _projectName = projectNode.GetAttribute("id", String.Empty); if (_projectName == null) { _projectName = String.Empty; } _projectFile = projectNode.GetAttribute("file", String.Empty); if (_projectFile == null) { _projectFile = String.Empty; } } XPathNavigator rootNode = projectNode; if (rootNode == null) { rootNode = documentNavigator.SelectSingleNode("topics"); } XPathNodeIterator iterator = rootNode.Select( "topic[starts-with(@id, 'N:')]"); if (iterator == null || iterator.Count == 0) { return(false); } _undocumentedNodes = new List <KeyValuePair <string, HierarchicalTocNode> >(); _namingMethod = this.EngineSettings.Naming; _tocFilePath = tocFilePath; _dicNavigators = new BuildDictionary <XPathNavigator>(); if (layoutType == ReferenceTocLayoutType.Hierarchical) { _tocContents = new HierarchicalTocContent(); _tocContents.BeginItems(_projectName, _projectFile); foreach (XPathNavigator navigator in iterator) { string nsText = navigator.GetAttribute("id", String.Empty); if (!String.IsNullOrEmpty(nsText) && nsText.Length > 2) { nsText = nsText.Substring(2); string projName = navigator.GetAttribute("project", String.Empty); string fileName = navigator.GetAttribute("file", String.Empty); if (_tocContents.AddItem(nsText, projName, fileName)) { _dicNavigators.Add(nsText, navigator.Clone()); } } } _tocContents.EndItems(); } else if (layoutType == ReferenceTocLayoutType.Custom) { _tocContents = this.Group.Content.HierarchicalToc; if (_tocContents != null) { foreach (XPathNavigator navigator in iterator) { string nsText = navigator.GetAttribute("id", String.Empty); if (!String.IsNullOrEmpty(nsText) && nsText.Length > 2) { nsText = nsText.Substring(2); string projName = navigator.GetAttribute("project", String.Empty); string fileName = navigator.GetAttribute("file", String.Empty); _dicNavigators.Add(nsText, navigator.Clone()); } } } } if (_tocContents == null) { return(false); } _rootNode = _tocContents.RootNode; return(_rootNode != null); }