Giter Site home page Giter Site logo

tracery's Introduction

Tracery

About

Tracery was developed by Kate Compton, beginning March 2013 as a class assignment. This is version 0.7 (This is the first numbered version of Tracery, chosen arbitrarily. All basic syntax is stable, but some advanced features like nested rules, if-statements, and modifiers with parameters are still in flux)

Tracery for Ruby

Tracery for Ruby is ported and maintained by Eli Brody. Javascript tracery can be found here. (This text has been adapted to the Ruby syntax, but it is based on the original readme file.)

Gem Version

Build Status

Basic usage

Create a grammar

Using the ruby port is very similar to the Javascript version. First, install the tracery gem: gem install tracery.

Create an empty grammar:

require 'tracery'
include Tracery
grammar = createGrammar();

Create a grammar from a Tracery-formatted object:

grammar = createGrammar({origin: "foo"});

Add modifiers to the grammar (mods-eng-basic.rb for basic English modifiers, or write your own)

require 'mods-eng-basic'
grammar.addModifiers(Modifiers.baseEngModifiers);

Expand rules

Get the fully-expanded string from a rule

expanded_text = grammar.flatten("#origin#")

Get the fully-expanded node from a rule, this will return a root node containing a full expanded tree with many potentially interesting properties, including "finishedText" for each node.

expanded_node = grammar.expand("#origin#")

Making Tracery deterministic

By default, Tracery uses Random#rand to generate random numbers. If you need Tracery to be deterministic, you can make it use your own random number generator using:

Tracery.setRng(rng_lambda)

where rng_lambda is a lambda that, like Random#rand, returns a floating-point, pseudo-random number in the range [0, 1). By using a local random number generator that takes a seed and controlling this seed, you can make Tracery's behavior completely deterministic.

Usage example:

Tracery.setRng(lambda { return 0.5 })

Note: Beware, this lambda is set globally, for all Tracery expansions.

Library Concepts

Grammar

A Grammar is

  • a dictionary of symbols: a key-value object matching keys (the names of symbols) to expansion rules
  • optional metadata such as a title, edit data, and author
  • optional connectivity graphs describing how symbols call each other

clearState: symbols and rulesets have state (the stack, and possible ruleset state recording recently called rules). This function clears any state, returning the dictionary to its original state;

Grammars are usually created by feeding in a raw JSON grammar, which is then parsed into symbols and rules. You can also build your own Grammar objects from scratch, without using this utility function, and can always edit the grammar after creating it.

Symbol

A symbol is a key (usually a short human-readable string) and a set of expansion rules

  • the key
  • rulesetStack: the stack of expansion rulesets for this symbol. This stack records the previous, inactive rulesets, and the current one.
  • optional connectivity data, such as average depth and average expansion length

Putting a key in hashtags, in a Tracery syntax object, will create a expansion node for that symbol within the text.

Each top-level key-value pair in the raw JSON object creates a symbol. The symbol's key is set from the key, and the value determines the ruleset.

Modifier

A function that takes a string (and optionally parameters) and returns a string. A set of these is included in mods-eng-basic.rb. Modifiers are applied, in order, after a tag is fully expanded.

To apply a modifier, add its name after a period, after the tag's main symbol: #animal.capitalize# #booktitle.capitalizeAll# Hundreds of #animal.s#

Modifiers can have parameters, too! (soon they will can have parameter that contain tags, which will be expanded when applying the modifier, but not yet) #story.replace(he,she).replace(him,her).replace(his,hers)#

Action

An action that occurs when its node is expanded. Built-in actions are

  • Generating some rules "[key:#rule#]" and pushing them to the "key" symbol's rule stack. If that symbol does not exist, it creates it.
  • Popping rules off of a rule stack, "[key:POP]"
  • Other functions

TODO: figure out syntax and implementation for generating arrays of rules, or other complex rulesets to push onto symbols' rulestacks

TODO: figure out syntax and storage for calling other functions, especially for async APIs.

Ruleset

A ruleset is an object that defines a getRule function. Calling this function may change the internal state of the ruleset, such as annotating which rules were most recently returned, or drawing and removing a rule from a shuffled list of available rules.

Basic ruleset

A basic ruleset is just an array of options.

They can be created by raw JSON by having an array or a string as the value, like this: "someKey":["rule0", "rule1", "some#complicated#rule"] If there is only one rule, it is acceptable short hand to leave off the array, but this only works with Strings. "someKey":"just one rule"

These use the default distribution of the Grammar that owns them, which itself defaults to regular stateless pseudo-randomness.

Rulesets with conditions, distributions, or ranked fallbacks

**this feature is under development, coming soon

These rulesets are created when the raw JSON has an object rather than an array as the value.

Some attributes of this object can be:

  • baseRules: a single ruleset,
  • ruleRanking: an array of rulesets, call getRule on each in order until one returns a value, if none do, return baseRules.getRule,
  • distribution: a new distribution to override the default)
  • conditionRule: a rule to expand
  • conditionValue: a value to match the expansion against
  • conditionSuccess: a ruleset to use if expanding conditionRule returns conditionValue, otherwise use baseRules

These can be nested, so it is possible to make a ruleset

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.