defmodule OrgGarden.Transform do @moduledoc """ Behaviour that all markdown transform modules must implement. ## Callbacks - `init/1` — called once before processing; returns transform-specific state. Default implementation returns the opts map unchanged. - `apply/3` — called per .md file; returns the (possibly modified) content. - `teardown/1` — optional cleanup after all files are processed. ## Example defmodule MyTransform do @behaviour OrgGarden.Transform @impl true def init(opts), do: %{some_state: opts[:value]} @impl true def apply(content, state, _opts) do String.replace(content, "foo", state.some_state) end end """ @doc "One-time initialisation. Returns opaque state passed to apply/3." @callback init(opts :: map()) :: term() @doc "Transform file content. Returns the (possibly modified) content string." @callback apply(content :: String.t(), state :: term(), opts :: map()) :: String.t() @doc "Optional cleanup after all files are processed." @callback teardown(state :: term()) :: :ok @optional_callbacks teardown: 1 defmacro __using__(_) do quote do @behaviour OrgGarden.Transform @impl OrgGarden.Transform def init(opts), do: opts defoverridable init: 1 end end end