[−][src]Crate tracery
Rust port of tracery
This library is a port of https://github.com/galaxykate/tracery, which implements Generative grammars. Given a set of rules, written in a specific syntax, it will generate strings of text.
Example:
let source = r##" { "origin": ["foo #bar#", "#baz# quux #qux#"], "bar": ["bar", "BAR"], "baz": ["baz", "BaZ", "bAZ"], "qux": ["qux", "QUX"] } "##; let grammar = tracery::from_json(source).unwrap(); // Starting from the "origin" rule, which is selected by default, fills in // random entries from the "bar", "baz", and "qux" rules, where called for // in the "origin" text: let flattened = grammar.flatten(&grammar, &mut BTreeMap::new())?; let matches = flattened.eq_ignore_ascii_case("foo bar") || flattened.eq_ignore_ascii_case("baz quux qux"); assert!(matches);
or, even shorter:
let source = r##" { "origin": ["foo #bar#", "#baz# quux #qux#"], "bar": ["bar", "BAR"], "baz": ["baz", "BaZ", "bAZ"], "qux": ["qux", "QUX"] } "##; let flattened = tracery::flatten(source)?; let matches = flattened.eq_ignore_ascii_case("foo bar") || flattened.eq_ignore_ascii_case("baz quux qux"); assert!(matches);
So, in the example above, we might end up with "foo bar"
or "BaZ quux lazy dog"
, etc
API
In the example above, we used Grammar.flatten
, but that is a convenience function that
does the following:
let grammar = tracery::from_json(r##"{ "origin": [ "#foo# is #bar#" ], "foo": [ "tracery" ], "bar": [ "fun" ] }"##)?; let flattened = grammar.flatten(&grammar, &mut BTreeMap::new())?; assert_eq!(flattened, "tracery is fun");
.from_json
will parse the rule set out into a tree-like structure, and .flatten
collapses that
tree-like structure into a single string.
More tracery
syntax
Tracery allows for more than just word replacement. You can attach "actions" and "modifiers" to rules as well. There are quite a few modifiers built-in to this library. Here is one:
let source = r##" { "origin": ["this word is in plural form: #noun.s#"], "noun": ["apple"] }"##; let grammar = tracery::from_json(source)?; let flattened = grammar.flatten(&grammar, &mut BTreeMap::new())?; assert_eq!("this word is in plural form: apples", flattened);
Actions allow you to, for example, lock in a specific value for a #tag#
, so that you can refer to it multiple
times in your story. Here is an example (modified from @galaxykate's official tutorial
http://www.crystalcodepalace.com/traceryTut.html)
let source = r##"{ "name": ["Arjun","Yuuma","Darcy","Mia","Chiaki","Izzi","Azra","Lina"], "animal": ["unicorn","raven","sparrow","scorpion","coyote","eagle","owl","lizard","zebra","duck","kitten"], "mood": ["vexed","indignant","impassioned","wistful","astute","courteous"], "story": ["#hero# traveled with her pet #heroPet#. #hero# was never #mood#, for the #heroPet# was always too #mood#."], "origin": ["#[hero:#name#][heroPet:#animal#]story#"] }"##; println!("{}", tracery::flatten(source)?);
We see, in the "origin" rule, the use of actions to lock-in the value of #hero#
and
#heroPet#
, so that we can use those tags in the "story" rule, and know that the same
generated value will be used in all cases.
Structs
Grammar | Represents a single grammar |
Rule | Represents a single expansion that tracery can select for a key. |
Tag | Structure representing a |
Enums
Error | The |
Node | Represents a part of a single expandable string |
Traits
Flatten | A trait for types that can be flattened into an output string |
Functions
flatten | Creates a new grammar from a JSON grammar string, then uses it to create a random output string |
from_json | Creates a new grammar from a JSON grammar string |
Type Definitions
Result | A convenience type for a |