/// <inheritdoc/>
        public void Execute(ExecutionContext context)
        {
            var mrefConfigPath = Path.Combine(builder.WorkingFolder, "MRefBuilder.config");
            var mrefConfig = XDocument.Load(mrefConfigPath);

            var xamlAttachedMembersAddInElement = (
                from addin in mrefConfig.Descendants("addin")
                where
                    (String)addin.Attribute("type") == "Microsoft.Ddue.Tools.XamlAttachedMembersAddIn"
                select addin).SingleOrDefault();

            xamlAttachedMembersAddInElement.ReplaceNodes(
                new XElement("dependencyPropertyTypeName", "TwistedLogik.Ultraviolet.UI.Presentation.DependencyProperty"),
                new XElement("dependencyPropertySuffix", "Property"),
                new XElement("routedEventTypeName", "TwistedLogik.Ultraviolet.UI.Presentation.RoutedEvent"),
                new XElement("routedEventSuffix", "Event"));

            mrefConfig.Save(mrefConfigPath);

            builder.ReportProgress("Configured MRefBuilder to use Ultraviolet Presentation Foundation dependency system types.");
        }
        /// <inheritdoc />
        public void Execute(ExecutionContext context)
        {
            // Look up the resize tool tip in the shared content resource items file
            if(context.BuildStep == BuildStep.GenerateSharedContent)
            {
                string sharedContentFile = Directory.EnumerateFiles(builder.PresentationStyleResourceItemsFolder,
                    "shared*content*", SearchOption.AllDirectories).FirstOrDefault();

                if(sharedContentFile != null)
                {
                    XDocument doc = XDocument.Load(sharedContentFile);
                    var toolTip = doc.XPathSelectElement("content/item[@id='resizeToolTip']");

                    if(toolTip != null)
                        resizeToolTip = toolTip.Value;
                }

                if(String.IsNullOrWhiteSpace(resizeToolTip))
                {
                    builder.ReportWarning("LWW0001", "Unable to locate resizeToolTip resource item.  " +
                        "Using default text.");
                    resizeToolTip = "Click or drag to resize";
                }

                return;
            }

            builder.ReportProgress("Adding lightweight search and TOC elements to each topic...");

            // Load the web TOC generated by SandcastleHtmlExtract
            XDocument webtoc = XDocument.Load(Path.Combine(builder.WorkingFolder, "WebTOC.xml"));

            // Remove the Id attribute from all nodes that contain a Url attribute
            foreach(XElement element in webtoc.XPathSelectElements("//node()[@Id and @Url]"))
                element.Attribute("Id").Remove();

            // Generate the TOC fragments
            Directory.CreateDirectory(Path.Combine(builder.WorkingFolder, "Output", "Website", "toc"));
            List<XElement> elements = new List<XElement>(webtoc.XPathSelectElements("//node()"));

            // Work around the problem of the root node only showing one type if there are no conceptual topics
            // or they are listed after the namespaces.  In such cases, expand the root node so that all
            // namespaces are listed on the default page.  This avoids confusion caused by only seeing one
            // namespace when the root node is collapsed by default.
            var firstElement = webtoc.Root.Elements().First();

            Parallel.ForEach(elements,
              new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 20 }, element =>
            {
                XDocument pageChildren = new XDocument(new XDeclaration("1.0", "utf-8", null));
                XElement copy = new XElement(element);

                pageChildren.Add(copy);

                foreach(XElement child in copy.Elements())
                {
                    if(!child.HasElements)
                        continue;

                    child.SetAttributeValue("HasChildren", true);
                    child.RemoveNodes();
                }

                string uri = null;

                if(copy.Attribute("Url") != null)
                    uri = copy.Attribute("Url").Value;
                else
                    if(copy.Attribute("Id") != null)
                        uri = copy.Attribute("Id").Value;
                    else
                        if(copy.Name.LocalName == "HelpTOC")
                            uri = "roottoc.html";
                        else
                            throw new NotImplementedException();

                string fileId = Path.GetFileNameWithoutExtension(uri.Substring(uri.LastIndexOf('/') + 1));

                if(element.HasElements)
                {
                    using(XmlWriter writer = XmlWriter.Create(Path.Combine(builder.WorkingFolder, "Output",
                      "Website", "toc", fileId + ".xml")))
                    {
                        pageChildren.WriteTo(writer);
                    }
                }

                if(string.IsNullOrEmpty((string)copy.Attribute("Url")))
                    return;

                // Generate the lightweight TOC pane
                XElement current = element;
                IEnumerable<XElement> parents = current.XPathSelectElements("parent::HelpTOCNode/ancestor::HelpTOCNode");
                XElement parent = current.XPathSelectElement("parent::HelpTOCNode");
                IEnumerable<XElement> siblings = current.Parent.Elements("HelpTOCNode");
                IEnumerable<XElement> children = current.Elements("HelpTOCNode");

                XElement tocNav = new XElement("div", new XAttribute("id", "tocNav"));

                // The documentation root
                tocNav.Add(GenerateTocRoot(parent == null && !children.Any()));

                // All the ancestors *except* the immediate parent, always collapsed by default
                foreach(XElement ancestor in parents)
                    tocNav.Add(GenerateTocAncestor(ancestor, 0, false));

                // The immediate parent is expanded if the current node has no children
                if(parent != null)
                {
                    bool expanded = !current.HasElements;
                    int level = expanded ? 1 : 0;
                    tocNav.Add(GenerateTocAncestor(parent, level, expanded));
                }

                // The siblings of the current node are shown if the parent is expanded, otherwise only the
                // current node is shown.
                foreach(XElement sibling in siblings)
                {
                    bool showSiblings;
                    int level;

                    if(parent == null && !current.HasElements)
                    {
                        showSiblings = true;
                        level = 1;
                    }
                    else
                    {
                        showSiblings = !current.HasElements;
                        level = current.HasElements || parent == null ? 1 : 2;
                    }

                    tocNav.Add(GenerateTocSibling(current, sibling, level, showSiblings));
                }

                // The children of the current node, if any exist, are always shown by default
                foreach(XElement child in children)
                    tocNav.Add(GenerateTocChild(child));

                XElement resizableBar =
                    new XElement("div",
                        new XAttribute("id", "tocResizableEW"),
                        new XAttribute("onmousedown", "OnMouseDown(event);"),
                    // Add empty text to force full start/end element.  This allows for proper display in the
                    // browser while still allowing XHTML output that's valid for post-processing.
                        new XText(String.Empty));

                XElement resizeUi =
                    new XElement("div",
                        new XAttribute("id", "TocResize"),
                        new XAttribute("class", "tocResize"),
                        new XElement("img",
                            new XAttribute("id", "ResizeImageIncrease"),
                            new XAttribute("src", "../icons/TocOpen.gif"),
                            new XAttribute("onclick", "OnIncreaseToc()"),
                            new XAttribute("alt", resizeToolTip),
                            new XAttribute("title", resizeToolTip)),
                        new XElement("img",
                            new XAttribute("id", "ResizeImageReset"),
                            new XAttribute("src", "../icons/TocClose.gif"),
                            new XAttribute("style", "display:none"),
                            new XAttribute("onclick", "OnResetToc()"),
                            new XAttribute("alt", resizeToolTip),
                            new XAttribute("title", resizeToolTip)));

                XElement leftNav =
                    new XElement("div",
                        new XAttribute("class", "leftNav"),
                        new XAttribute("id", "leftNav"),
                        tocNav,
                        resizableBar,
                        resizeUi);

                string path = Path.Combine(builder.WorkingFolder, @"Output\Website", current.Attribute("Url").Value);
                string outputFile = File.ReadAllText(path, Encoding.UTF8);

                // Search box
                int pos = outputFile.IndexOf("<div class=\"pageHeader\"", StringComparison.Ordinal);

                if(pos != -1)
                {
                    pos = outputFile.IndexOf("</div>", pos, StringComparison.Ordinal);

                    if(pos != -1)
                        outputFile = outputFile.Insert(pos, "<form id=\"SearchForm\" method=\"get\" " +
                            "action=\"#\" onsubmit=\"javascript:TransferToSearchPage(); return false;\">" +
                            "<input id=\"SearchTextBox\" type=\"text\" maxlength=\"200\" />" +
                            "<button id=\"SearchButton\" type=\"submit\"></button>" +
                            "</form>");
                }

                // Left nav
                pos = outputFile.IndexOf("<div class=\"topicContent\"", StringComparison.Ordinal);

                if(pos != -1)
                    outputFile = outputFile.Insert(pos, leftNav.ToString(SaveOptions.DisableFormatting));

                if(element == firstElement && firstElement.HasElements)
                {
                    outputFile = outputFile.Replace("</html>", @"<script type=""text/javascript"">
<!--
    var tocNav = document.getElementById(""tocNav"");
    var anchor = tocNav.children[0].children[0];
    Toggle(anchor);
    tocNav.children[0].className += "" current"";
-->
</script>
</html>");
                }

                File.WriteAllText(path, outputFile, Encoding.UTF8);
            });
        }
        /// <summary>
        /// Execute all plug-ins that need to execute in the given build step that have the given execution
        /// behavior.
        /// </summary>
        /// <param name="behavior">The execution behavior</param>
        /// <returns>True if at least one plug-in was executed or false if no plug-ins were executed.</returns>
        /// <remarks>Plug-ins will execute based on their execution priority.  Those with a higher priority value
        /// will execute before those with a lower value.  Plug-ins with identical priority values may execute
        /// in any order within their group.</remarks>
        private bool ExecutePlugIns(ExecutionBehaviors behavior)
        {
            List<IPlugIn> executeList;
            ExecutionContext context;
            BuildStep step;
            int numberExecuted = 0;

            if(loadedPlugIns == null)
                return false;

            step = progressArgs.BuildStep;

            // Find plug-ins that need to be executed
            executeList = loadedPlugIns.Values.Where(p => p.ExecutionPoints.RunsAt(step, behavior)).ToList();

            if(executeList.Count == 0)
                return false;

            // Sort by execution priority in descending order
            executeList.Sort((x, y) => y.ExecutionPoints.PriorityFor(step, behavior) -
                x.ExecutionPoints.PriorityFor(step, behavior));

            context = new ExecutionContext(step, behavior);

            foreach(IPlugIn plugIn in executeList)
            {
                var metadata = (HelpFileBuilderPlugInExportAttribute)plugIn.GetType().GetCustomAttributes(
                    typeof(HelpFileBuilderPlugInExportAttribute), false).First();

                try
                {
                    // Wrap plug-in output in an element so that it can be formatted differently
                    swLog.WriteLine("<plugIn name=\"{0}\" behavior=\"{1}\" priority=\"{2}\">", metadata.Id,
                        behavior, plugIn.ExecutionPoints.PriorityFor(step, behavior));

                    context.Executed = true;
                    plugIn.Execute(context);

                    swLog.Write("</plugIn>");
                }
                catch(Exception ex)
                {
                    swLog.WriteLine("</plugIn>");

                    throw new BuilderException("BE0029", "Unexpected error while executing plug-in '" +
                        metadata.Id + "': " + ex.ToString(), ex);
                }

                if(context.Executed)
                    numberExecuted++;
            }

            return (numberExecuted != 0);
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            Project msBuildProject = null;
            ProjectItem projectItem;
            Dictionary<string, string> assemblies = new Dictionary<string, string>();

            string filename, projectFile = builder.WorkingFolder + "GenerateRefInfo.proj";

            // If the project doesn't exist we have nothing to do.  However, it could be that some other plug-in
            // has bypassed it so only issue a warning.
            if(!File.Exists(projectFile))
            {
                builder.ReportWarning("WRP0003", "The reflection information generation project '{0}' could " +
                    "not be found.  The Wildcard References plug-in did not run.", projectFile);
                return;
            }

            // Find all unique references
            foreach(var r in referencePaths)
                foreach(string fullPath in Directory.EnumerateFiles(r.ReferencePath, r.Wildcard,
                  (r.Recursive) ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly))
                {
                    filename = Path.GetFileNameWithoutExtension(fullPath);

                    // "mscorlib" is ignored as it causes MRefBuilder to reset its target platform information.
                    // For something like Silverlight, that probably isn't what we want it to do so we'll ignore
                    // it.  It'll use what is passed in the platform configuration file option.
                    if(!assemblies.ContainsKey(filename) && !filename.Equals("mscorlib", StringComparison.OrdinalIgnoreCase))
                        assemblies.Add(filename, fullPath);
                }

            builder.ReportProgress("Adding wildcard references");

            try
            {
                msBuildProject = new Project(projectFile);

                // Remove references that are already there
                foreach(ProjectItem r in msBuildProject.GetItems("Reference"))
                    if(assemblies.ContainsKey(r.EvaluatedInclude))
                    {
                        builder.ReportProgress("    Skipping {0} ({1}) as it appears to already be present",
                            r.EvaluatedInclude, assemblies[r.EvaluatedInclude]);
                        assemblies.Remove(r.EvaluatedInclude);
                    }

                // Add the remaining references
                foreach(var r in assemblies)
                {
                    projectItem = msBuildProject.AddItem("Reference", r.Key)[0];
                    projectItem.SetMetadataValue(BuildItemMetadata.HintPath, r.Value);
                    builder.ReportProgress("    Added reference {0} ({1})", r.Key, r.Value);
                }

                msBuildProject.Save(projectFile);
            }
            finally
            {
                // If we loaded it, we must unload it.  If not, it is cached and may cause problems later.
                if(msBuildProject != null)
                {
                    ProjectCollection.GlobalProjectCollection.UnloadProject(msBuildProject);
                    ProjectCollection.GlobalProjectCollection.UnloadProject(msBuildProject.Xml);
                }
            }
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            builder.ReportProgress("Multilanguage Documentation Support ...");

            if (targetLanguage == null || targetLanguage.Length == 0)
            {
                builder.ReportProgress("No target language was specified.");
                goto DONE;
            }

            builder.ReportProgress("Target language = {0}", targetLanguage);

            foreach (XmlCommentsFile commentsFile in builder.CommentsFiles)
            {
                // Collect elements which have language tags.
                List<XmlNode> docNodeList = new List<XmlNode>();
                foreach (XmlNode docNode in commentsFile.Comments.SelectNodes("doc/members/member//*[en|ja|" + targetLanguage + "]"))
                {
                    docNodeList.Add(docNode);
                }

                // Process each element.
                bool modified = false;
                foreach (XmlNode docNode in docNodeList)
                {
                    // Collect language tags.
                    List<XmlNode> langNodes = new List<XmlNode>();
                    bool hasEnglishDoc = false;
                    bool hasTargetDoc = false;
                    foreach (XmlNode langNode in docNode.ChildNodes)
                    {
                        if (IsLangTag(langNode))
                        {
                            langNodes.Add(langNode);

                            if (langNode.LocalName == ENGLISH_TAG_NAME)
                                hasEnglishDoc = true;

                            if (langNode.LocalName == targetLanguage)
                                hasTargetDoc = true;
                        }
                    }

                    // Determine which language to leave.
                    string languageToLeave;
                    if (hasTargetDoc)
                    {
                        languageToLeave = targetLanguage;
                    }
                    else if (hasEnglishDoc)
                    {
                        languageToLeave = ENGLISH_TAG_NAME;
                        builder.ReportProgress("Missing target language ... use {0} : {1}", languageToLeave, GetMemberName(docNode));
                    }
                    else if (langNodes.Count > 0)
                    {
                        languageToLeave = langNodes[0].LocalName;
                    }
                    else
                    {
                        languageToLeave = null;
                        builder.ReportProgress("No language tag : {0}", GetMemberName(docNode));
                    }

                    // Strip targeted language tag, and remove other language tags.
                    if (languageToLeave != null)
                    {
                        foreach (XmlNode langNode in langNodes)
                        {
                            if (langNode.LocalName == languageToLeave)
                            {
                                StripLangTag(docNode, langNode);
                                modified = true;
                            }
                            else
                            {
                                docNode.RemoveChild(langNode);
                                modified = true;
                            }
                        }
                    }
                }

                if (modified)
                {
                    commentsFile.Save();
                }
            }

            DONE:
            builder.ReportProgress("Multilanguage Documentation Support Done.");
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        /// <remarks>Since this runs after completion of the build and the log file is closed, any progress
        /// messages reported here will not appear in it, just in the output window on the main form.</remarks>
        public void Execute(ExecutionContext context)
        {
            MailMessage msg = null;
            string logFilename = null;

            // There is nothing to do on completion if there is no success e-mail address
            if(context.BuildStep == BuildStep.Completed && successEMailAddress.Length == 0)
            {
                context.Executed = false;
                return;
            }

            try
            {
                logFilename = builder.LogFilename;

                // Run the log file through an XSL transform first?
                if(!String.IsNullOrEmpty(xslTransformFile) && File.Exists(logFilename))
                    logFilename = this.TransformLogFile();

                msg = new MailMessage();

                msg.IsBodyHtml = false;
                msg.Subject = String.Format(CultureInfo.InvariantCulture, "Build {0}: {1}", context.BuildStep,
                    builder.ProjectFilename);

                if(fromEMailAddress.Length != 0)
                    msg.From = new MailAddress(fromEMailAddress);
                else
                    msg.From = new MailAddress("*****@*****.**");

                if(context.BuildStep == BuildStep.Completed)
                {
                    msg.To.Add(successEMailAddress);

                    if(attachLogOnSuccess && File.Exists(logFilename))
                        msg.Attachments.Add(new Attachment(logFilename));
                }
                else
                {
                    msg.To.Add(failureEMailAddress);

                    if(attachLogOnFailure && File.Exists(logFilename))
                        msg.Attachments.Add(new Attachment(logFilename));
                }

                msg.Body = String.Format(CultureInfo.InvariantCulture,
                    "Build {0}: {1}{2}\r\nBuild output is located at {3}\r\n", context.BuildStep,
                    builder.ProjectFolder, builder.ProjectFilename, builder.OutputFolder);

                if(context.BuildStep != BuildStep.Completed || builder.CurrentProject.KeepLogFile)
                    msg.Body += "Build details can be found in the log file " + builder.LogFilename + "\r\n";

                using(SmtpClient smtp = new SmtpClient())
                {
                    if(smtpServer.Length != 0)
                    {
                        smtp.Host = smtpServer;
                        smtp.Port = smtpPort;
                    }

                    if(!credentials.UseDefaultCredentials)
                        smtp.Credentials = new NetworkCredential(credentials.UserName, credentials.Password);

                    smtp.Send(msg);
                }

                builder.ReportProgress("The build notification e-mail was sent successfully to {0}",
                    msg.To[0].Address);
            }
            catch(FormatException)
            {
                builder.ReportProgress("Failed to send build notification e-mail!  The e-mail addresses " +
                    "'{0}' appears to be invalid.", msg.To[0]);
            }
            catch(SmtpFailedRecipientException recipEx)
            {
                builder.ReportProgress("Failed to send build notification e-mail!  A problem occurred trying " +
                    "to send the e-mail to the recipient '{0}': {1}", recipEx.FailedRecipient, recipEx.Message);
            }
            catch(SmtpException smtpEx)
            {
                System.Diagnostics.Debug.WriteLine(smtpEx.ToString());

                builder.ReportProgress("Failed to send build notification e-mail!  A problem occurred trying " +
                    "to connect to the e-mail server.  Details:\r\n{0}\r\n", smtpEx.ToString());
            }
            finally
            {
                if(msg != null)
                    msg.Dispose();

                // Delete the transformed log file if it exists
                if(!String.IsNullOrEmpty(logFilename) && logFilename.EndsWith(".html",
                  StringComparison.OrdinalIgnoreCase))
                    File.Delete(logFilename);
            }
        }
Example #7
0
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(SandcastleBuilder.Utils.BuildComponent.ExecutionContext context)
        {
            Encoding        enc = Encoding.Default;
            Thread          browserThread;
            XmlDocument     sharedContent;
            XPathNavigator  navContent, item;
            XmlCommentsFile comments;
            string          sharedContentFilename, workingPath, content;

            // Copy any XML comments files from the project to the working folder.  Solutions, projects, and
            // assemblies are ignored as they won't be used with this build type.
            if (context.BuildStep == BuildStep.ValidatingDocumentationSources)
            {
                builder.ExecuteBeforeStepPlugIns();

                foreach (DocumentationSource ds in builder.CurrentProject.DocumentationSources)
                {
                    foreach (string commentsName in DocumentationSource.CommentsFiles(ds.SourceFile,
                                                                                      ds.IncludeSubFolders))
                    {
                        workingPath = builder.WorkingFolder + Path.GetFileName(commentsName);

                        // Warn if there is a duplicate and copy the comments file to a unique name to preserve
                        // its content.
                        if (File.Exists(workingPath))
                        {
                            workingPath = builder.WorkingFolder + Guid.NewGuid().ToString("B");

                            builder.ReportWarning("BE0063", "'{0}' matches a previously copied comments " +
                                                  "filename.  The duplicate will be copied to a unique name to preserve the " +
                                                  "comments it contains.", commentsName);
                        }

                        File.Copy(commentsName, workingPath, true);
                        File.SetAttributes(workingPath, FileAttributes.Normal);

                        // Add the file to the XML comments file collection
                        comments = new XmlCommentsFile(workingPath);

                        builder.CommentsFiles.Add(comments);
                        builder.ReportProgress("    {0} -> {1}", commentsName, workingPath);
                    }
                }

                builder.ExecuteAfterStepPlugIns();
                return;
            }

            // Remove the version information items from the shared content file as the AjaxDoc reflection file
            // doesn't contain version information.
            if (context.BuildStep == BuildStep.GenerateSharedContent)
            {
                builder.ReportProgress("Removing version information items from shared content file");

                sharedContentFilename = builder.WorkingFolder + "SHFBContent.xml";

                sharedContent = new XmlDocument();
                sharedContent.Load(sharedContentFilename);
                navContent = sharedContent.CreateNavigator();

                item = navContent.SelectSingleNode("content/item[@id='locationInformation']");

                if (item != null)
                {
                    item.DeleteSelf();
                }

                item = navContent.SelectSingleNode("content/item[@id='assemblyNameAndModule']");

                if (item != null)
                {
                    item.DeleteSelf();
                }

                sharedContent.Save(sharedContentFilename);
                return;
            }

            builder.ReportProgress("Using project '{0}'", projectName);

            if (regenerateFiles)
            {
                // Regenerate the files first.  This is done by starting a thread to invoke the AjaxDoc
                // application via a web browser control.  This is necessary as the browser control needs to run
                // in a thread with a single-threaded apartment state.  We can't just request the page as AjaxDoc
                // has to post back to itself in order to store the generated information.
                builder.ReportProgress("Generating XML comments and reflection information via AjaxDoc");

                browserThread = new Thread(RunBrowser);
                browserThread.SetApartmentState(ApartmentState.STA);

                navCount = 0;
                browserThread.Start();

                if (!browserThread.Join(11000))
                {
                    browserThread.Abort();
                }

                if (!String.IsNullOrEmpty(errorText))
                {
                    throw new BuilderException("ADP0003", "AjaxDoc encountered a scripting error: " + errorText);
                }

                if (commentsFile == null || reflectionFile == null)
                {
                    throw new BuilderException("ADP0004", "Unable to produce comments file and/or reflection file");
                }

                builder.ReportProgress("Generated comments file '{0}' and reflection file '{1}'", commentsFile,
                                       reflectionFile);
            }
            else
            {
                // Use the existing files
                commentsFile   = "Output/" + projectName + ".xml";
                reflectionFile = "Output/" + projectName + ".org";

                builder.ReportProgress("Using existing XML comments file '{0}' and reflection information " +
                                       "file '{1}'", commentsFile, reflectionFile);
            }

            // Allow Before step plug-ins to run
            builder.ExecuteBeforeStepPlugIns();

            // Download the files
            using (WebClient webClient = new WebClient())
            {
                webClient.UseDefaultCredentials = userCreds.UseDefaultCredentials;

                if (!userCreds.UseDefaultCredentials)
                {
                    webClient.Credentials = new NetworkCredential(userCreds.UserName, userCreds.Password);
                }

                webClient.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);

                if (proxyCreds.UseProxyServer)
                {
                    webClient.Proxy = new WebProxy(proxyCreds.ProxyServer, true);

                    if (!proxyCreds.Credentials.UseDefaultCredentials)
                    {
                        webClient.Proxy.Credentials = new NetworkCredential(proxyCreds.Credentials.UserName,
                                                                            proxyCreds.Credentials.Password);
                    }
                }

                // Since there are only two, download them synchronously
                workingPath = builder.WorkingFolder + projectName + ".xml";
                builder.ReportProgress("Downloading {0}", commentsFile);
                webClient.DownloadFile(ajaxDocUrl + commentsFile, workingPath);
                builder.CommentsFiles.Add(new XmlCommentsFile(workingPath));

                builder.ReportProgress("Downloading {0}", reflectionFile);
                webClient.DownloadFile(ajaxDocUrl + reflectionFile, builder.ReflectionInfoFilename);

                builder.ReportProgress("Downloads completed successfully");
            }

            // AjaxDoc 1.1 prefixes all member names with "J#" which causes BuildAssembler's
            // ResolveReferenceLinksComponent component in the Sept 2007 CTP to crash.  As such, we'll strip it
            // out.  I can't see a need for it anyway.
            content = BuildProcess.ReadWithEncoding(workingPath, ref enc);
            content = content.Replace(":J#", ":");

            using (StreamWriter sw = new StreamWriter(workingPath, false, enc))
            {
                sw.Write(content);
            }

            content = BuildProcess.ReadWithEncoding(builder.ReflectionInfoFilename, ref enc);
            content = content.Replace(":J#", ":");

            using (StreamWriter sw = new StreamWriter(builder.ReflectionInfoFilename, false, enc))
            {
                sw.Write(content);
            }

            builder.ReportProgress("Applying visibility settings manually");
            builder.ApplyVisibilityProperties(builder.ReflectionInfoFilename);

            // Don't apply the API filter settings in a partial build
            if (builder.PartialBuildType == PartialBuildType.None && builder.BuildApiFilter.Count != 0)
            {
                builder.ReportProgress("Applying API filter manually");
                builder.ApplyManualApiFilter(builder.BuildApiFilter, builder.ReflectionInfoFilename);
            }

            // Allow After step plug-ins to run
            builder.ExecuteAfterStepPlugIns();
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            string configFilename;

            // Merge the reflection file info into conceptual.config
            configFilename = builder.WorkingFolder + "conceptual.config";

            if(File.Exists(configFilename))
                this.AddBibliographyParameter(configFilename);

            // Merge the reflection file info into sancastle.config
            configFilename = builder.WorkingFolder + "sandcastle.config";

            if(File.Exists(configFilename))
                this.AddBibliographyParameter(configFilename);
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            XmlDocument config = new XmlDocument();
            XmlAttribute attr;
            XmlNode resolver, ddue, ignoreNode, assemblyNode;

            config.Load(builder.WorkingFolder + "MRefBuilder.config");
            resolver = config.SelectSingleNode("configuration/dduetools/resolver");

            if(resolver == null)
            {
                ddue = config.SelectSingleNode("configuration/dduetools");

                if(ddue == null)
                    throw new BuilderException("ABR0002", "Unable to locate configuration/dduetools or its " +
                        "child resolver element in MRefBuilder.config");

                builder.ReportProgress("Default resolver element not found, adding new element");
                resolver = config.CreateNode(XmlNodeType.Element, "resolver", null);
                ddue.AppendChild(resolver);

                attr = config.CreateAttribute("type");
                attr.Value = "Microsoft.Ddue.Tools.Reflection.AssemblyResolver";
                resolver.Attributes.Append(attr);

                attr = config.CreateAttribute("assembly");
                attr.Value = builder.SubstitutionTags.TransformText(@"{@SHFBFolder}MRefBuilder.exe");
                resolver.Attributes.Append(attr);

                attr = config.CreateAttribute("use-gac");
                attr.Value = "false";
                resolver.Attributes.Append(attr);
            }

            // Allow turning GAC resolution on
            resolver.Attributes["use-gac"].Value = useGac.ToString().ToLowerInvariant();

            if(redirects.Count != 0)
            {
                builder.ReportProgress("Adding binding redirections to assembly resolver configuration:");

                foreach(BindingRedirectSettings brs in redirects)
                    builder.ReportProgress("    {0}", brs);

                redirects.ToXml(config, resolver, false);
            }

            if(ignoreIfUnresolved.Count != 0)
            {
                builder.ReportProgress("Adding ignored assembly names to assembly resolver configuration:");

                ignoreNode = resolver.SelectSingleNode("ignoreIfUnresolved");

                if(ignoreNode == null)
                {
                    ignoreNode = config.CreateNode(XmlNodeType.Element, "ignoreIfUnresolved", null);
                    resolver.AppendChild(ignoreNode);
                }
                else
                    ignoreNode.RemoveAll();

                foreach(string ignoreName in ignoreIfUnresolved)
                {
                    assemblyNode = config.CreateNode(XmlNodeType.Element, "assemblyIdentity", null);
                    ignoreNode.AppendChild(assemblyNode);

                    attr = config.CreateAttribute("name");
                    attr.Value = ignoreName;
                    assemblyNode.Attributes.Append(attr);

                    builder.ReportProgress("    {0}", ignoreName);
                }
            }

            config.Save(builder.WorkingFolder + "MRefBuilder.config");
        }
