예제 #1
0
 /// <summary>
 /// Registers the given tag definition with the parser.
 /// </summary>
 /// <param name="definition">The tag definition to register.</param>
 /// <param name="isTopLevel">Specifies whether the tag is immediately in scope.</param>
 public void RegisterTag(TagDefinition definition, bool isTopLevel)
 {
     if (definition == null || _tagLookup.ContainsKey(definition.Name))
     {
         return;
     }
     _tagLookup.Add(definition.Name, definition);
 }
 /// <summary>
 /// Registers the given tag definition with the parser.
 /// </summary>
 /// <param name="definition">The tag definition to register.</param>
 /// <param name="isTopLevel">Specifies whether the tag is immediately in scope.</param>
 public void RegisterTag(TagDefinition definition, bool isTopLevel)
 {
     if (definition == null)
     {
         throw new ArgumentNullException("definition");
     }
     if (_tagLookup.ContainsKey(definition.Name))
     {
         string message = String.Format(Resources.DuplicateTagDefinition, definition.Name);
         throw new ArgumentException(message, "definition");
     }
     _tagLookup.Add(definition.Name, definition);
 }
예제 #3
0
 /// <summary>
 /// Registers the given tag definition with the parser.
 /// </summary>
 /// <param name="definition">The tag definition to register.</param>
 /// <param name="isTopLevel">Specifies whether the tag is immediately in scope.</param>
 public void RegisterTag(TagDefinition definition, bool isTopLevel)
 {
     if (definition == null)
     {
         throw new ArgumentNullException("definition");
     }
     if (_tagLookup.ContainsKey(definition.Name))
     {
         string message = String.Format("The {0} tag has already been registered.", definition.Name);
         throw new ArgumentException(message, "definition");
     }
     _tagLookup.Add(definition.Name, definition);
 }
예제 #4
0
 /// <summary>
 /// Registers the given tag definition with the parser.
 /// </summary>
 /// <param name="definition">The tag definition to register.</param>
 /// <param name="isTopLevel">Specifies whether the tag is immediately in scope.</param>
 public void RegisterTag(TagDefinition definition, bool isTopLevel)
 {
     if (definition == null)
     {
         throw new ArgumentNullException("definition");
     }
     if (_tagLookup.ContainsKey(definition.Name))
     {
         string message = String.Format(Resources.DuplicateTagDefinition, definition.Name);
         throw new ArgumentException(message, "definition");
     }
     _tagLookup.Add(definition.Name, definition);
 }
예제 #5
0
        private static string getTagRegex(TagDefinition definition)
        {
            StringBuilder regexBuilder = new StringBuilder();

            regexBuilder.Append(@"(?<open>(#(?<name>");
            regexBuilder.Append(definition.Name);
            regexBuilder.Append(@")");
            foreach (TagParameter parameter in definition.Parameters)
            {
                regexBuilder.Append(@"(\s+?");
                regexBuilder.Append(@"(?<argument>(");
                regexBuilder.Append(RegexHelper.Argument);
                regexBuilder.Append(@")))");
                if (!parameter.IsRequired)
                {
                    regexBuilder.Append("?");
                }
            }
            regexBuilder.Append(@"\s*?))");
            return(regexBuilder.ToString());
        }
예제 #6
0
        private Regex prepareRegex(TagDefinition definition)
        {
            Regex regex = null;

            if (!_regexLookup.TryGetValue(definition.Name, out regex))
            {
                List <string> matches = new List <string>()
                {
                    getKeyRegex(),
                    getCommentTagRegex()
                };
                foreach (string closingTag in definition.ClosingTags)
                {
                    matches.Add(getClosingTagRegex(closingTag));
                }
                foreach (TagDefinition globalDefinition in _tagLookup.Values)
                {
                    if (!globalDefinition.IsContextSensitive)
                    {
                        matches.Add(getTagRegex(globalDefinition));
                    }
                }
                foreach (string childTag in definition.ChildTags)
                {
                    TagDefinition childDefinition = _tagLookup[childTag];
                    matches.Add(getTagRegex(childDefinition));
                }
                matches.Add(getUnknownTagRegex());
                string combined = String.Join("|", matches);
                string match    = "{{(?<match>" + combined + ")}}";
                if (AreExtensionTagsAllowed)
                {
                    string tripleMatch = "{{{(?<extension>" + combined + ")}}}";
                    match = "(?:" + match + ")|(?:" + tripleMatch + ")";
                }
                regex = new Regex(match);
                _regexLookup.Add(definition.Name, regex);
            }
            return(regex);
        }
