Skip to content

A C# port of Kate Compton's Tracery text expansion library targeting .NET Standard

License

Notifications You must be signed in to change notification settings

ishanpranav/tracery-core

Repository files navigation

Tracery.Core

This is a rough port of Tracery by Kate Compton. The port is by Ishan Pranav and was heavily based on Tracery.Net by Josh Parry. Both projects are available under the Apache license 2.0.

Tracery.Core targets .NET Standard, so it can be used with .NET 5+, .NET Core, .NET Framework, Mono, Unity, Xamarin, and other compatible environments.

Motivation

I re-implemented Josh Parry's Tracery.Net to solve the following issues:

  • Tracery.Net targets the .NET Framework 4.x and is not suitable for cross-platform development.
  • It does not allow the Random number generator to be seeded. My project relied on determinism, so the ability to supply custom content selectors was essential.
  • I was already using the new System.Text.Json APIs and wanted to avoid unnecessary dependencies on Newtonsoft.Json and YamlDotNet.

Comparison

Feature Tracery.Core Tracery.Net
Target Framework .NET Standard 1.3+ .NET Framework 4.5.2
Dependencies None Newtonsoft.Json, YamlDotNet
Preferred serializer System.Text.Json Newtonsoft.Json
Built-in modifiers 4/8 8/8
Variables Yes Yes
Custom modifiers Yes Yes
Custom selectors Yes No
Deterministic Configurable No
Case-insensitive Configurable No

Modifiers

Tracery.Core uses Humanizer for its modifiers, making them more accurate and robust than those in Kate Compton's original Tracery specification.

Description Tracery.Core Tracery / Tracery.Net
Convert to title case capitalizeAll, title capitalizeAll
Convert to sentence case capitalize, sentence capitalize
Surround with quotation marks N/A inQuotes
Add succeeding comma N/A comma
Convert to "bee speak" N/A beeSpeak
Add preceding article N/A a
Convert noun to plural s, plural s
Convert verb to past tense N/A ed

Usage

The Grammar class implements IDictionary<string, IReadOnlyList<string>>, so both Newtonsoft.Json and System.Text.Json have built-in support:

await using (FileStream utf8Json = File.OpenRead("grammar.json"))
{
    Grammar grammar = await System.Text.Json.JsonSerializer.DeserializeAsync<Grammar>(utf8Json);
}

You can also initialize a grammar using either one of the two C# dictionary initializer syntaxes. For example:

Grammar grammar = new()
{
    ["name"] = new[] { "Arjun", "Yuuma", "Darcy", "Mia", "Chiaki", "Izzi", "Azra", "Lina" },
    ["animal"] = new[] { "unicorn", "raven", "sparrow", "scorpion", "coyote", "eagle", "owl", "lizard", "zebra", "duck", "kitten" },
    ["mood"] = new[] { "vexed", "indignant", "impassioned", "wistful", "astute", "courteous" },
    ["story"] = new[] { "#hero# traveled with her pet #heroPet#.  #hero# was never #mood#, for the #heroPet# was always too #mood#." },
    ["origin"] = new[] { "#[hero:#name#][heroPet:#animal#]story#" }
};

Optionally register modifiers:

grammar.AddTracery(); // Register built-in modifiers (requires Tracery.Humanizer.dll)
grammar.Modifiers.Add("pirateSpeak", x => x.Replace("r", "rrr")); // Register a custom modifier

Finally, use a content selector to generate a string:

Random random = Random.Shared;
IContentSelector contentSelector = new RandomContentSelector(random);

string result = grammar.Flatten("#origin#", contentSelector);

Potential outputs from Kate Compton's example grammar above:

Lina traveled with her pet duck. Lina was never indignant, for the duck was always too indignant.
Yuuma traveled with her pet unicorn. Yuuma was never wistful, for the unicorn was always too indignant.
Azra traveled with her pet coyote. Azra was never wistful, for the coyote was always too impassioned.
Yuuma traveled with her pet owl. Yuuma was never wistful, for the owl was always too courteous.
Azra traveled with her pet zebra. Azra was never impassioned, for the zebra was always too astute.

License

This repository is licensed with the Apache license 2.0.

Attribution

This software uses third-party libraries or other resources that may be distributed under licenses different than the software. Please see the third-party notices included here.

About

A C# port of Kate Compton's Tracery text expansion library targeting .NET Standard

Topics

Resources

License

Stars

Watchers

Forks

Languages