# `TuningFork.Pattern.Mini`
[🔗](https://github.com/jaman/tuning_fork/blob/v0.1.11/tuning_fork/lib/tuning_fork/pattern/mini.ex#L1)

Mini-notation strings parsed into a `TuningFork.Pattern`.

    iex> TuningFork.Pattern.first_cycle(TuningFork.Pattern.Mini.parse("bd sn"))
    [{0.0, 0.5, "bd"}, {0.5, 1.0, "sn"}]

# `locate`

```elixir
@spec locate(String.t(), number()) :: {non_neg_integer(), non_neg_integer()} | nil
```

Where in `source` the thing sounding at `cycle` was written, as `{from, to}`.

`cycle` is an absolute cycle position: `4.25` is a quarter of the way through cycle four.
`nil` when nothing is sounding then, or when the source will not parse. Timing applied to
the parsed pattern outside the string is not seen here.

    iex> TuningFork.Pattern.Mini.locate("bd sn hh", 0.5)
    {3, 5}
    iex> TuningFork.Pattern.Mini.locate("<bd sn>", 1.0)
    {4, 6}

# `located`

```elixir
@spec located(String.t()) :: TuningFork.Pattern.t()
```

The same pattern with every value paired with where it was written, as `{value, {from, to}}`.

`from` and `to` are character offsets into `source`. Raises `ArgumentError` on a string that
will not parse.

# `parse`

```elixir
@spec parse(String.t()) :: TuningFork.Pattern.t()
```

A pattern from a mini-notation string.

Accepted syntax: words and numbers in order (`bd sn hh`), `~` for a rest, `[ ]` to
subdivide one step, `< >` for one per cycle in turn, `,` for layers at the same time, `*n`
and `/n` for faster and slower, `!n` to repeat as separate steps, `@n` for a step's weight,
`?` or `?0.3` to drop at random, `(hits,steps)` or `(hits,steps,rotation)` for a euclidean
rhythm, and `word:n` for an indexed word. Modifiers stack left to right.

Words come back as strings, bare numbers as numbers, and `bd:3` as the string `"bd:3"`. An
empty string, or one holding only whitespace, gives `TuningFork.Pattern.silence/0`. A
string that will not parse raises `ArgumentError` naming what was wrong.

# `parse_safe`

```elixir
@spec parse_safe(String.t()) :: {:ok, TuningFork.Pattern.t()} | {:error, String.t()}
```

`parse/1` returning `{:ok, pattern}` or `{:error, message}` instead of raising.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
