 
   Plugins can alter the processed contents and metadata here.
   """
-  @callback processed_page(page :: Page.t()) :: Result.t(Page.t())
+  defcallback processed_page(page :: Page.t()) :: Result.t(Page.t())
 
   @doc """
   Called after Serum has processed each input file and produced

  Plugins can manipulate the list of files to be read and pass it to
  the next plugin.
  """
  @callback reading_posts(files :: [binary()]) :: Result.t([binary()])

  @doc """
  Called before reading input files.

  @type plugin_spec :: atom() | {atom(), [{:only, atom() | [atom()]}]}

  @optional_callbacks [
                        build_started: 2,
                        reading_pages: 1,
                        reading_posts: 1,
                        reading_templates: 1,
                        processing_page: 1,
                        processing_post: 1,
                        processing_template: 1,
                        processed_page: 1,
                        processed_post: 1,
                        processed_template: 1,
                        processed_list: 1,
                        processed_pages: 1,
                        processed_posts: 1,
                        rendering_fragment: 2,
                        rendered_fragment: 1,
                        rendered_page: 1,
                        wrote_file: 1,
                        build_succeeded: 2,
                        build_failed: 3,
                        finalizing: 2
                      ]
                      |> Enum.map(fn {name, arity} ->
                        [{name, arity}, {name, arity + 1}]
                      end)
                      |> List.flatten()

  @serum_version Version.parse!(Mix.Project.config()[:version])
  @elixir_version Version.parse!(System.version())