예제 #7
0
 /// <summary>
 /// Gets whether the given tag's generator should be used for a secondary (or substitute) text block.
 /// </summary>
 /// <param name="definition">The tag to inspect.</param>
 /// <returns>True if the tag's generator should be used as a secondary generator.</returns>
 public override bool ShouldCreateSecondaryGroup(TagDefinition definition)
 {
     return(new string[] { "elif", "else" }.Contains(definition.Name));
 }
예제 #8
0
 /// <summary>
 /// Requests which generator group to associate the given tag type.
 /// </summary>
 /// <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)
 {
     return(false);
 }
예제 #9
0
 /// <summary>
 /// Initializes a new instance of an InlineGenerator.
 /// </summary>
 /// <param name="definition">The tag to render the text for.</param>
 /// <param name="arguments">The arguments passed to the tag.</param>
 public InlineGenerator(TagDefinition definition, ArgumentCollection arguments)
 {
     _definition = definition;
     _arguments  = arguments;
 }
예제 #10
0
 /// <summary>
 /// Initializes a new instance of a CompoundGenerator.
 /// </summary>
 /// <param name="definition">The tag that the text is being generated for.</param>
 /// <param name="arguments">The arguments that were passed to the tag.</param>
 public CompoundGenerator(TagDefinition definition, ArgumentCollection arguments)
 {
     _definition = definition;
     _arguments = arguments;
     _primaryGenerators = new List<IGenerator>();
 }
예제 #11
0
 /// <summary>
 /// Requests which generator group to associate the given tag type.
 /// </summary>
 /// <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)
 {
     return false;
 }
예제 #12
0
 /// <summary>
 /// Initializes a new instance of a CompoundGenerator.
 /// </summary>
 /// <param name="definition">The tag that the text is being generated for.</param>
 /// <param name="arguments">The arguments that were passed to the tag.</param>
 public CompoundGenerator(TagDefinition definition, ArgumentCollection arguments)
 {
     _definition        = definition;
     _arguments         = arguments;
     _primaryGenerators = new List <IGenerator>();
 }
 /// <summary>
 /// Gets whether the given tag's generator should be used for a secondary (or substitute) text block.
 /// </summary>
 /// <param name="definition">The tag to inspect.</param>
 /// <returns>True if the tag's generator should be used as a secondary generator.</returns>
 public override bool ShouldCreateSecondaryGroup(TagDefinition definition)
 {
     return new string[] { "elif", "else" }.Contains(definition.Name);
 }
예제 #14
0
 private Match findNextTag(TagDefinition definition, string format, int formatIndex)
 {
     Regex regex = prepareRegex(definition);
     return regex.Match(format, formatIndex);
 }
예제 #15
0
 private static string getTagRegex(TagDefinition definition)
 {
     StringBuilder regexBuilder = new StringBuilder();
     regexBuilder.Append(@"(?<open>(#(?<name>");
     regexBuilder.Append(definition.Name);
     regexBuilder.Append(@")");
     foreach (TagParameter parameter in definition.Parameters)
     {
         regexBuilder.Append(@"(\s+?");
         regexBuilder.Append(@"(?<argument>(");
         regexBuilder.Append(RegexHelper.Argument);
         regexBuilder.Append(@")))");
         if (!parameter.IsRequired)
         {
             regexBuilder.Append("?");
         }
     }
     regexBuilder.Append(@"\s*?))");
     return regexBuilder.ToString();
 }
