/// <summary> /// Renders a source Markdown string to HTML /// </summary> /// <param name="srcMarkdown">The markdown to convert to HTML</param> /// <param name="useEmoji">Wwther to transform or not :emoji: into UTF-8 emojis</param> /// <returns>The resulting HTML</returns> public static string ConvertMarkdown2Html(string srcMarkdown, bool useEmoji, string extensions = "") { //Configure markdown conversion MarkdownPipelineBuilder mdPipe = new MarkdownPipelineBuilder().UseAdvancedExtensions(); //Add more extensions if (!string.IsNullOrWhiteSpace(extensions)) { mdPipe.Configure(extensions); } //Remove the indented code block parser (code blocks must always be fenced) //This is needed if you want to mix contents from MD and MDH files injected from FPFs and insertfile tags //and prevent problems when mixing HTML inside a Markdown file contents mdPipe.BlockParsers.Remove(mdPipe.BlockParsers.Find <Markdig.Parsers.IndentedCodeBlockParser>()); //Add support for non-ASCII characters in the Autolinks for headers //Remove the previous AutoIdentifierExtension mdPipe.Extensions.Remove(mdPipe.Extensions.Find <AutoIdentifierExtension>()); //Add AutoIdentifier extension with only AutoLink option mdPipe.UseAutoIdentifiers(AutoIdentifierOptions.AutoLink); //Check if we must generate emojis if (useEmoji) { mdPipe = mdPipe.UseEmojiAndSmiley(); } var pipeline = mdPipe.Build(); //Convert markdown to HTML return(Markdig.Markdown.ToHtml(srcMarkdown, pipeline)); //Convert to HTML }
/// <summary> /// Creates a pipeline automatically configured from an input markdown based on the presence of the configuration tag. /// </summary> /// <param name="inputText">The input text.</param> /// <returns>The pipeline configured from the input</returns> /// <exception cref="ArgumentNullException"></exception> public MarkdownPipeline CreatePipelineFromInput(string inputText) { if (inputText == null) { ThrowHelper.ArgumentNullException(nameof(inputText)); } var builder = new MarkdownPipelineBuilder(); string defaultConfig = DefaultExtensions; var indexOfSelfPipeline = inputText.IndexOf(SelfPipelineHintTagStart, StringComparison.OrdinalIgnoreCase); if (indexOfSelfPipeline >= 0) { var optionStart = indexOfSelfPipeline + SelfPipelineHintTagStart.Length; var endOfTag = inputText.IndexOf("-->", optionStart, StringComparison.OrdinalIgnoreCase); if (endOfTag >= 0) { defaultConfig = inputText.Substring(optionStart, endOfTag - optionStart).Trim(); } } if (!string.IsNullOrEmpty(defaultConfig)) { builder.Configure(defaultConfig); } return(builder.Build()); }
private MarkdownPipeline CreatePipeline() { MarkdownPipelineBuilder pipelineBuilder = new MarkdownPipelineBuilder(); pipelineBuilder.Configure(_configuration); pipelineBuilder.Extensions.AddRange(_extensions); return(pipelineBuilder.Build()); }
/// <summary> /// Enables optional Markdig extensions that are not added by default with DocFX /// </summary> /// <param name="pipeline">The markdown pipeline builder</param> /// <param name="optionalExtensions">The list of optional extensions</param> /// <returns>The pipeline with optional extensions enabled</returns> public static MarkdownPipelineBuilder UseOptionalExtensions( this MarkdownPipelineBuilder pipeline, IEnumerable <string> optionalExtensions) { if (!optionalExtensions.Any()) { return(pipeline); } pipeline.Configure(string.Join("+", optionalExtensions)); return(pipeline); }
internal static string Render( IExecutionContext context, string configuration, OrderedList <IMarkdownExtension> extensions, bool prependLinkRoot, string content) { // Create the pipeline MarkdownPipelineBuilder pipelineBuilder = new MarkdownPipelineBuilder(); pipelineBuilder.Configure(configuration); if (extensions != null) { pipelineBuilder.Extensions.AddRange(extensions); } MarkdownPipeline pipeline = pipelineBuilder.Build(); // Render the content using (StringWriter writer = new StringWriter()) { HtmlRenderer htmlRenderer = new HtmlRenderer(writer); pipeline.Setup(htmlRenderer); if (prependLinkRoot && context.Settings.ContainsKey(Keys.LinkRoot)) { htmlRenderer.LinkRewriter = (link) => { if (string.IsNullOrEmpty(link)) { return(link); } if (link[0] == '/') { // root-based url, must be rewritten by prepending the LinkRoot setting value // ex: '/virtual/directory' + '/relative/abs/link.html' => '/virtual/directory/relative/abs/link.html' link = context.Settings[Keys.LinkRoot] + link; } return(link); }; } MarkdownDocument document = MarkdownParser.Parse(content, pipeline); htmlRenderer.Render(document); writer.Flush(); return(writer.ToString()); } }
public static IEnumerable <KeyValuePair <string, MarkdownPipeline> > GetPipeline(string extensionsGroupText) { // For the standard case, we make sure that both the CommmonMark core and Extra/Advanced are CommonMark compliant! if (string.IsNullOrEmpty(extensionsGroupText)) { yield return(new KeyValuePair <string, MarkdownPipeline>("default", new MarkdownPipelineBuilder().Build())); //yield return new KeyValuePair<string, MarkdownPipeline>("default-trivia", new MarkdownPipelineBuilder().EnableTrackTrivia().Build()); yield return(new KeyValuePair <string, MarkdownPipeline>("advanced", new MarkdownPipelineBuilder() // Use similar to advanced extension without auto-identifier .UseAbbreviations() //.UseAutoIdentifiers() .UseCitations() .UseCustomContainers() .UseDefinitionLists() .UseEmphasisExtras() .UseFigures() .UseFooters() .UseFootnotes() .UseGridTables() .UseMathematics() .UseMediaLinks() .UsePipeTables() .UseListExtras() .UseGenericAttributes().Build())); yield break; } var extensionGroups = extensionsGroupText.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (var extensionsText in extensionGroups) { var builder = new MarkdownPipelineBuilder(); builder.DebugLog = Console.Out; if (extensionsText == "jiralinks") { builder.UseJiraLinks(new JiraLinkOptions("http://your.company.abc")); } else { builder = extensionsText == "self" ? builder.UseSelfPipeline() : builder.Configure(extensionsText); } yield return(new KeyValuePair <string, MarkdownPipeline>(extensionsText, builder.Build())); } }
private static void Check(string text, string expectedResult, string extensions = null) { var pipelineBuilder = new MarkdownPipelineBuilder().UsePreciseSourceLocation(); if (extensions != null) { pipelineBuilder.Configure(extensions); } var pipeline = pipelineBuilder.Build(); var document = Markdown.Parse(text, pipeline); var build = new StringBuilder(); foreach (var val in document.Descendants()) { var name = GetTypeName(val.GetType()); build.Append($"{name,-12} ({val.Line,2},{val.Column,2}) {val.Span.Start,2}-{val.Span.End}\n"); var attributes = val.TryGetAttributes(); if (attributes != null) { build.Append($"{"attributes",-12} ({attributes.Line,2},{attributes.Column,2}) {attributes.Span.Start,2}-{attributes.Span.End}\n"); } } var result = build.ToString().Trim(); expectedResult = expectedResult.Trim(); expectedResult = expectedResult.Replace("\r\n", "\n").Replace("\r", "\n"); if (expectedResult != result) { Console.WriteLine("```````````````````Source"); Console.WriteLine(TestParser.DisplaySpaceAndTabs(text)); Console.WriteLine("```````````````````Result"); Console.WriteLine(result); Console.WriteLine("```````````````````Expected"); Console.WriteLine(expectedResult); Console.WriteLine("```````````````````"); Console.WriteLine(); } TextAssert.AreEqual(expectedResult, result); }
/// <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(); } if (options.Abbreviations) { builder = builder.UseAbbreviations(); } if (options.StripYamlFrontMatter) { builder = builder.UseYamlFrontMatter(); } if (options.EmojiAndSmiley) { builder = builder.UseEmojiAndSmiley(); } 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 (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); } return(builder); }
/// <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); }