/// <summary>
        /// This is used to extract table of content information from a file
        /// that will appear in the help file's table of content.
        /// </summary>
        /// <param name="filename">The file from which to extract the
        /// information</param>
        /// <returns>The table of content entry</returns>
        private static TocEntry GetTocInfo(string filename)
        {
            TocEntry tocEntry;
            Encoding enc = Encoding.Default;
            string   content;

            content = BuildProcess.ReadWithEncoding(filename, ref enc);

            tocEntry                = new TocEntry();
            tocEntry.IncludePage    = !reTocExclude.IsMatch(content);
            tocEntry.IsDefaultTopic = reIsDefaultTopic.IsMatch(content);

            Match m = reSortOrder.Match(content);

            if (m.Success)
            {
                tocEntry.SortOrder = Convert.ToInt32(
                    m.Groups["SortOrder"].Value,
                    CultureInfo.InvariantCulture);
            }

            // Get the page title if possible.  If not found, use the filename
            // without the path or extension as the page title.
            m = rePageTitle.Match(content);
            if (!m.Success)
            {
                tocEntry.Title = Path.GetFileNameWithoutExtension(filename);
            }
            else
            {
                tocEntry.Title = HttpUtility.HtmlDecode(
                    m.Groups["Title"].Value).Replace("\r", "").Replace("\n", "");
            }

            // Since we've got the file loaded, see if there are links
            // that need to be resolved when the file is copied, if it
            // contains <pre> blocks that should be colorized, or if it
            // contains tags or shared content items that need replacing.
            tocEntry.HasLinks        = reResolveLinks.IsMatch(content);
            tocEntry.HasCodeBlocks   = reCodeBlock.IsMatch(content);
            tocEntry.NeedsColorizing = reColorizeCheck.IsMatch(content);
            tocEntry.HasProjectTags  = (reProjectTags.IsMatch(content) ||
                                        reSharedContent.IsMatch(content));

            return(tocEntry);
        }