예제 #16
0
 /// <summary>
 /// Adds the given generator, determining whether the generator should
 /// be part of the primary generators or added as an secondary generator.
 /// </summary>
 /// <param name="definition">The tag that the generator is generating text for.</param>
 /// <param name="generator">The generator to add.</param>
 public void AddGenerator(TagDefinition definition, IGenerator generator)
 {
     bool isSubGenerator = _definition.ShouldCreateSecondaryGroup(definition);
     addGenerator(generator, isSubGenerator);
 }
예제 #17
0
        private int buildCompoundGenerator(
            TagDefinition tagDefinition,
            List <Context> context,
            CompoundGenerator generator,
            string format, int formatIndex)
        {
            while (true)
            {
                Match match = findNextTag(tagDefinition, format, formatIndex);

                if (!match.Success)
                {
                    if (tagDefinition.ClosingTags.Any())
                    {
                        string message = String.Format(Resources.MissingClosingTag, tagDefinition.Name);
                        throw new FormatException(message);
                    }
                    break;
                }

                string leading = format.Substring(formatIndex, match.Index - formatIndex);

                if (match.Groups["key"].Success)
                {
                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    formatIndex = match.Index + match.Length;
                    string key        = match.Groups["key"].Value;
                    string alignment  = match.Groups["alignment"].Value;
                    string formatting = match.Groups["format"].Value;
                    if (key.StartsWith("@"))
                    {
                        VariableFoundEventArgs args = new VariableFoundEventArgs(key.Substring(1), alignment, formatting, context.ToArray());
                        if (VariableFound != null)
                        {
                            VariableFound(this, args);
                            key        = "@" + args.Name;
                            alignment  = args.Alignment;
                            formatting = args.Formatting;
                        }
                    }
                    else
                    {
                        PlaceholderFoundEventArgs args = new PlaceholderFoundEventArgs(key, alignment, formatting, context.ToArray());
                        if (PlaceholderFound != null)
                        {
                            PlaceholderFound(this, args);
                            key        = args.Key;
                            alignment  = args.Alignment;
                            formatting = args.Formatting;
                        }
                    }
                    KeyGenerator keyGenerator = new KeyGenerator(key, alignment, formatting);
                    generator.AddGenerator(keyGenerator);
                }
                else if (match.Groups["open"].Success)
                {
                    formatIndex = match.Index + match.Length;
                    string        tagName        = match.Groups["name"].Value;
                    TagDefinition nextDefinition = _tagLookup[tagName];
                    if (nextDefinition == null)
                    {
                        string message = String.Format(Resources.UnknownTag, tagName);
                        throw new FormatException(message);
                    }

                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    ArgumentCollection arguments = getArguments(nextDefinition, match, context);

                    if (nextDefinition.HasContent)
                    {
                        CompoundGenerator          compoundGenerator = new CompoundGenerator(nextDefinition, arguments);
                        IEnumerable <TagParameter> contextParameters = nextDefinition.GetChildContextParameters();
                        bool hasContext = contextParameters.Any();
                        if (hasContext)
                        {
                            ContextParameter[] parameters = contextParameters.Select(p => new ContextParameter(p.Name, arguments.GetKey(p))).ToArray();
                            context.Add(new Context(nextDefinition.Name, parameters));
                        }
                        formatIndex = buildCompoundGenerator(nextDefinition, context, compoundGenerator, format, formatIndex);
                        generator.AddGenerator(nextDefinition, compoundGenerator);
                        if (hasContext)
                        {
                            context.RemoveAt(context.Count - 1);
                        }
                    }
                    else
                    {
                        InlineGenerator inlineGenerator = new InlineGenerator(nextDefinition, arguments);
                        generator.AddGenerator(inlineGenerator);
                    }
                }
                else if (match.Groups["close"].Success)
                {
                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    string        tagName        = match.Groups["name"].Value;
                    TagDefinition nextDefinition = _tagLookup[tagName];
                    formatIndex = match.Index;
                    if (tagName == tagDefinition.Name)
                    {
                        formatIndex += match.Length;
                    }
                    break;
                }
                else if (match.Groups["comment"].Success)
                {
                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    formatIndex = match.Index + match.Length;
                }
                else if (match.Groups["command"].Success)
                {
                    var parameters = match.Groups["params"].Value ?? "";
                    var args       = new ArgumentCollection();
                    int index      = 0;
                    parameters
                    .Split(new[] { ',' })
                    .Select(a => a.Trim())
                    .ToList()
                    .ForEach(a => args.AddArgument(new TagParameter((index++).ToString()), new StringArgument(a)));

                    TagDefinition definition;
                    _tagLookup.TryGetValue(match.Groups["command"].Value, out definition);

                    if (definition == null)
                    {
                        throw new FormatException(string.Format(Resources.MissingCommand, match.Groups["command"].Value));
                    }

                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    generator.AddGenerator(new InlineGenerator(definition, args));
                    formatIndex = match.Index + match.Length;
                }
                else if (match.Groups["unknown"].Success)
                {
                    string tagName = match.Value;
                    string message = String.Format(Resources.UnknownTag, tagName);
                    throw new FormatException(message);
                }
            }
            return(formatIndex);
        }
