// Copyright (c) Alexandre Mutel. All rights reserved. // This file is licensed under the BSD-Clause 2 license. // See the license.txt file in the project root for more information. using System.Collections.Generic; using Markdig.Syntax.Inlines; namespace Markdig.Syntax { /// /// Extensions for visiting or /// public static class MarkdownObjectExtensions { /// /// Iterates over the descendant elements for the specified markdown element, including and . /// /// The markdown object. /// An iteration over the descendant elements public static IEnumerable Descendants(this MarkdownObject markdownObject) { // TODO: implement a recursiveless method var block = markdownObject as ContainerBlock; if (block != null) { foreach (var subBlock in block) { yield return subBlock; foreach (var sub in subBlock.Descendants()) { yield return sub; } // Visit leaf block that have inlines var leafBlock = subBlock as LeafBlock; if (leafBlock?.Inline != null) { foreach (var subInline in Descendants(leafBlock.Inline)) { yield return subInline; } } } } else { var inline = markdownObject as ContainerInline; if (inline != null) { var child = inline.FirstChild; while (child != null) { var next = child.NextSibling; yield return child; foreach (var sub in child.Descendants()) { yield return sub; } child = next; } } } } /// /// Iterates over the descendant elements for the specified markdown element and filters by the type {T}. /// /// Type to use for filtering the descendants /// The inline markdown object. /// /// An iteration over the descendant elements /// public static IEnumerable Descendants(this ContainerInline inline) where T : Inline { var child = inline.FirstChild; while (child != null) { var next = child.NextSibling; var childT = child as T; if (childT != null) { yield return childT; } var subContainer = child as ContainerInline; if (subContainer != null) { foreach (var sub in subContainer.Descendants()) { yield return sub; } } child = next; } } /// /// Iterates over the descendant elements for the specified markdown element and filters by the type {T}. /// /// Type to use for filtering the descendants /// The markdown object. /// /// An iteration over the descendant elements /// public static IEnumerable Descendants(this ContainerBlock block) where T : Block { foreach (var subBlock in block) { var subBlockT = subBlock as T; if (subBlockT != null) { yield return subBlockT; } var subBlockContainer = subBlock as ContainerBlock; if (subBlockContainer != null) { foreach (var sub in subBlockContainer.Descendants()) { yield return sub; } } } } } }