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);
}