예제 #18
0
 /// <summary>
 /// Initializes a new instance of an InlineGenerator.
 /// </summary>
 /// <param name="definition">The tag to render the text for.</param>
 /// <param name="arguments">The arguments passed to the tag.</param>
 public InlineGenerator(TagDefinition definition, ArgumentCollection arguments)
 {
     _definition = definition;
     _arguments = arguments;
 }
예제 #19
0
 private Regex prepareRegex(TagDefinition definition)
 {
     Regex regex;
     if (!_regexLookup.TryGetValue(definition.Name, out regex))
     {
         List<string> matches = new List<string>();
         matches.Add(getKeyRegex());
         matches.Add(getCommentTagRegex());
         foreach (string closingTag in definition.ClosingTags)
         {
             matches.Add(getClosingTagRegex(closingTag));
         }
         foreach (TagDefinition globalDefinition in _tagLookup.Values)
         {
             if (!globalDefinition.IsContextSensitive)
             {
                 matches.Add(getTagRegex(globalDefinition));
             }
         }
         foreach (string childTag in definition.ChildTags)
         {
             TagDefinition childDefinition = _tagLookup[childTag];
             matches.Add(getTagRegex(childDefinition));
         }
         matches.Add(getUnknownTagRegex());
         string match = "{{(" + String.Join("|", matches) + ")}}";
         regex = new Regex(match);
         _regexLookup.Add(definition.Name, regex);
     }
     return regex;
 }
예제 #20
0
 private Regex prepareRegex(TagDefinition definition)
 {
     Regex regex;
     if (!_regexLookup.TryGetValue(definition.Name, out regex))
     {
         List<string> matches = new List<string>();
         matches.Add(getKeyRegex());
         matches.Add(getCommentTagRegex());
         foreach (string closingTag in definition.ClosingTags)
         {
             matches.Add(getClosingTagRegex(closingTag));
         }
         foreach (TagDefinition globalDefinition in _tagLookup.Values)
         {
             if (!globalDefinition.IsContextSensitive)
             {
                 matches.Add(getTagRegex(globalDefinition));
             }
         }
         foreach (string childTag in definition.ChildTags)
         {
             TagDefinition childDefinition = _tagLookup[childTag];
             matches.Add(getTagRegex(childDefinition));
         }
         matches.Add(getUnknownTagRegex());
         string combined = String.Join("|", matches);
         string match = "{{(?<match>" + combined + ")}}";
         if (AreExtensionTagsAllowed)
         {
             string tripleMatch = "{{{(?<extension>" + combined + ")}}}";
             match = "(?:" + match + ")|(?:" + tripleMatch + ")";
         }
         regex = new Regex(match);
         _regexLookup.Add(definition.Name, regex);
     }
     return regex;
 }
 public override bool ShouldCreateSecondaryGroup(TagDefinition definition)
 {
     return this.GetChildTags().Contains(definition.Name);
 }
