Tersor 2.0.0

dotnet add package Tersor --version 2.0.0
                    
NuGet\Install-Package Tersor -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tersor" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tersor" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Tersor" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tersor --version 2.0.0
                    
#r "nuget: Tersor, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tersor@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tersor&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Tersor&version=2.0.0
                    
Install as a Cake Tool

Tersor

A Runtime Templating and Expression Language

Tersor is a domain-specific string transformation compiler, designed for advanced runtime templating and expression evaluation.

More formally, it is:

A runtime-compilable, token-aware expression engine and template compiler that binds to runtime data sources, allowing deeply nested property and method resolution.


Table of Contents


Quickstart


using System;

class Person { public string Name { get; set; } }

class Program
{
    static void Main()
    {
        // Compiler instance
        ITerserCompiler compiler = new MyTerserCompiler();

        // Runtime runner
        IRunTersor runner = new TersorRunner();
        runner.SetCompiler(compiler);

        // Lorraine mappings enable object-based resource loading
        runner.SetLorraineMappings(new[] { new TersorLorraineMapping { LorraineId = 0, QualifiedName = nameof(Person) } });

        // Load a data object
        var myData = new Person { Name = "Alice" };
        runner.LoadResource(myData);

        // Run a template
        string output = runner.Run(0, "/"Hello/" Name!");
        Console.WriteLine(output); // Output: "Hello Alice!"

        // Unload resource
        runner.UnloadResource(myData);
    }
}

Key Points:

  • SetLorraineMappings() allows LoadResource(object) and UnloadResource(object) without needing indices.
  • Run(objectIndex, template) executes the template using the mapped resources.

Overview

Tersor combines compile-time parsing with runtime execution:

  • Compiler (ITerserCompiler): parses, compiles, transforms templates.
  • Runner (IRunTersor): executes compiled templates, resolves resources.
  • Lorraine Mappings: maps object types to resource indices for convenient object-based access.

Language Syntax

Constants

String Literals

The following characters are treated as string literals:

& % - , * $ ~ @
  • Use double quotes to define string literals: "example"

Supported Types

int, double, float, time, date, datetime, string
  • Convert to identifier with ~ prefix: ~int

Methods

Legend
  • 🚧 = In Development (may be unstable or incomplete)

General Syntax:

method(obj, memberA, memberB, type):memberPath
  • method: Name of the method.
  • obj, memberA, memberB, type: Input parameters.
  • :memberPath: Optional accessor path into the returned object.
  • Categories: Logical, Conditional, Aggregate, Chaining

Note: Methods marked as In Development exist in the state diagram but may not be fully implemented. Their signatures may change.


Logical Methods

  • 🚧latest(array, startDate, endDate, referenceMember):otherMember Returns the most recent object in the array within a date range using referenceMember.

  • relevant(comparator, array, (DateTime) floor, (DateTime) ceiling) Returns the index of the object found between the given floor and ceiling DateTime properties. If multiple are found then the last found element's index is returned.

  • 🚧find(array, memberA, target) Searches an array for the first object where memberA matches target.

  • enumerate(memberA, start | [int1, int2, ..., intN], char1, ..., charN) Maps a sequence to specified values (non-linear enumerations supported).


Conditional Methods

  • 🚧lesser(object, memberA, memberB, type) Returns the lesser of memberA and memberB, typecasted to type.

  • 🚧greater(object, memberA, memberB) Returns the greater of memberA and memberB.

  • equal(memberA, memberB, [trueResult], [falseResult])

    • 2 args: Returns True or False.
    • 3 args: Returns trueResult if equal; else false.
    • 4 args: Returns trueResult or falseResult accordingly.
  • bool(bool | object, trueMember, falseMember, [falseResult])

    • If first param is boolean: returns trueMember or falseMember
    • If first param is object: compares values and returns trueMember if equal, else falseResult
  • exists(object, memberA, memberB) Returns memberA if object is not null; else returns memberB


Aggregate Methods

  • 🚧all(array, memberA) Returns a concatenated string of all memberA values from the array.

Chaining Methods

  • concatenate(memberA, memberB, ..., memberN) Converts inputs to strings and returns a space-separated string. Returns null if any input is null.

Typecasting

[[type]]

Supported typecasts: time, date, datetime, string, int, double, float


Placeholders

method(...):memberPath:-PlaceholderName

Example:

relevant(dateMember, myArray[], startDate, endDate):status:-Status
"Status": {{Status}}[[string]]

Source Targeting

Access properties from multiple data sources using %:

propertyFromPrimary propertyFromSecondary%2%

Array Indexes

  • Keywords like last or [0,1,2,...] can be used to access array indexes.

Grammar Features

  • Genitive Case (In Development): appending 's automatically formats genitive forms (e.g., child's or parents').

Syntax Limitations

  • Identifiers cannot include numbers.   Example: StringProperty1 is parsed as StringProperty + 1 (constant), not as a single identifier.

Runtime API

Interface:

public interface IRunTersor
{
    void SetCompiler(ITerserCompiler compiler);

    string Run(int objectOrigin, string code);

    void LoadResource(int index, object obj);

    void LoadResource(object obj);

    void UnloadResource(int index);

    void UnloadResource(object obj);

    void SetLorraineMappings(TersorLorraineMapping[] mappings);
}

Notes:

  • SetLorraineMappings() allows object-based Load/Unload without knowing indices.
  • TersorRunner is the default implementation of IRunTersor.

License

MIT License

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 486 8/26/2025
0.5.0 911 8/15/2025
0.5.0-alpha1 200 8/14/2025

ReleaseNotes.md