# `Expresso.Element.Math.Latex`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/element/math/latex.ex#L1)

A parser of the LaTeX of a formula into a tree of atoms

A `rewrite` entity of a derivation makes the LaTeX of a new line from the
LaTeX of an old line, so it must find the parts, the symbols and the groups
of the old line. `parse/1` reads LaTeX into a list of atoms, and `write/1`
writes the list back. `write(parse(tex))` returns `tex`, except for the
white space between a command and its brace groups. `docs/line-rewrites.md`
gives the design.

An atom is one of these tuples:

  * `{:symbol, text}`, a letter, a number, an operator or a parenthesis.
    A number is a run of digits, with a point in it.
  * `{:command, name, groups}`, a command such as `\lambda` or
    `\frac`, with the brace groups that follow it. A command with no group,
    such as `\alpha`, is a symbol for a rewrite.
  * `{:group, atoms}`, a brace group.
  * `{:script, mark}`, the mark `^` or `_` of an index.
  * `{:space, text}`, white space or a command of space, such as `\,`.

`\part{name}{…}` is a command with two groups, and `part/2` finds its body.

# `atom_t`

```elixir
@type atom_t() ::
  {:symbol, String.t()}
  | {:command, String.t(), [{:group, [atom_t()]}]}
  | {:group, [atom_t()]}
  | {:script, String.t()}
  | {:space, String.t()}
```

An atom of a formula

# `name_of`

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

Return the name of a command that gives a name to its second group, such as
`\part`, or `nil` for each other atom

# `parse`

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

Read LaTeX into a list of atoms

The function returns an error for a brace that has no partner.

    iex> Expresso.Element.Math.Latex.parse(~S"\lambda x.\,x^{2}")
    {:ok,
     [
       {:command, "\\lambda", []},
       {:space, " "},
       {:symbol, "x"},
       {:symbol, "."},
       {:space, "\\,"},
       {:symbol, "x"},
       {:script, "^"},
       {:group, [{:symbol, "2"}]}
     ]}

# `part`

```elixir
@spec part([atom_t()], String.t()) :: [atom_t()] | nil
```

Return the body of the `\part` or `\id` with a name, or `nil`

The function looks at each depth of the tree.

    iex> {:ok, atoms} = Expresso.Element.Math.Latex.parse(~S"a + \part{b}{c\,d}")
    iex> Expresso.Element.Math.Latex.part(atoms, "b")
    [{:symbol, "c"}, {:space, "\\,"}, {:symbol, "d"}]

# `write`

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

Write a list of atoms as LaTeX

    iex> {:ok, atoms} = Expresso.Element.Math.Latex.parse(~S"\frac{a}{b} + \part{x}{y}")
    iex> Expresso.Element.Math.Latex.write(atoms)
    ~S"\frac{a}{b} + \part{x}{y}"

---

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