예제 #22
0
 /// <summary>
 /// Initializes a new instance of a CompoundGenerator.
 /// </summary>
 /// <param name="definition">The tag that the text is being generated for.</param>
 /// <param name="arguments">The arguments that were passed to the tag.</param>
 public CompoundGenerator(TagDefinition definition, ArgumentCollection arguments)
 {
     _definition = definition;
     _arguments  = arguments;
 }
예제 #23
0
        private int buildCompoundGenerator(
            TagDefinition tagDefinition,
            List<Context> context,
            CompoundGenerator generator,
            string format, int formatIndex)
        {
            while (true)
            {
                Match match = findNextTag(tagDefinition, format, formatIndex);

                if (!match.Success)
                {
                    if (tagDefinition.ClosingTags.Any())
                    {
                        string message = String.Format(Resources.MissingClosingTag, tagDefinition.Name);
                        throw new FormatException(message);
                    }
                    break;
                }

                string leading = format.Substring(formatIndex, match.Index - formatIndex);

                if (match.Groups["key"].Success)
                {
                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    formatIndex = match.Index + match.Length;
                    bool isExtension = match.Groups["extension"].Success;
                    string key = match.Groups["key"].Value;
                    string alignment = match.Groups["alignment"].Value;
                    string formatting = match.Groups["format"].Value;
                    if (key.StartsWith("@"))
                    {
                        VariableFoundEventArgs args = new VariableFoundEventArgs(key.Substring(1), alignment, formatting, isExtension, context.ToArray());
                        if (VariableFound != null)
                        {
                            VariableFound(this, args);
                            key = "@" + args.Name;
                            alignment = args.Alignment;
                            formatting = args.Formatting;
                            isExtension = args.IsExtension;
                        }
                    }
                    else
                    {
                        PlaceholderFoundEventArgs args = new PlaceholderFoundEventArgs(key, alignment, formatting, isExtension, context.ToArray());
                        if (PlaceholderFound != null)
                        {
                            PlaceholderFound(this, args);
                            key = args.Key;
                            alignment = args.Alignment;
                            formatting = args.Formatting;
                            isExtension = args.IsExtension;
                        }
                    }
                    KeyGenerator keyGenerator = new KeyGenerator(key, alignment, formatting, isExtension);
                    generator.AddGenerator(keyGenerator);
                }
                else if (match.Groups["open"].Success)
                {
                    formatIndex = match.Index + match.Length;
                    string tagName = match.Groups["name"].Value;
                    TagDefinition nextDefinition = _tagLookup[tagName];
                    if (nextDefinition == null)
                    {
                        string message = String.Format(Resources.UnknownTag, tagName);
                        throw new FormatException(message);
                    }

                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    ArgumentCollection arguments = getArguments(nextDefinition, match, context);

                    if (nextDefinition.HasContent)
                    {
                        CompoundGenerator compoundGenerator = new CompoundGenerator(nextDefinition, arguments);
                        IEnumerable<TagParameter> contextParameters = nextDefinition.GetChildContextParameters();
                        bool hasContext = contextParameters.Any();
                        if (hasContext)
                        {
                            ContextParameter[] parameters = contextParameters.Select(p => new ContextParameter(p.Name, arguments.GetKey(p))).ToArray();
                            context.Add(new Context(nextDefinition.Name, parameters));
                        }
                        formatIndex = buildCompoundGenerator(nextDefinition, context, compoundGenerator, format, formatIndex);
                        generator.AddGenerator(nextDefinition, compoundGenerator);
                        if (hasContext)
                        {
                            context.RemoveAt(context.Count - 1);
                        }
                    }
                    else
                    {
                        InlineGenerator inlineGenerator = new InlineGenerator(nextDefinition, arguments);
                        generator.AddGenerator(inlineGenerator);
                    }
                }
                else if (match.Groups["close"].Success)
                {
                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    string tagName = match.Groups["name"].Value;
                    TagDefinition nextDefinition = _tagLookup[tagName];
                    formatIndex = match.Index;
                    if (tagName == tagDefinition.Name)
                    {
                        formatIndex += match.Length;
                    }
                    break;
                }
                else if (match.Groups["comment"].Success)
                {
                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    formatIndex = match.Index + match.Length;
                }
                else if (match.Groups["unknown"].Success)
                {
                    string tagName = match.Value;
                    string message = String.Format(Resources.UnknownTag, tagName);
                    throw new FormatException(message);
                }
            }
            return formatIndex;
        }
