Orasund/elm-tracery/4.0.1

NOTE: the latest version is 5.0.0

Tracery.Grammar

Creates a string generator based on a syntax.

Grammar

type alias Grammar =
{ output : List Command
, stack : List Command
, next : Maybe Command
, constants : Dict String (List Command)
, definitions : Dict String Definition
}
  • next - what needs to be generated next?
  • constants - what
  • definitions - the grammar rules (see Syntax)
fromDefinitions : Dict String Definition -> Grammar

Turns Definitions into a Grammar.

toString : ({ variable : String } -> String) -> Grammar -> String

Prints the Grammar

Generating

generateWhile : (Grammar -> Bool) -> Grammar -> Generator Grammar

Generates a string while a predicate is valid

generateOutput : (Grammar -> Bool) -> Strategy -> Grammar -> Generator Grammar

Generates an output found in the resulting grammar.

You can use generateCommands instead, If you intend to get the output right away.

import Dict
import Json.Decode
import Random exposing (Generator)
import Result.Extra
import Tracery.Syntax exposing (Definition(..), Expression(..))
import Set


andThenToString : ({ variable : String } -> String) -> Int -> (Grammar -> Generator Grammar) -> Grammar -> String
andThenToString fun seed gen grammar =
    Random.step (gen grammar) (Random.initialSeed seed)
        |> Tuple.first
        |> toString fun


input : Grammar
input =
    [ ( "origin", Choose [ [ Value "A ", Variable "animal" ] ] )
    , ( "animal"
      , Choose
            [ [ Value "cat, looking at a ", Variable "animal" ]
            , [ Value "bird." ]
            ]
      )
    ]
        |> Dict.fromList
        |> fromDefinitions


input
|> andThenToString (\{variable} -> "dog.") 42 (generateOutput (\_ -> True) defaultStrategy)
--> "A cat, looking at a cat, looking at a cat, looking at a cat, looking at a bird."


input
|> andThenToString (\{variable} -> "dog.") 42 (generateOutput (\_ -> True) (noRecursionStrategy (Set.fromList ["animal"])))
--> "A bird."
generateNext : Strategy -> Grammar -> Generator Grammar

Computes the command in grammar.next.

Afterwards the next command gets loaded

import Dict
import Json.Decode
import Random exposing (Generator)
import Result.Extra
import Tracery.Syntax exposing (Definition(..), Expression(..))


andThenToString : ({ variable : String } -> String) -> Int -> (Grammar -> Generator Grammar) -> Grammar -> String
andThenToString fun seed gen grammar =
    Random.step (gen grammar) (Random.initialSeed seed)
        |> Tuple.first
        |> toString fun


input : Grammar
input =
    [ ( "origin", Choose [ [ Value "A ", Variable "animal" ] ] )
    , ( "animal"
      , Choose
            [ [ Value "cat, looking at a ", Variable "animal" ]
            , [ Value "bird." ]
            ]
      )
    ]
        |> Dict.fromList
        |> fromDefinitions

using this function, you can step through the computation

input
|> andThenToString (\{variable} -> "dog.") 42 (generateNext defaultStrategy)
--> "A dog."

The second step does nothing (some steps only perform internal rearrangements)

input
|> andThenToString (\{variable} -> "dog.") 42
    (\g -> g
        |> (generateNext defaultStrategy)
        |> Random.andThen (generateNext defaultStrategy)
    )
--> "A dog."

Doing a second step results in

input
|> andThenToString (\{variable} -> "dog.") 42
    (\g -> g
        |> (generateNext defaultStrategy)
        |> Random.andThen (generateNext defaultStrategy)
        |> Random.andThen (generateNext defaultStrategy)
    )
--> "A cat, looking at a dog."

Strategy

type alias Strategy =
String -> List Expression -> Bool

The strategy specifies the algorithm to choose an option

defaultStrategy : String -> List Expression -> Bool

This strategy will choose any option

noRecursionStrategy : Set String -> String -> List Expression -> Bool

This strategy will never choose a recursive option

onlyRecursionStrategy : Set String -> String -> List Expression -> Bool

This strategy will only chose recursive options

Technical Utilities

toNext : Grammar -> Grammar

Moves to the next command without executing anything.

toNext : Grammar -> Grammar
toNext grammar =
    grammar |> withCommands grammar.stack
withCommands : List Command -> Grammar -> Grammar

Sets Commands of a Grammar.

rewind : Grammar -> Grammar

sets the output as input.

end : Grammar -> Grammar

set the remaining commands as output