# interp: Tracery-like randomized text interpolation

[ bsd3, interpolation, library, program, text ] [ Propose Tags ]

## Modules

[Index] [Quick Jump]

#### Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

• No Candidates
Versions [RSS] 1.0.0.0, 1.0.0.1, 1.0.0.2 aeson, base (>=4.7 && <5), bytestring, containers, hspec, interp, megaparsec, mtl, optparse-applicative, parser-combinators, random-fu, rvar, semigroups, text, transformers, unordered-containers, vector [details] BSD-3-Clause (c) 2019 sam raker sam raker sam.raker@gmail.com Text, Interpolation https://github.com/swizzard/interp#readme https://github.com/swizzard/interp/issues head: git clone https://github.com/swizzard/interp by swizzard at 2019-02-18T20:38:43Z NixOS:1.0.0.2 interp 1396 total (8 in the last 30 days) (no votes yet) [estimated by Bayesian average] λ λ λ Docs available Last success reported on 2019-02-18

[back to package description]

# interp

A randomized text-interpolation tool inspired by Tracery, in Haskell.

### Installation

#### Prerequisites

• Stack, unless you can work Cabal yourself

Clone this repo, cd into it, and then:

• if you want to use the CLI, run stack install
• if you want to use it as a library, just run stack build

#### Development

Fork this repo, make some changes, run stack test to make sure everything's ok, then (if you want) submit a PR. Thank you!

### Use

#### CLI

Usage: interp (--substitutions ARG | SUBST) (--interpolations ARG | INTERP)
Randomly interpolate values into a template

Available options:
--substitutions ARG      JSON file containing map of substitutions
SUBST                    JSON file containing map of substitutions
--interpolations ARG     file containing text to interpolate
INTERP                   file containing text to interpolate
-h,--help                Show this help text


substitutions is the (path to the) file containing the JSON map of substitutions. interpolations is (path to the) file containing the text to interpolate. See below for more on both.

#### Library

Data.Text.Interp.Interpolate.interp is probably what you'll want to use. It takes a Subst object (usually parsed from JSON, but you can make one yourself) and a NonEmpty list of ITexts. Check out Data.Text.Interp.Types for more on those types.

### Syntax

In both substitution and interpolation files, keys can be comprised of any letter or number, or the characters "_" or "-". Spaces and other punctuation are not allowed and will give you Problems.

#### Substitutions

{"coolThings": [
{"name": "computers",
"reason": "you can do haskell on them"
},
{"name": "dogs",
"reason": "they're good"
}
],
{"name": "flat tires",
"reason": "they make you late"
},
{"name": "jobs",
"reason": "they make you tired"
}
],
"sam": {
"likes": "computers"
}


The substitutions file is a JSON file. JSON maps are treated how one would expect. The values in a JSON array are chosen among randomly (but see also below on binding). Regular values are treated regularly, but note:

• because of how JSON is parsed, all numeric literals are treated as floating-point, so a 1 will be interpolated as "1.0". If this is an issue, just wrap your numbers in quotes and they'll be treated as strings.
• null values are explicitly forbidden; empty lists and maps should be avoided.

#### Interpolations

{{ ... }} sets off a thing to interpolate. Keys, corresponding to keys in the substitutions file, can be period-separated to 'dig into' nested maps. Thus, in the example above, sam.likes will be have the value "computers".

##### Binding

Within braces, values can be bound to variables using the syntax (varToBind#keys.to.bind).other.keys. When a variable is bound, references to that variable will be interpolated with that same value. Thus, given the interpolation template

{{ (cool#coolThings).name }} are cool because {{ cool.reason }}. {{ (bad#badThings).name }} are bad because {{ bad.reason }}.


cool in the first interpolation will be the same as cool in the second. Note that keys within the parentheses are part of the binding, while those after the closing parentheses are interpolated normally--{{ (cool#coolThings).name }} will be either "computers" or "dogs", while {{ cool.reason }} will be "you can do haskell on them" or "they're good", depending on which sub-map was randomly chosen to be bound to cool.

Binding is primarily useful for map values. It's possible to bind arrays, but since array elements are chosen randomly evey time, there's not much of a point. Similarly, there's no real difference between binding a simple value and just using the full path to it, unless you're trying to save characters.