# `Md.Parser`
[🔗](https://github.com/am-kantox/md/blob/v0.15.1/lib/md/parser.ex#L1)

Interface to implement for the custopm parsers.

Custom parsers might be used in syntax declaration when the generic functionality
is not enough.

Let’s consider one needs a specific handling of links with titles.

The generic engine does not support it, so one would need to implement a custom parser
and instruct `Md.Parser` to use it with:

```elixir
# config/prod.exs

config :md, syntax: %{
  custom: [
    {"![", {MyApp.Parsers.Img, %{}}},
    ...
  ]
}
```

Once the original parser would meet the `"!["` binary, it’d call `MyApp.Parsers.Img.parse/2`.
The latter must proceed until the tag is closed and return the remainder and the updated state
as a tuple.

Custom parsers implementation examples might be found [here](https://github.com/am-kantox/md/tree/master/examples).

# `options`

```elixir
@type options() :: [
  parser: module(),
  walker: walker(),
  format: :none | :indent,
  pre: :none | :indent,
  code: :none | :indent
]
```

Options accepted by `generate/2`

# `parsing_stage`

```elixir
@type parsing_stage() :: {binary(), Md.Listener.state()}
```

The type to be used in all the intermediate states of parsing.

The first element iof the tuple is the continuation (not parsed yet input,)
and the latter is the current state.

# `walker`

```elixir
@type walker() ::
  (Md.Listener.branch() -&gt; Md.Listener.branch() | nil)
  | (Md.Listener.branch(), any() -&gt; {Md.Listener.branch() | nil, any()})
  | {:pre | :post, (Md.Listener.branch() -&gt; Md.Listener.branch() | nil)}
  | {:pre | :post,
     (Md.Listener.branch(), any() -&gt; {Md.Listener.branch() | nil, any()})}
  | {:pre | :post,
     (Md.Listener.branch(), any() -&gt; {Md.Listener.branch() | nil, any()}),
     any()}
```

A function applied to the AST before it is rendered.

A walk function may return `nil` for a node to drop it.

# `parse`

```elixir
@callback parse(binary(), Md.Listener.state()) :: parsing_stage()
```

Takes a not parsed yet input and the state, returns the updated remainder and state.

# `generate`

```elixir
@spec generate(binary() | Md.Listener.state(), options() | module()) ::
  binary() | {binary(), any()}
```

The main function transforming the MD input to XML output.

`options` are passed to `XmlBuilder.generate/2` as is, save for
  the special two special options, `parser:` and `walker:`.

`parser:` option which is a module implementing `Parser` behaviour,
  is telling what parser to use for parsing.

`walker:` option which might be a function of arity 2,
  or a tuple `{:pre | :post, fun}` where `fun` is a function of arity 1 or 2.

If passed, `XmlBuilder.{pre,post}walk/{2,3}` is being called before generation.

A walk function may return `nil` for a node; such nodes are dropped from the
tree rather than being handed to `XmlBuilder` (which would render them as a
meaningless empty element). If the walker leaves nothing behind, the empty
string is returned.

If `walker:` was not passed, this function returns the binary `XML` as is,
otherwise it returns a tuple `{XML, accumulator}` where `accumulator` is what
has been returned from the underlying calls to `XmlBuilder.traverse/4`.

# `generate`

> This function is deprecated. Use generate/2 instead passing `parser: parser` as option.

```elixir
@spec generate(binary() | Md.Listener.state(), module(), keyword()) ::
  binary() | {binary(), any()}
```

---

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