defmodule ExamplesStyler do @moduledoc """ Styles code examples in ".ex", ".exs", ".md", and ".cheatmd" files. Add to `:plugins` value of your `.formatter.exs` file. """ @behaviour Mix.Tasks.Format alias ExamplesStyler.Utils alias Mix.Tasks.Format @doc false @impl Format @spec features(Utils.format_opts()) :: [sigils: [atom()], extensions: [String.t()]] def features(_), do: [sigils: [], extensions: [".ex", ".exs", ".md", ".cheatmd"]] @doc false @impl Format @spec format(String.t(), Utils.format_opts()) :: String.t() def format(input, opts) do sigils = opts |> Keyword.fetch!(:sigils) |> MapSet.new() extension = Keyword.fetch!(opts, :extension) elixir_plugin = Utils.find_elixir_formatter(opts) Enum.reduce([elixir_plugin, ExamplesStyler.Examples], input, fn plugin, input -> features = plugin.features(opts) plugin_sigils = features |> Keyword.fetch!(:sigils) |> MapSet.new() plugin_extensions = Keyword.fetch!(features, :extensions) if extension in plugin_extensions or not MapSet.disjoint?(sigils, plugin_sigils) do plugin.format(input, opts) else input end end) end end