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