Пример #1
0
    void Parse2Helper(XmlNode px, TocItem pt)
    {
        foreach (XmlNode e in px.ChildNodes)
        {
            switch (e.Name)
            {
            case "navLabel":
            {
                pt.name = e.InnerText;
            }
            break;

            case "content":
            {
                pt.url = ReferPath(tocPath, e.Attributes["src"].Value);
            }
            break;

            case "navPoint":
            {
                var n = pt.AddChild();
                Parse2Helper(e, n);
            }
            break;
            }
        }
    }
Пример #2
0
 void Parse3Helper(XmlNode px, TocItem pt)
 {
     foreach (XmlNode e in px.ChildNodes)
     {
         if (e.Name == "li")
         {
             var node = pt.AddChild();
             foreach (XmlNode a in e.ChildNodes)
             {
                 if (a.Name == "a" && node.name == "")
                 {
                     node.name = a.InnerText;
                     node.url  = ReferPath(tocPath, ((XmlElement)a).GetAttribute("href"));
                     continue;
                 }
                 if (a.Name == "span" && node.name == "")
                 {
                     node.name = a.InnerText;
                     continue;
                 }
                 if (a.Name == "ol")
                 {
                     Parse3Helper(a, node);
                 }
             }
         }
     }
 }
Пример #3
0
    //http://idpf.org/epub/30/spec/epub30-contentdocs.html#sec-xhtml-nav-def-model
    public void Parse3()
    {
        var f = epub.toc.GetFile() as TextEpubFileEntry;

        tocPath = f.fullName;
        XmlDocument xml = new XmlDocument();

        xml.LoadXml(f.text);
        var navs = xml.GetElementsByTagName("nav");

        foreach (XmlElement nav in navs)
        {
            if (nav.GetAttribute("epub:type") == "toc")
            {
                tocTree          = new TocItem(epub);
                tocTree.children = new List <TocItem>();
                var root = nav.GetElementsByTagName("ol")[0];
                Parse3Helper(root, tocTree);
                return;
            }
        }
        //We have <nav>, but no epub:type is toc, so last try:
        if (navs.Count > 0)
        {
            var nav = navs[0] as XmlElement;
            tocTree          = new TocItem(epub);
            tocTree.children = new List <TocItem>();
            var root = nav.GetElementsByTagName("ol")[0];
            Parse3Helper(root, tocTree);
        }
    }
        /// <summary>
        /// Serialize a toc item.
        /// </summary>
        /// <param name="writer">Writer to use for output.</param>
        /// <param name="tocItem">the toc item to serialize.</param>
        /// <param name="isRoot">Is this the root, then we don't indent extra.</param>
        /// <remarks>The representation is like this:
        /// items:
        /// - name: Document One
        ///   href: document-one.md
        /// - name: Document Two
        ///   href: document-two.md
        /// - name: Sub Folder
        ///   href: sub-folder/index.md
        ///   items:
        ///   - name: Index
        ///     href: sub-folder/index.md
        ///   - name: Sub Document One
        ///     href: sub-folder/sub-document-one.md.
        /// </remarks>
        private static void Serialize(IndentedTextWriter writer, TocItem tocItem, bool isRoot = false)
        {
            if (!string.IsNullOrEmpty(tocItem.Title))
            {
                writer.WriteLine($"- name: {tocItem.Title}");
            }

            if (!string.IsNullOrEmpty(tocItem.Href))
            {
                writer.WriteLine($"  href: {tocItem.Href}");
            }

            if (tocItem.Items != null)
            {
                if (!isRoot)
                {
                    writer.Indent++;
                }

                writer.WriteLine("items:");
                foreach (TocItem toc in tocItem.Items)
                {
                    Serialize(writer, toc);
                }

                if (!isRoot)
                {
                    writer.Indent--;
                }
            }
        }
Пример #5
0
 private static void BuildTheTocChildMap(TocItem[] items, List <TocItem> parents)
 {
     foreach (TocItem item in items)
     {
         foreach (TocItem parent in parents)
         {
             if (parent.Children == null)
             {
                 parent.Children = ";";
             }
             parent.Children = parent.Children + item.url + ";";
         }
         if (item.TocItem1 != null)
         {
             List <TocItem> newParents = new List <TocItem>();
             if (parents.Count > 0)
             {
                 TocItem[] oldParents = new TocItem[parents.Count];
                 parents.CopyTo(oldParents);
                 newParents = oldParents.ToList();
             }
             newParents.Add(item);
             BuildTheTocChildMap(item.TocItem1, newParents);
         }
     }
 }