Example #10
0
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            XmlDocument toc;
            XPathNavigator root, navToc, tocEntry, tocParent;
            bool hasParent;

            // Scan the XML comments files.  The files aren't available soon after this step and by now
            // everything that other plug-ins may have added to the collection should be there.
            builder.ReportProgress("Searching for comment members containing <tocexclude />...");

            foreach(XmlCommentsFile f in builder.CommentsFiles)
                foreach(XmlNode member in f.Members.SelectNodes("member[count(.//tocexclude) > 0]/@name"))
                    exclusionList.Add(member.Value);

            builder.ReportProgress("Found {0} members to exclude from the TOC", exclusionList.Count);

            if(exclusionList.Count == 0)
                return;

            builder.ReportProgress("Removing members from the TOC");

            toc = new XmlDocument();
            toc.Load(builder.WorkingFolder + "toc.xml");
            navToc = toc.CreateNavigator();

            // If a root namespace container node is present, we need to look in it rather than the document root
            // node.
            root = navToc.SelectSingleNode("topics/topic[starts-with(@id, 'R:')]");

            if(root == null)
                root = navToc.SelectSingleNode("topics");

            foreach(string id in exclusionList)
            {
                tocEntry = root.SelectSingleNode("//topic[@id='" + id + "']");

                // Ignore if null, it was probably excluded by the API filter
                if(tocEntry != null)
                {
                    // Remove the entry.  If this results in the parent being an empty node, remove it too.
                    do
                    {
                        tocParent = tocEntry.Clone();
                        hasParent = tocParent.MoveToParent();

                        builder.ReportProgress("    Removing '{0}'", tocEntry.GetAttribute("id", String.Empty));
                        tocEntry.DeleteSelf();

                    } while(hasParent && !tocParent.HasChildren);
                }
            }

            toc.Save(builder.WorkingFolder + "toc.xml");
        }
