Lumis.Formatter behaviour (Lumis v0.10.0)

Copy Markdown View Source

Behaviour for custom formatters.

Lumis syntax-highlights the source and composes caller-provided annotations before calling render/3. The formatter receives one properly nested, sequential event stream.

Lumis adds event kinds as it grows, so a formatter should match the ones it renders and skip the rest:

_event, acc -> {[], acc}

Without that clause a newer Lumis raises FunctionClauseError rather than rendering. The built-in formatters do the same thing with annotations, which they cannot render without knowing the caller's data.

Options

render/3 receives the options the formatter was given, plus :language, which is always the language highlighting actually used. A caller who named none gets the detected one rather than nil, so a formatter can label its output without running detection a second time:

def render(source, events, options) do
  Lumis.Formatter.HTML.open_code_tag(Keyword.fetch!(options, :language))
end

Summary

Types

A syntax, caller-provided annotation, or Lumis decoration event.

Callbacks

Renders a unified event stream for source.

Types

event(data)

@type event(data) ::
  {:start, %{scope: String.t(), language: String.t()}}
  | {:source, %{start: non_neg_integer(), end: non_neg_integer()}}
  | :end
  | {:annotation_start,
     %{range: {non_neg_integer(), non_neg_integer()}, data: data}}
  | :annotation_end
  | {:decoration_start, Lumis.Decoration.RainbowBracket.t()}
  | :decoration_end

A syntax, caller-provided annotation, or Lumis decoration event.

Callbacks

render(source, events, options)

@callback render(source :: String.t(), events :: [event(term())], options :: keyword()) ::
  iodata()

Renders a unified event stream for source.