Get items from parsed MarkdownDocument #289

Closed
opened 2026-01-29 14:32:53 +00:00 by claunia · 3 comments
Owner

Originally created by @asbjornu on GitHub (Apr 24, 2019).

After parsing some Markdown to a MarkdownDocument, I'm wondering how I can iterate through the document to find all LeafInline objects that is of a certain extension class I've implemented. I'm dumbfounded by how to get further down into the document than at the Block level. Are leaf nodes not available in the MarkdownDocument?

This is my code:

var checklistExtension = new ChecklistExtension();
var pipelineBuilder = new MarkdownPipelineBuilder();
pipelineBuilder.Extensions.Add(checklistExtension);
pipelineBuilder.DisableHtml();
var pipeline = pipelineBuilder.Build();

using (var stringWriter = new StringWriter())
{
    var document = Markdown.ToHtml("…", stringWriter, pipeline);
    var html = stringWriter.ToString();
    // How do I get to the leaf nodes within 'document'?
}
Originally created by @asbjornu on GitHub (Apr 24, 2019). After parsing some Markdown to a `MarkdownDocument`, I'm wondering how I can iterate through the document to find all `LeafInline` objects that is of a certain extension class I've implemented. I'm dumbfounded by how to get further down into the document than at the `Block` level. Are leaf nodes not available in the `MarkdownDocument`? [This is my code](https://gist.github.com/asbjornu/4bbab38b6d65cd7b832669db68ef1828): ```c# var checklistExtension = new ChecklistExtension(); var pipelineBuilder = new MarkdownPipelineBuilder(); pipelineBuilder.Extensions.Add(checklistExtension); pipelineBuilder.DisableHtml(); var pipeline = pipelineBuilder.Build(); using (var stringWriter = new StringWriter()) { var document = Markdown.ToHtml("…", stringWriter, pipeline); var html = stringWriter.ToString(); // How do I get to the leaf nodes within 'document'? } ```
Author
Owner

@asbjornu commented on GitHub (Apr 24, 2019):

I think I figured it out:

private void AddChecklistItems(ContainerBlock containerBlock, IList<ChecklistItem> checklist)
{
    foreach (var block in containerBlock)
    {
        if (block is LeafBlock leafBlock)
        {
            foreach (var inline in leafBlock.Inline)
            {
                if (inline is ChecklistItem checklistItem)
                {
                    checklist.Add(checklistItem);
                }
            }
        }

        if (block is ContainerBlock cb)
        {
            AddChecklistItems(cb, list);
        }
    }                        
}

// …

var document = Markdown.ToHtml("…", stringWriter, pipeline);
var checklist = new List<ChecklistItem>();
AddChecklistItems(document, checklist);
@asbjornu commented on GitHub (Apr 24, 2019): I think I figured it out: ```c# private void AddChecklistItems(ContainerBlock containerBlock, IList<ChecklistItem> checklist) { foreach (var block in containerBlock) { if (block is LeafBlock leafBlock) { foreach (var inline in leafBlock.Inline) { if (inline is ChecklistItem checklistItem) { checklist.Add(checklistItem); } } } if (block is ContainerBlock cb) { AddChecklistItems(cb, list); } } } // … var document = Markdown.ToHtml("…", stringWriter, pipeline); var checklist = new List<ChecklistItem>(); AddChecklistItems(document, checklist); ```
Author
Owner

@MihaZupan commented on GitHub (Apr 24, 2019):

@asbjornu You might find these ways of traversing the AST useful

foreach (var markdownObject in document.Descendants())
{
    if (markdownObject is EmphasisInline myInline)
    {

    }
}

// anything
IEnumerable<EmphasisInline> anything = document.Descendants().Where(o => o is EmphasisInline).Cast<EmphasisInline>();

// blocks only
IEnumerable<ParagraphBlock> blocks = document.Descendants<ParagraphBlock>();

// inlines on containerInline only
IEnumerable<EmphasisInline> someInline = containerInline.FindDescendants<EmphasisInline>(); 

I suppose a Descendants<Inline> could be added

@MihaZupan commented on GitHub (Apr 24, 2019): @asbjornu You might find these ways of traversing the AST useful ```c# foreach (var markdownObject in document.Descendants()) { if (markdownObject is EmphasisInline myInline) { } } // anything IEnumerable<EmphasisInline> anything = document.Descendants().Where(o => o is EmphasisInline).Cast<EmphasisInline>(); // blocks only IEnumerable<ParagraphBlock> blocks = document.Descendants<ParagraphBlock>(); // inlines on containerInline only IEnumerable<EmphasisInline> someInline = containerInline.FindDescendants<EmphasisInline>(); ``` I suppose a `Descendants<Inline>` could be added
Author
Owner

@asbjornu commented on GitHub (Apr 25, 2019):

Thanks for the tip, @MihaZupan!

@asbjornu commented on GitHub (Apr 25, 2019): Thanks for the tip, @MihaZupan!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/markdig#289