Example #11
0
 /// <summary>
 /// This method is used to execute the plug-in during the build process
 /// </summary>
 /// <param name="context">The current execution context</param>
 public void Execute(ExecutionContext context)
 {
     if(this.ModifyMRefBuilderConfig())
         this.ModifyGenerateRefInfoProject();
 }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            List<string> namespaceList = new List<string>();
            Dictionary<string, XmlNode> namespaceNodes = new Dictionary<string, XmlNode>();
            XmlDocument toc;
            XPathNavigator root, navToc;
            XmlAttribute attr;
            XmlNode tocEntry = null, tocParent;
            string[] parts;
            string name, parent, topicTitle, referenceContentFile;
            int parentIdx, childIdx, entriesAdded;

            builder.ReportProgress("Retrieving namespace topic title from shared content...");

            referenceContentFile = Directory.EnumerateFiles(builder.PresentationStyleResourceItemsFolder,
                "reference*content*", SearchOption.AllDirectories).FirstOrDefault();

            if(referenceContentFile != null)
            {
                toc = new XmlDocument();
                toc.Load(referenceContentFile);
                tocEntry = toc.SelectSingleNode("content/item[@id='namespaceTopicTitle']");
            }

            if(tocEntry != null)
                topicTitle = tocEntry.InnerText;
            else
            {
                builder.ReportWarning("HTP0003", "Unable to locate namespace topic title in reference " +
                    "content file.  Using default.");
                topicTitle = "{0} Namespace";
            }

            builder.ReportProgress("Creating namespace hierarchy...");

            toc = new XmlDocument();
            toc.Load(builder.WorkingFolder + "toc.xml");
            navToc = toc.CreateNavigator();

            // Get a list of the namespaces.  If a root namespace container node is present, we need to look in
            // it rather than the document root node.
            root = navToc.SelectSingleNode("topics/topic[starts-with(@id, 'R:')]");

            if(root == null)
                root = navToc.SelectSingleNode("topics");

            foreach(XPathNavigator ns in root.Select("topic[starts-with(@id, 'N:')]"))
            {
                name = ns.GetAttribute("id", String.Empty);
                namespaceList.Add(name);
                namespaceNodes.Add(name, ((IHasXmlNode)ns).GetNode());
            }

            // See if any container nodes need to be created for namespaces with a common root name
            for(parentIdx = 0; parentIdx < namespaceList.Count; parentIdx++)
            {
                parts = namespaceList[parentIdx].Split('.');

                // Only do it for namespaces with a minimum number of parts
                if(parts.Length > minParts)
                {
                    for(childIdx = minParts; childIdx < parts.Length; childIdx++)
                    {
                        name = String.Join(".", parts, 0, childIdx);

                        if(!namespaceList.Contains(name))
                        {
                            if(namespaceList.FindAll(
                              ns => ns.StartsWith(name + ".", StringComparison.Ordinal)).Count > 0)
                            {
                                // The nodes will be created later once we know where to insert them
                                namespaceList.Add(name);
                                namespaceNodes.Add(name, null);
                            }
                        }
                    }
                }
            }

            // Sort them in reverse order
            namespaceList.Sort((n1, n2) => String.Compare(n2, n1, StringComparison.Ordinal));

            // If any container namespaces were added, create nodes for them and insert them before the namespace
            // ahead of them in the list.
            foreach(string key in namespaceList)
                if(namespaceNodes[key] == null)
                {
                    tocEntry = toc.CreateElement("topic");
                    attr = toc.CreateAttribute("id");

                    attr.Value = String.Format(CultureInfo.InvariantCulture, topicTitle,
                        (key.Length > 2) ? key.Substring(2) : "Global");
                    tocEntry.Attributes.Append(attr);

                    parentIdx = namespaceList.IndexOf(key);
                    tocParent = namespaceNodes[namespaceList[parentIdx - 1]];
                    tocParent.ParentNode.InsertBefore(tocEntry, tocParent);
                    namespaceNodes[key] = tocEntry;
                }

            for(parentIdx = 1; parentIdx < namespaceList.Count; parentIdx++)
            {
                parent = namespaceList[parentIdx];
                entriesAdded = 0;

                // Check each preceding namespace.  If it starts with the parent's name, insert it as a child of
                // that one.
                for(childIdx = 0; childIdx < parentIdx; childIdx++)
                {
                    name = namespaceList[childIdx];
                    
                    if(name.StartsWith(parent + ".", StringComparison.Ordinal))
                    {
                        tocEntry = namespaceNodes[name];
                        tocParent = namespaceNodes[parent];

                        if(insertBelow && entriesAdded < tocParent.ChildNodes.Count)
                            tocParent.InsertAfter(tocEntry, tocParent.ChildNodes[
                                tocParent.ChildNodes.Count - entriesAdded - 1]);
                        else
                            tocParent.InsertBefore(tocEntry, tocParent.ChildNodes[0]);

                        namespaceList.RemoveAt(childIdx);
                        entriesAdded++;
                        parentIdx--;
                        childIdx--;
                    }
                }
            }

            toc.Save(builder.WorkingFolder + "toc.xml");
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            string workingPath, configFilename;
            bool success;

            if(context.BuildStep == BuildStep.GenerateNamespaceSummaries)
            {
                // Merge the additional reference links information
                builder.ReportProgress("Performing partial builds on additional targets' projects");

                // Build each of the projects
                foreach(ReferenceLinkSettings vs in otherLinks)
                {
                    using(SandcastleProject tempProject = new SandcastleProject(vs.HelpFileProject, true))
                    {
                        // Set the configuration and platform here so that they are evaluated properly in project
                        // properties when the project is loaded below.
                        tempProject.Configuration = builder.CurrentProject.Configuration;
                        tempProject.Platform = builder.CurrentProject.Platform;

                        // This looks odd but is necessary.  If we are in Visual Studio, the above constructor
                        // may return an instance that uses an underlying MSBuild project loaded in Visual
                        // Studio.  Since the BuildProject() method modifies the project, those changes are
                        // propagated to the Visual Studio copy which we do not want to happen.  As such, we use
                        // this constructor to clone the MSBuild project XML thus avoiding modifications to the
                        // original project.
                        using(SandcastleProject project = new SandcastleProject(tempProject))
                        {
                            // We'll use a working folder below the current project's working folder
                            workingPath = builder.WorkingFolder + vs.HelpFileProject.GetHashCode().ToString("X",
                                CultureInfo.InvariantCulture) + "\\";

                            success = this.BuildProject(project, workingPath);

                            // Switch back to the original folder for the current project
                            Directory.SetCurrentDirectory(builder.ProjectFolder);

                            if(!success)
                                throw new BuilderException("ARL0003", "Unable to build additional target " +
                                    "project: " + project.Filename);
                        }
                    }

                    // Save the reflection file location as we need it later
                    vs.ReflectionFilename = workingPath + "reflection.xml";
                }

                return;
            }

            if(context.BuildStep == BuildStep.GenerateInheritedDocumentation)
            {
                this.MergeInheritedDocConfig();
                return;
            }

            if(context.BuildStep == BuildStep.CreateBuildAssemblerConfigs)
            {
                builder.ReportProgress("Adding additional reference link namespaces...");

                var rn = builder.ReferencedNamespaces;

                HashSet<string> validNamespaces = new HashSet<string>(Directory.EnumerateFiles(
                    builder.FrameworkReflectionDataFolder, "*.xml", SearchOption.AllDirectories).Select(
                        f => Path.GetFileNameWithoutExtension(f)));

                foreach(ReferenceLinkSettings vs in otherLinks)
                    if(!String.IsNullOrEmpty(vs.ReflectionFilename))
                        foreach(var n in builder.GetReferencedNamespaces(vs.ReflectionFilename, validNamespaces))
                            rn.Add(n);

                return;
            }

            // Merge the reflection file info into conceptual.config
            configFilename = builder.WorkingFolder + "conceptual.config";

            if(File.Exists(configFilename))
                this.MergeReflectionInfo(configFilename, true);

            // Merge the reflection file info into sancastle.config
            configFilename = builder.WorkingFolder + "sandcastle.config";

            if(File.Exists(configFilename))
                this.MergeReflectionInfo(configFilename, false);
        }
