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

Turns a typed line of mini-notation or Elixir into a pattern.

    iex> {:ok, pattern} = TuningFork.Pattern.Source.parse("bd sn")
    iex> TuningFork.Pattern.first_cycle(pattern)
    [{0.0, 0.5, "bd"}, {0.5, 1.0, "sn"}]

# `continues?`

```elixir
@spec continues?(String.t()) :: boolean()
```

Whether this line carries on the one above it rather than starting its own pattern.

    iex> TuningFork.Pattern.Source.continues?("|> pianoroll()")
    true
    iex> TuningFork.Pattern.Source.continues?("s(\"bd\")")
    false

Join such a line to the one it follows before passing it to `parse/1`.

# `openings`

```elixir
@spec openings() :: [String.t()]
```

The openings that mark a line as Elixir: every function name of `TuningFork.Pattern` and
`TuningFork.Pattern.Control` followed by `(`.

# `parse`

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

The pattern `source` describes, or why it will not read.

A line that `starts_code?/1` is evaluated as Elixir with `TuningFork.Pattern` and
`TuningFork.Pattern.Control` imported, and can do whatever Elixir can; any other line is read
as `TuningFork.Pattern.Mini` notation. Returns `{:ok, pattern}` or `{:error, message}` with
the reason trimmed to one line. An empty line is `TuningFork.Pattern.silence/0`; a line that
`continues?/1` is an error.

Lines that parse:

    [bd(3,8), hh*8]
    n("<0 4 0 9 7>*16") |> scale("g:minor") |> transpose(-12) |> shape(:saw)

# `starts_code?`

```elixir
@spec starts_code?(String.t()) :: boolean()
```

Whether this line is Elixir rather than mini-notation: it opens with one of `openings/0`.

    iex> TuningFork.Pattern.Source.starts_code?("n(\"0 4\")")
    true
    iex> TuningFork.Pattern.Source.starts_code?("bd*4")
    false

---

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