Exemplo n.º 2
0
        /// <summary>
        /// This is called to fixup the comments for C++ compiler generated
        /// XML comments files.
        /// </summary>
        /// <remarks>The C++ compiler generates method signatures that differ
        /// from the other .NET compilers for methods that take generics as
        /// parameters.  These methods fail to get documented as they do not
        /// match the output of <b>MRefBuilder</b>.  The C# and VB.NET
        /// compilers generate names that do match it and this option is not
        /// needed for comments files generated by them.</remarks>
        public void FixupComments()
        {
            this.Save();
            comments = null;
            members  = null;
            enc      = Encoding.UTF8;

            // Read it with the appropriate encoding
            string content = BuildProcess.ReadWithEncoding(
                sourcePath, ref enc);

            // Strip out "`" followed by digits and "^" in member names
            content = reFixupComments1.Replace(content, "$1");
            content = reFixupComments2.Replace(content, "$1");

            // Write the file back out using its original encoding
            using (StreamWriter sw = new StreamWriter(sourcePath,
                                                      false, enc))
            {
                sw.Write(content);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// This is called to generate the HTML table of content when
        /// creating the website output.
        /// </summary>
        /// <returns>The HTML to insert for the table of content.</returns>
        protected string GenerateHtmlToc()
        {
            XmlDocument   toc;
            Encoding      enc = Encoding.Default;
            StringBuilder sb  = new StringBuilder(2048);

            string content;

            // When reading the file, use the default encoding but detect the
            // encoding if byte order marks are present.
            content = BuildProcess.ReadWithEncoding(workingFolder +
                                                    project.HtmlHelpName + ".hhc", ref enc);

            toc = new XmlDocument();
            toc.LoadXml(content);

            // Get the TOC entries from the first UL tag in the body
            XmlNodeList entries = toc.ChildNodes[0].ChildNodes[0].
                                  ChildNodes[0].ChildNodes;

            this.AppendTocEntry(entries, sb);

            return(sb.ToString());
        }
        /// <summary>
        /// This is called to load an additional content file, resolve links
        /// to namespace content and copy it to the output folder.
        /// </summary>
        /// <param name="sourceFile">The source filename to copy</param>
        /// <param name="destFile">The destination filename</param>
        /// <param name="entry">The entry being resolved.</param>
        private void ResolveLinksAndCopy(string sourceFile, string destFile,
                                         TocEntry entry)
        {
            Encoding enc = Encoding.Default;
            string   content, script, syntaxFile;
            int      pos;

            this.ReportProgress("{0} -> {1}", sourceFile, destFile);

            // When reading the file, use the default encoding but detect the
            // encoding if byte order marks are present.
            content = BuildProcess.ReadWithEncoding(sourceFile, ref enc);

            // Use a regular expression to find and replace all <see>
            // tags with link to the help file content.
            if (entry.HasLinks)
            {
                content = reResolveLinks.Replace(content, linkMatchEval);
            }

            // Expand <code> tags if necessary
            if (entry.HasCodeBlocks)
            {
                content = reCodeBlock.Replace(content, codeBlockMatchEval);
            }

            // Colorize <pre> tags if necessary
            if (entry.NeedsColorizing || entry.HasCodeBlocks)
            {
                // Initialize code colorizer on first use
                if (codeColorizer == null)
                {
                    codeColorizer = new CodeColorizer(
                        shfbFolder + @"Colorizer\highlight.xml",
                        shfbFolder + @"Colorizer\highlight.xsl");
                }

                // Set the path the "Copy" image
                codeColorizer.CopyImageUrl = pathToRoot + "icons/CopyCode.gif";

                // Colorize it and replace the "Copy" literal text with the
                // shared content include item so that it gets localized.
                content = codeColorizer.ProcessAndHighlightText(content);
                content = content.Replace(codeColorizer.CopyText + "</span",
                                          "<include item=\"copyCode\"/></span");
                entry.HasProjectTags = true;

                // Add the links to the colorizer stylesheet and script files
                script = String.Format(CultureInfo.InvariantCulture,
                                       "<link type='text/css' rel='stylesheet' " +
                                       "href='{0}html/highlight.css' />" +
                                       "<script type='text/javascript' " +
                                       "src='{0}html/highlight.js'></script>", pathToRoot);

                pos = content.IndexOf("</head>");

                // Create a <head> section if one doesn't exist
                if (pos == -1)
                {
                    script = "<head>" + script + "</head>";
                    pos    = content.IndexOf("<html>");

                    if (pos != -1)
                    {
                        pos += 6;
                    }
                    else
                    {
                        pos = 0;
                    }
                }

                content = content.Insert(pos, script);

                // Copy the colorizer files if not already there
                if (!File.Exists(workingFolder + @"Output\html\highlight.css"))
                {
                    syntaxFile = shfbFolder + @"Colorizer\highlight.css";
                    File.Copy(syntaxFile, workingFolder +
                              @"Output\html\highlight.css");
                    File.SetAttributes(syntaxFile, FileAttributes.Normal);

                    syntaxFile = shfbFolder + @"Colorizer\highlight.js";
                    File.Copy(syntaxFile, workingFolder +
                              @"Output\html\highlight.js");
                    File.SetAttributes(syntaxFile, FileAttributes.Normal);

                    // This one may exist as the default presentation styles
                    // contain an image by this name.
                    syntaxFile = shfbFolder + @"Colorizer\CopyCode.gif";
                    File.Copy(syntaxFile, workingFolder +
                              @"Output\icons\CopyCode.gif", true);
                    File.SetAttributes(syntaxFile, FileAttributes.Normal);
                }
            }

            // Replace project option tags with project option values
            if (entry.HasProjectTags)
            {
                content = reProjectTags.Replace(content, fieldMatchEval);

                // Shared content items can be nested
                while (reSharedContent.IsMatch(content))
                {
                    content = reSharedContent.Replace(content, contentMatchEval);
                }
            }

            // Write the file back out with the appropriate encoding
            using (StreamWriter sw = new StreamWriter(destFile, false, enc))
            {
                sw.Write(content);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// This is called to determine the default topic for the help file
        /// and insert any additional table of content entries for the
        /// additional content files.
        /// </summary>
        /// <param name="format">The format of the table of content
        /// (HtmlHelp1x, HtmlHelp2x, or Website).</param>
        /// <remarks>In the absence of an additional content item with a
        /// default topic indicator, the default page is determined by
        /// extracting the first entry from the generated table of contents
        /// file.  If an additional content item with a default topic indicator
        /// has been specified, it will be the used instead.  The default
        /// topic is not used by HTML Help 2.x files.</remarks>
        /// <exception cref="ArgumentException">This is thrown if the
        /// format is not <b>HtmlHelp1x</b>, <b>HtmlHelp2x</b>, or
        /// <b>Website</b>.</exception>
        protected void UpdateTableOfContent(HelpFileFormat format)
        {
            Encoding enc = Encoding.Default;

            string tocFile, content;
            bool   tocChanged = false;
            int    endTagPos;

            if (format != HelpFileFormat.HtmlHelp1x &&
                format != HelpFileFormat.HtmlHelp2x &&
                format != HelpFileFormat.Website)
            {
                throw new ArgumentException("The format specified must be " +
                                            "a single format, not a combination", "format");
            }

            // HTML 2.x or HTML 1.x/website
            if (format != HelpFileFormat.HtmlHelp2x)
            {
                tocFile = workingFolder + project.HtmlHelpName + ".hhc";
            }
            else
            {
                tocFile = workingFolder + project.HtmlHelpName + ".hxt";
            }

            // When reading the file, use the default encoding but detect the
            // encoding if byte order marks are present.
            content = BuildProcess.ReadWithEncoding(tocFile, ref enc);

            // We only need the default page for HTML Help 1.x files and
            // websites.
            if (format != HelpFileFormat.HtmlHelp2x)
            {
                // Don't bother if an explicit default has been specified
                if (defaultTopic == null)
                {
                    Match m = reExtractDefTopic.Match(content);

                    if (!m.Success)
                    {
                        throw new BuilderException("Unable to determine " +
                                                   "default page in " + tocFile);
                    }

                    defaultTopic = m.Groups["Filename"].Value;
                }

                // Remove the root namespace container if not wanted and it
                // is there.
                if (!project.RootNamespaceContainer &&
                    re1xRootEntry.IsMatch(content))
                {
                    tocChanged = true;
                    content    = re1xRootEntry.Replace(content, String.Empty, 1);
                    endTagPos  = content.LastIndexOf("</UL>");

                    if (endTagPos != -1)
                    {
                        content = content.Remove(endTagPos, 5);
                    }
                }

                // Reset the encoding as HTML 1.x does not appear to
                // support UTF-8 encoding in the table of content.
                enc        = Encoding.Default;
                tocChanged = true;
            }
            else
            {
                // Remove the root namespace container if not wanted and
                // it is there.
                if (!project.RootNamespaceContainer &&
                    content.LastIndexOf("</HelpTOCNode>") != -1)
                {
                    tocChanged = true;
                    content    = re2xRootEntry.Replace(content, String.Empty, 1);
                    endTagPos  = content.LastIndexOf("</HelpTOCNode>");
                    content    = content.Remove(endTagPos, 14);
                }
            }

            // Update and save table of content with additional items
            if (tocChanged || (toc != null && toc.Count != 0))
            {
                // The additional entries can go in ahead of the namespace
                // documentation entries or after them.
                if (toc != null && toc.Count != 0)
                {
                    if (format != HelpFileFormat.HtmlHelp2x)
                    {
                        if (project.ContentPlacement == ContentPlacement.AboveNamespaces)
                        {
                            content = content.Insert(content.IndexOf(
                                                         "<UL>") + 6, toc.ToString());
                        }
                        else
                        {
                            content = content.Insert(content.LastIndexOf(
                                                         "</UL>"), toc.ToString());
                        }
                    }
                    else
                    {
                        if (project.ContentPlacement == ContentPlacement.AboveNamespaces)
                        {
                            content = content.Insert(content.IndexOf(
                                                         "\"1.0\">") + 8,
                                                     toc.ToString(HelpFileFormat.HtmlHelp2x));
                        }
                        else
                        {
                            content = content.Insert(content.IndexOf(
                                                         "</HelpTOC>"),
                                                     toc.ToString(HelpFileFormat.HtmlHelp2x));
                        }
                    }
                }

                // We'll parse the HTML TOC as an XML file later on to
                // generate the tree view TOC for the website.  This
                // requires some fix-ups to the <param> tags and the
                // removal of the DOCTYPE tag.
                if (format == HelpFileFormat.Website)
                {
                    content = reParamFixUp.Replace(content, "<param$1/>");
                    content = reEncodeLeft.Replace(content, "$1&lt;$3");
                    content = reEncodeRight.Replace(content, "$1&gt;$3");
                    content = content.Remove(0, content.IndexOf("<HTML>"));
                }

                // Write the file back out with the appropriate encoding
                using (StreamWriter sw = new StreamWriter(tocFile, false, enc))
                {
                    sw.Write(content);
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Transform the specified template by inserting the necessary
        /// values into the place holders and saving it to the working folder.
        /// </summary>
        /// <param name="template">The template to transform</param>
        /// <param name="sourceFolder">The folder where the template is
        /// located</param>
        /// <param name="destFolder">The folder in which to save the
        /// transformed file</param>
        /// <returns>The path to the transformed file</returns>
        protected string TransformTemplate(string template,
                                           string sourceFolder, string destFolder)
        {
            Encoding enc = Encoding.Default;
            string   templateText, transformedFile;

            if (template == null)
            {
                throw new ArgumentNullException("template");
            }

            if (sourceFolder == null)
            {
                throw new ArgumentNullException("sourceFolder");
            }

            if (destFolder == null)
            {
                throw new ArgumentNullException("destFolder");
            }

            if (!sourceFolder.EndsWith(@"\"))
            {
                sourceFolder += @"\";
            }

            if (!destFolder.EndsWith(@"\"))
            {
                destFolder += @"\";
            }

            try
            {
                // When reading the file, use the default encoding but
                // detect the encoding if byte order marks are present.
                templateText = BuildProcess.ReadWithEncoding(
                    sourceFolder + template, ref enc);

                // Use a regular expression to find and replace all field
                // tags with a matching value from the project.
                templateText = reField.Replace(templateText, fieldMatchEval);

                transformedFile = destFolder + template;

                // Write the file back out using its original encoding
                using (StreamWriter sw = new StreamWriter(transformedFile,
                                                          false, enc))
                {
                    sw.Write(templateText);
                }
            }
            catch (Exception ex)
            {
                throw new BuilderException(String.Format(
                                               CultureInfo.CurrentCulture,
                                               "Unable to transform template '{0}': {1}", template,
                                               ex.Message), ex);
            }

            return(transformedFile);
        }