Example #14
0
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="executionContext">The current execution context</param>
        public void Execute(ExecutionContext executionContext)
        {
            _buildProcess.ReportProgress(Resources.PlugInBuildProgress);
            var messageReporter = new MessageReporter(_buildProcess);
            var configuration = new Configuration
                                {
                                    OutputFolderPath = _buildProcess.WorkingFolder,
                                    DocumentRootSchemas = _configuration.DocumentRootSchemas,
                                    DocumentRootElements = _configuration.DocumentRootElements,
                                    DocumentConstraints = _configuration.DocumentConstraints,
                                    DocumentSchemas = _configuration.DocumentSchemas,
                                    DocumentSyntax = _configuration.DocumentSyntax,
                                    UseTypeDocumentationForUndocumentedAttributes = _configuration.UseTypeDocumentationForUndocumentedAttributes,
                                    UseTypeDocumentationForUndocumentedElements = _configuration.UseTypeDocumentationForUndocumentedElements,
                                    SchemaSetContainer = _configuration.SchemaSetContainer,
                                    SchemaSetTitle = _configuration.SchemaSetTitle,
                                    NamespaceContainer = _configuration.NamespaceContainer,
                                    IncludeLinkUriInKeywordK = _configuration.IncludeLinkUriInKeywordK,
                                    AnnotationTransformFileName = _configuration.AnnotationTransformFilePath.ExpandedPath,
                                    SchemaFileNames = ExpandFiles(_configuration.SchemaFilePaths),
                                    SchemaDependencyFileNames = ExpandFiles(_configuration.SchemaDependencyFilePaths),
                                    DocFileNames = ExpandFiles(_configuration.DocFilePaths)
                                };

            var contentGenerator = new ContentGenerator(messageReporter, configuration);
            contentGenerator.Generate();

            var contentLayoutItem = AddLinkedItem(BuildAction.ContentLayout, contentGenerator.ContentFile);
            contentLayoutItem.SetMetadataValue("SortOrder", Convert.ToString(_configuration.SortOrder, CultureInfo.InvariantCulture));

            foreach (var topicFileName in contentGenerator.TopicFiles)
                AddLinkedItem(BuildAction.None, topicFileName);

            foreach (var mediaItem in contentGenerator.MediaItems)
            {
                var mediaFileItem = AddLinkedItem(BuildAction.Image, mediaItem.FileName);
                mediaFileItem.SetMetadataValue("ImageId", mediaItem.ArtItem.Id);
                mediaFileItem.SetMetadataValue("AlternateText", mediaItem.ArtItem.AlternateText);
            }

            var componentConfig = GetComponentConfiguration(contentGenerator.IndexFile);

            _buildProcess.CurrentProject.ComponentConfigurations.Add(GetComponentId(), true, componentConfig);

            // Needed so that all links are properly evaluated before processed by SHFB.
            _tempProject.MSBuildProject.ReevaluateIfNecessary();

            // Add the items to the conceptual content settings
            _buildProcess.ConceptualContent.MergeContentFrom(_tempProject);
        }
