# `Expresso.Element.Diagram.Pele`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/element/diagram/pele.ex#L1)

Draws a diagram in the language of Mermaid with Pele, and names its elements

A `diagram` with a `.mmd` file, or with the `source` option and
`lang: :mermaid`, calls `draw!/3`. [Pele](https://pele.run) is a library in
JavaScript, so the function runs Node with the script `priv/pele/render.mjs`,
through `Expresso.Element.Diagram.Tool`. The project holds a copy of
`pele.js` and its license in `priv/pele/`, so a render needs Node and no
package of npm. `version/0` gives the version of the copy.

The script writes the SVG of Pele and the model of its `parse()`. Pele gives
each part of a diagram the attribute `data-id`, and the model gives the
ends of each edge and the members of each group. `name/1` gives each part
an `id` and the marks of `Expresso.Element.Diagram.Outline`, with the plan
of its type, such as `Expresso.Element.Diagram.Pele.Flowchart`.
`Expresso.Element.Diagram.Pele.Plan` gives the contract of a plan.

The name of an edge has its two ends and its arrow, as for Graphviz and D2,
so a part names an edge as the source names its ends. Some parts have more
than one element with the same `data-id`, such as an edge and its label, or
an actor of a sequence diagram at the top and at the bottom. Each element
gets the same `id`, so a part shows them at the same steps. Only the first
element whose plan gives marks gets them, so the list for a screen reader
holds each part one time.

A diagram of a type without a plan keeps the `data-id` of Pele as the name
of each part, with no marks.

# `draw!`

```elixir
@spec draw!(String.t(), String.t(), Expresso.Element.Diagram.Font.t()) ::
  {String.t(), [String.t()]}
```

Draw the source of a Mermaid diagram, and return the SVG and the names

`label` names the diagram in a message, such as the path of its file. Pele
writes the family of `font` in the SVG, and it measures each text with the
advance widths of the characters of `font`, from
`Expresso.Element.Diagram.Font.advances/2`. The widths cover each character
of the source and each printable character of ASCII, because Pele can write
a text that is not in the source, such as a number on an axis. The function
raises an
`ArgumentError` when Node is not present and when Pele cannot draw the
source, with the message of Pele.

# `json!`

```elixir
@spec json!(String.t(), String.t(), Expresso.Element.Diagram.Font.t()) :: String.t()
```

Run the script on a source, and return the text of its JSON

The JSON holds the SVG, the type of the diagram and the model of `parse()`.
`draw!/3` reads it, and the fixtures of the tests hold it as it is.

# `layouts`

```elixir
@spec layouts() :: [atom()]
```

Pele has one layout, so a diagram of Mermaid takes no `layout` option

# `name`

```elixir
@spec name(map()) :: {String.t(), [String.t()]}
```

Give each part of the result of the script its name and its marks

The result holds the SVG, the type of the diagram and the model of
`parse()`. The function returns the SVG and the names, in the order of the
file.

    iex> svg = ~s(<svg><g class="pele-node" data-id="web"></g></svg>)
    iex> Expresso.Element.Diagram.Pele.name(%{"svg" => svg, "type" => "flowchart", "model" => %{"edges" => [], "subgraphs" => []}})
    {~s(<svg><g class="pele-node" data-id="web" id="web" data-graph-kind="node"></g></svg>), ["web"]}

# `planned`

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

The types of Pele that have a plan, with the names and the marks of their parts

# `script`

```elixir
@spec script() :: Path.t()
```

The path of the script that runs Pele

# `theme`

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

Give a diagram of Pele the colors of the theme

Pele writes each color as a custom property with a fallback, such as
`var(--pele-fg, #1f1f1f)`, and the style sheet of the deck sets the
properties for the class `diagram-pele`. Therefore the SVG needs no change.

# `tool`

```elixir
@spec tool() :: Expresso.Element.Diagram.Tool.t()
```

The tool, for `Expresso.Element.Diagram.Tool`

# `version`

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

The version of the copy of Pele

---

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