/// <summary> /// This method is used to initialize the plug-in at the start of the build process /// </summary> /// <param name="buildProcess">A reference to the current build process</param> /// <param name="configuration">The configuration data that the plug-in should use to initialize itself</param> /// <exception cref="BuilderException">This is thrown if the plug-in configuration is not valid</exception> public void Initialize(BuildProcess buildProcess, XPathNavigator configuration) { XPathNavigator root, node; string value; builder = buildProcess; attachLogOnSuccess = false; attachLogOnFailure = true; smtpServer = successEMailAddress = failureEMailAddress = xslTransformFile = String.Empty; credentials = new UserCredentials(); smtpPort = 25; var metadata = (HelpFileBuilderPlugInExportAttribute)this.GetType().GetCustomAttributes( typeof(HelpFileBuilderPlugInExportAttribute), false).First(); builder.ReportProgress("{0} Version {1}\r\n{2}", metadata.Id, metadata.Version, metadata.Copyright); root = configuration.SelectSingleNode("configuration"); if(root.IsEmptyElement) throw new BuilderException("CNP0001", "The Completion Notification plug-in has not been " + "configured yet"); node = root.SelectSingleNode("smtpServer"); if(node != null) { smtpServer = node.GetAttribute("host", String.Empty).Trim(); value = node.GetAttribute("port", String.Empty); if(!Int32.TryParse(value, out smtpPort)) smtpPort = 25; } credentials = UserCredentials.FromXPathNavigator(root); node = root.SelectSingleNode("fromEMail"); if(node != null) fromEMailAddress = node.GetAttribute("address", String.Empty).Trim(); node = root.SelectSingleNode("successEMail"); if(node != null) { successEMailAddress = node.GetAttribute("address", String.Empty).Trim(); attachLogOnSuccess = Convert.ToBoolean(node.GetAttribute("attachLog", String.Empty), CultureInfo.InvariantCulture); } node = root.SelectSingleNode("failureEMail"); if(node != null) { failureEMailAddress = node.GetAttribute("address", String.Empty).Trim(); attachLogOnFailure = Convert.ToBoolean(node.GetAttribute("attachLog", String.Empty), CultureInfo.InvariantCulture); } node = root.SelectSingleNode("xslTransform"); if(node != null) xslTransformFile = builder.TransformText(node.GetAttribute("filename", String.Empty).Trim()); if((!credentials.UseDefaultCredentials && (credentials.UserName.Length == 0 || credentials.Password.Length == 0)) || failureEMailAddress.Length == 0) throw new BuilderException("CNP0002", "The Completion Notification plug-in has an invalid " + "configuration"); }
/// <summary> /// Write out the topic metadata /// </summary> /// <param name="writer">The writer to which the metadata is written</param> /// <param name="builder">The build process</param> /// <remarks>This will recursively write out metadata for sub-topics /// as well.</remarks> internal void WriteMetadata(XmlWriter writer, BuildProcess builder) { // MS Help Viewer doesn't support empty place holders so we automatically // generate a dummy place holder file for them. if(!noFile || (builder.CurrentProject.HelpFileFormat & HelpFileFormat.MSHelpViewer) != 0) { writer.WriteStartElement("topic"); writer.WriteAttributeString("id", this.Id); writer.WriteAttributeString("revisionNumber", this.RevisionNumber.ToString(CultureInfo.InvariantCulture)); // Write out the help file version project property value writer.WriteStartElement("item"); writer.WriteAttributeString("id", "PBM_FileVersion"); writer.WriteValue(builder.TransformText(builder.CurrentProject.HelpFileVersion)); writer.WriteEndElement(); // If no title is specified, use the display title writer.WriteStartElement("title"); if(!String.IsNullOrEmpty(title)) writer.WriteString(title); else writer.WriteString(this.DisplayTitle); writer.WriteEndElement(); // TOC title is optional if(!String.IsNullOrEmpty(tocTitle)) writer.WriteElementString("tableOfContentsTitle", tocTitle); // The running header text ID is set to "runningHeaderText" // so that it pulls in the shared content item by that name. // This will equate to the project's HTML encoded HelpTitle // property value. writer.WriteStartElement("runningHeaderText"); writer.WriteAttributeString("uscid", "runningHeaderText"); writer.WriteEndElement(); // Each topic includes the project-level help attributes foreach(MSHelpAttr attr in builder.CurrentProject.HelpAttributes) { writer.WriteStartElement("attribute"); writer.WriteAttributeString("name", attr.AttributeName); // Replace tags with their project property value writer.WriteValue(builder.TransformText(attr.AttributeValue)); writer.WriteEndElement(); } // Add topic-specific attributes foreach(MSHelpAttr attr in helpAttributes) { writer.WriteStartElement("attribute"); writer.WriteAttributeString("name", attr.AttributeName); // Replace tags with their project property value writer.WriteValue(builder.TransformText(attr.AttributeValue)); writer.WriteEndElement(); } // Add topic-specific index keywords foreach(MSHelpKeyword kw in keywords) { writer.WriteStartElement("keyword"); writer.WriteAttributeString("index", kw.Index); // Replace tags with their project property value writer.WriteValue(builder.TransformText(kw.Term)); writer.WriteEndElement(); } // If this is the default topic and the NamedUrlIndex keywords // for DefaultPage and/or HomePage are not present, add them. if(this.IsDefaultTopic) { if(!keywords.Contains(new MSHelpKeyword("NamedUrlIndex", "DefaultPage"))) { writer.WriteStartElement("keyword"); writer.WriteAttributeString("index", "NamedUrlIndex"); writer.WriteValue("DefaultPage"); writer.WriteEndElement(); } if(!keywords.Contains(new MSHelpKeyword("NamedUrlIndex", "HomePage"))) { writer.WriteStartElement("keyword"); writer.WriteAttributeString("index", "NamedUrlIndex"); writer.WriteValue("HomePage"); writer.WriteEndElement(); } } writer.WriteEndElement(); // </topic> } // Write metadata for sub-topics too foreach(Topic t in subtopics) t.WriteMetadata(writer, builder); }
/// <summary> /// This method is used to initialize the plug-in at the start of the build process /// </summary> /// <param name="buildProcess">A reference to the current build process</param> /// <param name="configuration">The configuration data that the plug-in should use to initialize itself</param> public void Initialize(BuildProcess buildProcess, XPathNavigator configuration) { XPathNavigator root, node; builder = buildProcess; var metadata = (HelpFileBuilderPlugInExportAttribute)this.GetType().GetCustomAttributes( typeof(HelpFileBuilderPlugInExportAttribute), false).First(); builder.ReportProgress("{0} Version {1}\r\n{2}", metadata.Id, metadata.Version, metadata.Copyright); root = configuration.SelectSingleNode("configuration"); if(root.IsEmptyElement) throw new BuilderException("DFP0001", "The DBCS Fix plug-in has not been configured yet"); node = root.SelectSingleNode("sbAppLocale"); if(node != null) sbAppLocalePath = node.GetAttribute("path", String.Empty).Trim(); if(String.IsNullOrWhiteSpace(sbAppLocalePath)) { builder.ReportWarning("DFP0002", "A path to the Steel Bytes App Locale tool was not specified " + "and it will not be used for this build."); } else { // If relative, the path is relative to the project folder sbAppLocalePath = FilePath.RelativeToAbsolutePath(builder.ProjectFolder, builder.TransformText(sbAppLocalePath)); if(!File.Exists(sbAppLocalePath)) throw new BuilderException("DFP0003", "Unable to locate SBAppLocale tool at " + sbAppLocalePath); } // If not building HTML Help 1, there's nothing to do if((builder.CurrentProject.HelpFileFormat & HelpFileFormats.HtmlHelp1) == 0) { executionPoints.Clear(); builder.ReportWarning("DFP0007", "An HTML Help 1 file is not being built. This plug-in will " + "not be ran."); } }
/// <summary> /// View the last build HTML Help 1 file, MS Help 2 file, or website Index.aspx/Index.html page /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void miViewBuiltHelpFile_Click(object sender, EventArgs e) { // Make sure we start out in the project's output folder in case the output folder is relative to it Directory.SetCurrentDirectory(Path.GetDirectoryName(Path.GetFullPath(project.Filename))); string outputPath = project.OutputPath, help2Viewer = Settings.Default.HTMLHelp2ViewerPath; // If the output path contains MSBuild variables, get the evaluated value from the project if(outputPath.IndexOf("$(", StringComparison.Ordinal) != -1) outputPath = project.MSBuildProject.GetProperty("OutputPath").EvaluatedValue; if(String.IsNullOrEmpty(outputPath)) outputPath = Directory.GetCurrentDirectory(); else outputPath = Path.GetFullPath(outputPath); if(sender == miViewHtmlHelp1) outputPath += project.HtmlHelpName + ".chm"; else if(sender == miViewMSHelp2) { outputPath += project.HtmlHelpName + ".hxs"; if(help2Viewer.Length == 0 || !File.Exists(help2Viewer)) { MessageBox.Show("MS Help 2 files must be registered in a collection to be viewed " + "or you can use a standalone viewer. Use Project | User Preferences to define a " + "standalone viewer. See Links to Resources in the help file if you need one.", Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } } else if(sender == miViewOpenXml) outputPath += project.HtmlHelpName + ".docx"; else outputPath += "Index.html"; // If there are substitution tags present, have a go at resolving them if(outputPath.IndexOf("{@", StringComparison.Ordinal) != -1) { try { var bp = new BuildProcess(project); outputPath = bp.TransformText(outputPath); } catch { // Ignore errors MessageBox.Show("The help filename appears to contain substitution tags but they could " + "not be resolved to determine the actual file to open for viewing. Building " + "website output and viewing it can be used to work around this issue.", Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } } if(!File.Exists(outputPath)) { MessageBox.Show("A copy of the help file does not appear to exist yet. It may need to be built.", Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } try { if(outputPath.EndsWith(".hxs", StringComparison.OrdinalIgnoreCase)) System.Diagnostics.Process.Start(help2Viewer, outputPath); else System.Diagnostics.Process.Start(outputPath); } catch(Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); MessageBox.Show(String.Format(CultureInfo.CurrentCulture, "Unable to open help file '{0}'\r\nReason: {1}", outputPath, ex.Message), Constants.AppName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
/// <summary> /// This method is used to initialize the plug-in at the start of the /// build process. /// </summary> /// <param name="buildProcess">A reference to the current build /// process.</param> /// <param name="configuration">The configuration data that the plug-in /// should use to initialize itself.</param> public void Initialize(BuildProcess buildProcess, XPathNavigator configuration) { XPathNavigator root, node; builder = buildProcess; builder.ReportProgress("{0} Version {1}\r\n{2}", this.Name, this.Version, this.Copyright); root = configuration.SelectSingleNode("configuration"); if(root.IsEmptyElement) throw new BuilderException("DFP0001", "The DBCS Fix plug-in " + "has not been configured yet"); node = root.SelectSingleNode("sbAppLocale"); if(node != null) sbAppLocalePath = node.GetAttribute("path", String.Empty).Trim(); if(String.IsNullOrEmpty(sbAppLocalePath)) throw new BuilderException("DFP0002", "A path to the Steel " + "Bytes App Locale tool is required"); // If relative, the path is relative to the project folder sbAppLocalePath = FilePath.RelativeToAbsolutePath( builder.ProjectFolder, builder.TransformText(sbAppLocalePath)); if(!File.Exists(sbAppLocalePath)) throw new BuilderException("DFP0003", "Unable to locate " + "SBAppLocale tool at " + sbAppLocalePath); // If not building HTML Help 1, there's nothing to do if((builder.CurrentProject.HelpFileFormat & HelpFileFormat.HtmlHelp1) == 0) { executionPoints.Clear(); builder.ReportWarning("DFP0007", "An HTML Help 1 file is not " + "being built. This plug-in will not be ran."); } }
/// <summary> /// This method is used to initialize the plug-in at the start of the build process /// </summary> /// <param name="buildProcess">A reference to the current build process</param> /// <param name="configuration">The configuration data that the plug-in should use to initialize itself</param> public void Initialize(BuildProcess buildProcess, XPathNavigator configuration) { XPathNavigator root, node; builder = buildProcess; var metadata = (HelpFileBuilderPlugInExportAttribute)this.GetType().GetCustomAttributes( typeof(HelpFileBuilderPlugInExportAttribute), false).First(); builder.ReportProgress("{0} Version {1}\r\n{2}", metadata.Id, metadata.Version, metadata.Copyright); // If the file format is Open XML, this plug-in is not supported and will not run if((builder.CurrentProject.HelpFileFormat & HelpFileFormats.OpenXml) != 0) { builder.ReportWarning("BIP0005", "The bibliography plug-in is not supported in the Open XML " + "file format and will not run."); executionPoints = new List<ExecutionPoint>(); return; } root = configuration.SelectSingleNode("configuration"); if(root.IsEmptyElement) throw new BuilderException("BIP0001", "The Bibliography support plug-in has not been " + "configured yet"); node = root.SelectSingleNode("bibliography"); if(node != null) bibliographyFile = node.GetAttribute("path", String.Empty).Trim(); if(String.IsNullOrEmpty(bibliographyFile)) throw new BuilderException("BIP0002", "A path to the bibliography file is required"); // If relative, the path is relative to the project folder bibliographyFile = FilePath.RelativeToAbsolutePath(builder.ProjectFolder, builder.TransformText(bibliographyFile)); if(!File.Exists(bibliographyFile)) throw new BuilderException("BIP0003", "Unable to locate bibliography file at " + bibliographyFile); }
/// <summary> /// This method is used to initialize the plug-in at the start of the /// build process. /// </summary> /// <param name="buildProcess">A reference to the current build /// process.</param> /// <param name="configuration">The configuration data that the plug-in /// should use to initialize itself.</param> public void Initialize(BuildProcess buildProcess, XPathNavigator configuration) { XPathNavigator root, node; builder = buildProcess; builder.ReportProgress("{0} Version {1}\r\n{2}\r\n", this.Name, this.Version, this.Copyright); root = configuration.SelectSingleNode("configuration"); if(root.IsEmptyElement) throw new BuilderException("BIB0001", "The Bibliography " + "support plug-in has not been configured yet"); node = root.SelectSingleNode("bibliography"); if(node != null) bibliographyFile = node.GetAttribute("path", String.Empty).Trim(); if(String.IsNullOrEmpty(bibliographyFile)) throw new BuilderException("BIB0002", "A path to the " + "bibliography file is required"); // If relative, the path is relative to the project folder bibliographyFile = FilePath.RelativeToAbsolutePath( builder.ProjectFolder, builder.TransformText(bibliographyFile)); if(!File.Exists(bibliographyFile)) throw new BuilderException("BIB0003", "Unable to locate " + "bibliography file at " + bibliographyFile); }