# `Hakushi.Mermaid`
[🔗](https://github.com/hattoriai/hakushi/blob/v0.6.0/lib/hakushi/mermaid.ex#L1)

Helpers for kits that write their canvas as a Mermaid diagram in
Markdown, and read it back (`c:Hakushi.Kit.to_markdown/1`,
`c:Hakushi.Kit.from_markdown/1`).

Mermaid says what is on a canvas, not where: so that a canvas comes back
as it was, `places/2` writes each node's place, size and id in comments
(`%% hakushi {...}`), which Mermaid renderers leave out, and
`read_places/1` reads them back. A diagram with no such comments (one a
person wrote) gets a layout of its own (`layers/2`).

    ```mermaid
    %% hakushi kit=flow
    flowchart LR
      n1(["Invoice paid"])
      n2["Send the receipt"]
      n1 --> n2
    %% hakushi {"m":"n1","id":"paid","x":0,"y":40}
    %% hakushi {"m":"n2","id":"receipt","x":300,"y":40}
    ```

# `edge_places`

```elixir
@spec edge_places([Hakushi.Edge.t()], %{required(String.t()) =&gt; String.t()}) ::
  String.t()
```

The comments that keep `edges` as they are (their handles, label, path,
marker): one for each, with the Mermaid ids of its ends (`ids`).

# `fence`

```elixir
@spec fence(String.t(), String.t()) :: String.t()
```

Puts a diagram in a fenced `mermaid` block, after the kit's marker.

# `flowchart`

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

The nodes and edges of a Mermaid flowchart: `{:ok, nodes, edges}`, with
each node a map of its Mermaid id (`m`), `shape` (`:stadium` for
`([...])`, `:circle` for `((...))`, `:rhombus` for `{...}`, `:round` for
`(...)`, `:trapezoid` for `[/...\]`, `:box` for the others), `text` and
`class` (`:::name`), in the order they come; and each edge a map of
`from`, `to` and `label`. `:error` for a text that is not a
flowchart.

It reads what kits write and what people commonly write (`a --> b`,
`a -->|label| b`, `a -- label --> b`, chains, shapes on the way), not
every form of Mermaid.

# `graph`

```elixir
@spec graph([map()], [map()], %{required(String.t()) =&gt; map()}) :: Hakushi.Graph.t()
```

A graph of nodes and edges read from a diagram: each node at its kept
place, or at a place of `layers/3`.

# `ids`

```elixir
@spec ids([Hakushi.Node.t()]) :: %{required(String.t()) =&gt; String.t()}
```

Mermaid ids for nodes: `n1`, `n2`, ... in their order (a node's own id
may have characters Mermaid does not take).

# `kit`

```elixir
@spec kit(String.t()) :: String.t() | nil
```

The kit a diagram names (`%% hakushi kit=schema`), or `nil`.

# `label`

```elixir
@spec label(String.t() | nil) :: String.t()
```

A label for Mermaid, in double quotes: its quotes and its line breaks
written as Mermaid writes them.

# `layers`

```elixir
@spec layers([String.t()], [{String.t(), String.t()}], keyword()) :: %{
  required(String.t()) =&gt; {number(), number()}
}
```

Places for nodes that a diagram did not keep: in layers along the edges
(a node right of the nodes it comes from), from left to right. `nodes`
are ids in their order, `edges` pairs of ids.

# `lines`

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

The lines of a diagram, trimmed, without its comments and blank lines.

# `places`

```elixir
@spec places([Hakushi.Node.t()], %{required(String.t()) =&gt; String.t()}, map()) ::
  String.t()
```

The comments that keep the places of `nodes`: one for each, with its
Mermaid id (from `ids`, node id to Mermaid id), its own id, its place and
size, and `extra` data of the kit's (a map from node id to a map).

# `read_edges`

```elixir
@spec read_edges(String.t()) :: [map()] | nil
```

The edges a diagram keeps (`edge_places/2`), as maps for `graph/3`, or
`nil` when it keeps none.

# `read_places`

```elixir
@spec read_places(String.t()) :: %{required(String.t()) =&gt; map()}
```

The places a diagram keeps, by Mermaid id.

# `unfence`

```elixir
@spec unfence(String.t()) :: String.t()
```

The diagram of a Markdown text: the body of its fenced `mermaid` block,
or the text itself.

# `unlabel`

```elixir
@spec unlabel(String.t()) :: String.t()
```

A label read from Mermaid: without its quotes, with its entities and line breaks.

---

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