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;
private readonly List> _notFoundHandlers;
private readonly List> _valueRequestedHandlers;
///
/// Initializes a new instance of a Generator.
///
/// The text generator to wrap.
internal Generator(IGenerator generator)
{
_generator = generator;
_foundHandlers = new List>();
_notFoundHandlers = new List>();
_valueRequestedHandlers = new List>();
}
///
/// 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;
}
}
}