using System; using System.Collections.Generic; using System.Globalization; using System.IO; namespace Mustache { /// /// Generates text by substituting an object's values for placeholders. /// public sealed class Generator { private readonly IGenerator _generator; private readonly List> _foundHandlers = new List>(); private readonly List> _notFoundHandlers = new List>(); private readonly List> _valueRequestedHandlers = new List>(); /// /// Initializes a new instance of a Generator. /// /// The text generator to wrap. internal Generator(IGenerator generator) { _generator = generator; } /// /// Occurs when a key/property is found. /// public event EventHandler KeyFound { add { _foundHandlers.Add(value); } remove { _foundHandlers.Remove(value); } } /// /// Occurs when a key/property is not found in the object graph. /// public event EventHandler KeyNotFound { add { _notFoundHandlers.Add(value); } remove { _notFoundHandlers.Remove(value); } } /// /// Occurs when a setter is encountered and requires a value to be provided. /// public event EventHandler ValueRequested { add { _valueRequestedHandlers.Add(value); } remove { _valueRequestedHandlers.Remove(value); } } /// /// Occurs when a tag is replaced by its text. /// public event EventHandler TagFormatted; /// /// Gets the text that is generated for the given object. /// /// The object to generate the text with. /// The text generated for the given object. public string Render(object source) { return render(CultureInfo.CurrentCulture, source); } /// /// Gets the text that is generated for the given object. /// /// The format provider to use. /// The object to generate the text with. /// The text generated for the given object. public string Render(IFormatProvider provider, object source) { if (provider == null) { provider = CultureInfo.CurrentCulture; } return render(provider, source); } private string render(IFormatProvider provider, object source) { Scope keyScope = new Scope(source); Scope contextScope = new Scope(new Dictionary()); foreach (EventHandler handler in _foundHandlers) { keyScope.KeyFound += handler; contextScope.KeyFound += handler; } foreach (EventHandler handler in _notFoundHandlers) { keyScope.KeyNotFound += handler; contextScope.KeyNotFound += handler; } foreach (EventHandler handler in _valueRequestedHandlers) { contextScope.ValueRequested += handler; } StringWriter writer = new StringWriter(provider); _generator.GetText(writer, keyScope, contextScope, postProcess); return writer.ToString(); } private void postProcess(Substitution substitution) { if (TagFormatted == null) { return; } TagFormattedEventArgs args = new TagFormattedEventArgs(substitution.Key, substitution.Substitute, substitution.IsExtension); TagFormatted(this, args); substitution.Substitute = args.Substitute; } } }