Пример #6
0
 internal TocItemContextMenuEventArgs(object source, ContextMenuEventArgs args, TocItem item, ContextMenu menu, ItemCollection menuItems)
     : base(args.RoutedEvent, source)
 {
     Item      = item;
     Menu      = menu;
     MenuItems = menuItems;
 }
Пример #7
0
        static void Main(string[] args)
        {
            Console.WriteLine("Enter Source folder path");
            string src = Console.ReadLine();

            Console.WriteLine("Enter Destination folder path");
            string dest = Console.ReadLine();

            var myFileUtil = new FileUtility(src, dest);

            myFileUtil.WalkPath();

            rootFolder = dest;
            var tocRootItems = new TocItem();

            System.IO.DirectoryInfo rootDir = new System.IO.DirectoryInfo(rootFolder);
            WalkDirectoryTree(rootDir, ref tocRootItems);

            var    serializer = new Serializer();
            string output     = null;

            if (string.IsNullOrEmpty(tocRootItems.name))
            {
                output = serializer.Serialize(tocRootItems.items);
            }
            else
            {
                output = serializer.Serialize(tocRootItems.items);
            }

            System.IO.File.WriteAllText(dest + "/toc.yml", output);
        }
 public void AddItem(TocItem item)
 {
     if (_items == null)
     {
         _items = new List <TocItem>();
     }
     _items.Add(item);
 }
        /// <summary>
        /// Walk through sub-folders and add if they contain content.
        /// </summary>
        /// <param name="folder">Folder to get sub-folders from.</param>
        /// <param name="order">Order list.</param>
        /// <param name="yamlNode">yamlNode to add entries to.</param>
        /// <param name="overrides">The overrides.</param>
        private static void GetDirectories(DirectoryInfo folder, List <string> order, TocItem yamlNode, Dictionary <string, string> overrides)
        {
            message.Verbose($"Process {folder.FullName} for sub-directories.");

            // Now find all the subdirectories under this directory.
            DirectoryInfo[] subDirs = folder.GetDirectories();
            foreach (DirectoryInfo dirInfo in subDirs)
            {
                // skip hidden folders (starting with .)
                if (dirInfo.Name.StartsWith(".", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                // Get all the md files only
                FileInfo[] subFiles = dirInfo.GetFiles("*.md");
                if (subFiles.Any() == false)
                {
                    message.Warning($"WARNING: Folder {dirInfo.FullName} skipped as it doesn't contain MD files. This might skip further sub-folders. Solve this by adding a README.md or INDEX.md in the folder.");
                    continue;
                }

                TocItem newTocItem = new TocItem();

                // if the directory is in the .order file, take the index as sequence nr
                if (order.Contains(Path.GetFileName(dirInfo.Name)))
                {
                    newTocItem.Sequence = order.IndexOf(Path.GetFileName(dirInfo.Name));
                }

                string title = string.Empty;
                if (options.UseOverride)
                {
                    if (overrides.ContainsKey(dirInfo.Name))
                    {
                        title = overrides[dirInfo.Name];
                    }
                }

                // Cleanup the title to be readable
                title = title.Length == 0 ? ToTitleCase(dirInfo.Name) : title;
                newTocItem.Filename = dirInfo.FullName;
                newTocItem.Title    = title;
                if (subFiles.Length == 1 && dirInfo.GetDirectories().Length == 0)
                {
                    newTocItem.Href = GetRelativePath(subFiles[0].FullName, options.DocFolder);
                }
                else
                {
                    string entryFile = WalkDirectoryTree(dirInfo, newTocItem);
                    newTocItem.Href = GetRelativePath(entryFile, options.DocFolder);
                }

                message.Verbose($"Add directory seq={newTocItem.Sequence} title={newTocItem.Title} href={newTocItem.Href}");

                yamlNode.AddItem(newTocItem);
            }
        }
        /// <summary>
        /// Get the list of the files in the current directory.
        /// </summary>
        /// <param name="folder">The folder to search.</param>
        /// <param name="order">Order list.</param>
        /// <param name="yamlNode">The current toc node.</param>
        /// <param name="overrides">The overrides.</param>
        private static void GetFiles(DirectoryInfo folder, List <string> order, TocItem yamlNode, Dictionary <string, string> overrides)
        {
            message.Verbose($"Process {folder.FullName} for files.");

            List <FileInfo> files = folder
                                    .GetFiles("*.md")
                                    .OrderBy(f => f.Name)
                                    .ToList();

            if (files == null)
            {
                message.Verbose($"No MD files found in {folder.FullName}.");
                return;
            }

            foreach (FileInfo fi in files)
            {
                if (fi.Name.StartsWith(".", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                // see if the file is mentioned in the order-list for ordering.
                int sequence = int.MaxValue;
                if (order.Contains(Path.GetFileNameWithoutExtension(fi.Name)))
                {
                    sequence = order.IndexOf(Path.GetFileNameWithoutExtension(fi.Name));
                }

                string title = string.Empty;
                if (options.UseOverride && (overrides.Count > 0))
                {
                    // get possible title override from the .override file
                    var key = fi.Name.Substring(0, fi.Name.Length - 3);
                    if (overrides.ContainsKey(key))
                    {
                        title = overrides[key];
                    }
                }

                title = title.Length == 0 ? GetCleanedFileName(fi) : title;

                yamlNode.AddItem(new TocItem
                {
                    Sequence = sequence,
                    Filename = fi.FullName,
                    Title    = title,
                    Href     = GetRelativePath(fi.FullName, options.DocFolder),
                });

                message.Verbose($"Add file seq={sequence} title={title} href={GetRelativePath(fi.FullName, options.DocFolder)}");
            }
        }
Пример #11
0
        public TocItem AddChild()
        {
            if (children == null)
            {
                children = new List <TocItem>();
            }
            TocItem n = new TocItem(belongTo);

            n.parent = this;
            children.Add(n);
            return(n);
        }
        /// <summary>
        /// Run the logic of the app with the given parameters.
        /// Given folders are checked if they exist.
        /// </summary>
        /// <param name="o">Parsed commandline options.</param>
        private static void RunLogic(CommandlineOptions o)
        {
            options = o;
            message = new MessageHelper(options);

            if (string.IsNullOrEmpty(options.OutputFolder))
            {
                options.OutputFolder = options.DocFolder;
            }

            message.Verbose($"Documentation folder: {options.DocFolder}");
            message.Verbose($"Output folder       : {options.OutputFolder}");
            message.Verbose($"Verbose             : {options.Verbose}");
            message.Verbose($"Use .order          : {options.UseOrder}");
            message.Verbose($"Use .override       : {options.UseOverride}");
            message.Verbose($"Use .ignore         : {options.UseIgnore}");
            message.Verbose($"Auto index          : {options.AutoIndex}\n");

            if (!Directory.Exists(options.DocFolder))
            {
                message.Error($"ERROR: Documentation folder '{options.DocFolder}' doesn't exist.");
                returnvalue = 1;
                return;
            }

            if (!Directory.Exists(options.OutputFolder))
            {
                message.Error($"ERROR: Destination folder '{options.OutputFolder}' doesn't exist.");
                returnvalue = 1;
                return;
            }

            // we start at the root to generate the TOC items
            TocItem       tocRootItems = new TocItem();
            DirectoryInfo rootDir      = new DirectoryInfo(options.DocFolder);

            WalkDirectoryTree(rootDir, tocRootItems);

            // we have the TOC, so serialize to a string
            using (StringWriter sw = new StringWriter())
            {
                using (IndentedTextWriter writer = new IndentedTextWriter(sw, "  "))
                {
                    writer.WriteLine("# This is an automatically generated file");
                    Serialize(writer, tocRootItems, true);
                }

                // now write the TOC to disc
                File.WriteAllText(Path.Combine(options.OutputFolder, "toc.yml"), sw.ToString());
            }

            message.Verbose($"{Path.Combine(options.OutputFolder, "toc.yml")} created.");
        }
Пример #13
0
        static void WalkDirectoryTree(System.IO.DirectoryInfo folder, ref TocItem yamlNodes)
        {
            System.IO.DirectoryInfo[] subDirs = null;

            var files = GetMarkdownFiles(folder);

            foreach (var file in files)
            {
                var newTocItem = new TocItem();
                newTocItem.name = Path.GetFileNameWithoutExtension(file.FullName);
                newTocItem.href = GetRelativePath(file.FullName, rootFolder);
                yamlNodes.AddItem(newTocItem);
            }

            // Now find all the subdirectories under this directory.
            subDirs = folder.GetDirectories();

            foreach (System.IO.DirectoryInfo dirInfo in subDirs)
            {
                if (dirInfo.Name.StartsWith("."))
                {
                    continue;
                }

                var subFiles = GetFiles(dirInfo);
                if (!subFiles.Any() && !dirInfo.GetDirectories().Any())
                {
                    continue;
                }

                var newTocItem = new TocItem();
                newTocItem.name = UppercaseFirst(dirInfo.Name.Replace("-", " "));

                if (subFiles.Count >= 1 && dirInfo.GetDirectories().Length == 0)
                {
                    newTocItem.href = GetRelativePath(subFiles[0].FullName, rootFolder);
                }
                else if (subFiles.Count >= 1 && dirInfo.GetDirectories().Length > 0)
                {
                    newTocItem.href = GetRelativePath(subFiles[0].FullName, rootFolder);
                    WalkDirectoryTree(dirInfo, ref newTocItem);
                }
                else
                {
                    newTocItem.topichref = GetRelativePath(dirInfo.FullName, rootFolder) + @"/";
                    WalkDirectoryTree(dirInfo, ref newTocItem);
                }
                yamlNodes.AddItem(newTocItem);
            }
        }
Пример #14
0
    void Parse2()
    {
        var f = epub.toc.GetFile() as TextEpubFileEntry;

        tocPath = f.fullName;
        XmlDocument xml = new XmlDocument();

        xml.LoadXml(f.text);
        var root = xml.GetElementsByTagName("navMap")[0];

        tocTree          = new TocItem(epub);
        tocTree.children = new List <TocItem>();
        Parse2Helper(root, tocTree);
    }
        private void ContextMenuEventHandler(object sender, ContextMenuEventArgs e)
        {
            (sender as FrameworkElement).ContextMenu = null;
            var        vm   = (e.OriginalSource as FrameworkElement)?.DataContext;
            TocItem    item = null;
            LegendInfo info = null;

            if (vm is LegendInfo li)
            {
                info = li;
                var parent = System.Windows.Media.VisualTreeHelper.GetParent(e.OriginalSource as DependencyObject) as FrameworkElement;
                while (parent != null)
                {
                    if (parent.DataContext is TocItem tocItem)
                    {
                        item = tocItem;
                        break;
                    }

                    parent = System.Windows.Media.VisualTreeHelper.GetParent(parent) as FrameworkElement;
                }
            }

            if (vm is TocItem ti)
            {
                item = ti;
            }

            if (vm != null)
            {
                if (TableOfContentContextMenuOpening != null)
                {
                    var ctm  = new ContextMenu();
                    var args = new TableOfContentsContextMenuEventArgs(sender, e)
                    {
                        MenuItems          = ctm.Items,
                        TableOfContentItem = item?.Content,
                        LegendInfo         = info,
                        Menu = ctm
                    };
                    TableOfContentContextMenuOpening?.Invoke(this, args);
                    e.Handled = args.Handled;
                    if (args.MenuItems.Count > 0)
                    {
                        (sender as FrameworkElement).ContextMenu = args.Menu;
                    }
                }
            }
        }
        /// <summary>
        /// See if there is a 1) README.md or 2) index.md.
        /// If those don't exist, we add a standard index.md.
        /// </summary>
        /// <param name="folder">Folder to work with.</param>
        /// <param name="yamlNode">Toc item for the folder.</param>
        /// <param name="overrides">The overrides.</param>
        /// <returns>Name of the file where the index was added.</returns>
        private static string AddIndex(DirectoryInfo folder, TocItem yamlNode, Dictionary <string, string> overrides)
        {
            // don't add index if there is nothing to index
            if (yamlNode.Items == null || !yamlNode.Items.Any())
            {
                return(string.Empty);
            }

            // determine output file. Standard is index.md.
            string readmeFile = Path.Combine(folder.FullName, "README.md");
            string indexFile  = Path.Combine(folder.FullName, "index.md");

            // if one of these files exists, we don't add an index.
            if (File.Exists(readmeFile) || File.Exists(indexFile))
            {
                return(string.Empty);
            }

            if (WriteIndex(indexFile, yamlNode))
            {
                // if a new index has been created, add that to the TOC (top of list)
                FileInfo fi    = folder.GetFiles().FirstOrDefault(x => string.Equals(x.Name, Path.GetFileName(indexFile), StringComparison.OrdinalIgnoreCase));
                string   title = string.Empty;
                if (options.UseOverride && (overrides.Count > 0))
                {
                    string key = folder.Name;
                    if (overrides.ContainsKey(key))
                    {
                        title = overrides[key];
                    }
                }

                TocItem newItem = new TocItem
                {
                    Sequence = -1,
                    Filename = indexFile,
                    Title    = title.Length == 0 ? GetCleanedFileName(fi) : title,
                    Href     = GetRelativePath(indexFile, options.DocFolder),
                };

                // insert index item at the top
                yamlNode.AddItem(newItem, true);
                message.Verbose($"Added index.md to top of list of files.");
            }

            return(indexFile);
        }
Пример #17
0
        private TagBuilder CreateMenuItem(TocItem item, TocItem?current, int menu)
        {
            var li = new TagBuilder("li");

            if (item.Items.Count > 0)
            {
                li.AddCssClass("nav-group");
            }
            li.AddCssClass("nav-item");
            var active = current?.IsCurrent(item) ?? false;
            var anchor = new TagBuilder("a");

            if (active)
            {
                anchor.AddCssClass("active");
            }
            anchor.MergeAttribute("title", item.Name);
            anchor.AddCssClass($"nav-link");
            var span = new TagBuilder("span");

            span.InnerHtml.Append(item.Name);
            anchor.InnerHtml.AppendHtml(span);
            li.InnerHtml.AppendHtml(anchor);
            if (item.Items.Count > 0)
            {
                anchor.AddCssClass("dropdown-indicator");
                if (active)
                {
                    anchor.MergeAttribute("aria-expanded", "true");
                }
                else
                {
                    anchor.AddCssClass("collapsed");
                }
                anchor.MergeAttribute("data-bs-toggle", "collapse");
                anchor.MergeAttribute("href", "#" + item.Id);
                CreateChildren(li, item.Items, current, menu + 1, item.Id, active);
            }
            else
            {
                var url = item.Href;
                anchor.MergeAttribute("href", url);
            }
            return(li);
        }
        /// <summary>
        /// Main function going through all the folders, files and subfolders.
        /// </summary>
        /// <param name="folder">The folder to search.</param>
        /// <param name="yamlNode">An item.</param>
        /// <returns>Full path of the entry-file of this folder.</returns>
        private static string WalkDirectoryTree(DirectoryInfo folder, TocItem yamlNode)
        {
            message.Verbose($"Processing folder {folder.FullName}");

            List <string> order = GetOrderList(folder);
            Dictionary <string, string> overrides = options.UseOverride ? GetOverrides(folder) : new Dictionary <string, string>();
            List <string> ignore = GetIgnore(folder);

            // add doc files to the node
            GetFiles(folder, order, yamlNode, overrides);

            // add directories with content to the node
            GetDirectories(folder, order, yamlNode, overrides, ignore);

            if (yamlNode.Items != null)
            {
                // now sort the files and directories with the order-list and further alphabetically
                yamlNode.Items = new Collection <TocItem>(yamlNode.Items.OrderBy(x => x.Sequence).ThenBy(x => x.SortableTitle).ToList());
                message.Verbose($"Items ordered in {folder.FullName}");
            }

            if (!string.IsNullOrWhiteSpace(yamlNode.Filename))
            {
                // if indicated, add a folder index - but not for the root folder.
                if (options.AutoIndex)
                {
                    string indexFile = AddIndex(folder, yamlNode, GetOverrides(folder.Parent));
                    if (!string.IsNullOrEmpty(indexFile))
                    {
                        yamlNode.Href = GetRelativePath(indexFile, options.DocFolder);
                    }
                }
                else
                {
                    if (yamlNode.Items != null && yamlNode.Items.Any())
                    {
                        yamlNode.Href = GetRelativePath(yamlNode.Items.First().Filename, options.DocFolder);
                    }
                }
            }

            return(yamlNode.Items == null ? string.Empty : yamlNode.Items.First().Filename);
        }
Пример #19
0
        /// <summary>
        /// The tree.dki encodes the tree using indentation.
        /// </summary>
        private static TocItem CreateTree(IEnumerable <TocItem> items)
        {
            TocItem item = items.Aggregate((parent, next) =>
            {
                while (next.Level <= parent.Level)
                {
                    parent = parent.ParentConcrete;
                }

                parent.AddChild(next);
                return(next);
            });

            while (item.ParentConcrete != null)
            {
                item = item.ParentConcrete;
            }

            return(item);
        }
Пример #20
0
 static void GetPlainStructHelper(List <string> urls, TocItem p, ref string[] plain, string intro = "")
 {
     foreach (TocItem i in p.children)
     {
         if (i.url != null)
         {
             string u     = i.url.Split('#')[0];
             int    index = urls.IndexOf(u);
             if (index >= 0)
             {
                 if (plain[index] == null)
                 {
                     plain[index] = intro + i.name;
                 }
             }
         }
         if (i.children != null)
         {
             GetPlainStructHelper(urls, i, ref plain, intro + i.name + " > ");
         }
     }
 }
        /// <summary>
        /// Write the index in the given outputFile.
        /// </summary>
        /// <param name="outputFile">File to write to.</param>
        /// <param name="yamlNode">TOC Item to get files from.</param>
        /// <returns>Was a NEW index file created TRUE/FALSE.</returns>
        private static bool WriteIndex(string outputFile, TocItem yamlNode)
        {
            if (File.Exists(outputFile))
            {
                return(false);
            }

            message.Verbose($"Index will be written to {outputFile}");

            // read lines if existing file.
            List <string> lines = new List <string>();

            lines.Add($"# {yamlNode.Title}");
            lines.Add(string.Empty);
            foreach (TocItem item in yamlNode.Items)
            {
                lines.Add($"* [{item.Title}](./{Path.GetFileName(item.Filename)})");
            }

            File.WriteAllLines(outputFile, lines);
            message.Verbose($"Written {lines.Count} lines to {outputFile} (index).");
            return(true);
        }
Пример #22
0
        private bool CustomMergeToc(string mergedToc, TocContent tocContent)
        {
            _tocContext.LoadAll();

            IBuildNamedList <BuildGroupTocInfo> groupTocItems = _tocContext.Items;

            Debug.Assert(groupTocItems != null && groupTocItems.Count != 0);

            int itemCount = tocContent.Count;

            List <BuildTopicTocInfo> listToc = new List <BuildTopicTocInfo>();

            for (int i = 0; i < itemCount; i++)
            {
                TocItem           tocItem    = tocContent[i];
                TocItemSourceType sourceType = tocItem.SourceType;
                if (sourceType == TocItemSourceType.None)
                {
                    continue;
                }

                BuildGroupTocInfo groupToc = null;
                BuildTopicTocInfo tocInfo  = null;
                switch (sourceType)
                {
                case TocItemSourceType.None:
                    break;

                case TocItemSourceType.Group:
                    groupToc = groupTocItems[tocItem.SourceId];
                    Debug.Assert(groupToc != null);
                    break;

                case TocItemSourceType.Namespace:
                    tocInfo = _tocContext[tocItem.SourceId];
                    break;

                case TocItemSourceType.NamespaceRoot:
                    groupToc = groupTocItems[tocItem.SourceId];
                    Debug.Assert(groupToc != null);
                    if (groupToc != null)
                    {
                        if (groupToc.IsRooted)
                        {
                            tocInfo = groupToc[0];
                        }
                        else
                        {
                            throw new BuildException(
                                      "The specified reference group does not have a root container.");
                        }
                        groupToc = null;
                    }
                    break;

                case TocItemSourceType.Topic:
                    tocInfo = _tocContext[tocItem.SourceId];
                    break;
                }

                if (groupToc != null)
                {
                    if (!groupToc.Exclude && groupToc.Count != 0)
                    {
                        listToc.AddRange(groupToc.Items);
                    }
                    continue;
                }

                if (tocInfo == null)
                {
                    if (_logger != null)
                    {
                        _logger.WriteLine(String.Format(
                                              "The TOC topic for the item '{0}' cannot be found.", tocItem.Name),
                                          BuildLoggerLevel.Warn);
                    }

                    continue;
                }

                BuildTopicTocInfo topicToc = null;
                if (tocItem.SourceRecursive)
                {
                    topicToc = tocInfo;
                }
                else
                {
                    topicToc = new BuildTopicTocInfo(tocInfo.Name,
                                                     tocInfo.Source, null);
                    topicToc.Container = tocInfo.Container;
                }

                listToc.Add(topicToc);

                for (int j = 0; j < tocItem.ItemCount; j++)
                {
                    this.CustomMergeToc(topicToc, tocItem[j]);
                }
            }

            if (listToc.Count == 0)
            {
                if (_logger != null)
                {
                    _logger.WriteLine("The custom merging of the table of contents failed.",
                                      BuildLoggerLevel.Error);
                }

                return(false);
            }

            XmlWriter xmlWriter = null;

            try
            {
                XmlWriterSettings writerSettings = new XmlWriterSettings();
                writerSettings.Indent             = true;
                writerSettings.OmitXmlDeclaration = false;
                xmlWriter = XmlWriter.Create(mergedToc, writerSettings);

                xmlWriter.WriteStartElement("topics");

                for (int i = 0; i < listToc.Count; i++)
                {
                    listToc[i].WriteXml(xmlWriter);
                }

                xmlWriter.WriteEndElement();

                xmlWriter.Close();
                xmlWriter = null;

                return(true);
            }
            catch (Exception ex)
            {
                if (xmlWriter != null)
                {
                    xmlWriter.Close();
                    xmlWriter = null;
                }

                if (_logger != null)
                {
                    _logger.WriteLine(ex);
                }

                return(false);
            }
        }
Пример #23
0
        private void CustomMergeToc(BuildTopicTocInfo topicParent, TocItem tocItem)
        {
            TocItemSourceType sourceType = tocItem.SourceType;

            if (sourceType == TocItemSourceType.None)
            {
                return;
            }

            IBuildNamedList <BuildGroupTocInfo> groupTocItems = _tocContext.Items;
            BuildGroupTocInfo groupToc = null;
            BuildTopicTocInfo tocInfo  = null;

            switch (sourceType)
            {
            case TocItemSourceType.None:
                break;

            case TocItemSourceType.Group:
                groupToc = groupTocItems[tocItem.SourceId];
                Debug.Assert(groupToc != null);
                break;

            case TocItemSourceType.Namespace:
                tocInfo = _tocContext[tocItem.SourceId];
                break;

            case TocItemSourceType.NamespaceRoot:
                groupToc = groupTocItems[tocItem.SourceId];
                Debug.Assert(groupToc != null);
                if (groupToc != null)
                {
                    if (groupToc.IsRooted)
                    {
                        tocInfo = groupToc[0];
                    }
                    else
                    {
                        throw new BuildException(
                                  "The specified reference group does not have a root container.");
                    }
                    groupToc = null;
                }
                break;

            case TocItemSourceType.Topic:
                tocInfo = _tocContext[tocItem.SourceId];
                break;
            }

            if (groupToc != null)
            {
                if (!groupToc.Exclude)
                {
                    topicParent.AddRange(groupToc.Items);
                }
                return;
            }

            if (tocInfo == null)
            {
                if (_logger != null)
                {
                    _logger.WriteLine(String.Format(
                                          "The TOC topic for the item '{0}' cannot be found.", tocItem.Name),
                                      BuildLoggerLevel.Warn);
                }

                return;
            }

            BuildTopicTocInfo topicToc = null;

            if (tocItem.SourceRecursive)
            {
                topicToc = tocInfo;
            }
            else
            {
                topicToc = new BuildTopicTocInfo(tocInfo.Name,
                                                 tocInfo.Source, topicParent);
                topicToc.Container = tocInfo.Container;
            }

            topicParent.Add(topicToc);

            for (int j = 0; j < tocItem.ItemCount; j++)
            {
                this.CustomMergeToc(topicToc, tocItem[j]);
            }
        }
Пример #24
0
        public static void Create(BuildDocumenter documenter,
                                  TestOptions options)
        {
            CustomTocType tocType = options.TocType;

            if (tocType == CustomTocType.None)
            {
                return;
            }

            BuildSettings           settings       = documenter.Settings;
            ReferenceEngineSettings engineSettings = settings.EngineSettings[
                BuildEngineType.Reference] as ReferenceEngineSettings;

            IList <BuildGroup> listGroups = documenter.Groups;

            // Create a custom TOC layout for the CHM format only...
            if (tocType != CustomTocType.Default)
            {
                FormatChm chmFormat =
                    settings.Formats[BuildFormatType.HtmlHelp1] as FormatChm;
                if (chmFormat != null && chmFormat.Enabled)
                {
                    TocContent chmTocContent = new TocContent();
                    for (int i = 0; i < listGroups.Count; i++)
                    {
                        TocItem tocItem = new TocItem();
                        tocItem.SourceType      = TocItemSourceType.Group;
                        tocItem.SourceRecursive = true;
                        tocItem.SourceId        = listGroups[i].Id;
                        chmTocContent.Add(tocItem);
                    }

                    chmFormat.TocContent = chmTocContent;
                }
            }

            BuildToc   buildToc   = settings.Toc;
            TocContent tocContent = buildToc.Content;

            switch (tocType)
            {
            case CustomTocType.None:
                break;

            case CustomTocType.Default:
                for (int i = 0; i < listGroups.Count; i++)
                {
                    TocItem tocItem = new TocItem();
                    tocItem.SourceType      = TocItemSourceType.Group;
                    tocItem.SourceRecursive = true;
                    tocItem.SourceId        = listGroups[i].Id;
                    tocContent.Add(tocItem);
                }
                break;

            case CustomTocType.ReferenceRoot:
                // Assumes there are three groups and the third is reference group,
                // and root namespaces container is enabled...
                if (listGroups.Count == 3 &&
                    (engineSettings != null && engineSettings.RootNamespaceContainer))
                {
                    TocItem rootItem = new TocItem();
                    rootItem.SourceType      = TocItemSourceType.NamespaceRoot;
                    rootItem.SourceRecursive = false;
                    rootItem.SourceId        = listGroups[2].Id;
                    tocContent.Add(rootItem);

                    for (int i = 0; i < listGroups.Count - 1; i++)
                    {
                        TocItem tocItem = new TocItem();
                        tocItem.SourceType      = TocItemSourceType.Group;
                        tocItem.SourceRecursive = true;
                        tocItem.SourceId        = listGroups[i].Id;
                        rootItem.Add(tocItem);
                    }

                    TocItem namespaceItem1 = new TocItem();
                    namespaceItem1.SourceType      = TocItemSourceType.Namespace;
                    namespaceItem1.SourceRecursive = true;
                    namespaceItem1.SourceId        = "N:ANamespace";
                    rootItem.Add(namespaceItem1);

                    TocItem namespaceItem2 = new TocItem();
                    namespaceItem2.SourceType      = TocItemSourceType.Namespace;
                    namespaceItem2.SourceRecursive = true;
                    namespaceItem2.SourceId        = "N:TestLibrary";
                    rootItem.Add(namespaceItem2);
                }
                break;

            case CustomTocType.TopicRoot:
                if (settings.BuildConceptual && settings.BuildReferences)
                {
                    TocItem rootTocItem = new TocItem();
                    rootTocItem.SourceType      = TocItemSourceType.Topic;
                    rootTocItem.SourceRecursive = true;
                    rootTocItem.SourceId        = "d36e744f-c053-4e94-9ac9-b1ee054d8de2";
                    tocContent.Add(rootTocItem);
                    for (int i = 0; i < listGroups.Count; i++)
                    {
                        TocItem tocItem = new TocItem();
                        tocItem.SourceType      = TocItemSourceType.Group;
                        tocItem.SourceRecursive = true;
                        tocItem.SourceId        = listGroups[i].Id;
                        rootTocItem.Add(tocItem);
                    }
                }
                break;
            }
        }