templates support

This commit is contained in:
EugeneTes
2026-01-21 15:56:37 +01:00
parent 729679d283
commit 9fbc61dede
60 changed files with 5678 additions and 14 deletions

View File

@@ -0,0 +1,14 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public record BindingNode(string Path, string? Format, SourcePosition Position) : ITemplateNode
{
public IReadOnlyList<ITemplateNode> Children => Array.Empty<ITemplateNode>();
public static BindingNode Parse(string value, SourcePosition position)
{
var parts = value.Split(':', 2);
var path = parts[0].Trim();
var format = parts.Length > 1 ? parts[1].Trim() : null;
return new BindingNode(path, format, position);
}
}

View File

@@ -0,0 +1,27 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public enum ColumnAlignment
{
Left,
Right,
Center
}
public record ColumnNode(
int Width,
ColumnAlignment Alignment,
List<ITemplateNode> ContentNodes,
SourcePosition Position) : ITemplateNode
{
public IReadOnlyList<ITemplateNode> Children => ContentNodes;
public static (int Width, ColumnAlignment Alignment) ParseColumnSpec(string value)
{
var parts = value.Split(',', 2);
var width = int.Parse(parts[0]);
var align = parts.Length > 1
? Enum.TryParse<ColumnAlignment>(parts[1], true, out var a) ? a : ColumnAlignment.Left
: ColumnAlignment.Left;
return (width, align);
}
}

View File

@@ -0,0 +1,6 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public record EmptyLineNode(SourcePosition Position) : ITemplateNode
{
public IReadOnlyList<ITemplateNode> Children => Array.Empty<ITemplateNode>();
}

View File

@@ -0,0 +1,21 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public record ForeachNode(
string ItemVariable,
string CollectionPath,
List<ITemplateNode> Body,
SourcePosition Position) : ITemplateNode
{
public IReadOnlyList<ITemplateNode> Children => Body;
public static (string ItemVariable, string CollectionPath) ParseForeach(string value)
{
// Expected format: "item in collection" or "item in collection.path"
var parts = value.Split(" in ", 2, StringSplitOptions.TrimEntries);
if (parts.Length != 2)
{
throw new FormatException($"Invalid foreach syntax: '{value}'. Expected 'item in collection'.");
}
return (parts[0], parts[1]);
}
}

View File

@@ -0,0 +1,7 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public interface ITemplateNode
{
SourcePosition Position { get; }
IReadOnlyList<ITemplateNode> Children { get; }
}

View File

@@ -0,0 +1,31 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public record ConditionBranch(
string Condition,
List<ITemplateNode> Body,
SourcePosition Position);
public record IfNode(
ConditionBranch IfBranch,
IReadOnlyList<ConditionBranch> ElseIfBranches,
List<ITemplateNode>? ElseBranch,
SourcePosition Position) : ITemplateNode
{
public IReadOnlyList<ITemplateNode> Children
{
get
{
var children = new List<ITemplateNode>();
children.AddRange(IfBranch.Body);
foreach (var branch in ElseIfBranches)
{
children.AddRange(branch.Body);
}
if (ElseBranch != null)
{
children.AddRange(ElseBranch);
}
return children;
}
}
}

View File

@@ -0,0 +1,6 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public record RowNode(List<ColumnNode> Columns, SourcePosition Position) : ITemplateNode
{
public IReadOnlyList<ITemplateNode> Children => Columns;
}

View File

@@ -0,0 +1,14 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public enum SeparatorStyle
{
Dash, // ---
Equals, // ===
Star, // ***
Tilde // ~~~
}
public record SeparatorNode(SeparatorStyle Style, SourcePosition Position) : ITemplateNode
{
public IReadOnlyList<ITemplateNode> Children => Array.Empty<ITemplateNode>();
}

View File

@@ -0,0 +1,9 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public record StyledTextNode(
IReadOnlyList<string> Styles,
List<ITemplateNode> ContentNodes,
SourcePosition Position) : ITemplateNode
{
public IReadOnlyList<ITemplateNode> Children => ContentNodes;
}

View File

@@ -0,0 +1,7 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public record TemplateNode(List<ITemplateNode> ChildNodes) : ITemplateNode
{
public SourcePosition Position => new(1, 1);
public IReadOnlyList<ITemplateNode> Children => ChildNodes;
}

View File

@@ -0,0 +1,6 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
public record TextNode(string Text, SourcePosition Position) : ITemplateNode
{
public IReadOnlyList<ITemplateNode> Children => Array.Empty<ITemplateNode>();
}