Example #15
0
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            XmlNamespaceManager nsm;
            XmlDocument project;
            XmlNode property;
            string projectFile;

            // Localize the content when extracting keyword and TOC info
            if(context.BuildStep == BuildStep.ExtractingHtmlInfo)
            {
                // Since we need to localize all of the content, we must manually copy the presentation style
                // Help 1 content which isn't normally copied until after the current build step.  This assumes
                // that none of the replacement tags in the standard content depend on information generated in
                // this step (i.e. it wouldn't work for website output in the older presentation styles which
                // rely on the WebTOC.xml file for the index page).
                builder.ReportProgress("Copying Help 1 presentation style content ready for localization");

                builder.PresentationStyle.CopyHelpContent(HelpFileFormats.HtmlHelp1, String.Format(
                    CultureInfo.InvariantCulture, @"{0}Output\{1}", builder.WorkingFolder, HelpFileFormats.HtmlHelp1),
                    builder.ReportProgress, (name, source, dest) => builder.TransformTemplate(name, source, dest));

                builder.ReportProgress("Adding DBCS Fix localization folder");

                projectFile = builder.WorkingFolder + "ExtractHtmlInfo.proj";
                project = new XmlDocument();
                project.Load(projectFile);
                nsm = new XmlNamespaceManager(project.NameTable);
                nsm.AddNamespace("MSBuild", project.DocumentElement.NamespaceURI);

                property = project.SelectSingleNode("//MSBuild:LocalizedFolder", nsm);

                if(property == null)
                    throw new BuilderException("DFP0004", "Unable to locate LocalizedFolder element in " +
                        "project file");

                property.InnerText = @".\Localized";
                project.Save(projectFile);
                return;
            }

            if(builder.CurrentFormat != HelpFileFormats.HtmlHelp1)
                return;

            builder.ReportProgress("Adding localization options to build task");

            projectFile = builder.WorkingFolder + "Build1xHelpFile.proj";
            project = new XmlDocument();
            project.Load(projectFile);
            nsm = new XmlNamespaceManager(project.NameTable);
            nsm.AddNamespace("MSBuild", project.DocumentElement.NamespaceURI);

            property = project.SelectSingleNode("//MSBuild:WorkingFolder", nsm);

            if(property == null)
                throw new BuilderException("DFP0005", "Unable to locate WorkingFolder element in project file");

            property.InnerText = @".\Localized";

            property = project.SelectSingleNode("//MSBuild:LocalizeApp", nsm);

            if(property == null)
                throw new BuilderException("DFP0006", "Unable to locate LocalizeApp element in project file");

            property.InnerText = (sbAppLocalePath ?? String.Empty);
            project.Save(projectFile);
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            XmlDocument config;
            XPathNavigator navConfig, item, deleteItem;
            bool moreItems = true;
            string id;

            if(context.BuildStep == BuildStep.MergeCustomConfigs)
            {
                builder.ReportProgress("Removing non-member topics from the build manifest...");

                config = new XmlDocument();
                config.Load(builder.WorkingFolder + "manifest.xml");
                navConfig = config.CreateNavigator();

                item = navConfig.SelectSingleNode("topics/topic");

                while(item != null && moreItems)
                {
                    id = item.GetAttribute("id", String.Empty);

                    if(id.Length < 2 || id[1] != ':' || id[0] == 'R' || id[0] == 'G')
                    {
                        deleteItem = item.Clone();
                        moreItems = item.MoveToNext();
                        deleteItem.DeleteSelf();
                    }
                    else
                        moreItems = item.MoveToNext();
                }

                config.Save(builder.WorkingFolder + "manifest.xml");

                builder.ReportProgress("Removing irrelevant build components from the configuration file...");
                config = new XmlDocument();
                config.Load(builder.WorkingFolder + "sandcastle.config");
                navConfig = config.CreateNavigator();

                // The IntalliSense build component must be there
                item = navConfig.SelectSingleNode("//component[@id='IntelliSense Component']");

                if(item == null)
                    throw new BuilderException("ISO0001", "The IntelliSense Only plug-in requires that the " +
                        "IntelliSense Component be added to the project and configured.");

                // Remove Syntax Component
                item = navConfig.SelectSingleNode("//component[@id='Syntax Component']");

                if(item != null)
                    item.DeleteSelf();

                // Remove Code Block Component
                item = navConfig.SelectSingleNode("//component[@id='Code Block Component']");

                if(item != null)
                    item.DeleteSelf();

                // Remove the XSL Transform Component and everything after it
                item = navConfig.SelectSingleNode("//component[@id='XSL Transform Component']");
                moreItems = true;

                while(item != null && moreItems)
                {
                    deleteItem = item.Clone();
                    moreItems = item.MoveToNext();
                    deleteItem.DeleteSelf();
                }

                config.Save(builder.WorkingFolder + "sandcastle.config");
            }

            // Ignore all other the steps
        }
