Skip to content
mloenow edited this page Mar 12, 2016 · 4 revisions

Extensibility

Block.AsEnumerable()

Provides an easy solution to visit every node of the parsed markdown document and perform simple modifications.

// parse markdown into document structure
var document = CommonMarkConverter.Parse("[click this link](~/hello)");

// walk the document node tree
foreach (var node in document.AsEnumerable())
{
    if (
        // start and end of each node may be visited separately
        node.IsOpening
        // blocks are elemets like paragraphs and lists, inlines are
        // elements like emphasis, links, images.
        && node.Inline != null 
        && node.Inline.Tag == InlineTag.Link)
    {
        if (node.Inline.TargetUrl.StartsWith("~"))
            node.Inline.TargetUrl = "http://server/app/" +
                node.Inline.TargetUrl.Substring(1);
    }
}

using (var writer = new System.IO.StringWriter())
{
    // write the HTML output
    CommonMarkConverter.ProcessStage3(document, writer);
    Console.WriteLine(writer.ToString());
}

HtmlFormatter

Provides methods to override the default HTML output by replacing only the parts needed.

private class CustomHtmlFormatter : CommonMark.Formatters.HtmlFormatter
{
    public CustomHtmlFormatter(System.IO.TextWriter target, CommonMarkSettings settings)
        : base(target, settings)
    {
    }

    protected override void WriteInline(Inline inline, bool isOpening, bool isClosing, out bool ignoreChildNodes)
    {
        if (
            // verify that the inline element is one that should be modified
            inline.Tag == InlineTag.Link
            // verify that the formatter should output HTML and not plain text
            && !this.RenderPlainTextInlines.Peek())
        {
            // instruct the formatter to process all nested nodes automatically
            ignoreChildNodes = false;

            // start and end of each node may be visited separately
            if (isOpening)
            {
                this.Write("<a target=\"_blank\" href=\"");
                this.WriteEncodedUrl(inline.TargetUrl);
                this.Write("\">");
            }

            // note that isOpening and isClosing can be true at the same time
            if (isClosing)
            {
                this.Write("</a>");
            }
        }
        else
        {
            // in all other cases the default implementation will output the correct HTML
            base.WriteInline(inline, isOpening, isClosing, out ignoreChildNodes);
        }
    }
}

// set the default HTML formatter for all future conversions
CommonMarkSettings.Default.OutputDelegate =
    (doc, output, settings) =>
    new CustomHtmlFormatter(output, settings).WriteDocument(doc);

var html = CommonMarkConverter.Convert("[click **this** link](~/hello)");
Clone this wiki locally