using System; using System.Collections.Generic; using System.IO; namespace Mustache { /// /// Builds text by combining the output of other generators. /// internal sealed class CompoundGenerator : IGenerator { private readonly TagDefinition _definition; private readonly ArgumentCollection _arguments; private readonly LinkedList _primaryGenerators; private IGenerator _subGenerator; /// /// Initializes a new instance of a CompoundGenerator. /// /// The tag that the text is being generated for. /// The arguments that were passed to the tag. public CompoundGenerator(TagDefinition definition, ArgumentCollection arguments) { _definition = definition; _arguments = arguments; _primaryGenerators = new LinkedList(); } /// /// Adds the given generator. /// /// The generator to add. public void AddGenerator(IGenerator generator) { addGenerator(generator, false); } /// /// Adds the given generator, determining whether the generator should /// be part of the primary generators or added as an secondary generator. /// /// The tag that the generator is generating text for. /// The generator to add. public void AddGenerator(TagDefinition definition, IGenerator generator) { bool isSubGenerator = _definition.ShouldCreateSecondaryGroup(definition); addGenerator(generator, isSubGenerator); } /// /// Creates a StaticGenerator from the given value and adds it. /// /// The static generators to add. public void AddStaticGenerators(IEnumerable generators) { foreach (StaticGenerator generator in generators) { LinkedListNode node = _primaryGenerators.AddLast(generator); generator.Node = node; } } private void addGenerator(IGenerator generator, bool isSubGenerator) { if (isSubGenerator) { _subGenerator = generator; } else { _primaryGenerators.AddLast(generator); } } void IGenerator.GetText(KeyScope scope, TextWriter writer, object contextData) { Dictionary arguments = _arguments.GetArguments(scope); IEnumerable contexts = _definition.GetChildContext(writer, scope, arguments); LinkedList generators; if (_definition.ShouldGeneratePrimaryGroup(arguments)) { generators = _primaryGenerators; } else { generators = new LinkedList(); if (_subGenerator != null) { generators.AddLast(_subGenerator); } } foreach (NestedContext context in contexts) { foreach (IGenerator generator in generators) { generator.GetText(context.KeyScope ?? scope, context.Writer ?? writer, context.Data); if (context.WriterNeedsConsidated) { writer.Write(_definition.ConsolidateWriter(context.Writer ?? writer, arguments)); } } } } } }