/// <summary> /// Create the template output /// </summary> public virtual string TransformText() { this.Write("\r\n"); this.Write("\r\n"); #line 15 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\DocumentationData.tt" var documentation = new List<string>(); if(Documentation.Summary.Count > 0) { documentation.Add(string.Format("\"summary\":\"{0}\"", CommonMarkConverter.Convert(Documentation.Summary.ToMarkdown(StepInput.SDProject.Tokens).Transform(Helper.TransformLinkToken)).ToObjectString())); } if(Documentation.Remarks.Count > 0) { documentation.Add(string.Format("\"remarks\":\"{0}\"", CommonMarkConverter.Convert(Documentation.Remarks.ToMarkdown(StepInput.SDProject.Tokens).Transform(Helper.TransformLinkToken)).ToObjectString())); } if(Documentation.Example.Count > 0) { documentation.Add(string.Format("\"example\":\"{0}\"", CommonMarkConverter.Convert(Documentation.Example.ToMarkdown(StepInput.SDProject.Tokens).Transform(Helper.TransformLinkToken)).ToObjectString())); } if(Documentation.Returns.ContainsKey("default")) { documentation.Add(string.Format("\"returns\":\"{0}\"", CommonMarkConverter.Convert(Documentation.Returns["default"].ToMarkdown(StepInput.SDProject.Tokens).Transform(Helper.TransformLinkToken)).ToObjectString())); } if(Documentation.Exceptions.Count > 0) { documentation.Add(string.Format("\"exceptions\":[{0}]", string.Join(",", Documentation.Exceptions.Select(exception => string.Format("{{\"key\": \"{0}\",\"value\": \"{1}\"}}", exception.Key, CommonMarkConverter.Convert(exception.Value.ToMarkdown(StepInput.SDProject.Tokens).Transform(Helper.TransformLinkToken)).ToObjectString()))))); } if(Documentation.Params.Count > 0) { documentation.Add(string.Format("\"params\":[{0}]", string.Join(",", Documentation.Params.Select(param => string.Format("{{\"key\": \"{0}\",\"value\": \"{1}\"}}", param.Key, CommonMarkConverter.Convert(param.Value.ToMarkdown(StepInput.SDProject.Tokens).Transform(Helper.TransformLinkToken)).ToObjectString()))))); } if(Documentation.TypeParams.Count > 0) { documentation.Add(string.Format("\"params\":[{0}]", string.Join(",", Documentation.TypeParams.Select(typeParam => string.Format("{{\"key\": \"{0}\",\"value\": \"{1}\"}}", typeParam.Key, CommonMarkConverter.Convert(typeParam.Value.ToMarkdown(StepInput.SDProject.Tokens).Transform(Helper.TransformLinkToken)).ToObjectString()))))); } if(Documentation.SeeAlsos.Count > 0 ){ var seeAlsos = new List<string>(); foreach(var sdToken in Documentation.SeeAlsos){ var seeAlso = (SDSeeToken)sdToken; seeAlsos.Add(string.Format("{{\"type\":\"type\", \"id\":\"{0}\", \"name\":\"{1}\"}}", seeAlso.Identifier, seeAlso.Name)); } documentation.Add(string.Format("\"seeAlsos\":[{0}]", string.Join(",", seeAlsos))); } #line default #line hidden this.Write("\r\n"); #line 55 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\DocumentationData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(string.Join(",", documentation))); #line default #line hidden this.Write("\r\n\r\n\r\n"); return this.GenerationEnvironment.ToString(); }
/// <summary> /// Create the template output /// </summary> public virtual string TransformText() { this.Write("\r\n"); this.Write("\r\n{\r\n\t"); #line 19 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\MemberData.tt" var properties = new List<string>(); properties.Add($"\"id\": \"{Member.Identifier}\""); properties.Add($"\"urlId\": \"{Member.Identifier.RemoveIllegalHtmlIdChars()}\""); properties.Add($"\"type\": \"{MemberType}\""); properties.Add($"\"accessibility\": \"{Member.Accessibility}\""); if(Member is SDMethod) { var sdMethod = (SDMethod)Member; properties.Add($"\"name\": \"{sdMethod.Signature}\""); if(!sdMethod.IsSequenceDiagramEmpty()) { properties.Add($"\"diagramId\": \"{sdMethod.Guid}\""); properties.Add($"\"sequenceDiagram\": \"{sdMethod.GetSequenceDiagram(Repository).ToSvg().Transform(Helper.TransformLinkToken).ToObjectString()}\""); } } else { properties.Add($"\"name\": \"{Member.Name}\""); } if(Member is SDField && !string.IsNullOrEmpty(((SDField)Member).ConstantValue)) { properties.Add($"\"constantValue\": \"{((SDField)Member).ConstantValue.ToObjectString()}\""); } if(Member.Region != null){ properties.Add($"\"region\": {{\"start\": \"{Member.Region.StartLine}\", \"end\": \"{Member.Region.EndLine}\", \"filename\": \"{Member.Region.Filename.ToObjectString()}\"}}"); } var documentation = Member.Documentations.GetElementOrDefault(StepInput.CurrentLanguage); if(documentation != null){ var documentationTemplate = new DocumentationData { Documentation = documentation }; var documentationText = documentationTemplate.TransformText(); if(!string.IsNullOrWhiteSpace(documentationText)) properties.Add(documentationText); } properties.Add($"\"syntax\": \"{Member.Syntax}\""); properties.Add($"\"linkedSyntax\": \"{Member.SyntaxTemplate.Transform(Helper.TransformLinkToken).ToObjectString()}\""); #line default #line hidden this.Write("\t"); #line 56 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\MemberData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(string.Join(",", properties))); #line default #line hidden this.Write("\t\t\r\n}\r\n\r\n"); return this.GenerationEnvironment.ToString(); }
public IEnumerable<NewsData> GetAllWithoutContent() { var newsList = new List<NewsData>(); var fileProvider = _hostingEnvironment.WebRootFileProvider; var directoryContents = fileProvider.GetDirectoryContents(_newsPath).Where(x => x.Name.EndsWith(".json")); foreach (var directoryContent in directoryContents) { newsList.Add(GetNewsFromJsonFile(directoryContent)); } return newsList; }
public static List<string> LoadPreviousExtensionsChangelog() { var html = new List<string> {"<h1>Changelogs</h1>"}; using (new HourGlass()) { var webClient = new WebClient(); WebClientHelper.SetHeaders(webClient); var releases = JsonConvert.DeserializeObject<List<GitHubVersion>>( webClient.DownloadString("https://api.github.com/repos/zachsaw/MPDN_Extensions/releases")); foreach (var gitHubVersion in releases) { html.Add(string.Format("<h2>{0}</h2>", gitHubVersion.tag_name)); html.Add(CommonMarkConverter.Convert(gitHubVersion.body)); } } return html; }
public IEnumerable<NewsData> GetAll() { var newsList = new List<NewsData>(); newsList.AddRange(GetAllWithoutContent()); var fileProvider = _hostingEnvironment.WebRootFileProvider; var directoryContents = fileProvider.GetDirectoryContents(_newsPath).Where(x => x.Name.EndsWith("_content.md")); foreach (var news in newsList) { var contentFileForNews = directoryContents.Single(x => x.Name == $"{news.Id}_content.md"); string htmlContent = GetHtmlContentFromMarkdownFile(contentFileForNews); news.Content = htmlContent; } return newsList; }
/// <summary> /// Initializes a new instance of <see cref="ProjbookHtmlFormatter"/>. /// </summary> /// <param name="contextName">Initializes the required <see cref="ContextName"/></param> /// <param name="target">Initializes the required text writer used as output.</param> /// <param name="settings">Initializes the required common mark settings used by the formatting.</param> /// <param name="sectionTitleBase">Initializes the section title base.</param> /// <param name="snippetDictionary">Initializes the snippet directory.</param> /// <param name="snippetReferencePrefix">Initializes the snippet reference prefix.</param> public ProjbookHtmlFormatter(string contextName, TextWriter target, CommonMarkSettings settings, int sectionTitleBase, Dictionary<Guid, Extension.Model.Snippet> snippetDictionary, string snippetReferencePrefix) : base(target, settings) { // Data validation Ensure.That(() => contextName).IsNotNullOrWhiteSpace(); Ensure.That(target is StreamWriter).IsTrue(); Ensure.That(() => sectionTitleBase).IsGte(0); Ensure.That(() => snippetDictionary).IsNotNull(); Ensure.That(() => snippetReferencePrefix).IsNotNull(); // Initialize this.ContextName = contextName; this.pageBreak = new List<PageBreakInfo>(); this.writer = target as StreamWriter; this.sectionTitleBase = sectionTitleBase; this.snippetDictionary = snippetDictionary; this.snippetReferencePrefix = snippetReferencePrefix; }
//[HttpPost] public async Task<IActionResult> Viewer(IFormFile file = null, string gitHubUrl = "") { var fileContent = string.Empty; //get file content as string if (file != null) { //read incoming file to a string using (var reader = new StreamReader(file.OpenReadStream())) { fileContent = reader.ReadToEnd(); } } else if (!string.IsNullOrEmpty(gitHubUrl)) { //check if gitHubUrl is base 64, decoded if it is gitHubUrl = DecodeBase64(gitHubUrl); //get file content from GitHUb fileContent = await GetGitHubFile(gitHubUrl); } else { //return back to index return RedirectToAction("Index"); } //convert markdown file to array of html section strings var sections = ConvertFile(fileContent); //find and extract h1 for page title from array of html strings var title = GetTitle(sections); //enumerate HTML sections and construct array of slides for Owl Carousel List<string> slides = new List<string>(); foreach (var section in sections) { var outputSb = new StringBuilder(); //eliminate empty sections if (section.ToLower() != "<p></p>\r\n") { //populate owl format carosel slides outputSb.AppendLine("<div class=\"item\">"); outputSb.AppendLine(section); outputSb.AppendLine("</div>"); } //add slide to array slides.Add(outputSb.ToString()); } //View model var viewModel = new Viewer() { Title = title, SlidesHtml = slides }; return View(viewModel); }
private string GetTitle(List<string> sections) { HtmlDocument agilityDoc = new HtmlDocument(); var title = string.Empty; foreach (var section in sections) { agilityDoc.LoadHtml(section); title = agilityDoc.DocumentNode.Descendants("h1").Select(nd => nd.InnerText).FirstOrDefault(); if (title != string.Empty) break; } return title; }
public static List<string> LoadPreviousMpdnChangelog() { var html = new List<string>(); using (new HourGlass()) { var webClient = new WebClient(); WebClientHelper.SetHeaders(webClient); var changelog = webClient.DownloadString(string.Format("{0}ChangeLog.txt", UpdateChecker.LatestFolderUrl)); html.Add("<h1>Changelogs</h1>"); foreach (var line in Regex.Split(changelog, "\r\n|\r|\n")) { if (line.Contains("Changelog") && Version.ContainsVersionString(line)) { html.Add(string.Format("<h2>{0}</h2><ol>", line)); } else if (string.IsNullOrWhiteSpace(line)) { html.Add("</ol>"); } else { html.Add(string.Format("<li>{0}</li>", line)); } } } return html; }
/// <summary> /// Generates a file. /// </summary> /// <param name="templateName">The template name use as input.</param> /// <param name="outputFileHtml">The output html file.</param> /// <param name="configuration">The configuration to inject.</param> /// <param name="pages">The pages to inject.</param> private void GenerateFile(string templateName, string outputFileHtml, Configuration configuration, List<Model.Page> pages) { // Generate final documentation from the template using razor engine var fileConfiguration = new { Title = configuration.Title, Pages = pages }; this.WriteFile(templateName, outputFileHtml, fileConfiguration); }
public static List<string> ParseMpdnChangelog(List<string> changelog) { var lines = new List<string> {"<h1>Changelog</h1>", "<div id='changelog'><ol>"}; lines.AddRange( changelog.Select(line => string.IsNullOrWhiteSpace(line) ? null : string.Format("<li>{0}</li>", line))); lines.Add("</ol></div>"); return lines; }
/// <summary> /// Generates documentation. /// </summary> /// <returns>The generation errors.</returns> public Model.GenerationError[] Generate(Configuration configuration) { // Initialize the list containing all generation errors List<Model.GenerationError> generationError = new List<Model.GenerationError>(); // Ensure output directory exists if (!this.OutputDirectory.Exists) { this.OutputDirectory.Create(); } // Process all pages List<Model.Page> pages = new List<Model.Page>(); foreach (Page page in configuration.Pages) { // Compute the page id used as a tab id and page prefix for bookmarking string pageId = page.Path.Replace(".", string.Empty).Replace("/", string.Empty).Replace("\\", string.Empty); // Load the document Block document; // Process the page string pageFilePath = this.fileSystem.FileInfo.FromFileName(page.FileSystemPath).FullName; using (StreamReader reader = new StreamReader(this.fileSystem.File.Open(pageFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))) { document = CommonMarkConverter.ProcessStage1(reader); } // Process snippet CommonMarkConverter.ProcessStage2(document); Dictionary<Guid, Extension.Model.Snippet> snippetDictionary = new Dictionary<Guid, Extension.Model.Snippet>(); foreach (var node in document.AsEnumerable()) { // Filter fenced code if (node.Block != null && node.Block.Tag == BlockTag.FencedCode) { // Build extraction rule string fencedCode = node.Block.FencedCodeData.Info; // Do not trigger extraction if the fenced code is empty if (string.IsNullOrWhiteSpace(fencedCode)) { continue; } SnippetExtractionRule snippetExtractionRule = SnippetExtractionRule.Parse(fencedCode); // Extract and inject snippet and the factory were able to create an extractor if (null != snippetExtractionRule) { // Cleanup Projbook specific syntax node.Block.FencedCodeData.Info = snippetExtractionRule.Language; // Inject snippet try { // Retrieve the extractor instance ISnippetExtractor snippetExtractor; if (!this.extractorCache.TryGetValue(snippetExtractionRule.TargetPath, out snippetExtractor)) { snippetExtractor = this.snippetExtractorFactory.CreateExtractor(snippetExtractionRule); this.extractorCache[snippetExtractionRule.TargetPath] = snippetExtractor; } // Look for the file in available source directories FileSystemInfoBase fileSystemInfo = null; DirectoryInfoBase[] directoryInfos = null; if (TargetType.FreeText != snippetExtractor.TargetType) { directoryInfos = this.ExtractSourceDirectories(this.CsprojFile); foreach (DirectoryInfoBase directoryInfo in directoryInfos) { // Get directory name string directoryName = directoryInfo.FullName; if (1 == directoryName.Length && Path.DirectorySeparatorChar == directoryName[0]) directoryName = string.Empty; // Compute file full path string fullFilePath = this.fileSystem.Path.GetFullPath(this.fileSystem.Path.Combine(directoryName, snippetExtractionRule.TargetPath ?? string.Empty)); switch (snippetExtractor.TargetType) { case TargetType.File: if (this.fileSystem.File.Exists(fullFilePath)) { fileSystemInfo = this.fileSystem.FileInfo.FromFileName(fullFilePath); } break; case TargetType.Folder: if (this.fileSystem.Directory.Exists(fullFilePath)) { fileSystemInfo = this.fileSystem.DirectoryInfo.FromDirectoryName(fullFilePath); } break; } // Stop lookup if the file system info is found if (null != fileSystemInfo) { break; } } } // Raise an error if cannot find the file if (null == fileSystemInfo && TargetType.FreeText != snippetExtractor.TargetType) { // Locate block line int line = this.LocateBlockLine(node.Block, page); // Compute error column: Index of the path in the fenced code + 3 (for the ``` prefix) + 1 (to be 1 based) int column = fencedCode.IndexOf(snippetExtractionRule.TargetPath) + 4; // Report error generationError.Add(new Model.GenerationError( sourceFile: page.Path, message: string.Format("Cannot find target '{0}' in any referenced project ({0})", snippetExtractionRule.TargetPath, string.Join(";", directoryInfos.Select(x => x.FullName))), line: line, column: column)); continue; } // Extract the snippet Extension.Model.Snippet snippet = TargetType.FreeText == snippetExtractor.TargetType ? snippetExtractor.Extract(null, snippetExtractionRule.TargetPath) : snippetExtractor.Extract(fileSystemInfo, snippetExtractionRule.Pattern); // Reference snippet Guid guid = Guid.NewGuid(); snippetDictionary[guid] = snippet; // Inject reference as content StringContent code = new StringContent(); string content = SNIPPET_REFERENCE_PREFIX + guid; code.Append(content, 0, content.Length); node.Block.StringContent = code; // Change tag to html for node snippets NodeSnippet nodeSnippet = snippet as NodeSnippet; if (null != nodeSnippet) { node.Block.Tag = BlockTag.HtmlBlock; } } catch (SnippetExtractionException snippetExtraction) { // Locate block line int line = this.LocateBlockLine(node.Block, page); // Compute error column: Fenced code length - pattern length + 3 (for the ``` prefix) + 1 (to be 1 based) int column = fencedCode.Length - snippetExtractionRule.Pattern.Length + 4; // Report error generationError.Add(new Model.GenerationError( sourceFile: page.Path, message: string.Format("{0}: {1}", snippetExtraction.Message, snippetExtraction.Pattern), line: line, column: column)); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError( sourceFile: page.Path, message: exception.Message, line: 0, column: 0)); } } } } // Write to output ProjbookHtmlFormatter projbookHtmlFormatter = null; MemoryStream documentStream = new MemoryStream(); using (StreamWriter writer = new StreamWriter(documentStream)) { // Setup custom formatter CommonMarkSettings.Default.OutputDelegate = (d, o, s) => (projbookHtmlFormatter = new ProjbookHtmlFormatter(pageId, o, s, configuration.SectionTitleBase, snippetDictionary, SNIPPET_REFERENCE_PREFIX)).WriteDocument(d); // Render CommonMarkConverter.ProcessStage3(document, writer); } // Initialize the pre section content string preSectionContent = string.Empty; // Retrieve page content byte[] pageContent = documentStream.ToArray(); // Set the whole page content if no page break is detected if (projbookHtmlFormatter.PageBreak.Length == 0) { preSectionContent = System.Text.Encoding.UTF8.GetString(pageContent); } // Compute pre section content from the position 0 to the first page break position if (projbookHtmlFormatter.PageBreak.Length > 0 && projbookHtmlFormatter.PageBreak.First().Position > 0) { preSectionContent = this.StringFromByteArray(pageContent, 0, projbookHtmlFormatter.PageBreak.First().Position); } // Build section list List<Model.Section> sections = new List<Model.Section>(); for (int i = 0; i < projbookHtmlFormatter.PageBreak.Length; ++i) { // Retrieve the current page break PageBreakInfo pageBreak = projbookHtmlFormatter.PageBreak[i]; // Extract the content from the current page break to the next one if any string content = null; if (i < projbookHtmlFormatter.PageBreak.Length - 1) { PageBreakInfo nextBreak = projbookHtmlFormatter.PageBreak[1 + i]; content = this.StringFromByteArray(pageContent, pageBreak.Position, nextBreak.Position - pageBreak.Position); } // Otherwise extract the content from the current page break to the end of the content else { content = this.StringFromByteArray(pageContent, pageBreak.Position, pageContent.Length - pageBreak.Position); } // Create a new section and add to the known list sections.Add(new Model.Section( id: pageBreak.Id, level: pageBreak.Level, title: pageBreak.Title, content: content)); } // Add new page pages.Add(new Model.Page( id: pageId, title: page.Title, preSectionContent: preSectionContent, sections: sections.ToArray())); } // Html generation if (configuration.GenerateHtml) { try { string outputFileHtml = this.fileSystem.Path.Combine(this.OutputDirectory.FullName, configuration.OutputHtml); this.GenerateFile(configuration.TemplateHtml, outputFileHtml, configuration, pages); } catch (TemplateParsingException templateParsingException) { generationError.Add(new Model.GenerationError(configuration.TemplateHtml, string.Format("Error during HTML generation: {0}", templateParsingException.Message), templateParsingException.Line, templateParsingException.Column)); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError(configuration.TemplateHtml, string.Format("Error during HTML generation: {0}", exception.Message), 0, 0)); } } // Pdf generation if (configuration.GeneratePdf && !this.SkipPdf) { try { // Generate the pdf template string outputFileHtml = this.fileSystem.Path.Combine(this.OutputDirectory.FullName, configuration.OutputPdf); this.GenerateFile(configuration.TemplatePdf, outputFileHtml, configuration, pages); #if !NOPDF // Compute file names string outputPdf = this.fileSystem.Path.ChangeExtension(configuration.OutputPdf, ".pdf"); string outputFilePdf = this.fileSystem.Path.Combine(this.OutputDirectory.FullName, outputPdf); // Prepare the converter MultiplexingConverter pdfConverter = new MultiplexingConverter(); pdfConverter.ObjectSettings.Page = outputFileHtml; pdfConverter.Error += (s, e) => { generationError.Add(new Model.GenerationError(configuration.TemplatePdf, string.Format("Error during PDF generation: {0}", e.Value), 0, 0)); }; // Prepare file system if abstracted bool requireCopyToFileSystem = !File.Exists(outputFileHtml); try { // File system may be abstracted, this requires to copy the pdf generation file to the actual file system // in order to allow wkhtmltopdf to process the generated html as input file if (requireCopyToFileSystem) { File.WriteAllBytes(outputFileHtml, this.fileSystem.File.ReadAllBytes(outputFileHtml)); } // Run pdf converter using (pdfConverter) using (Stream outputFileStream = this.fileSystem.File.Open(outputFilePdf, FileMode.Create, FileAccess.Write, FileShare.None)) { try { byte[] buffer = pdfConverter.Convert(); outputFileStream.Write(buffer, 0, buffer.Length); } catch { // Ignore generation errors at that level // Errors are handled by the error handling having the best description } } } finally { if (requireCopyToFileSystem && File.Exists(outputFileHtml)) { File.Delete(outputFileHtml); } } #endif } catch (TemplateParsingException templateParsingException) { generationError.Add(new Model.GenerationError(configuration.TemplatePdf, string.Format("Error during PDF generation: {0}", templateParsingException.Message), templateParsingException.Line, templateParsingException.Column)); } catch (System.Exception exception) { if (null != exception.InnerException && INCORRECT_FORMAT_HRESULT == exception.InnerException.HResult) { // Report detailed error message for wrong architecture loading string runningArchitectureProccess = IntPtr.Size == 8 ? "x64" : "x86"; string otherRunningArchitectureProccess = IntPtr.Size != 8 ? "x64" : "x86"; generationError.Add(new Model.GenerationError(configuration.TemplatePdf, string.Format("Error during PDF generation: Could not load wkhtmltopdf for {0}. Try again running as a {1} process.", runningArchitectureProccess, otherRunningArchitectureProccess), 0, 0)); } else { // Report unknown error generationError.Add(new Model.GenerationError(configuration.TemplatePdf, string.Format("Error during PDF generation: {0}", exception.Message), 0, 0)); } } } // Return the generation errors return generationError.ToArray(); }
/// <summary> /// Generates the index page for the documentation. /// </summary> /// <param name="indexConfiguration">The index configuration.</param> /// <returns>The generation errors.</returns> public GenerationError[] GenerateIndex(IndexConfiguration indexConfiguration) { // Data validation Ensure.That(() => indexConfiguration).IsNotNull(); // Try to generate the index html file List<GenerationError> generationError = new List<GenerationError>(); try { string outputFileHtml = this.fileSystem.Path.Combine(this.OutputDirectory.FullName, indexConfiguration.Output); this.GenerateIndexFile(indexConfiguration.Template, outputFileHtml, indexConfiguration); } catch (TemplateParsingException templateParsingException) { generationError.Add(new Model.GenerationError(indexConfiguration.Template, string.Format("Error during HTML generation: {0}", templateParsingException.Message), templateParsingException.Line, templateParsingException.Column)); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError(indexConfiguration.Template, string.Format("Error during HTML generation: {0}", exception.Message), 0, 0)); } // Return generation errors return generationError.ToArray(); }
/// <summary> /// Specializes block writing for anchor injection. /// For each formatted header we generate an anchor based on the context name, the header content and eventually add an integer suffix in order to prevent conflicts. /// </summary> /// <param name="block">The block to process.</param> /// <param name="isOpening">Define whether the block is opening.</param> /// <param name="isClosing">Defines whether the block is closing.</param> /// <param name="ignoreChildNodes">return whether the processing ignored child nodes.</param> protected override void WriteBlock(Block block, bool isOpening, bool isClosing, out bool ignoreChildNodes) { // Process block content if (null != block.StringContent) { // Read current block content string content = block.StringContent.TakeFromStart(block.StringContent.Length); // Detect snippet reference if (content.StartsWith(snippetReferencePrefix)) { // Fetch matching snippet Extension.Model.Snippet snippet = snippetDictionary[Guid.Parse(content.Substring(snippetReferencePrefix.Length))]; // Render and write plain text snippet PlainTextSnippet plainTextSnippet = snippet as PlainTextSnippet; if (null != plainTextSnippet) { block.StringContent.Replace(plainTextSnippet.Text, 0, plainTextSnippet.Text.Length); } // Render and write node snippet NodeSnippet nodeSnippet = snippet as NodeSnippet; if (null != nodeSnippet) { // Render node as html string renderedNode = Render(nodeSnippet.Node); // Write rendering block.StringContent.Replace(renderedNode, 0, renderedNode.Length); } } } // Filter opening header if (isOpening && null != block && block.Tag == BlockTag.AtxHeading) { // Apply section title base block.Heading = new HeadingData(block.Heading.Level + this.sectionTitleBase); // Retrieve header content string headerContent; if (null != block.InlineContent && null != block.InlineContent.LiteralContent) { // Read the whole content Inline inline = block.InlineContent; StringBuilder stringBuilder = new StringBuilder(); do { stringBuilder.Append(inline.LiteralContent); inline = inline.NextSibling; } while (null != inline); headerContent = stringBuilder.ToString(); } else { headerContent = "unknown"; } // Compute the anchor value string sectionId = headerContent.ToLower(); sectionId = invalidTitleChars.Replace(string.Format("{0}-{1}", this.ContextName, sectionId), "-"); // Detect anchor conflict if (sectionConflict.ContainsKey(sectionId)) { // Append the index sectionId = string.Format("{0}-{1}", sectionId, ++sectionConflict[sectionId]); } // Flush the writer to move the stream position used during page break creation this.writer.Flush(); // Add a new page break this.pageBreak.Add(new PageBreakInfo(sectionId, Math.Max(0, (int)block.Heading.Level), headerContent, this.writer.BaseStream.Position)); // Initialize section conflict sectionConflict[sectionId] = 1; } // Read all paragraph inline strings in order to make table detectable List<string> tableParts = new List<string>(); List<string[]> splittedTableParts = new List<string[]>(); Match[] headerDelimiterMatches = null; if (isOpening && null != block && block.Tag == BlockTag.Paragraph) { Inline inline = block.InlineContent; while (null != inline) { if (inline.Tag == InlineTag.String) { // Read and split line on '|' tableParts.Add(inline.LiteralContent); string line = inline.LiteralContent.Trim(); string[] lineParts = line.Split(new char[] { '|' }, StringSplitOptions.None).Select(x => x.Trim()).ToArray(); // At the third line of the same block, ensure we're processing a table before to continue table parsing if (splittedTableParts.Count == 2) { // If the second line cannot be a header delimiter, break the table parsing if (splittedTableParts[1].Any(x => string.IsNullOrWhiteSpace(x)) || (splittedTableParts[1].Length < 2 && !tableParts[1].Contains('|'))) { break; } // Matches the second line as header delimiter and abort table parsing if the match fail headerDelimiterMatches = splittedTableParts[1].Select(x => dashDelimiter.Match(x)).ToArray(); if (!headerDelimiterMatches.All(x => x.Success)) { break; } } // Define parts boundaries int startPos = 0; int numbber = lineParts.Length; // Ignore the first part if the line starts with '|' if ('|' == line.First()) { ++startPos; --numbber; } // Ignore the last part if the line ends with '|' if ('|' == line.Last()) { --numbber; } // Add the line to splitted parts splittedTableParts.Add(lineParts.Skip(startPos).Take(numbber).ToArray()); } inline = inline.NextSibling; } } // Process table rendering if (null != headerDelimiterMatches && splittedTableParts.Count > 2) { // Remove the delimiter splittedTableParts.RemoveAt(1); // Render table this.Write(@"<table class=""table"">"); for (int i = 0; i < splittedTableParts.Count; ++i) { // Render rows this.Write("<tr>"); // Render cells for (int j = 0; j < splittedTableParts[i].Length; ++j) { // Determine text alignment string style = "text-left"; if (headerDelimiterMatches.Length > j && 0 < i) { Match match = headerDelimiterMatches[j]; if (":" == match.Groups[1].Value && ":" == match.Groups[2].Value) { style = "text-center"; } else if ("" == match.Groups[1].Value && ":" == match.Groups[2].Value) { style = "text-right"; } } // Generate markup string tag = 0 == i ? "th" : "td"; this.Write(string.Format(@"<{0} class=""{1}"">", tag, style)); this.Write(splittedTableParts[i][j]); this.Write(string.Format("</{0}>", tag)); } this.Write("</tr>"); } this.Write("</table>"); // Report rendering finished ignoreChildNodes = true; return; } // Trigger parent rendering for the default html rendering base.WriteBlock(block, isOpening, isClosing, out ignoreChildNodes); }
/// <summary> /// Create the template output /// </summary> public virtual string TransformText() { this.Write("\r\n"); this.Write("\r\n\""); #line 14 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(TargetFx.Name)); #line default #line hidden this.Write("\": {\r\n\t\t\"name\": \""); #line 15 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(Namespace.Fullname)); #line default #line hidden this.Write("\",\r\n\t\t\"assembly\": \""); #line 16 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(Namespace.Assemblyname)); #line default #line hidden this.Write("\",\r\n\t\t\"description\": \""); #line 17 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(Namespace.Descriptions.GetElementOrDefault(StepInput.CurrentLanguage) != null ? CommonMarkConverter.Convert(Namespace.Descriptions.GetElementOrDefault(StepInput.CurrentLanguage).Transform(Helper.TransformLinkToken)).ToObjectString() : string.Empty)); #line default #line hidden this.Write("\", \r\n\t\t"); #line 20 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" if(Namespace.UsedBy.Count > 0) { #line default #line hidden this.Write("\t\t\"usedBy\": [\r\n\t\t\t"); #line 22 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(string.Join(",", Namespace.UsedBy.Select(usedBy => string.Format("{{\"id\": \"{0}\",\"name\": \"{1}\"}}", usedBy.Identifier, usedBy.Fullname))))); #line default #line hidden this.Write("\r\n\t\t],\r\n\t\t"); #line 25 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" } if(Namespace.Uses.Count > 0) { #line default #line hidden this.Write("\t\t\"uses\": [\r\n\t\t\t"); #line 27 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(string.Join(",", Namespace.Uses.Select(use => string.Format("{{\"id\": \"{0}\",\"name\": \"{1}\"}}", use.Identifier, use.Fullname))))); #line default #line hidden this.Write("\r\n\t\t], \r\n\t\t"); #line 30 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" } #line default #line hidden this.Write("\t\t\"types\":[\r\n\t\t\t"); #line 32 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" var types = new List<string>(); foreach(var sdType in Namespace.Types){ var documentation = sdType.Documentations.GetElementOrDefault(StepInput.CurrentLanguage); var docString = documentation != null ? CommonMarkConverter.Convert(documentation.Summary.ToMarkdown(StepInput.SDProject.Tokens).Transform(Helper.TransformLinkToken)).ToObjectString() : string.Empty; types.Add(string.Format("{{\"id\":\"{0}\",\"kind\":\"{1}\",\"accessibility\":\"{2}\",\"name\":\"{3}\",\"summary\":\"{4}\"}}", sdType.Identifier.RemoveIllegalPathChars(), sdType.Kind, sdType.Accessibility, sdType.Name, docString)); } #line default #line hidden this.Write("\t\t\t"); #line 41 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\NamespaceData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(string.Join(",", types))); #line default #line hidden this.Write("\r\n\t\t]\r\n\t}\r\n\r\n"); return this.GenerationEnvironment.ToString(); }
public static string Render(Game game, ActionResult result) { string body = ""; if (game == null || game.CurrentAR == null || game.CurrentAR.Storylet == null) return "No storylet!"; body += "<div class='storylet'>"; body += string.Format("<h3>{0}</h3>\n", game.CurrentAR.Storylet.Title); foreach(var test in game.CurrentAR.Tests) { if (test != null && test.Test != null) { var qual = Data.GetQuality(test.Test.QualityName); if (qual != null) body += string.Format("<p>You {0} a test of {1} {2}</p>\n", (test.Success) ? "succeeded" : "failed", qual.Title, test.Test.Value); } } body += CommonMarkConverter.Convert(game.CurrentAR.Storylet.Body); body += "</div>"; if (result != null) { foreach(var inv in result.InventoryOps) { body += RenderInventoryOp(inv); } } List<KeyValuePair<string, Storylet.Link>> specialLinks = new List<KeyValuePair<string, Storylet.Link>>(); foreach (var kvp in game.CurrentAR.Options) { if (string.IsNullOrEmpty(kvp.Value.Special)) { body += RenderLink(kvp.Value, kvp.Key, game.Items); } else { specialLinks.Add(kvp); } } foreach (var link in game.CurrentAR.NonOptions) { body += RenderLink(link, null, game.Items); } foreach (var kvp in specialLinks) { body += RenderLink(kvp.Value, kvp.Key, game.Items); } return body; }
/// <summary> /// Generates documentation. /// </summary> public Model.GenerationError[] Generate() { // Initialize the list containing all generation errors List<Model.GenerationError> generationError = new List<Model.GenerationError>(); // Ensute output directory exists if (!this.OutputDirectory.Exists) { this.OutputDirectory.Create(); } // Read configuration ConfigurationLoader configurationLoader = new ConfigurationLoader(); Configuration configuration; try { configuration = configurationLoader.Load(this.ConfigFile); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError(this.ConfigFile.FullName, string.Format("Error during loading configuration: {0}", exception.Message))); return generationError.ToArray(); } // Process all pages List<Model.Page> pages = new List<Model.Page>(); foreach (Page page in configuration.Pages) { // Compute the page id used as a tab id and page prefix for bookmarking string pageId = page.Path.Replace(".", string.Empty).Replace("/", string.Empty); // Load the document Block document; FileInfo fileInfo = new FileInfo(page.Path); // Skip the page if doesn't exist if (!fileInfo.Exists) { generationError.Add(new Model.GenerationError(this.ConfigFile.FullName, string.Format("Error during loading configuration: Could not find file '{0}'", fileInfo.FullName))); continue; } // Process the page using (StreamReader reader = new StreamReader(new FileStream(new FileInfo(page.Path).FullName, FileMode.Open))) { document = CommonMarkConverter.ProcessStage1(reader); } // Process snippet CommonMarkConverter.ProcessStage2(document); foreach (var node in document.AsEnumerable()) { // Filter fenced code if (node.Block != null && node.Block.Tag == BlockTag.FencedCode) { // Buil extraction rule string fencedCode = node.Block.FencedCodeData.Info; SnippetExtractionRule snippetExtractionRule = SnippetExtractionRule.Parse(fencedCode); // Extract and inject snippet and the factory were able to create an extractor if (null != snippetExtractionRule) { // Cleanup Projbook specific syntax node.Block.FencedCodeData.Info = snippetExtractionRule.Language; // Inject snippet try { // Retrieve the extractor instance ISnippetExtractor snippetExtractor; if (!this.extractorCache.TryGetValue(snippetExtractionRule.FileName, out snippetExtractor)) { snippetExtractor = this.snippetExtractorFactory.CreateExtractor(snippetExtractionRule); this.extractorCache[snippetExtractionRule.FileName] = snippetExtractor; } // Extract the snippet Model.Snippet snippet = snippetExtractor.Extract(snippetExtractionRule.FileName, snippetExtractionRule.Pattern); StringContent code = new StringContent(); code.Append(snippet.Content, 0, snippet.Content.Length); node.Block.StringContent = code; } catch (SnippetExtractionException snippetExtraction) { generationError.Add(new Model.GenerationError( sourceFile: page.Path, message: string.Format("{0}: {1}", snippetExtraction.Message, snippetExtraction.Pattern))); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError( sourceFile: page.Path, message: exception.Message)); } } } } // Setup custom formatter CommonMarkSettings.Default.OutputDelegate = (d, o, s) => new InjectAnchorHtmlFormatter(pageId, this.sectionSplittingIdentifier, o, s).WriteDocument(d); // Write to output MemoryStream documentStream = new MemoryStream(); using (StreamWriter writer = new StreamWriter(documentStream)) { CommonMarkConverter.ProcessStage3(document, writer); } // Initialize the pre section content string preSectionContent = string.Empty; // Retrieve page content string pageContent = System.Text.Encoding.UTF8.GetString(documentStream.ToArray()); // Build section list List<Model.Section> sections = new List<Model.Section>(); Match match = regex.Match(pageContent); bool matched = false; while(match.Success) { // Initialize the pre section part from 0 to the first matching index for the first matching if (!matched) { preSectionContent = pageContent.Substring(0, match.Groups[0].Index); } // Create a new section and add to the known list sections.Add(new Model.Section( id: match.Groups[2].Value, title: match.Groups[1].Value, content: match.Groups[3].Value)); // Mode to the next match match = match.NextMatch(); matched = true; } // If nothing has been matching simple consider the whole input as pre section content if (!matched) { preSectionContent = pageContent; } // Add new page pages.Add(new Model.Page( id: pageId, title: page.Title, preSectionContent: preSectionContent, sections: sections.ToArray())); } // Standard generation try { this.GenerateFile(this.TemplateFile.FullName, this.TemplateFile.FullName, configuration, pages); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError(this.TemplateFile.FullName, string.Format("Error during HTML generation: {0}", exception.Message))); } // Pdf specific generation string pdfTemplate = this.TemplateFilePdf.Exists ? this.TemplateFilePdf.FullName : this.TemplateFile.FullName; try { this.GenerateFile(pdfTemplate, this.TemplateFilePdf.FullName, configuration, pages); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError(pdfTemplate, string.Format("Error during PDF generation: {0}", exception.Message))); } // Return the generation errors return generationError.ToArray(); }
public IEnumerable<StaticPageBuilderResponse> Convert(StaticPageConverterRequest request) { if (request == null) throw new ArgumentNullException("request"); Contract.EndContractBlock(); DirectoryInfo requestSourceRoot; IEnumerable<FileInfo> sourceFiles; var requestSourceFile = new FileInfo(request.Source); if (requestSourceFile.Exists) { requestSourceRoot = requestSourceFile.Directory; sourceFiles = new[] { requestSourceFile }; } else { requestSourceRoot = new DirectoryInfo(request.Source); if (requestSourceRoot.Exists) { var directories = request.Recursive ? SearchAllDirectories(requestSourceRoot) : new[] { requestSourceRoot }; sourceFiles = directories.SelectMany(d => d.EnumerateFiles("*.md")); } else { sourceFiles = Enumerable.Empty<FileInfo>(); } } var templateFile = requestSourceRoot.EnumerateFiles("_template.cshtml").FirstOrDefault(); string razorTemplateCacheKey = null; if (templateFile != null && templateFile.Exists) { razorTemplateCacheKey = templateFile.FullName; Razor.Compile(File.ReadAllText(templateFile.FullName), typeof(TemplateModel), razorTemplateCacheKey); } CommonMarkSettings settings = null; var sourceRootUri = new Uri(requestSourceRoot.FullName + Path.DirectorySeparatorChar); var results = new List<StaticPageBuilderResponse>(); foreach (var sourceFile in sourceFiles) { var localFileUri = new Uri(sourceFile.FullName); var relativeSourceFilePath = sourceRootUri.MakeRelative(localFileUri); if (Path.DirectorySeparatorChar != '/') { relativeSourceFilePath = relativeSourceFilePath.Replace('/', Path.DirectorySeparatorChar); } var relativeTargetFilePath = Path.ChangeExtension(relativeSourceFilePath, "html"); var targetFile = new FileInfo(Path.Combine(request.RelativeDestination, relativeTargetFilePath)); CommonMark.Syntax.Block parsedDocument; using (var sourceStream = File.Open(sourceFile.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var reader = new StreamReader(sourceStream)) { parsedDocument = CommonMarkConverter.ProcessStage1(reader, settings); } CommonMarkConverter.ProcessStage2(parsedDocument, settings); if (!targetFile.Directory.Exists) { targetFile.Directory.Create(); } using (var targetStream = File.Open(targetFile.FullName, FileMode.Create, FileAccess.ReadWrite, FileShare.None)) using (var writer = new StreamWriter(targetStream)) { if (razorTemplateCacheKey != null) { var markdownText = new StringBuilder(); using (var markdownWriter = new StringWriter(markdownText)) { CommonMarkConverter.ProcessStage3(parsedDocument, markdownWriter, settings); } var htmlResultText = Razor.Run(razorTemplateCacheKey, new TemplateModel{ ContentHtml = markdownText.ToString() }); writer.Write(htmlResultText); } else { CommonMarkConverter.ProcessStage3(parsedDocument, writer, settings); } } results.Add(new StaticPageBuilderResponse { ResultFile = targetFile }); } return results; }
/// <summary> /// Generates all documents. /// </summary> /// <returns>The generation errors.</returns> public GenerationError[] GenerateAll() { // Register bundles if pdf generation is not skipped if (!this.SkipPdf) this.RegisterHtmlToXLibraries(); // Run generation for each configuration List<GenerationError> errors = new List<GenerationError>(); foreach (Configuration configuration in this.IndexConfiguration.Configurations) { // Generate the documentation errors.AddRange(this.Generate(configuration)); } // Generate the index html file if any index template is set if (!string.IsNullOrWhiteSpace(this.IndexConfiguration.Template)) { errors.AddRange(this.GenerateIndex(this.IndexConfiguration)); } // Report processing successful return errors.ToArray(); }
/// <summary> /// Create the template output /// </summary> public virtual string TransformText() { this.Write("\r\n"); this.Write("\r\n\""); #line 16 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\TypeData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(TargetFx.Name)); #line default #line hidden this.Write("\": { \r\n\t\t"); #line 17 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\TypeData.tt" var properties = new List<string>(); properties.Add($"\"name\": \"{Type.Name}\""); properties.Add($"\"namespace\": \"{Type.Namespace.Fullname}\""); properties.Add($"\"syntax\": \"{Type.Syntax}\""); properties.Add($"\"linkedSyntax\": \"{Type.SyntaxTemplate.Transform(Helper.TransformLinkToken).ToObjectString()}\""); if(!Type.IsClassDiagramEmpty()) { var height = Type.GetClassDiagram().GetSvgSize().Height; height = height > 300 ? 375 : height + 75; properties.Add($"\"classDiagram\": \"{Type.GetClassDiagram().ToSvg().Transform(Helper.TransformLinkToken).ToObjectString()}\""); properties.Add($"\"classDiagramHeight\": \"{height}\""); properties.Add($"\"fit\": \"{height == 375}\""); } if(Type.BaseTypes.Count > 0) { var baseTypes = string.Join(",", Type.BaseTypes.Select(baseType => string.Format("{{\"id\": \"{0}\",\"name\": \"{1}\"}}", baseType.Type.Identifier, baseType.Type.Fullname))); properties.Add($"\"baseTypes\": [ {baseTypes} ]"); } if(Type.ImplementedInterfaces.Count > 0) { var implements = string.Join(",", Type.ImplementedInterfaces.Select(implementedInterface => string.Format("{{\"id\": \"{0}\",\"name\": \"{1}\"}}", implementedInterface.Type.Identifier, implementedInterface.Type.Fullname))); properties.Add($"\"implements\": [ {implements} ]"); } if(Type.Regions.Count > 0 && StepInput.HtmlConfig.ShowCode){ var allRegions = new List<string>(); foreach(var region in Type.Regions){ allRegions.Add($"{{\"start\": \"{region.StartLine}\", \"end\": \"{region.EndLine}\", \"filepath\": \"{region.FilePath.ToObjectString()}\", \"filename\": \"{region.Filename.ToObjectString()}\", \"content\": \"{region.Content.ToObjectString().Replace("\t", " ")}\"}}"); } properties.Add($"\"regions\": [{string.Join(",", allRegions)}]"); } var documentation = Type.Documentations.GetElementOrDefault(StepInput.CurrentLanguage); if(documentation != null){ var documentationTemplate = new DocumentationData { Documentation = documentation }; var documentationText = documentationTemplate.TransformText(); if(!string.IsNullOrWhiteSpace(documentationText)) properties.Add(documentationText); } if(Type.Fields.Count > 0) { properties.Add(string.Format("\"fields\": [{0}]", string.Join(",", Type.Fields.Select(sdField => new MemberData { Member = sdField, MemberType = "field", Repository = Repository }.TransformText())))); } if(Type.Constructors.Count > 0) { properties.Add(string.Format("\"constructors\": [{0}]", string.Join(",", Type.Constructors.Select(sdContructor => new MemberData { Member = sdContructor, MemberType = "method", Repository = Repository }.TransformText())))); } if(Type.Methods.Count > 0) { properties.Add(string.Format("\"methods\": [{0}]", string.Join(",", Type.Methods.Select(sdMethod => new MemberData { Member = sdMethod, MemberType = "method", Repository = Repository }.TransformText())))); } if(Type.Events.Count > 0) { properties.Add(string.Format("\"events\": [{0}]", string.Join(",", Type.Events.Select(sdEvent => new MemberData { Member = sdEvent, MemberType = "event", Repository = Repository }.TransformText())))); } if(Type.Properties.Count > 0){ properties.Add(string.Format("\"properties\": [{0}]", string.Join(",", Type.Properties.Select(sdProperty => new MemberData { Member = sdProperty, MemberType = "property", Repository = Repository }.TransformText())))); } #line default #line hidden this.Write("\r\n\t\t"); #line 76 "D:\Github\SharpDox.Plugins.Html\src\SharpDox.Plugins.Html\Templates\Repository\TypeData.tt" this.Write(this.ToStringHelper.ToStringWithCulture(string.Join(",", properties))); #line default #line hidden this.Write("\t\r\n\t}\r\n\r\n"); return this.GenerationEnvironment.ToString(); }
/// <summary> /// Extracts source directories from the csproj file. /// The expected directory info list is the csproj's directory and all project references. /// </summary> /// <param name="csprojFile"></param> /// <returns></returns> private DirectoryInfoBase[] ExtractSourceDirectories(FileInfoBase csprojFile) { // Data validation Ensure.That(() => csprojFile).IsNotNull(); Ensure.That(csprojFile.Exists, string.Format("Could not find '{0}' file", csprojFile)).IsTrue(); // Initialize the extracted directories List<DirectoryInfoBase> extractedSourceDirectories = new List<DirectoryInfoBase>(); // Add the csproj's directory DirectoryInfoBase projectDirectory = this.fileSystem.DirectoryInfo.FromDirectoryName(this.fileSystem.Path.GetDirectoryName(csprojFile.FullName)); extractedSourceDirectories.Add(projectDirectory); // Load xml document XmlDocument xmlDocument = new XmlDocument(); using (Stream stream = csprojFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { xmlDocument.Load(stream); } // Extract XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable); xmlNamespaceManager.AddNamespace("msbuild", "http://schemas.microsoft.com/developer/msbuild/2003"); XmlNodeList xmlNodes = xmlDocument.SelectNodes("//msbuild:ProjectReference", xmlNamespaceManager); for (int i = 0; i < xmlNodes.Count; ++i) { XmlNode xmlNode = xmlNodes.Item(i); string includeValue = xmlNode.Attributes["Include"].Value; string combinedPath = this.fileSystem.Path.Combine(projectDirectory.FullName, includeValue); // The combinedPath can contains both forward and backslash path chunk. // In linux environment we can end up having "/..\" in the path which make the GetDirectoryName method bugging (returns empty). // For this reason we need to make sure that the combined path uses forward slashes combinedPath = combinedPath.Replace(@"\", "/"); // Add the combined path extractedSourceDirectories.Add(this.fileSystem.DirectoryInfo.FromDirectoryName(this.fileSystem.Path.GetDirectoryName(this.fileSystem.Path.GetFullPath(combinedPath)))); } // Return the extracted directories return extractedSourceDirectories.ToArray(); }
public WebServiceGateway() { sseEventBuffer = new List<SseEvent>(); }
public static List<string> ParseExtensionChangelog(List<string> changelog) { var lines = new List<string> { "<h1>Changelog</h1>", "<div id='changelog'>", CommonMarkConverter.Convert(string.Join("\n", changelog)), "</div>" }; return lines; }
static int Main(string[] args) { try { var argc = args.Length; int i; bool ast = false; List<string> files = new List<string>(); string target = null; for (i = 0; i < argc; i++) { if (string.Equals(args[i], "--version", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("CommonMark.NET {0}", Document.AssemblyVersion); Console.WriteLine(" - (c) 2014 Kārlis Gaņģis"); return 0; } else if ((string.Equals(args[i], "--help", StringComparison.OrdinalIgnoreCase)) || (string.Equals(args[i], "-h", StringComparison.OrdinalIgnoreCase))) { print_usage(); return 0; } else if (string.Equals(args[i], "--ast", StringComparison.OrdinalIgnoreCase)) { ast = true; } else if (string.Equals(args[i], "--out", StringComparison.OrdinalIgnoreCase)) { if (i == argc - 1 || args[i + 1].StartsWith("-")) { print_usage(); return 1; } i++; target = args[i]; } else if (args[i].StartsWith("-")) { print_usage(); return 1; } else { // treat as file argument files.Add(args[i]); } } OutputFormat format = ast ? OutputFormat.SyntaxTree : OutputFormat.Html; System.IO.TextWriter writer = target == null ? Console.Out : new System.IO.StreamWriter(target); try { if (files.Count == 0) { // read from stdin if (!Console.IsInputRedirected) { Console.WriteLine("Only redirected STDIN is supported."); print_usage(); return 2; } Document.Load(Console.In).Export(writer, format); } else { // iterate over input file pointers for (var g = 0; g < files.Count; g++) { using (var reader = new System.IO.StreamReader(files[g])) { Document.Load(reader).Export(writer, format); } } } } finally { if (writer != Console.Out) writer.Close(); } return 0; } catch (Exception ex) { Console.Error.WriteLine(ex.ToString()); return -1; } }
/// <summary> /// Generates documentation. /// </summary> public Model.GenerationError[] Generate() { // Initialize the list containing all generation errors List<Model.GenerationError> generationError = new List<Model.GenerationError>(); // Ensute output directory exists if (!this.OutputDirectory.Exists) { this.OutputDirectory.Create(); } // Read configuration ConfigurationLoader configurationLoader = new ConfigurationLoader(); Configuration configuration; try { configuration = configurationLoader.Load(this.ConfigFile); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError(this.ConfigFile.FullName, string.Format("Error during loading configuration: {0}", exception.Message))); return generationError.ToArray(); } // Process all pages List<Model.Page> pages = new List<Model.Page>(); bool first = true; foreach (Page page in configuration.Pages) { // Declare formatter InjectAnchorHtmlFormatter formatter = null; // Load the document Block document; FileInfo fileInfo = new FileInfo(page.Path); // Skip the page if doesn't exist if (!fileInfo.Exists) { generationError.Add(new Model.GenerationError(this.ConfigFile.FullName, string.Format("Error during loading configuration: Could not find file '{0}'", fileInfo.FullName))); continue; } // Process the page using (StreamReader reader = new StreamReader(new FileStream(new FileInfo(page.Path).FullName, FileMode.Open))) { document = CommonMarkConverter.ProcessStage1(reader); } // Process snippet CommonMarkConverter.ProcessStage2(document); foreach (var node in document.AsEnumerable()) { // Filter fenced code if (node.Block != null && node.Block.Tag == BlockTag.FencedCode) { // Extract snippet string fencedCode = node.Block.FencedCodeData.Info; ISnippetExtractor snippetExtractor = this.snippetExtractorFactory.CreateExtractor(fencedCode); // Extract and inject snippet and the factory were able to create an extractor if (null != snippetExtractor) { // Cleanup Projbook specific syntax node.Block.FencedCodeData.Info = snippetExtractor.Language; // Inject snippet try { Model.Snippet snippet = snippetExtractor.Extract(); StringContent code = new StringContent(); code.Append(snippet.Content, 0, snippet.Content.Length); node.Block.StringContent = code; } catch (SnippetExtractionException snippetExtraction) { generationError.Add(new Model.GenerationError( sourceFile: page.Path, message: string.Format("{0}: {1}", snippetExtraction.Message, snippetExtraction.Pattern))); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError( sourceFile: page.Path, message: exception.Message)); } } } } // Setup custom formatter CommonMarkSettings.Default.OutputDelegate = (d, output, settings) => { formatter = new InjectAnchorHtmlFormatter(page.Path, output, settings); formatter.WriteDocument(d); }; // Write to output MemoryStream documentStream = new MemoryStream(); using (StreamWriter writer = new StreamWriter(documentStream)) { CommonMarkConverter.ProcessStage3(document, writer); } // Add new page pages.Add(new Model.Page( id: page.Path.Replace(".", string.Empty).Replace("/", string.Empty), title: page.Title, isHome: first, anchor: formatter.Anchors, content: System.Text.Encoding.UTF8.GetString(documentStream.ToArray()))); first = false; } // Standard generation try { this.GenerateFile(this.TemplateFile.FullName, this.TemplateFile.FullName, configuration, pages); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError(this.TemplateFile.FullName, string.Format("Error during HTML generation: {0}", exception.Message))); } // Pdf specific generation string pdfTemplate = this.TemplateFilePdf.Exists ? this.TemplateFilePdf.FullName : this.TemplateFile.FullName; try { this.GenerateFile(pdfTemplate, this.TemplateFilePdf.FullName, configuration, pages); } catch (System.Exception exception) { generationError.Add(new Model.GenerationError(pdfTemplate, string.Format("Error during PDF generation: {0}", exception.Message))); } // Return the generation errors return generationError.ToArray(); }
/// <summary> /// Generates a file. /// </summary> /// <param name="templateName">The template name use as input.</param> /// <param name="targetName">The target name used as output.</param> /// <param name="configuration">The configuration to inject.</param> /// <param name="pages">The pages to inject.</param> private void GenerateFile(string templateName, string targetName, Configuration configuration, List<Model.Page> pages) { // Generate final documentation from the template using razor engine string fileName = string.Format("{0}-generated{1}", Path.GetFileNameWithoutExtension(targetName), Path.GetExtension(targetName)); string outputFileHtml = Path.Combine(this.OutputDirectory.FullName, fileName); using (var reader = new StreamReader(new FileStream(templateName, FileMode.Open))) using (var writer = new StreamWriter(new FileStream(outputFileHtml, FileMode.Create))) { var config = new TemplateServiceConfiguration(); config.Language = Language.CSharp; config.EncodedStringFactory = new RawStringFactory(); var service = RazorEngineService.Create(config); Engine.Razor = service; string processed = Engine.Razor.RunCompile(new LoadedTemplateSource(reader.ReadToEnd()), string.Empty, null, new { Title = configuration.Title, Pages = pages }); writer.WriteLine(processed); } }
static int Main(string[] args) { var sources = new List<System.IO.TextReader>(); var benchmark = false; var benchmarkIterations = 20; var target = Console.Out; var runPerlTests = false; var settings = CommonMarkSettings.Default.Clone(); try { for (var i = 0; i < args.Length; i++) { if (string.Equals(args[i], "--version", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("CommonMark.NET {0}", CommonMarkConverter.Version); Console.WriteLine(" - (c) 2014-2015 Kārlis Gaņģis"); return 0; } else if ((string.Equals(args[i], "--help", StringComparison.OrdinalIgnoreCase)) || (string.Equals(args[i], "-h", StringComparison.OrdinalIgnoreCase))) { PrintUsage(); return 0; } else if (string.Equals(args[i], "--perltest", StringComparison.OrdinalIgnoreCase)) { runPerlTests = true; } else if (string.Equals(args[i], "--ast", StringComparison.OrdinalIgnoreCase)) { settings.OutputFormat = OutputFormat.SyntaxTree; } else if (string.Equals(args[i], "--sourcepos", StringComparison.OrdinalIgnoreCase)) { settings.TrackSourcePosition = true; } else if (string.Equals(args[i], "--bench", StringComparison.OrdinalIgnoreCase)) { benchmark = true; if (i != args.Length - 1) { if (!int.TryParse(args[i + 1], System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out benchmarkIterations)) benchmarkIterations = 20; else i++; } } else if (string.Equals(args[i], "--out", StringComparison.OrdinalIgnoreCase)) { if (i == args.Length - 1 || args[i + 1].StartsWith("-")) { PrintUsage(); return 1; } i++; target = new System.IO.StreamWriter(args[i]); } else if (args[i].StartsWith("-")) { PrintUsage(args[i]); return 1; } else { // treat as file argument sources.Add(new System.IO.StreamReader(args[i])); } } if (sources.Count == 0) { if (runPerlTests) { Console.InputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8; // runtests.pl writes directly to STDIN but will not send Ctrl+C and also // will get confused by the additional information written to STDOUT var sb = new StringBuilder(); while (Console.In.Peek() != -1) sb.AppendLine(Console.In.ReadLine()); sources.Add(new System.IO.StringReader(sb.ToString())); } else if (!Console.IsInputRedirected) { Console.InputEncoding = Encoding.Unicode; Console.OutputEncoding = Encoding.Unicode; Console.WriteLine("Enter the source. Press Enter after the last line and" + Environment.NewLine + "then press Ctrl+C to run parser."); Console.WriteLine(); Console.CancelKeyPress += (s, a) => { a.Cancel = true; Console.WriteLine("Output:"); Console.WriteLine(); }; sources.Add(Console.In); } else { Console.InputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8; sources.Add(Console.In); } } if (benchmark) { Console.WriteLine("Running the benchmark..."); foreach (var source in sources) { // by using a in-memory source, the disparity of results is reduced. var data = source.ReadToEnd(); // in-memory source that gets reused further reduces the disparity. var builder = new StringBuilder(2 * 1024 * 1024); var sw = new System.Diagnostics.Stopwatch(); var mem = GC.GetTotalMemory(true); long mem2 = 0; for (var x = -1 - benchmarkIterations / 10; x < benchmarkIterations; x++) { if (x == 0) sw.Start(); builder.Length = 0; using (var reader = new System.IO.StringReader(data)) using (var twriter = new System.IO.StringWriter(builder)) CommonMarkConverter.Convert(reader, twriter, settings); if (mem2 == 0) mem2 = GC.GetTotalMemory(false); GC.Collect(); } sw.Stop(); target.WriteLine("Time spent: {0:0.#}ms Approximate memory usage: {1:0.000}MB", (decimal)sw.ElapsedMilliseconds / benchmarkIterations, (mem2 - mem) / 1024M / 1024M); } } else { foreach (var source in sources) CommonMarkConverter.Convert(source, target, settings); } if (System.Diagnostics.Debugger.IsAttached) { Console.WriteLine("Press any key to continue..."); Console.ReadKey(true); } return 0; } catch (Exception ex) { Console.Error.WriteLine(ex.ToString()); return -1; } finally { foreach (var s in sources) if (s != Console.In) s.Close(); if (target != Console.Out) target.Close(); } }
private void ExecuteRefreshCommandInternal() { DocumentationHtmlContent = null; IUttBaseScriptItem scriptItem = (ProjectService.CurrentProject as VuGenProject)?.Script; var actionFilePaths = new List<string>(); Factotum.ProcessRecursively( scriptItem, item => //// ReSharper disable once RedundantEnumerableCastCall - False detection (item as IUttCollectionScriptItem<IUttBaseScriptItem>)?.ScriptItems ?? (item as IUttCollectionScriptItem<IActionScriptItem>)?.ScriptItems .Cast<IUttBaseScriptItem>(), item => { var actionScriptItem = item as IActionScriptItem; if (actionScriptItem != null) { actionFilePaths.Add(actionScriptItem.FullFileName); } }); var parsedFiles = Parser.ParseFiles(actionFilePaths); var content = parsedFiles .SelectMany(obj => obj.Elements) .OfType<ParsedComment>() .Select(obj => obj.Content) .Join(Environment.NewLine + Environment.NewLine); var settings = CommonMarkSettings.Default.Clone(); settings.AdditionalFeatures = CommonMarkAdditionalFeatures.All; settings.RenderSoftLineBreaksAsLineBreaks = true; var document = CommonMarkConverter.Parse(content, settings); ////var htmlContent = CommonMarkConverter.Convert(content, settings); ////Trace.WriteLine(htmlContent); using (var stringWriter = new StringWriter()) { var formatter = new HtmlFormatter(stringWriter, settings); formatter.WriteDocument(document); DocumentationHtmlContent = stringWriter.ToString(); } }