   defp render_list(posts, page_num, first?, last?, state) do
     base = state.project_info.base_url
     path = state.list_path
-    prev = if first?, do: Path.join([base, path, "page-#{page_num - 1}.html"])
-    next = if last?, do: Path.join([base, path, "page-#{page_num + 1}.html"])
+    prev =
+      unless first?, do: Path.join([base, path, "page-#{page_num - 1}.html"])
+    next =
+      unless last?, do: Path.join([base, path, "page-#{page_num + 1}.html"])
     list_ctx = [
       header: state.list_title,
       posts: posts,

      {:error, _} = error -> error
    end
  end

  @spec save_lists([binary], binary) :: :ok

  defp save_lists([first|_] = htmls, list_dir) do
    path_index = Path.join list_dir, "index.html"
    fwrite path_index, first
    msg_gen path_index
    htmls
    |> Enum.with_index(1)
    |> Enum.each(fn {html, page_num} ->
      path = Path.join list_dir, "page-#{page_num}.html"
      fwrite path, html
      msg_gen path
    end)
  end

  @spec launch_tag(Build.mode, map, state) :: [Task.t]

  defp launch_tag(:parallel, tagmap, state) do
    %{dest: dir} = state
    tagmap
    |> Task.async_stream(__MODULE__, :tag_task, [dir, state], @async_opt)
    |> Enum.map(&elem(&1, 1))
  end

  defp launch_tag(:sequential, tagmap, state) do
    %{dest: dir} = state
    tagmap
    |> Enum.map(&tag_task(&1, dir, state))
  end

  @doc false
  @spec tag_task({Serum.Tag.t, [PostInfo.t]}, binary, state) :: :ok

  def tag_task({tag, posts}, dest, state) do
    tagdir = Path.join [dest, "tags", tag.name]
    fmt = state.project_info.list_title_tag
    title = fmt |> :io_lib.format([tag.name]) |> IO.iodata_to_binary
    File.mkdir_p! tagdir
    msg_mkdir tagdir
    save_list Path.join(tagdir, "index.html"), title, posts, state
  end

  @spec save_list(binary, binary, [PostInfo.t], state) :: :ok

  defp save_list(path, title, posts, state) do
    list_ctx = [header: title, posts: posts]
    case Renderer.render "list", list_ctx, [page_title: title], state do
      {:ok, html} ->
        fwrite path, html
        msg_gen path
      error -> error
    end
  end

  """
  # for the first page
  path_index = Path.join state.list_dir, "index.html"
  fwrite path_index, html
  msg_gen path_index

  path = Path.join state.list_dir, "page-1.html"
  fwrite path, html
  msg_gen path

  # for other pages
  path = Path.join state.list_dir, "page-# {page_num}.html"
  fwrite path, html
  msg_gen path
  """

  @spec render_lists([[PostInfo.t]], integer, [Error.result(binary)], state)
    :: Error.result([binary])

  def run(mode, state) do
    IO.puts "Generating posts index..."

    tags = state.tag_map
    case index_task({nil, state.site_ctx[:posts]}, state) do
      :ok ->
        result = launch_tag mode, tags, state
        Error.filter_results result, :index_builder
      {:error, _} = error -> error
    end
  end

  @spec launch_tag(Build.mode, map, state) :: [Error.result]

  defp launch_tag(:parallel, tagmap, state) do
    tagmap
    |> Task.async_stream(__MODULE__, :index_task, [state], @async_opt)
    |> Enum.map(&elem(&1, 1))
  end

  defp launch_tag(:sequential, tagmap, state) do
    tagmap
    |> Enum.map(&index_task(&1, state))
  end

  @doc false
  @spec index_task({nil | Tag.t, [PostInfo.t]}, state) :: Error.result

  def index_task({tag, posts}, state) do
    pagination? = state.project_info.pagination
    posts_per_page = state.project_info.posts_per_page

    list_path = tag && Path.join("tags", tag.name) || "posts"
    list_dir = Path.join state.dest, list_path
    list_title =
      if is_nil(tag) do