예제 #24
0
        private Match findNextTag(TagDefinition definition, string format, int formatIndex)
        {
            Regex regex = prepareRegex(definition);

            return(regex.Match(format, formatIndex));
        }
예제 #25
0
        private ArgumentCollection getArguments(TagDefinition definition, Match match, List<Context> context)
        {
            // make sure we don't have too many arguments
            List<Capture> captures = match.Groups["argument"].Captures.Cast<Capture>().ToList();
            List<TagParameter> parameters = definition.Parameters.ToList();
            if (captures.Count > parameters.Count)
            {
                string message = String.Format(Resources.WrongNumberOfArguments, definition.Name);
                throw new FormatException(message);
            }

            // provide default values for missing arguments
            if (captures.Count < parameters.Count)
            {
                captures.AddRange(Enumerable.Repeat((Capture)null, parameters.Count - captures.Count));
            }

            // pair up the parameters to the given arguments
            // provide default for parameters with missing arguments
            // throw an error if a missing argument is for a required parameter
            Dictionary<TagParameter, string> arguments = new Dictionary<TagParameter, string>();
            foreach (var pair in parameters.Zip(captures, (p, c) => new { Capture = c, Parameter = p }))
            {
                string value = null;
                if (pair.Capture != null)
                {
                    value = pair.Capture.Value;
                }
                else if (pair.Parameter.IsRequired)
                {
                    string message = String.Format(Resources.WrongNumberOfArguments, definition.Name);
                    throw new FormatException(message);
                }
                arguments.Add(pair.Parameter, value);
            }

            // indicate that a key/variable has been encountered
            // update the key/variable name
            ArgumentCollection collection = new ArgumentCollection();
            foreach (var pair in arguments)
            {
                string placeholder = pair.Value;
                IArgument argument = null;
                if (placeholder != null)
                {
                    if (placeholder.StartsWith("@"))
                    {
                        string variableName = placeholder.Substring(1);
                        VariableFoundEventArgs args = new VariableFoundEventArgs(placeholder.Substring(1), String.Empty, String.Empty, false, context.ToArray());
                        if (VariableFound != null)
                        {
                            VariableFound(this, args);
                            variableName = args.Name;
                        }
                        argument = new VariableArgument(variableName);
                    }
                    else if (RegexHelper.IsString(placeholder))
                    {
                        string value = placeholder.Trim('\'');
                        argument = new StringArgument(value);
                    }
                    else if (RegexHelper.IsNumber(placeholder))
                    {
                        decimal number;
                        if (Decimal.TryParse(placeholder, out number))
                        {
                            argument = new NumberArgument(number);
                        }
                    }
                    else
                    {
                        string placeholderName = placeholder;
                        PlaceholderFoundEventArgs args = new PlaceholderFoundEventArgs(placeholder, String.Empty, String.Empty, false, context.ToArray());
                        if (PlaceholderFound != null)
                        {
                            PlaceholderFound(this, args);
                            placeholderName = args.Key;
                        }
                        argument = new PlaceholderArgument(placeholderName);
                    }
                }
                collection.AddArgument(pair.Key, argument);
            }
            return collection;
        }
