diff --git a/README.md b/README.md index 08701298..57144056 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ReportGenerator supports merging several reports into one. It is also possible to pass one XML file containing several reports to ReportGenerator (e.g. a build log file). The following output formats are supported by ReportGenerator: -* HTML, HTMLSummary, HTMLChart +* HTML, HTMLSummary, HTMLChart, [MHTML](https://en.wikipedia.org/wiki/MHTML) * XML, XMLSummary * Latex, LatexSummary * TextSummary diff --git a/Readme.txt b/Readme.txt index ebd84c3a..6229c7ce 100644 --- a/Readme.txt +++ b/Readme.txt @@ -24,7 +24,7 @@ ReportGenerator (e.g. a build log file). The following output formats are supported by ReportGenerator: --HTML, HTMLSummary, HTMLChart +-HTML, HTMLSummary, HTMLChart, MHTML -XML, XMLSummary -Latex, LatexSummary -TextSummary @@ -65,6 +65,7 @@ CHANGELOG * New: Issue #57: Added support for OpenCover's 'Crap Score' and 'NPath complexity' metric * New: Issue #61: Added support for Cobertura + * New: Issue #68: Added new report type (MHTML) * New: Issue #63: Visual indicator for partially covered lines (OpenCover, CodeCoverage.exe, Cobertura) * Fix: Issue #62: Improved HTML report (Keeping state of summary report, diff --git a/ReportGenerator.Reporting/MhtmlReportBuilder.cs b/ReportGenerator.Reporting/MhtmlReportBuilder.cs new file mode 100644 index 00000000..35df5659 --- /dev/null +++ b/ReportGenerator.Reporting/MhtmlReportBuilder.cs @@ -0,0 +1,166 @@ +using System.Collections.Generic; +using System.IO; +using Palmmedia.ReportGenerator.Parser.Analysis; + +namespace Palmmedia.ReportGenerator.Reporting +{ + /// + /// Creates MHTML which is a container for the complete HTML report. + /// + [System.ComponentModel.Composition.Export(typeof(IReportBuilder))] + public class MhtmlReportBuilder : IReportBuilder + { + /// + /// The . + /// + private readonly IReportBuilder htmlReportBuilder = new HtmlReportBuilder(); + + /// + /// The target directory. + /// + private string targetDirectory; + + /// + /// The temporary HTML report target directory. + /// + private string htmlReportTargetDirectory; + + /// + /// Gets the report type. + /// + /// + /// The report type. + /// + public string ReportType => "MHtml"; + + /// + /// Gets or sets the target directory where reports are stored. + /// + /// + /// The target directory. + /// + public string TargetDirectory + { + get + { + return this.targetDirectory; + } + + set + { + this.targetDirectory = value; + this.htmlReportTargetDirectory = Path.Combine(value, "tmphtml"); + + this.htmlReportBuilder.TargetDirectory = this.htmlReportTargetDirectory; + } + } + + /// + /// Creates a class report. + /// + /// The class. + /// The file analyses that correspond to the class. + public void CreateClassReport(Class @class, IEnumerable fileAnalyses) + { + if (!Directory.Exists(this.htmlReportTargetDirectory)) + { + Directory.CreateDirectory(this.htmlReportTargetDirectory); + } + + this.htmlReportBuilder.CreateClassReport(@class, fileAnalyses); + } + + /// + /// Creates the summary report. + /// + /// The summary result. + public void CreateSummaryReport(SummaryResult summaryResult) + { + this.htmlReportBuilder.CreateSummaryReport(summaryResult); + + this.CreateMhtmlFile(); + + Directory.Delete(this.htmlReportTargetDirectory, true); + } + + /// + /// Writes a file to the given StreamWriter. + /// + /// The writer. + /// The file path. + /// Type of the content. + /// The content. + private static void WriteFile(StreamWriter writer, string filePath, string contentType, string content) + { + writer.WriteLine("------=_NextPart_000_0000_01D23618.54EBCBE0"); + writer.Write("Content-Type: "); + writer.Write(contentType); + writer.WriteLine(";"); + writer.WriteLine("\tcharset=\"utf-8\""); + writer.WriteLine("Content-Transfer-Encoding: 8bit"); + writer.Write("Content-Location: file:///"); + writer.WriteLine(filePath); + writer.WriteLine(); + writer.WriteLine(content); + writer.WriteLine(); + } + + /// + /// Adds the 'file:///' prefix for CSS and java script links. + /// + /// The content. + /// The processed content. + private static string AddFilePrefixForCssAndJavaScript(string content) + { + content = content.Replace("", ""); + content = content.Replace("", ""); + + return content; + } + + /// + /// Creates the MHTML file. + /// + private void CreateMhtmlFile() + { + using (var writer = new StreamWriter(new FileStream(Path.Combine(this.TargetDirectory, "Summary.mht"), FileMode.Create))) + { + writer.WriteLine("MIME-Version: 1.0"); + writer.WriteLine("Content-Type: multipart/related;"); + writer.WriteLine("\ttype=\"text/html\";"); + writer.WriteLine("\tboundary=\"----=_NextPart_000_0000_01D23618.54EBCBE0\""); + writer.WriteLine(); + + string file = "index.htm"; + string content = File.ReadAllText(Path.Combine(this.htmlReportTargetDirectory, file)); + content = AddFilePrefixForCssAndJavaScript(content); + content = content.Replace(" +