Example #17
0
 /// <summary>
 /// This method is used to execute the plug-in during the build process
 /// </summary>
 /// <param name="context">The current execution context</param>
 public void Execute(ExecutionContext context)
 {
     // TODO: Add your execution code here
     builder.ReportProgress("In $safeprojectname$PlugIn Execute() method");
 }
Example #18
0
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            XmlDocument configFile;
            XmlAttribute attr;
            XmlNode argument;
            string configFilename = builder.WorkingFolder + "sandcastle.config";

            if(!File.Exists(configFilename))
                return;

            builder.ReportProgress("\r\nAdding bibliography parameter to {0}...", configFilename);
            configFile = new XmlDocument();
            configFile.Load(configFilename);

            // Find the XSL Transform Components in the configuration file and add a new argument to them:
            // <argument key="bibliographyData" value="C:\Path\To\bibliography.xml" />
            XmlNodeList components = configFile.SelectNodes("//component[@id='XSL Transform Component']/transform");

            if(components.Count == 0)
                throw new BuilderException("BIP0004", "Unable to locate XSL Transform Component configuration in " +
                    configFilename);

            foreach(XmlNode transform in components)
            {
                argument = configFile.CreateElement("argument");

                attr = configFile.CreateAttribute("key");
                attr.Value = "bibliographyData";
                argument.Attributes.Append(attr);

                attr = configFile.CreateAttribute("value");
                attr.Value = bibliographyFile;
                argument.Attributes.Append(attr);

                transform.AppendChild(argument);
            }

            configFile.Save(configFilename);
        }