예제 #26
0
        private int buildCompoundGenerator(
            TagDefinition tagDefinition,
            List <Context> context,
            CompoundGenerator generator,
            string format, int formatIndex)
        {
            while (true)
            {
                Match match = findNextTag(tagDefinition, format, formatIndex);

                if (!match.Success)
                {
                    if (tagDefinition.ClosingTags.Any())
                    {
                        string message = String.Format("Expected a matching {0} tag but none was found.", tagDefinition.Name);
                        throw new FormatException(message);
                    }
                    break;
                }

                string leading = format.Substring(formatIndex, match.Index - formatIndex);

                if (match.Groups["key"].Success)
                {
                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    formatIndex = match.Index + match.Length;
                    string key        = match.Groups["key"].Value;
                    string alignment  = match.Groups["alignment"].Value;
                    string formatting = match.Groups["format"].Value;
                    if (key.StartsWith("@"))
                    {
                        VariableFoundEventArgs args = new VariableFoundEventArgs(key.Substring(1), alignment, formatting, context.ToArray());
                        if (VariableFound != null)
                        {
                            VariableFound(this, args);
                            key        = "@" + args.Name;
                            alignment  = args.Alignment;
                            formatting = args.Formatting;
                        }
                    }
                    else
                    {
                        PlaceholderFoundEventArgs args = new PlaceholderFoundEventArgs(key, alignment, formatting, context.ToArray());
                        if (PlaceholderFound != null)
                        {
                            PlaceholderFound(this, args);
                            key        = args.Key;
                            alignment  = args.Alignment;
                            formatting = args.Formatting;
                        }
                    }
                    KeyGenerator keyGenerator = new KeyGenerator(key, alignment, formatting);
                    generator.AddGenerator(keyGenerator);
                }
                else if (match.Groups["open"].Success)
                {
                    formatIndex = match.Index + match.Length;
                    string        tagName        = match.Groups["name"].Value;
                    TagDefinition nextDefinition = _tagLookup[tagName];
                    if (nextDefinition == null)
                    {
                        string message = String.Format("Encountered an unknown tag: {0}. It was either not registered or exists in a different context.", tagName);
                        throw new FormatException(message);
                    }

                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    ArgumentCollection arguments = getArguments(nextDefinition, match, context);

                    if (nextDefinition.HasContent)
                    {
                        CompoundGenerator          compoundGenerator = new CompoundGenerator(nextDefinition, arguments);
                        IEnumerable <TagParameter> contextParameters = nextDefinition.GetChildContextParameters();
                        bool hasContext = contextParameters.Any();
                        if (hasContext)
                        {
                            ContextParameter[] parameters = contextParameters.Select(p => new ContextParameter(p.Name, arguments.GetKey(p))).ToArray();
                            context.Add(new Context(nextDefinition.Name, parameters));
                        }
                        formatIndex = buildCompoundGenerator(nextDefinition, context, compoundGenerator, format, formatIndex);
                        generator.AddGenerator(nextDefinition, compoundGenerator);
                        if (hasContext)
                        {
                            context.RemoveAt(context.Count - 1);
                        }
                    }
                    else
                    {
                        InlineGenerator inlineGenerator = new InlineGenerator(nextDefinition, arguments);
                        generator.AddGenerator(inlineGenerator);
                    }
                }
                else if (match.Groups["close"].Success)
                {
                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    string        tagName        = match.Groups["name"].Value;
                    TagDefinition nextDefinition = _tagLookup[tagName];
                    formatIndex = match.Index;
                    if (tagName == tagDefinition.Name)
                    {
                        formatIndex += match.Length;
                    }
                    break;
                }
                else if (match.Groups["comment"].Success)
                {
                    generator.AddGenerator(new StaticGenerator(leading, RemoveNewLines));
                    formatIndex = match.Index + match.Length;
                }
                else if (match.Groups["unknown"].Success)
                {
                    string tagName = match.Value;
                    string message = String.Format("Encountered an unknown tag: {0}. It was either not registered or exists in a different context.", tagName);
                    throw new FormatException(message);
                }
            }
            return(formatIndex);
        }
예제 #27
0
 /// <summary>
 /// Registers the given tag definition with the parser.
 /// </summary>
 /// <param name="definition">The tag definition to register.</param>
 /// <param name="isTopLevel">Specifies whether the tag is immediately in scope.</param>
 public void RegisterTag(TagDefinition definition, bool isTopLevel)
 {
     compiler.RegisterTag(definition, isTopLevel);
 }
