static int Main(string[] args) { // Parse commandline options. var options = new CommandLineOptions(); var parser = new CommandLineParser(options); if (!parser.ParseCommandLine(args)) { return 1; } // Run the program logic. try { var docsrc = PreprocessDocuments(options); GenerateIndexTopics(options, docsrc); } catch (Exception e) { Console.Error.WriteLine("Error: {0}\n\n{1}:\n{2}", e.Message, e.GetType(), e.StackTrace); return 1; } return 0; }
static XDocument[] PreprocessDocuments(CommandLineOptions options) { Console.WriteLine("Preprocessing documentation sources"); Directory.CreateDirectory(options.DocSrcOutput); var allDocuments = (from filename in options.DocSrc select new { Filename = filename, Document = XDocument.Load(filename) }).ToList(); var templates = allDocuments.SelectMany(doc => doc.Document.Descendants("template")).ToList(); templates.ForEach(template => template.Remove()); foreach (var doc in allDocuments) { ExpandTemplates(doc.Document, templates); PreprocessDocument(doc.Document, doc.Filename); string output = Path.Combine(options.DocSrcOutput, Path.GetFileName(doc.Filename)); doc.Document.Save(output); } return allDocuments.Select(doc => doc.Document).ToArray(); }
static object FormatChildTopic(CommandLineOptions options, XDocument[] docsrc, XElement childTopic) { // Row of the table consists of a link to the child topic, plus topic description text. var childTopicRow = FormatTableRow( new XElement(ns + "link", new XAttribute(xlink + "href", childTopic.Attribute("id").Value), (childTopic.Attribute("tocTitle") ?? childTopic.Attribute("title")).Value ), GetTopicSummary(options, childTopic) ); if (childTopic.Attribute("apiParentMode") != null) { // Insert reference documentation namespace links at the location marked by apiParentMode attribute. if (childTopic.Attribute("apiParentMode").Value != "InsertBefore") throw new NotSupportedException(); var namespaceList = FormatNamespaceList(docsrc); return namespaceList.Concat(new XElement[] { childTopicRow }); } else { // Otherwise just directly insert the row for this child topic. return childTopicRow; } }
static object GetTopicSummary(CommandLineOptions options, XElement topic) { // Do we have a .aml file matching this topic? string topicId = topic.Attribute("id").Value; var filename = options.AmlSrc.FirstOrDefault(aml => topicId.Equals(Path.GetFileNameWithoutExtension(aml), StringComparison.OrdinalIgnoreCase)); if (filename != null) { // Include the first paragraph of the .aml article in the index page. var doc = XDocument.Load(filename); return doc.Descendants(ns + "para").First().Nodes(); } else { // If no .aml file, look for a summary attribute in the Layout.content metadata. var summary = topic.Attribute("summary"); return (summary != null) ? summary.Value : null; } }
static void GenerateTopicPage(CommandLineOptions options, XDocument[] docsrc, XElement parentTopic) { string topicId = parentTopic.Attribute("id").Value; var summaryAttribute = parentTopic.Attribute("summary"); var summaryElement = summaryAttribute != null ? new XElement(ns + "para", summaryAttribute.Value) : null; var topicPage = new XDocument( new XElement("topic", new XAttribute("id", topicId), new XAttribute("revisionNumber", 1), new XElement(ns + "developerConceptualDocument", new XAttribute(XNamespace.Xmlns + "xlink", xlink), new XElement(ns + "section", new XElement(ns + "content", summaryElement, new XElement(ns + "table", // Each child of this topic forms one row of the table. from childTopic in parentTopic.Elements("Topic") select FormatChildTopic(options, docsrc, childTopic) ) ) ) ) ) ); string output = Path.Combine(options.TopicsOutput, topicId + ".aml"); topicPage.Save(output); }
static void GenerateIndexTopics(CommandLineOptions options, XDocument[] docsrc) { Console.WriteLine("Processing layout content"); Directory.CreateDirectory(options.TopicsOutput); // Find index topics in the Sandcastle Layout.content file that don't already have handwritten .aml content. var layoutContent = XDocument.Load(options.LayoutContent); var topics = from element in layoutContent.Descendants("Topic") where HasAttribute(element, "generateTopic") select element; // Autogenerate .aml content for these topics. foreach (var topic in topics) { GenerateTopicPage(options, docsrc, topic); } }
static XDocument[] PreprocessDocuments(CommandLineOptions options) { Console.WriteLine("Preprocessing documentation sources"); Directory.CreateDirectory(options.DocSrcOutput); var allDocuments = new List<XDocument>(); foreach (var filename in options.DocSrc) { var doc = XDocument.Load(filename); PreprocessDocument(doc, filename); string output = Path.Combine(options.DocSrcOutput, Path.GetFileName(filename)); doc.Save(output); allDocuments.Add(doc); } return allDocuments.ToArray(); }