/// <summary> /// Builds a text generator based on the given format. /// </summary> /// <param name="format">The format to parse.</param> /// <returns>The text generator.</returns> public Generator Compile(string format) { if (format == null) { throw new ArgumentNullException("format"); } CompoundGenerator generator = new CompoundGenerator(_masterDefinition, new ArgumentCollection()); Trimmer trimmer = new Trimmer(); int formatIndex = buildCompoundGenerator(_masterDefinition, generator, trimmer, format, 0); string trailing = format.Substring(formatIndex); generator.AddStaticGenerators(trimmer.RecordText(trailing, false, false)); trimmer.Trim(); return new Generator(generator); }
private int buildCompoundGenerator( TagDefinition tagDefinition, CompoundGenerator generator, Trimmer trimmer, 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.AddStaticGenerators(trimmer.RecordText(leading, true, true)); formatIndex = match.Index + match.Length; string key = match.Groups["key"].Value; string alignment = match.Groups["alignment"].Value; string formatting = match.Groups["format"].Value; 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); } if (nextDefinition.HasContent) { generator.AddStaticGenerators(trimmer.RecordText(leading, true, false)); ArgumentCollection arguments = getArguments(nextDefinition, match); CompoundGenerator compoundGenerator = new CompoundGenerator(nextDefinition, arguments); formatIndex = buildCompoundGenerator(nextDefinition, compoundGenerator, trimmer, format, formatIndex); generator.AddGenerator(nextDefinition, compoundGenerator); } else { generator.AddStaticGenerators(trimmer.RecordText(leading, true, true)); Match nextMatch = findNextTag(nextDefinition, format, formatIndex); ArgumentCollection arguments = getArguments(nextDefinition, nextMatch); InlineGenerator inlineGenerator = new InlineGenerator(nextDefinition, arguments); generator.AddGenerator(inlineGenerator); } } else if (match.Groups["close"].Success) { generator.AddStaticGenerators(trimmer.RecordText(leading, true, false)); 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.AddStaticGenerators(trimmer.RecordText(leading, true, false)); formatIndex = match.Index + match.Length; } else if (match.Groups["unknown"].Success) { throw new FormatException(Resources.UnknownTag); } } return formatIndex; }