/// <summary> /// Converts the <see cref="Message.Contents"/> of <paramref name="message"/> to HTML. /// </summary> public static string GetHtmlContents(this Message message) { var pipelineBuilder = new MarkdownPipelineBuilder(); pipelineBuilder.DisableHtml(); return(Markdown.ToHtml(message.Contents, pipelineBuilder.Build())); }
public static string MarkupArticle(string secdata, bool forum, bool frontPage = false) { var pipelineBuilder = new MarkdownPipelineBuilder() .UseAdvancedExtensions(); if (forum) { pipelineBuilder.DisableHtml(); } var pipeline = pipelineBuilder.Build(); //Parse and Render Markup while applying special optimizations //Shamelessly ripped off from https://github.com/lunet-io/markdig/issues/293#issuecomment-456376415 var document = Markdown.Parse(secdata, pipeline); foreach (var descendant in document.Descendants()) { string url = null; bool isImage = false; if (descendant is AutolinkInline autoLink) { url = autoLink.Url; } else if (descendant is LinkInline linkInline) { url = linkInline.Url; isImage = linkInline.IsImage; if (isImage && !Shared.Helpers.IsUrlAbsolute(url)) { var imageUrl = url.TrimStart('/'); var imageHashEntry = ContentHash.GetContentHashEntryForFile(SystemInfoHelpers.ContentRootPath, "wwwroot", imageUrl, Html.GetRelativeHashPath, true).Result; if (imageHashEntry != null) { linkInline.Url = url = Html.GetRelativeHashPath(imageHashEntry.Hash, imageHashEntry.WebPath); } } } if (!isImage && Shared.Helpers.IsUrlAbsolute(url)) { descendant.GetAttributes().AddPropertyIfNotExist("target", "_blank"); } } using (var writer = new StringWriter()) { var renderer = new HtmlRenderer(writer); pipeline.Setup(renderer); renderer.Render(document); //Return finalized HTML if (!frontPage || !Settings.Current.SummaryModeFront) { return(writer.ToString()); } return(writer.ToString().DataTruncate(-3)); } }
private static MarkdownPipeline CreateUntrustedPipeline() { var pb = new MarkdownPipelineBuilder(); pb.DisableHtml(); pb.DisableHeadings(); pb.InlineParsers.TryRemove <LinkInlineParser>(); return(pb.Build()); }
public static string MarkupArticle(string secdata, bool forum) { var pipeline = new MarkdownPipelineBuilder() .UseAdvancedExtensions(); if (forum) { pipeline.DisableHtml(); } return(Markdown.ToHtml(secdata, pipeline.Build())); }
public void ParseMarkdownWithDisabledHtml(string data, string expected, bool disableHtml) { var builder = new MarkdownPipelineBuilder(); if (disableHtml) { builder.DisableHtml(); } var parsedResults = Markdown.ToHtml(data, builder.Build()); Assert.AreEqual(expected, parsedResults); }
static Renderer() { _NormalizeOptions = new Nr.NormalizeOptions { ListItemCharacter = '-', }; var builder = new MarkdownPipelineBuilder(); builder.DisableHtml(); builder.BlockParsers.RemoveAll(bp => !(bp is Markdig.Parsers.ParagraphBlockParser)); builder.UseAutoLinks(); _Pipeline = builder.Build(); }
/// <summary> /// Builds the Markdig processing pipeline and returns a builder. /// Use this method to override any custom pipeline addins you want to /// add or append. /// /// Note you can also add addins using options.MarkdigExtensions which /// use MarkDigs extension syntax using commas instead of +. /// </summary> /// <param name="options"></param> /// <param name="builder"></param> /// <returns></returns> protected virtual MarkdownPipelineBuilder BuildPipeline(MarkdownOptionsConfiguration options, MarkdownPipelineBuilder builder) { if (options.AutoLinks) { builder = builder.UseAutoLinks(); } if (options.AutoHeaderIdentifiers) { builder = builder.UseAutoIdentifiers(Markdig.Extensions.AutoIdentifiers.AutoIdentifierOptions.GitHub); } if (options.Abbreviations) { builder = builder.UseAbbreviations(); } if (options.UseTables) { builder = builder .UsePipeTables() .UseGridTables(); } if (options.StripYamlFrontMatter) { builder = builder.UseYamlFrontMatter(); } if (options.EmojiAndSmiley) { builder = builder.UseEmojiAndSmiley(true); } if (options.MediaLinks) { builder = builder.UseMediaLinks(); } if (options.ListExtras) { builder = builder.UseListExtras(); } if (options.Figures) { builder = builder.UseFigures(); } if (options.GithubTaskLists) { builder = builder.UseTaskLists(); } if (options.SmartyPants) { builder = builder.UseSmartyPants(); } if (options.Diagrams) { builder = builder.UseDiagrams(); } if (options.CustomContainers) { builder = builder.UseCustomContainers(); } if (options.Attributes) { builder = builder.UseGenericAttributes(); } if (options.FootersAndFootnotes) { builder = builder .UseFooters() .UseFootnotes(); } if (options.NoHtml) { builder = builder.DisableHtml(); } builder = builder.UseEmphasisExtras(); if (UsePragmaLines) { builder = builder.UsePragmaLines(); } try { if (!string.IsNullOrWhiteSpace(options.MarkdigExtensions)) { builder = builder.Configure(options.MarkdigExtensions.Replace(",", "+")); } } catch (ArgumentException ex) { // One or more of the extension options is invalid. mmApp.Log("Failed to load Markdig extensions: " + options.MarkdigExtensions + "\r\n" + ex.Message, ex); // reset to default options.MarkdigExtensions = string.Empty; builder = builder.Configure(options.MarkdigExtensions.Replace(",", "+")); } return(builder); }
/// <summary> /// Parses the actual markdown down to html /// </summary> /// <param name="markdown"></param> /// <returns></returns> public override string Parse(string markdown) { var options = mmApp.Configuration.MarkdownOptions; var builder = new MarkdownPipelineBuilder(); var errors = Array.Empty <string>(); var tokens = new Dictionary <string, string>(); var files = new Dictionary <string, string>(); var actualErrors = new List <string>(); var actualDependencies = new HashSet <string>(); var context = new MarkdownContext( getToken: key => tokens.TryGetValue(key, out var value) ? value : null, logInfo: (a, b, c, d) => { }, logSuggestion: Log("suggestion"), logWarning: Log("warning"), logError: Log("error"), readFile: ReadFile); // Fake root path to what MM sees as the root path (.markdown, project file, project open etc.) string filePath = mmApp.Model.ActiveDocument?.Filename; if (string.IsNullOrEmpty(filePath) || filePath.Equals("untitled", StringComparison.OrdinalIgnoreCase)) { filePath = mmApp.Model.ActiveDocument?.PreviewWebRootPath; if (string.IsNullOrEmpty(filePath)) { filePath = "preview.md"; } else { filePath += "\\preview"; } } files.Add(filePath, markdown); builder = builder.UseEmphasisExtras(EmphasisExtraOptions.Strikethrough) .UseAutoIdentifiers(AutoIdentifierOptions.GitHub) .UseMediaLinks() .UsePipeTables() .UseAutoLinks() .UseHeadingIdRewriter() .UseIncludeFile(context) .UseCodeSnippet(context) .UseDFMCodeInfoPrefix() .UseQuoteSectionNote(context) .UseXref() .UseEmojiAndSmiley(false) .UseTabGroup(context) .UseMonikerRange(context) .UseInteractiveCode() .UseRow(context) .UseNestedColumn(context) .UseTripleColon(context) .UseNoloc(); builder = RemoveUnusedExtensions(builder); builder = builder .UseYamlFrontMatter() .UseLineNumber(); if (options.NoHtml) { builder = builder.DisableHtml(); } if (UsePragmaLines) { builder = builder.UsePragmaLines(); } var pipeline = builder.Build(); string html; using (InclusionContext.PushFile(filePath)) { html = Markdown.ToHtml(markdown, pipeline); } html = ParseFontAwesomeIcons(html); if (mmApp.Configuration.MarkdownOptions.RenderLinksAsExternal) { html = ParseExternalLinks(html); } if (!mmApp.Configuration.MarkdownOptions.AllowRenderScriptTags) { html = HtmlUtils.SanitizeHtml(html); } return(html); MarkdownContext.LogActionDelegate Log(string level) { return((code, message, origin, line) => actualErrors.Add(code)); } // Handler to fix up file paths for nested/included documents (string content, object file) ReadFile(string path, MarkdownObject origin) { string key; var rootPath = mmApp.Model.ActiveDocument?.PreviewWebRootPath; if (rootPath == null) { rootPath = Path.GetDirectoryName(files.FirstOrDefault().Key); } string parentDocPath = null; //relativeTo as string; NOT PROVIDEd BY DOCFX ANYMORE??? //if (!string.IsNullOrEmpty(parentDocPath)) // parentDocPath = Path.GetDirectoryName(parentDocPath); //fully qualified path if (path.Contains(":/") || path.Contains(":\\")) { key = path; } else if (!string.IsNullOrEmpty(rootPath) && path.StartsWith("~/")) { path = path.Substring(2); key = Path.Combine(rootPath, path).Replace('\\', '/'); } // Site relative path else if (!string.IsNullOrEmpty(rootPath) && path.StartsWith("/")) { path = path.Substring(1); key = Path.Combine(rootPath, path).Replace('\\', '/'); } // Site relative path else if (!string.IsNullOrEmpty(parentDocPath)) { key = Path.GetFullPath(Path.Combine(parentDocPath, path)); } else { key = path; } actualDependencies.Add(key); files.TryGetValue(key, out var value); if (value == null) { try { value = File.ReadAllText(key)?.Trim(); } catch { } } if (value == null) { return(null, null); } return(value, key as object); } }
/// <summary> /// Parses the actual markdown down to html /// </summary> /// <param name="markdown"></param> /// <returns></returns> public override string Parse(string markdown) { var options = mmApp.Configuration.MarkdownOptions; var builder = new MarkdownPipelineBuilder(); var errors = Array.Empty <string>(); var tokens = new Dictionary <string, string>(); var files = new Dictionary <string, string>(); var actualErrors = new List <string>(); var actualDependencies = new HashSet <string>(); var context = new MarkdownContext( getToken: key => tokens.TryGetValue(key, out var value) ? value : null, logInfo: (a, b, c, d) => { }, logSuggestion: Log("suggestion"), logWarning: Log("warning"), logError: Log("error"), readFile: ReadFile); // Fake root path to what MM sees as the root path (.markdown, project file, project open etc.) string filePath = mmApp.Model.ActiveDocument?.Filename; if (string.IsNullOrEmpty(filePath) || filePath.Equals("untitled", StringComparison.OrdinalIgnoreCase)) { filePath = mmApp.Model.ActiveDocument?.PreviewWebRootPath; if (string.IsNullOrEmpty(filePath)) { filePath = "preview.md"; } else { filePath += "\\preview"; } } files.Add(filePath, markdown); builder = builder.UseEmphasisExtras(EmphasisExtraOptions.Strikethrough) .UseAutoIdentifiers(AutoIdentifierOptions.GitHub) .UseMediaLinks() .UsePipeTables() .UseAutoLinks() .UseHeadingIdRewriter() .UseIncludeFile(context) .UseCodeSnippet(context) .UseDFMCodeInfoPrefix() .UseQuoteSectionNote(context) .UseXref() .UseEmojiAndSmiley(false) .UseTabGroup(context) .UseMonikerRange(context) .UseInteractiveCode() .UseRow(context) .UseNestedColumn(context) .UseTripleColon(context) .UseNoloc(); builder = RemoveUnusedExtensions(builder); builder = builder .UseYamlFrontMatter() .UseLineNumber(); if (options.NoHtml) { builder = builder.DisableHtml(); } if (UsePragmaLines) { builder = builder.UsePragmaLines(); } var pipeline = builder.Build(); string html; try { using (InclusionContext.PushFile(filePath)) { html = Markdown.ToHtml(markdown, pipeline); } html = ParseFontAwesomeIcons(html); } catch (Exception ex) { if (markdown.Length > 10000) { markdown = markdown.Substring(0, 10000); } mmApp.Log("Unable to render Markdown Document (docFx)\n" + markdown, ex, logLevel: LogLevels.Warning); html = $@" <h1><i class='fa fa-warning text-error'></i> Unable to render Markdown Document</h1> <p> An error occurred trying to parse the Markdown document to HTML: </p> <b style='font-size: 1.2em'>{ex.Message}</b> <p> <a id='hrefShow' href='#0' style='font-size: 0.8em; font-weight: normal'>more info...</a> </p> <div id='detail' style='display:none'> <p style='margin-top: 2em'> <b>Markdown Parser</b>: {options.MarkdownParserName} </p> <pre style='padding: 8px; background: #eee; color: #333' >{System.Net.WebUtility.HtmlEncode(StringUtils.NormalizeIndentation(ex.StackTrace))}</pre> </div> <script> $('#hrefShow').click(function () {{ $('#detail').show(); }}); </script> "; return(html); } if (mmApp.Configuration.MarkdownOptions.RenderLinksAsExternal) { html = ParseExternalLinks(html); } if (!mmApp.Configuration.MarkdownOptions.AllowRenderScriptTags) { html = HtmlUtils.SanitizeHtml(html); } return(html); MarkdownContext.LogActionDelegate Log(string level) { return((code, message, origin, line) => actualErrors.Add(code)); } // Handler to fix up file paths for nested/included documents (string content, object file) ReadFile(string path, object relativeTo, MarkdownObject origin) { string key; var relativeDocumentPath = relativeTo as string; var rootPath = mmApp.Model.ActiveDocument?.PreviewWebRootPath; if (rootPath == null) { rootPath = Path.GetDirectoryName(files.FirstOrDefault().Key); } var parentDocPath = relativeTo as string; if (!string.IsNullOrEmpty(parentDocPath)) { parentDocPath = Path.GetDirectoryName(parentDocPath); } //fully qualified path if (path.Contains(":/") || path.Contains(":\\")) { key = path; } else if (!string.IsNullOrEmpty(rootPath) && path.StartsWith("~/")) { path = path.Substring(2); key = Path.Combine(rootPath, path).Replace('\\', '/'); } // Site relative path else if (!string.IsNullOrEmpty(rootPath) && path.StartsWith("/")) { path = path.Substring(1); key = Path.Combine(rootPath, path).Replace('\\', '/'); } // Site relative path else if (!string.IsNullOrEmpty(parentDocPath)) { key = Path.GetFullPath(Path.Combine(parentDocPath, path)); } else { key = path; } actualDependencies.Add(key); files.TryGetValue(key, out var value); if (value == null) { try { value = File.ReadAllText(key)?.Trim(); }catch { } } if (value == null) { return(null, null); } return(value, key as object); } }
private async Task <MarkdownPipeline> GetMarkdownPipelineImpl(HtmlBuilder htmlBuilder) { var pipelineBuilder = new MarkdownPipelineBuilder(); htmlBuilder.UseVSCodeMarkdownStylesheet(); htmlBuilder.AddKeyboardListener(); htmlBuilder.AddCharset(); if (!await _settings.IsHtmlEnabled()) { pipelineBuilder.DisableHtml(); } if (await _settings.IsAbbreviationEnabled()) { pipelineBuilder.UseAbbreviations(); } // TODO AutoIdentifierOptions if (await _settings.IsAutoIdentifierEnabled()) { pipelineBuilder.UseAutoIdentifiers(); } if (await _settings.IsBootstrapEnabled()) { pipelineBuilder.UseBootstrap(); } if (await _settings.IsCitationEnabled()) { pipelineBuilder.UseCitations(); } if (await _settings.IsDefinitionListEnabled()) { pipelineBuilder.UseDefinitionLists(); } // TODO EmojiSmileyOptions if (await _settings.IsEmojiSmileyEnabled()) { pipelineBuilder.UseEmojiAndSmiley(); } if (await _settings.IsFigureEnabled()) { pipelineBuilder.UseFigures(); } if (await _settings.IsFooterEnabled()) { pipelineBuilder.UseFooters(); } if (await _settings.IsFootnoteEnabled()) { pipelineBuilder.UseFootnotes(); } // TODO MediaLinkOptions if (await _settings.IsMedialinkEnabled()) { pipelineBuilder.UseMediaLinks(); } if (await _settings.IsSoftlineAsHardlineBreakEnabled()) { pipelineBuilder.UseSoftlineBreakAsHardlineBreak(); } // TODO SmartyPantsOptions if (await _settings.IsSmartyPantEnabled()) { pipelineBuilder.UseSmartyPants(); } if (await _settings.IsGenericAttributeEnabled()) { pipelineBuilder.UseGenericAttributes(); } if (await _settings.IsDiagramEnabled()) { pipelineBuilder.UseDiagrams(); if (await _settings.IsMermaidEnabled()) { htmlBuilder.UseMermaid(); } if (await _settings.IsNomnomlEnabled()) { htmlBuilder.UseNomnoml(); } } if (await _settings.IsEmphasisEnabled()) { EmphasisExtraOptions options = 0; if (await _settings.IsStrikethroughEnabled()) { options |= EmphasisExtraOptions.Strikethrough; } if (await _settings.IsInsertedEnabled()) { options |= EmphasisExtraOptions.Inserted; } if (await _settings.IsMarkedEnabled()) { options |= EmphasisExtraOptions.Marked; } if (await _settings.IsSuperSubScriptEnabled()) { options = options | EmphasisExtraOptions.Subscript | EmphasisExtraOptions.Superscript; } pipelineBuilder.UseEmphasisExtras(options); } if (await _settings.IsListEnabled()) { if (await _settings.IsTaskListEnabled()) { pipelineBuilder.UseTaskLists(); } if (await _settings.IsListExtraEnabled()) { pipelineBuilder.UseListExtras(); } } if (await _settings.IsMathEnabled()) { pipelineBuilder.UseMyMathExtension(); htmlBuilder.UseMathjax(); } if (await _settings.IsSyntaxHighlightingEnabled()) { htmlBuilder.UsePrismSyntaxHighlighting(); } if (await _settings.IsTableEnabled()) { if (await _settings.IsGridTableEnabled()) { pipelineBuilder.UseGridTables(); } // TODO PipeTableOptions if (await _settings.IsPipeTableEnabled()) { pipelineBuilder.UsePipeTables(); } } pipelineBuilder.UseMyWikiLinkExtension(); pipelineBuilder.UseTagExtension(); pipelineBuilder.UseYamlFrontMatter(); htmlBuilder.Flush(); return(pipelineBuilder.Build()); }