예제 #28
0
        private ArgumentCollection getArguments(TagDefinition definition, Match match, List <Context> context)
        {
            // make sure we don't have too many arguments
            List <Capture>      captures   = match.Groups["argument"].Captures.Cast <Capture>().ToList();
            List <TagParameter> parameters = definition.Parameters.ToList();

            if (captures.Count > parameters.Count)
            {
                string message = String.Format("The wrong number of arguments were passed to an {0} tag.", definition.Name);
                throw new FormatException(message);
            }

            // provide default values for missing arguments
            if (captures.Count < parameters.Count)
            {
                captures.AddRange(Enumerable.Repeat((Capture)null, parameters.Count - captures.Count));
            }

            // pair up the parameters to the given arguments
            // provide default for parameters with missing arguments
            // throw an error if a missing argument is for a required parameter
            Dictionary <TagParameter, string> arguments = new Dictionary <TagParameter, string>();

            foreach (var pair in parameters.Zip(captures, (p, c) => new { Capture = c, Parameter = p }))
            {
                string value = null;
                if (pair.Capture != null)
                {
                    value = pair.Capture.Value;
                }
                else if (pair.Parameter.IsRequired)
                {
                    string message = String.Format("The wrong number of arguments were passed to an {0} tag.", definition.Name);
                    throw new FormatException(message);
                }
                arguments.Add(pair.Parameter, value);
            }

            // indicate that a key/variable has been encountered
            // update the key/variable name
            ArgumentCollection collection = new ArgumentCollection();

            foreach (var pair in arguments)
            {
                string    placeholder = pair.Value;
                IArgument argument    = null;
                if (placeholder != null)
                {
                    if (placeholder.StartsWith("@"))
                    {
                        string variableName         = placeholder.Substring(1);
                        VariableFoundEventArgs args = new VariableFoundEventArgs(placeholder.Substring(1), String.Empty, String.Empty, context.ToArray());
                        if (VariableFound != null)
                        {
                            VariableFound(this, args);
                            variableName = args.Name;
                        }
                        argument = new VariableArgument(variableName);
                    }
                    else if (RegexHelper.IsString(placeholder))
                    {
                        string value = placeholder.Trim('\'');
                        argument = new StringArgument(value);
                    }
                    else if (RegexHelper.IsNumber(placeholder))
                    {
                        decimal number;
                        if (Decimal.TryParse(placeholder, out number))
                        {
                            argument = new NumberArgument(number);
                        }
                    }
                    else
                    {
                        string placeholderName         = placeholder;
                        PlaceholderFoundEventArgs args = new PlaceholderFoundEventArgs(placeholder, String.Empty, String.Empty, context.ToArray());
                        if (PlaceholderFound != null)
                        {
                            PlaceholderFound(this, args);
                            placeholderName = args.Key;
                        }
                        argument = new PlaceholderArgument(placeholderName);
                    }
                }
                collection.AddArgument(pair.Key, argument);
            }
            return(collection);
        }
예제 #29
0
        /// <summary>
        /// Adds the given generator, determining whether the generator should
        /// be part of the primary generators or added as an secondary generator.
        /// </summary>
        /// <param name="definition">The tag that the generator is generating text for.</param>
        /// <param name="generator">The generator to add.</param>
        public void AddGenerator(TagDefinition definition, IGenerator generator)
        {
            bool isSubGenerator = _definition.ShouldCreateSecondaryGroup(definition);

            addGenerator(generator, isSubGenerator);
        }
예제 #30
0
 /// <summary>
 /// Registers the given tag definition with the parser.
 /// </summary>
 /// <param name="definition">The tag definition to register.</param>
 /// <param name="isTopLevel">Specifies whether the tag is immediately in scope.</param>
 public void RegisterTag(TagDefinition definition, bool isTopLevel)
 {
     compiler.RegisterTag(definition, isTopLevel);
 }