using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Mustache { /// /// Defines a tag that conditionally prints its content. /// internal abstract class ConditionTagDefinition : ContentTagDefinition { private const string conditionParameter = "condition"; /// /// Initializes a new instance of a ConditionTagDefinition. /// /// The name of the tag. protected ConditionTagDefinition(string tagName) : base(tagName, true) { } /// /// Gets the parameters that can be passed to the tag. /// /// The parameters. protected override IEnumerable GetParameters() { return new TagParameter[] { new TagParameter(conditionParameter) { IsRequired = true } }; } /// /// Gets the tags that come into scope within the context of the current tag. /// /// The child tag definitions. protected override IEnumerable GetChildTags() { return new string[] { "elif", "else" }; } /// /// Gets whether the given tag's generator should be used for a secondary (or substitute) text block. /// /// The tag to inspect. /// True if the tag's generator should be used as a secondary generator. public override bool ShouldCreateSecondaryGroup(TagDefinition definition) { return new string[] { "elif", "else" }.Contains(definition.Name); } /// /// Gets whether the primary generator group should be used to render the tag. /// /// The arguments passed to the tag. /// /// True if the primary generator group should be used to render the tag; /// otherwise, false to use the secondary group. /// public override bool ShouldGeneratePrimaryGroup(Dictionary arguments) { object condition = arguments[conditionParameter]; return isConditionSatisfied(condition); } private bool isConditionSatisfied(object condition) { if (condition == null || condition == DBNull.Value) { return false; } if (condition is IEnumerable enumerable) { return enumerable.Cast().Any(); } if (condition is Char) { return (Char)condition != '\0'; } try { decimal number = (decimal)Convert.ChangeType(condition, typeof(decimal)); return number != 0.0m; } catch { return true; } } /// /// 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[0]; } } }