using System; using System.Collections.Generic; using System.Collections.ObjectModel; using mustache.Properties; namespace mustache { /// /// Defines the attributes of a custom tag. /// public abstract class TagDefinition { private readonly string _tagName; /// /// Initializes a new instance of a TagDefinition. /// /// The name of the tag. /// The name of the tag is null or blank. protected TagDefinition(string tagName) : this(tagName, false) { } /// /// Initializes a new instance of a TagDefinition. /// /// The name of the tag. /// Specifies whether the tag is built-in or not. Checks are not performed on the names of built-in tags. internal TagDefinition(string tagName, bool isBuiltIn) { if (!isBuiltIn && !RegexHelper.IsValidIdentifier(tagName)) { throw new ArgumentException(Resources.BlankTagName, "tagName"); } _tagName = tagName; } /// /// Gets the name of the tag. /// public string Name { get { return _tagName; } } /// /// Gets the parameters that are defined for the tag. /// public IEnumerable Parameters { get { return new ReadOnlyCollection(GetParameters()); } } /// /// Specifies which parameters are passed to the tag. /// /// The tag parameters. protected abstract TagParameter[] GetParameters(); /// /// Gets whether the tag contains content. /// public abstract bool HasBody { get; } /// /// Gets the tags that can indicate that the tag has closed. /// This field is only used if no closing tag is expected. /// public virtual IEnumerable ClosingTags { get { if (HasBody) { return new TagDefinition[] { this }; } else { return new TagDefinition[0]; } } } /// /// Gets the tags that are in scope within the current tag. /// public IEnumerable ChildTags { get { return new ReadOnlyCollection(GetChildTags()); } } /// /// Specifies which tags are scoped under the current tag. /// /// The child tag definitions. protected abstract TagDefinition[] GetChildTags(); /// /// Gets the scope to use when building the inner text of the tag. /// /// The current scope. /// The arguments passed to the tag. /// The scope to use when building the inner text of the tag. public virtual IEnumerable GetChildScopes(KeyScope scope, Dictionary arguments) { yield return scope; } /// /// Applies additional formatting to the inner text of the tag. /// /// The format provider to use. /// The inner text of the tag. /// The arguments passed to the tag. /// The decorated inner text. public virtual string Decorate(IFormatProvider provider, string innerText, Dictionary arguments) { return innerText; } /// /// Requests which generator group to associate the given tag type. /// /// The child tag definition being grouped. /// The name of the group to associate the given tag with. public virtual bool ShouldCreateSecondaryGroup(TagDefinition definition) { return false; } /// /// Gets whether the group with the given name should have text generated for them. /// /// The arguments passed to the tag. /// True if text should be generated for the group; otherwise, false. public virtual bool ShouldGeneratePrimaryGroup(Dictionary arguments) { return true; } } }