Example #19
0
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            builder.ReportProgress("Fixing up member IDs in comments...");

            foreach(var commentsFile in builder.CommentsFiles)
            {
                // Use the instance to get the comments in case changes were made elsewhere and not save yet
                string content = commentsFile.Comments.OuterXml;

                foreach(var matchExpr in expressions)
                    if(matchExpr.MatchAsRegEx)
                        content = matchExpr.RegularExpression.Replace(content, matchExpr.ReplacementValue);
                    else
                        content = content.Replace(matchExpr.MatchExpression, matchExpr.ReplacementValue);

                using(StreamWriter sw = new StreamWriter(commentsFile.SourcePath, false, commentsFile.Encoding))
                {
                    sw.Write(content);
                }

                // Force a reload so that any further references to the content get our updated content
                commentsFile.ForceReload();
            }
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            XmlDocument refInfo = new XmlDocument();
            XmlNodeList nodes;

            refInfo.Load(builder.ReflectionInfoFilename);

            foreach(string expression in expressions)
            {
                builder.ReportProgress("Removing items matching '{0}'", expression);

                nodes = refInfo.SelectNodes(expression);

                foreach(XmlNode node in nodes)
                    node.ParentNode.RemoveChild(node);

                builder.ReportProgress("    Removed {0} items", nodes.Count);
            }

            refInfo.Save(builder.ReflectionInfoFilename);
        }
