using System.Collections; using System.Collections.Generic; using System.IO; namespace Mustache { /// /// Defines a tag that can iterate over a collection of items and render /// the content using each item as the context. /// internal sealed class EachTagDefinition : ContentTagDefinition { private const string collectionParameter = "collection"; private static readonly TagParameter collection = new TagParameter(collectionParameter) { IsRequired = true }; /// /// Initializes a new instance of an EachTagDefinition. /// public EachTagDefinition() : base("each", true) { } /// /// Gets whether the tag only exists within the scope of its parent. /// protected override bool GetIsContextSensitive() { return false; } /// /// Gets the parameters that can be passed to the tag. /// /// The parameters. protected override IEnumerable GetParameters() { return new TagParameter[] { collection }; } /// /// Gets the context to use when building the inner text of the tag. /// /// The text writer passed /// The current scope. /// The arguments passed to the tag. /// The scope to use when building the inner text of the tag. public override IEnumerable GetChildContext( TextWriter writer, Scope keyScope, Dictionary arguments, Scope contextScope) { object value = arguments[collectionParameter]; if (!(value is IEnumerable enumerable)) { yield break; } int index = 0; foreach (object item in enumerable) { NestedContext childContext = new NestedContext() { KeyScope = keyScope.CreateChildScope(item), Writer = writer, ContextScope = contextScope.CreateChildScope(), }; childContext.ContextScope.Set("index", index); yield return childContext; ++index; } } /// /// Gets the tags that are in scope under this tag. /// /// The name of the tags that are in scope. protected override IEnumerable GetChildTags() { return new string[] { "index" }; } /// /// Gets the parameters that are used to create a new child context. /// /// The parameters that are used to create a new child context. public override IEnumerable GetChildContextParameters() { return new TagParameter[] { collection }; } } }