HTML Templates with Javascript Support pre-alpha

master
Harald Wolff 2020-02-29 00:13:16 +01:00
parent 35bd3dc356
commit ac19c349e5
16 changed files with 943 additions and 0 deletions

View File

@ -117,6 +117,7 @@ namespace ln.templates
Template = template;
ExpressionContext = new Expression.Context(null, null);
ExpressionContext.AddMappedValue("__template__", template.SourceFilename);
ExpressionContext.AddMappedValue("__provider__", template.Provider);
}
public Context(Context parent,String framedContent)
{

View File

@ -0,0 +1,31 @@
// /**
// * File: DocumentElement.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.IO;
namespace ln.templates.html
{
public class DocumentElement : Element
{
public DocumentElement()
:base("#document")
{
}
public override void Render(TextWriter writer)
{
writer.Write("<!DOCTYPE html>");
foreach (Element element in Children)
element.Render(writer);
}
}
}

93
html/Element.cs 100644
View File

@ -0,0 +1,93 @@
// /**
// * File: Element.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace ln.templates.html
{
public class Element
{
public string Name { get; }
public Element Parent { get; private set; }
public bool IsVoid => IsVoidElement(Name);
List<Element> children = new List<Element>();
Dictionary<string, string> attributes = new Dictionary<string, string>();
public IEnumerable<KeyValuePair<string, string>> Attributes => attributes;
public Element(string elementName)
{
Name = elementName;
}
public Element(string elementName,IEnumerable<KeyValuePair<string,string>> attributes)
:this(elementName)
{
foreach (KeyValuePair<string, string> keyValuePair in attributes)
this.attributes[keyValuePair.Key] = keyValuePair.Value;
}
public virtual bool HasAttribute(string attributeName) => attributes.ContainsKey(attributeName);
public virtual string GetAttribute(string attributeName) => attributes[attributeName];
public virtual void SetAttribute(string attributeName, string attributeValue) => attributes[attributeName] = attributeValue;
public IEnumerable<Element> Children => children;
public void AppendChild(Element element)
{
if (element.Parent != null)
element.Parent.RemoveChild(element);
children.Add(element);
element.Parent = this;
}
public void RemoveChild(Element element)
{
if (element.Parent != this)
throw new KeyNotFoundException();
children.Remove(element);
element.Parent = null;
}
public virtual void Render(TextWriter writer)
{
writer.Write("<{0}", Name);
foreach (KeyValuePair<String, String> attributePair in attributes)
writer.Write(" {0}=\"{1}\"", attributePair.Key, attributePair.Value);
writer.Write(">");
if (!IsVoid)
{
foreach (Element element in children)
element.Render(writer);
writer.Write("</{0}>",Name);
}
}
public override string ToString()
{
StringWriter stringWriter = new StringWriter();
Render(stringWriter);
return stringWriter.ToString();
}
static HashSet<string> voidElementNames = new HashSet<string>(){
"!doctype",
"area","base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"
};
public static string[] VoidElementNames => voidElementNames.ToArray();
public bool IsVoidElement(string elementName) => voidElementNames.Contains(elementName);
}
}

View File

@ -0,0 +1,69 @@
// /**
// * File: ElementReader.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Collections.Generic;
namespace ln.templates.html
{
public class ElementReader : HtmlReader
{
Stack<Element> elements = new Stack<Element>();
public Element CurrentElement => elements.Peek();
public virtual DocumentElement Document { get; }
public ElementReader()
{
Document = CreateDocument();
elements.Push(Document);
}
public virtual DocumentElement CreateDocument() => new DocumentElement();
public virtual Element CreateElement(string tagName)
{
switch (tagName.ToUpper())
{
default:
return new Element(tagName);
}
}
public virtual Element CreateTextElement(string text) => new TextElement(text);
void Push(Element element)
{
CurrentElement.AppendChild(element);
elements.Push(element);
}
void Pop()
{
elements.Pop();
}
public override void OpenTag(string tagName)
{
Push(CreateElement(tagName));
}
public override void CloseTag(string tagName)
{
Pop();
}
public override void Attribute(string attributeName, string attributeValue)
{
CurrentElement.SetAttribute(attributeName, attributeValue);
}
public override void Text(string text)
{
CurrentElement.AppendChild(
CreateTextElement(text)
);
}
}
}

View File

@ -0,0 +1,40 @@
// /**
// * File: ExpressionElement.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using ln.templates.script;
using System.IO;
namespace ln.templates.html
{
public class ExpressionElement : TemplateElement
{
public string ExpressionText { get; }
public NewExpression Expression { get; }
public ExpressionElement(string expression)
:base("#expression")
{
ExpressionText = expression;
Expression = new NewExpression(ExpressionText);
}
public override void Render(TextWriter writer)
{
writer.Write("{{{{{0}}}}}", ExpressionText);
}
public override void RenderTemplate(RenderContext renderContext)
{
object o = Expression.Resolve(renderContext);
renderContext.ContentWriter.Write(o?.ToString());
}
}
}

170
html/HtmlReader.cs 100644
View File

@ -0,0 +1,170 @@
// /**
// * File: Parser.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
namespace ln.templates.html
{
public class HtmlReader
{
public HtmlReader()
{
}
public void Read(string source) => Read(new StringReader(source));
public void Read(Stream sourceStream)
{
using (StreamReader streamReader = new StreamReader(sourceStream))
Read(streamReader);
}
public void Read(TextReader textReader)
{
while (textReader.Peek() != -1)
{
switch (textReader.Peek())
{
case '<':
ReadTag(textReader);
break;
default:
ReadText(textReader);
break;
}
}
}
public void ReadTag(TextReader textReader)
{
if (textReader.Read() != '<')
throw new FormatException("Expected <");
bool closing = false;
if (textReader.Peek()=='/')
{
textReader.Read();
closing = true;
}
if (textReader.Peek()=='!')
{
textReader.Read();
string doctype = ReadTagName(textReader);
if (!doctype.Equals("DOCTYPE"))
throw new FormatException("Expected DOCTYPE");
string type = ReadAttributeName(textReader);
DOCTYPE(type);
if (textReader.Read() != '>')
throw new FormatException("Expected >");
return;
}
string tagName = ReadTagName(textReader);
if (closing)
{
CloseTag(tagName);
}
else
{
OpenTag(tagName);
while (TestChar((char)textReader.Peek(), (ch) => !char.IsWhiteSpace(ch) && (ch != '\0') && (ch != '"') && (ch != '\'') && (ch != '>') && (ch != '/') && (ch != '=')))
{
string attributeName = ReadAttributeName(textReader);
string attributeValue = "";
if (textReader.Peek() == '=')
{
textReader.Read();
attributeValue = ReadAttributeValue(textReader);
}
Attribute(attributeName, attributeValue);
}
if (textReader.Peek()=='/')
{
textReader.Read();
CloseTag(tagName);
}
}
if (textReader.Read() != '>')
throw new FormatException("Expected >");
}
bool TestChar(char ch, Func<char, bool> condition) => condition(ch);
public string ReadToken(TextReader textReader, Func<char, bool> condition)
{
StringBuilder characters = new StringBuilder();
while (condition((char)textReader.Peek()) && textReader.Peek() != -1)
{
characters.Append((char)textReader.Read());
}
return characters.ToString();
}
public string ReadTokenLWS(TextReader textReader, Func<char, bool> condition)
{
string token = ReadToken(textReader, condition);
ReadToken(textReader, char.IsWhiteSpace);
return token;
}
void ReadLWS(TextReader textReader) => ReadToken(textReader, char.IsWhiteSpace);
public string ReadTagName(TextReader textReader) => ReadTokenLWS(textReader, (ch) => char.IsLetterOrDigit(ch));
public string ReadAttributeName(TextReader textReader) => ReadTokenLWS(textReader, (ch) => !char.IsWhiteSpace(ch) && (ch != '\0') && (ch != '"') && (ch != '\'') && (ch != '>') && (ch != '/') && (ch != '='));
public string ReadAttributeValue(TextReader textReader)
{
switch (textReader.Peek())
{
case '"':
return ReadTokenLWS(textReader, (ch) => ch != '"');
case '\'':
return ReadTokenLWS(textReader, (ch)=> ch != '\'');
default:
return ReadTokenLWS(textReader, (ch) => !char.IsWhiteSpace(ch) && (ch != '"') && (ch != '\'') && (ch != '<') && (ch != '>') && (ch != '`'));
}
}
public void ReadText(TextReader textReader)
{
StringBuilder stringBuilder = new StringBuilder();
while (textReader.Peek() != '<')
stringBuilder.Append((char)textReader.Read());
Text(stringBuilder.ToString());
}
public virtual void DOCTYPE(string type)
{
}
public virtual void OpenTag(string tagName)
{
}
public virtual void CloseTag(string tagName)
{
}
public virtual void Attribute(string attributeName,string attributeValue)
{
}
public virtual void Text(string text)
{
}
}
}

View File

@ -0,0 +1,33 @@
// /**
// * File: RenderContext.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.IO;
using System.Collections.Generic;
using ln.templates.script;
namespace ln.templates.html
{
public class RenderContext : IScriptContext
{
public TextWriter ContentWriter { get; }
Dictionary<string, object> scriptObjects = new Dictionary<string, object>();
public IEnumerable<string> ScriptObjectNames => scriptObjects.Keys;
public RenderContext(TextWriter contentWriter)
{
ContentWriter = contentWriter;
}
Dictionary<string, object> values = new Dictionary<string, object>();
public object GetScriptObject(string itemName) => scriptObjects[itemName];
public void SetScriptObject(string itemName, object value) => scriptObjects[itemName] = value;
}
}

View File

@ -0,0 +1,38 @@
// /**
// * File: TemplateDocument.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.IO;
namespace ln.templates.html
{
public class TemplateDocument : DocumentElement
{
public TemplateDocument()
{
}
public void RenderTemplate(TextWriter contentWriter) => RenderTemplate(new RenderContext(contentWriter));
public void RenderTemplate(RenderContext renderContext)
{
renderContext.ContentWriter.Write("<!DOCTYPE html>");
foreach (Element element in Children)
{
if (element is TemplateElement templateElement)
{
templateElement.RenderTemplate(renderContext);
} else
{
renderContext.ContentWriter.Write(element.ToString());
}
}
}
}
}

View File

@ -0,0 +1,67 @@
// /**
// * File: TemplateElement.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.IO;
using System.Collections.Generic;
namespace ln.templates.html
{
public class TemplateElement : Element
{
Dictionary<string, Expression> expressions = new Dictionary<string, Expression>();
Dictionary<string, Expression> loops = new Dictionary<string, Expression>();
List<Expression> conditions = new List<Expression>();
public TemplateElement(string tagName)
:base(tagName)
{
}
public override void SetAttribute(string attributeName, string attributeValue)
{
if (attributeName.StartsWith("v-for:",StringComparison.InvariantCultureIgnoreCase))
loops.Add(attributeName.Substring(6), new Expression(attributeValue));
else if (attributeName.Equals("v-if",StringComparison.InvariantCultureIgnoreCase))
conditions.Add(new Expression(attributeValue));
else if (attributeName[0] == ':')
expressions.Add(attributeName.Substring(1), new Expression(attributeValue));
else
base.SetAttribute(attributeName, attributeValue);
}
public virtual void RenderTemplate(RenderContext renderContext)
{
renderContext.ContentWriter.Write("<{0}", Name);
foreach (KeyValuePair<String, String> attributePair in Attributes)
renderContext.ContentWriter.Write(" {0}=\"{1}\"", attributePair.Key, attributePair.Value);
renderContext.ContentWriter.Write(">");
if (!IsVoid)
{
foreach (Element element in Children)
{
if (element is TemplateElement templateElement)
{
templateElement.RenderTemplate(renderContext);
}
else
{
renderContext.ContentWriter.Write(element.ToString());
}
}
renderContext.ContentWriter.Write("</{0}>", Name);
}
}
}
}

View File

@ -0,0 +1,70 @@
// /**
// * File: TemplateReader.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.IO;
namespace ln.templates.html
{
public class TemplateReader : ElementReader
{
public virtual TemplateDocument TemplateDocument => Document as TemplateDocument;
public TemplateReader()
{
}
public override DocumentElement CreateDocument() => new TemplateDocument();
public override Element CreateElement(string tagName) => new TemplateElement(tagName);
public override void Text(string text)
{
if (text.Contains("{{"))
{
int pOpen = 0;
int pClose = 0;
while (pOpen < text.Length)
{
pOpen = text.IndexOf("{{", pClose);
if (pOpen == -1)
pOpen = text.Length;
string preText = text.Substring(pClose, pOpen - pClose);
if (preText.Length > 0)
{
CurrentElement.AppendChild(CreateTextElement(preText));
}
if (pOpen == text.Length)
break;
pOpen += 2;
pClose = text.IndexOf("}}", pOpen);
if (pClose == -1)
throw new FormatException("missing }}");
string expr = text.Substring(pOpen, pClose - pOpen - 1);
pClose += 2;
CurrentElement.AppendChild(new ExpressionElement(expr));
}
} else
{
CurrentElement.AppendChild(
CreateTextElement(text)
);
}
}
}
}

View File

@ -0,0 +1,30 @@
// /**
// * File: TextElement.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.IO;
namespace ln.templates.html
{
public class TextElement : Element
{
public string Text { get; }
public TextElement(string text)
:base("#text")
{
Text = text;
}
public override void Render(TextWriter writer)
{
writer.Write(Text);
}
}
}

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.ChakraCore.1.11.16\build\netstandard1.0\Microsoft.ChakraCore.props" Condition="Exists('..\packages\Microsoft.ChakraCore.1.11.16\build\netstandard1.0\Microsoft.ChakraCore.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@ -29,6 +30,112 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Runtime.CompilerServices.Unsafe">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Text.Encoding.CodePages">
<HintPath>..\packages\System.Text.Encoding.CodePages.4.5.1\lib\net461\System.Text.Encoding.CodePages.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<Package>nunit</Package>
</Reference>
<Reference Include="System.Buffers">
<HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Collections.Immutable">
<HintPath>..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.Numerics.Vectors">
<HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="mscorlib" />
<Reference Include="System.Numerics" />
<Reference Include="System.Reflection.Metadata">
<HintPath>..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll</HintPath>
</Reference>
<Reference Include="System.Memory">
<HintPath>..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.3\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
<Reference Include="System.Console">
<HintPath>..\packages\System.Console.4.3.0\lib\net46\System.Console.dll</HintPath>
</Reference>
<Reference Include="System.Diagnostics.FileVersionInfo">
<HintPath>..\packages\System.Diagnostics.FileVersionInfo.4.3.0\lib\net46\System.Diagnostics.FileVersionInfo.dll</HintPath>
</Reference>
<Reference Include="System.Diagnostics.StackTrace">
<HintPath>..\packages\System.Diagnostics.StackTrace.4.3.0\lib\net46\System.Diagnostics.StackTrace.dll</HintPath>
</Reference>
<Reference Include="System.IO">
<HintPath>..\packages\System.IO.4.3.0\lib\net462\System.IO.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression">
<HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem.Primitives">
<HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem">
<HintPath>..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll</HintPath>
</Reference>
<Reference Include="System.Linq">
<HintPath>..\packages\System.Linq.4.3.0\lib\net463\System.Linq.dll</HintPath>
</Reference>
<Reference Include="System.Linq.Expressions">
<HintPath>..\packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll</HintPath>
</Reference>
<Reference Include="System.Reflection">
<HintPath>..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll</HintPath>
</Reference>
<Reference Include="System.Runtime">
<HintPath>..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Runtime.Extensions">
<HintPath>..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.InteropServices">
<HintPath>..\packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding">
<HintPath>..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives">
<HintPath>..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Algorithms">
<HintPath>..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates">
<HintPath>..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
</Reference>
<Reference Include="System.Threading.Thread">
<HintPath>..\packages\System.Threading.Thread.4.3.0\lib\net46\System.Threading.Thread.dll</HintPath>
</Reference>
<Reference Include="System.ValueTuple">
<HintPath>..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Xml.ReaderWriter">
<HintPath>..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml.XmlDocument">
<HintPath>..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll</HintPath>
</Reference>
<Reference Include="System.Xml.XPath">
<HintPath>..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll</HintPath>
</Reference>
<Reference Include="System.Xml.XPath.XDocument">
<HintPath>..\packages\System.Xml.XPath.XDocument.4.3.0\lib\net46\System.Xml.XPath.XDocument.dll</HintPath>
</Reference>
<Reference Include="Jint">
<HintPath>..\packages\Jint.2.11.58\lib\net451\Jint.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
@ -43,9 +150,34 @@
<Compile Include="elements\Element.cs" />
<Compile Include="elements\IncludeElement.cs" />
<Compile Include="elements\Conditionals.cs" />
<Compile Include="html\Element.cs" />
<Compile Include="html\TextElement.cs" />
<Compile Include="html\ExpressionElement.cs" />
<Compile Include="html\HtmlReader.cs" />
<Compile Include="test\HtmlTests.cs" />
<Compile Include="html\ElementReader.cs" />
<Compile Include="html\DocumentElement.cs" />
<Compile Include="html\TemplateElement.cs" />
<Compile Include="html\TemplateReader.cs" />
<Compile Include="html\RenderContext.cs" />
<Compile Include="script\IScriptContext.cs" />
<Compile Include="html\TemplateDocument.cs" />
<Compile Include="script\NewExpression.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="elements\" />
<Folder Include="html\" />
<Folder Include="test\" />
<Folder Include="script\" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\ln.types\ln.types.csproj">
<Project>{8D9AB9A5-E513-4BA7-A450-534F6456BF28}</Project>
<Name>ln.types</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

51
packages.config 100644
View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Jint" version="2.11.58" targetFramework="net47" />
<package id="Microsoft.ChakraCore" version="1.11.16" targetFramework="net47" developmentDependency="true" />
<package id="System.Buffers" version="4.4.0" targetFramework="net47" />
<package id="System.Collections" version="4.3.0" targetFramework="net47" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net47" />
<package id="System.Collections.Immutable" version="1.5.0" targetFramework="net47" />
<package id="System.Console" version="4.3.0" targetFramework="net47" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net47" />
<package id="System.Diagnostics.FileVersionInfo" version="4.3.0" targetFramework="net47" />
<package id="System.Diagnostics.StackTrace" version="4.3.0" targetFramework="net47" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net47" />
<package id="System.Dynamic.Runtime" version="4.3.0" targetFramework="net47" />
<package id="System.Globalization" version="4.3.0" targetFramework="net47" />
<package id="System.IO" version="4.3.0" targetFramework="net47" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net47" />
<package id="System.IO.FileSystem" version="4.3.0" targetFramework="net47" />
<package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net47" />
<package id="System.Linq" version="4.3.0" targetFramework="net47" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net47" />
<package id="System.Memory" version="4.5.3" targetFramework="net47" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net47" />
<package id="System.Reflection" version="4.3.0" targetFramework="net47" />
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net47" />
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net47" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net47" />
<package id="System.Runtime" version="4.3.0" targetFramework="net47" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.2" targetFramework="net47" />
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net47" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net47" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net47" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net47" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net47" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net47" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net47" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net47" />
<package id="System.Text.Encoding.CodePages" version="4.5.1" targetFramework="net47" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net47" />
<package id="System.Threading" version="4.3.0" targetFramework="net47" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net47" />
<package id="System.Threading.Tasks.Extensions" version="4.5.3" targetFramework="net47" />
<package id="System.Threading.Tasks.Parallel" version="4.3.0" targetFramework="net47" />
<package id="System.Threading.Thread" version="4.3.0" targetFramework="net47" />
<package id="System.ValueTuple" version="4.3.0" targetFramework="net47" />
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net47" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net47" />
<package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="net47" />
<package id="System.Xml.XPath" version="4.3.0" targetFramework="net47" />
<package id="System.Xml.XPath.XDocument" version="4.3.0" targetFramework="net47" />
</packages>

View File

@ -0,0 +1,20 @@
// /**
// * File: IScriptContext.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Collections.Generic;
namespace ln.templates.script
{
public interface IScriptContext
{
IEnumerable<string> ScriptObjectNames { get; }
object GetScriptObject(string itemName);
void SetScriptObject(string itemName, object value);
}
}

View File

@ -0,0 +1,61 @@
// /**
// * File: NewExpression.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using Jint;
using Jint.Native.String;
namespace ln.templates.script
{
public class NewExpression
{
public string ExpressionText { get; }
public NewExpression(string expression)
{
ExpressionText = expression;
}
public virtual object Resolve(IScriptContext scriptContext)
{
Engine engine = new Engine();
foreach (string itemName in scriptContext.ScriptObjectNames)
engine.SetValue(itemName, scriptContext.GetScriptObject(itemName));
return engine.Eval.Call(null, new Jint.Native.JsValue[] { ExpressionText });
}
public virtual bool IsTrue(IScriptContext scriptContext)
{
object resolved = Resolve(scriptContext);
if (resolved == null)
return false;
if (resolved is bool b)
return b;
if (resolved is string s)
return s.Length > 0;
if (resolved is int i)
return i != 0;
if (resolved is long l)
return l != 0;
if (resolved is short sh)
return sh != 0;
if (resolved is byte by)
return by != 0;
if (resolved is float f)
return Math.Abs(f) > float.Epsilon;
if (resolved is double d)
return Math.Abs(d) > double.Epsilon;
return true;
}
}
}

37
test/HtmlTests.cs 100644
View File

@ -0,0 +1,37 @@
// /**
// * File: HtmlTests.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using NUnit.Framework;
using System;
using ln.templates.html;
using System.IO;
namespace ln.templates.test
{
[TestFixture()]
public class HtmlTests
{
[Test()]
public void TestCase()
{
ln.templates.html.TemplateReader templateReader = new ln.templates.html.TemplateReader();
templateReader.Read("<!DOCTYPE HTML>\n<html>\n<head>\n <title>Hello</title>\n</head>\n<body>\n <p>Welcome to this example.</p>\n <p>{{ 'Ich bin ein ScriptText!' }}</p>\n <p>DateTime: {{ Date }}</p>\n <p>Ein bisschen JavaScript: {{ 5 + ' mal ' + 5 + ' = ' + (5*5) }}</p>\n</body>\n</html>");
Console.WriteLine("Source rendered:\n{0}", templateReader.Document.ToString());
StringWriter stringWriter = new StringWriter();
RenderContext renderContext = new RenderContext(stringWriter);
renderContext.SetScriptObject("Date", DateTime.Now);
templateReader.TemplateDocument.RenderTemplate(renderContext);
Console.WriteLine("Template rendered:\n{0}", stringWriter.ToString());
}
}
}