Example #21
0
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            // Deploy each of the selected help file formats
            if(builder.CurrentFormat == HelpFileFormats.HtmlHelp1)
            {
                builder.ReportProgress("Deploying HTML Help 1 file");
                this.DeployOutput(builder.Help1Files, deployHelp1);
            }

            if(builder.CurrentFormat == HelpFileFormats.MSHelp2)
            {
                builder.ReportProgress("Deploying MS Help 2 files");
                this.DeployOutput(builder.Help2Files, deployHelp2);
            }

            if(builder.CurrentFormat == HelpFileFormats.MSHelpViewer)
            {
                builder.ReportProgress("Deploying MS Help Viewer files");
                this.DeployOutput(builder.HelpViewerFiles, deployHelpViewer);
            }

            if(builder.CurrentFormat == HelpFileFormats.Website)
            {
                builder.ReportProgress("Deploying website files");
                this.DeployOutput(builder.WebsiteFiles, deployWebsite);
            }

            if(builder.CurrentFormat == HelpFileFormats.OpenXml)
            {
                builder.ReportProgress("Deploying Open XML files");
                this.DeployOutput(builder.OpenXmlFiles, deployOpenXml);
            }
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            string workingPath;
            bool success;

            // Update shared content version items
            if(context.BuildStep == BuildStep.GenerateSharedContent)
            {
                this.UpdateVersionItems();
                return;
            }

            // Set the current version's reflection info filename and sort the collection so that the versions
            // are in ascending order.
            currentVersion.ReflectionFilename = builder.ReflectionInfoFilename;
            allVersions.Sort();

            // Merge the version information
            builder.ReportProgress("\r\nPerforming partial builds on prior version projects");

            // Build each of the projects
            foreach(VersionSettings vs in allVersions)
            {
                // Not needed for current project
                if(vs.HelpFileProject == null)
                    continue;

                using(SandcastleProject tempProject = new SandcastleProject(vs.HelpFileProject, true))
                {
                    // Set the configuration and platform here so that they are evaluated property in project
                    // properties when the project is loaded below.
                    tempProject.Configuration = builder.CurrentProject.Configuration;
                    tempProject.Platform = builder.CurrentProject.Platform;

                    // This looks odd but is necessary.  If we are in Visual Studio, the above constructor may
                    // return an instance that uses an underlying MSBuild project loaded in Visual Studio.
                    // Since the BuildProject() method modifies the project, those changes are propagated to the
                    // Visual Studio copy which we do not want to happen.  As such, we use this constructor to
                    // clone the MSBuild project XML thus avoiding modifications to the original project.
                    using(SandcastleProject project = new SandcastleProject(tempProject))
                    {
                        // We'll use a working folder below the current project's working folder
                        workingPath = builder.WorkingFolder + vs.HelpFileProject.GetHashCode().ToString("X",
                            CultureInfo.InvariantCulture) + "\\";

                        success = this.BuildProject(project, workingPath);

                        // Switch back to the original folder for the current project
                        Directory.SetCurrentDirectory(builder.ProjectFolder);

                        if(!success)
                            throw new BuilderException("VBP0003", "Unable to build prior version project: " +
                                project.Filename);
                    }
                }

                // Save the reflection file location as we need it later
                vs.ReflectionFilename = workingPath + "reflection.org";
            }

            // Create the Version Builder configuration and add the parameters to the transform project
            this.CreateVersionBuilderConfigurationFile();
            this.ModifyTransformManifestProject();
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            XmlDocument config;
            XPathNavigator navConfig;
            List<XPathNavigator> deleteTargets = new List<XPathNavigator>();

            // Create a dummy reflection.org and reflection.xml file
            if(context.BuildStep == BuildStep.GenerateReflectionInfo)
            {
                // Allow Before step plug-ins to run
                builder.ExecuteBeforeStepPlugIns();

                using(StreamWriter sw = new StreamWriter(builder.ReflectionInfoFilename, false, Encoding.UTF8))
                {
                    sw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                    sw.WriteLine("<reflection>");
                    sw.WriteLine("  <assemblies/>");
                    sw.WriteLine("  <apis>");
                    sw.WriteLine("    <api id=\"N:\"/>");
                    sw.WriteLine("  </apis>");
                    sw.WriteLine("</reflection>");
                }

                File.Copy(builder.ReflectionInfoFilename, Path.ChangeExtension(builder.ReflectionInfoFilename,
                    ".xml"), true);

                // Allow After step plug-ins to run
                builder.ExecuteAfterStepPlugIns();
            }
            else
                if(context.BuildStep == BuildStep.MergeCustomConfigs &&
                  builder.CurrentProject.HasItems(BuildAction.ContentLayout))
                {
                    // Remove the reflection.xml file from the conceptual configuration file since it isn't valid
                    config = new XmlDocument();
                    config.Load(builder.WorkingFolder + "conceptual.config");
                    navConfig = config.CreateNavigator();

                    XPathNodeIterator allTargets = navConfig.Select("//targets[@files='reflection.xml']");

                    foreach(XPathNavigator target in allTargets)
                        deleteTargets.Add(target);

                    foreach(var t in deleteTargets)
                        t.DeleteSelf();

                    config.Save(builder.WorkingFolder + "conceptual.config");
                }

            // Ignore all other the steps
        }
        /// <summary>
        /// This method is used to execute the plug-in during the build process
        /// </summary>
        /// <param name="context">The current execution context</param>
        public void Execute(ExecutionContext context)
        {
            builder.ReportProgress("Applying visibility settings manually");
            this.ApplyVisibilityProperties(builder.ReflectionInfoFilename);

            // Don't apply the API filter settings in a partial build
            if(builder.PartialBuildType == PartialBuildType.None && builder.CurrentProject.ApiFilter.Count != 0)
            {
                builder.ReportProgress("Applying API filter manually");
                this.ApplyManualApiFilter(builder.CurrentProject.ApiFilter, builder.ReflectionInfoFilename);
            }
        }