# `Linocut.Derive`
[🔗](https://github.com/jaman/cauldron/blob/v0.1.3/linocut/lib/linocut/derive.ex#L1)

A picture made from another by a short line of operations, so one drawing gives many
views: a recoloured costume, a mirrored heading, a hat laid on.

    from knight; colour C #c02020; flip h
    from walk; frame 2; over hat 0 -2

The operations, separated by `;`, in the order they run:

  * `from NAME` — the picture to start from; always first
  * `colour KEY COLOUR` (or `color`) — what `KEY` means, as a palette line takes it
  * `swap KEY KEY` — exchange what two keys mean
  * `flip h` / `flip v` — mirror left to right, or top to bottom
  * `turn 90` / `180` / `270` — clockwise, a quarter turn at a time
  * `shift DX DY` — move the picture, what leaves the edge lost, what enters transparent
  * `frame N` — keep the `N`th frame alone, counting from 1
  * `reverse` — the frames in the other order
  * `over NAME [DX DY]` — lay `NAME`'s first frame on every frame, its transparent
    keys letting the picture through, moved by `DX DY`; the palettes are merged, and a
    key the two pictures use for different colours is refused

Everything works on the text of a `.pic` — keys, not pixels — so a derived picture is
a picture like any other, edited in the same editors and rendered the same way.
`derive/2` takes the line and a function from a name to the text it names — `{:ok,
text}`, `:error` for a name it does not know, or `{:error, message}` with a reason of
its own.

# `lookup`

```elixir
@type lookup() :: (String.t() -&gt; {:ok, String.t()} | :error | {:error, String.t()})
```

# `op`

```elixir
@type op() ::
  {:from, String.t()}
  | {:colour, String.t(), String.t()}
  | {:swap, String.t(), String.t()}
  | {:flip, :h | :v}
  | {:turn, 90 | 180 | 270}
  | {:shift, integer(), integer()}
  | {:frame, pos_integer()}
  | :reverse
  | {:over, String.t(), integer(), integer()}
```

# `derive`

```elixir
@spec derive(String.t(), lookup()) :: {:ok, String.t()} | {:error, String.t()}
```

The picture `line` describes, with `lookup` giving the text behind each name it uses.

# `parse`

```elixir
@spec parse(String.t()) :: {:ok, [op()]} | {:error, String.t()}
```

The operations in `line`, or why it could not be read.

## Examples

    iex> Linocut.Derive.parse("from ship; flip h; colour H #fff")
    {:ok, [{:from, "ship"}, {:flip, :h}, {:colour, "H", "#fff"}]}

# `run`

```elixir
@spec run([op()], lookup()) :: {:ok, String.t()} | {:error, String.t()}
```

The picture the operations make, as text.

---

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