// Parse chapter structure from a dita topic (leaf node) private List <DitaCollectionLinkJson> ParseChaptersFromTopic(DitaFileTopicAbstract topic, string navTitle = null) { List <DitaCollectionLinkJson> chapters = new List <DitaCollectionLinkJson>(); try { // Build a page for this topic DitaPageJson topicPage = new DitaPageJson(topic, Collection); Pages.Add(topicPage); // Add this chapter to the toc for this page DitaCollectionLinkJson chapter = new DitaCollectionLinkJson { FileName = topicPage.FileName, Title = navTitle ?? topicPage.Title }; chapters.Add(chapter); Trace.TraceInformation($"Found link to topic {chapter.FileName}."); } catch (Exception ex) { Trace.TraceError($"Error parsing topic {topic.FileName} - {ex}"); } return(chapters); }
// Parse the metadata from the given element? private void ParseMetaCategories(DitaElement parentElement) { try { List <DitaElement> categoriesData = parentElement?.FindChildren("category"); if (categoriesData != null) { foreach (DitaElement categoryData in categoriesData) { foreach (DitaElement data in categoryData.Children) { if (data?.Attributes.ContainsKey("name") ?? false) { if (BookMeta.ContainsKey(data?.Attributes["name"])) { Trace.TraceWarning($"BookMeta already contains a value for {data?.Attributes["name"]}"); } else { BookMeta.Add(data?.Attributes["name"], data?.Attributes["value"]); } } } } } } catch (Exception ex) { Trace.TraceError(ex); } }
// Build the internal structure based on a map private void ParseMap() { try { // Read the title BookTitle.Add("mainbooktitle", RootMap.Title); // Read the metadata ParseMapMeta(); if (!BookMeta.ContainsKey("document title")) { BookMeta.Add("document title", RootMap.Title); } // Add the chapters Chapters.AddRange(ParseChaptersFromFile(RootMap)); // Removes any blank topics and replaces them with links to their first populate child RemoveBlankPages(); } catch (Exception ex) { Trace.TraceError(ex); } }
// Build the internal structure based on the bookmap private void ParseBookMap() { // Find the booktitle element try { // Read the title ParseBookMapTitle(); // Read the metadata ParseBookMapBookMeta(); // Read the front matter // IGNORE // Read the chapters ParseBookMapChapters(); // Read the back matter // IGNORE // Removes any blank topics and replaces them with links to their first populate child RemoveBlankPages(); } catch (Exception ex) { Trace.TraceError(ex); } }
// Parse chapter structure from a .ditamap file private List <DitaCollectionLinkJson> ParseChaptersFromMap(DitaFileMap map) { Trace.TraceInformation($"Found link to map {map.NewFileName ?? map.FileName}."); // Find all the topic references List <DitaCollectionLinkJson> chapters = ParseRefs(map.RootElement.FindChildren(_refElements)); return(chapters); }
// Write this collection to a given folder public void SerializeToFile(string output) { using (StreamWriter file = File.CreateText(Path.Combine(output, CollectionFileName))) { JsonSerializerSettings settings = new JsonSerializerSettings { Formatting = Formatting.Indented }; JsonSerializer serializer = JsonSerializer.Create(settings); BookMeta["doc path"] = new DirectoryInfo(output).Name; serializer.Serialize(file, this); } Trace.TraceInformation($"Wrote {CollectionFileName}"); }
// Removes blank pages from the output private void RemoveBlankPages() { // Remove links to blank pages MarkBlankChapterLinks(Chapters); // Remove the blank pages List <DitaPageJson> removePages = new List <DitaPageJson>(); foreach (DitaPageJson page in Pages) { if (page.IsEmpty) { Trace.TraceWarning($"Removing empty page {page.FileName} ({page.OriginalFileName})"); removePages.Add(page); } } Pages = Pages.Except(removePages).ToList(); }
// Parse chapter structure from a dita file private List <DitaCollectionLinkJson> ParseChaptersFromFile(DitaFile linkedFile, string navTitle = null) { Trace.TraceInformation($"Converting {linkedFile}"); // What type of file is this? switch (linkedFile) { case DitaFileBookMap bookMap: // This should never happen throw new Exception($"Found bookmap {linkedFile} nested in bookmap."); case DitaFileMap map: return(ParseChaptersFromMap(map)); case DitaFileTopicAbstract topic: return(ParseChaptersFromTopic(topic, navTitle)); } return(null); }
private List <DitaCollectionLinkJson> ParseRefs(List <DitaElement> topicRefElements) { List <DitaCollectionLinkJson> chapters = new List <DitaCollectionLinkJson>(); if (topicRefElements?.Count > 0) { foreach (DitaElement topicRefElement in topicRefElements) { // Try to find the linked file string topicRefHref = topicRefElement.AttributeValueOrDefault("href", ""); string topicRefKeyRef = topicRefElement.AttributeValueOrDefault("keyref", ""); string topicRefNavTitle = topicRefElement?.FindOnlyChild("topicmeta")?.FindOnlyChild("navtitle")?.ToString(); // If there is no navtitle, check the topicmeta if (string.IsNullOrWhiteSpace(topicRefNavTitle)) { topicRefNavTitle = topicRefElement.AttributeValueOrDefault("navtitle", ""); } // Is this an external link? if (topicRefElement.AttributeValueOrDefault("scope", "") == "external") { DitaCollectionLinkJson externalLink = new DitaCollectionLinkJson { FileName = topicRefHref, Title = topicRefNavTitle, IsExternal = true }; chapters.Add(externalLink); } else { // Local scope DitaFile linkedFile = null; if (!string.IsNullOrWhiteSpace(topicRefHref)) { linkedFile = Collection.GetFileByName(topicRefHref); } // If no href, try to find by keyref if (linkedFile == null && !string.IsNullOrWhiteSpace(topicRefKeyRef)) { linkedFile = Collection.GetFileByKey(topicRefKeyRef); } if (linkedFile != null) { if (string.IsNullOrWhiteSpace(linkedFile.Title)) { linkedFile.Title = topicRefNavTitle; } else if (string.IsNullOrWhiteSpace(topicRefNavTitle)) { topicRefNavTitle = linkedFile.Title; } // Add references from the linked files List <DitaCollectionLinkJson> newChapters = ParseChaptersFromFile(linkedFile, topicRefNavTitle); if (newChapters != null && newChapters.Count > 0) { // Are there child chapters? List <DitaCollectionLinkJson> childChapters = ParseRefs(topicRefElement.FindChildren(_refElements)); if (newChapters.Count > 1 && childChapters.Count > 0) { // This should never happen throw new Exception("Found multiple children in a map and topic refs."); } if (childChapters != null && childChapters.Count > 0) { newChapters[0]?.Children?.AddRange(childChapters); } chapters.AddRange(newChapters); } } else { Trace.TraceWarning($"Reference with missing href/keyref: {topicRefElement}"); } } } } return(chapters); }