using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using mustache.Properties; namespace mustache { /// /// Defines the attributes of a custom tag. /// public sealed class TagDefinition { private readonly string _tagName; private readonly List _parameters; private readonly List _childTagDefinitions; private TagParameter _scopeParameter; /// /// Initializes a new instance of a TagDefinition. /// /// The name of the tag. /// The name of the tag is null or blank. public TagDefinition(string tagName) { if (!RegexHelper.IsValidIdentifier(tagName)) { throw new ArgumentException(Resources.BlankTagName, "tagName"); } _tagName = tagName; _parameters = new List(); _childTagDefinitions = new List(); } /// /// Gets the name of the tag. /// public string Name { get { return _tagName; } } /// /// Specifies that the tag expects the given parameter information. /// /// The parameter to add. /// The parameter is null. /// A parameter with the same name already exists. public void AddParameter(TagParameter parameter) { if (parameter == null) { throw new ArgumentNullException("parameter"); } if (_parameters.Any(p => p.Name == parameter.Name)) { throw new ArgumentException(Resources.DuplicateParameter, "parameter"); } _parameters.Add(parameter); if (parameter.IsScopeContext) { _scopeParameter = parameter; } } /// /// Gets the parameters that are defined for the tag. /// public IEnumerable Parameters { get { return new ReadOnlyCollection(_parameters); } } /// /// Gets or sets whether the tag contains content. /// public bool HasBody { get; set; } /// /// Gets or sets whether the tag defines a new scope based on an argument. /// public bool IsScoped { get; set; } /// /// Specifies that the given tag is in scope within the current tag. /// /// The tag that is in scope within the current tag. public void AddChildTag(TagDefinition childTag) { if (childTag == null) { throw new ArgumentNullException("childTag"); } _childTagDefinitions.Add(childTag); } /// /// Gets the tags that are in scope within the current tag. /// public IEnumerable ChildTags { get { return new ReadOnlyCollection(_childTagDefinitions); } } } }