// 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);
        }
 // Does the given chapter link point to an empty page?
 private bool IsLinkToEmptyPage(DitaCollectionLinkJson link, out DitaPageJson pageJson)
 {
     pageJson = Pages.FirstOrDefault(o => o.FileName == link.FileName);
     // Is the page empty?
     return(pageJson?.IsEmpty ?? false);
 }
        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);
        }