Example #1
0
        /// <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
        }
Example #2
0
        /// <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());
        }
Example #3
0
        private MarkdownPipeline CreatePipeline()
        {
            MarkdownPipelineBuilder pipelineBuilder = new MarkdownPipelineBuilder();

            pipelineBuilder.Configure(_configuration);
            pipelineBuilder.Extensions.AddRange(_extensions);
            return(pipelineBuilder.Build());
        }
Example #4
0
        /// <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());
            }
        }
Example #6
0
        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);
        }
Example #9
0
        /// <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);
        }