ln.templates/Template.cs

135 lines
4.3 KiB
C#

using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using ln.templates.streams;
using ln.templates.elements;
namespace ln.templates
{
public class Template
{
public TemplateProvider Provider { get; private set; }
public String SourceFilename { get; private set; }
public String PseudoFilename { get; private set; }
public DateTime SourceTimeStamp { get; private set; }
public Element RootElement { get; private set; }
public Expression FrameExpression { get; private set; }
public Template(String sourceFilename)
{
SourceFilename = sourceFilename;
PseudoFilename = sourceFilename;
LoadSource(null);
}
public Template(String sourceFilename, TemplateProvider provider)
{
Provider = provider;
SourceFilename = sourceFilename;
PseudoFilename = sourceFilename;
LoadSource(null);
}
public Template(String source,String pseudoFilename,TemplateProvider provider)
{
Provider = provider;
PseudoFilename = pseudoFilename;
LoadSource(source);
}
private void LoadSource(String source)
{
if (source == null)
{
using (FileStream fileStream = new FileStream(SourceFilename, FileMode.Open))
{
byte[] loadBuffer = new byte[fileStream.Length];
fileStream.Read(loadBuffer, 0, loadBuffer.Length);
fileStream.Close();
source = Encoding.UTF8.GetString(loadBuffer);
SourceTimeStamp = File.GetLastWriteTimeUtc(SourceFilename);
}
}
TemplateReader templateReader = new TemplateReader(source);
RootElement = templateReader.RootElement;
FrameExpression = templateReader.FrameExpression;
}
public String Generate()
{
return Generate(false);
}
public String Generate(bool unframed)
{
Context context = new Context(this);
return Generate(context);
}
public String Generate(Context context)
{
return Generate(context, false);
}
public String Generate(Context context,bool unframed)
{
if (SourceFilename != null)
{
DateTime ts = File.GetLastWriteTimeUtc(SourceFilename);
if (ts > SourceTimeStamp)
LoadSource(null);
}
StringWriter writer = new StringWriter();
RootElement.Generate(writer, context);
if (!unframed && (FrameExpression != null))
{
Template frame = context.Provider.FindTemplate(FrameExpression.Evaluate(context.ExpressionContext) as string);
if (frame == null)
{
throw new NullReferenceException(String.Format("FindTemplate() returned null for {0}",FrameExpression.Source));
}
return frame.Generate(new Context(context, writer.ToString()));
}
return writer.ToString();
}
public class Context
{
public Context Parent { get; }
public Template Template { get; }
public TemplateProvider Provider => Template.Provider;
public String FramedContent { get; }
public Expression.Context ExpressionContext { get; }
public Context(Template template)
{
Template = template;
ExpressionContext = new Expression.Context(null, null);
ExpressionContext.AddMappedValue("__template__", template.SourceFilename);
ExpressionContext.AddMappedValue("__provider__", template.Provider);
}
public Context(Context parent,String framedContent)
{
Parent = parent;
Template = parent.Template;
FramedContent = framedContent;
ExpressionContext = new Expression.Context(parent.ExpressionContext);
if (framedContent != null)
ExpressionContext.SetMappedValue("__frame__", framedContent);
}
}
}
}