 
   ## Code blocks
 
-  defp process_code([], code, indent) do
+  defp process_code([], code, indent, _colors) do
     write_code(code, indent)
   end
 
   # Blank line between code blocks
-  defp process_code([ "", "    " <> line | rest ], code, indent) do
-    process_code(rest, [line, "" | code], indent)
-  end
-
-  defp process_code([ "    " <> line | rest ], code, indent) do
-    process_code(rest, [line|code], indent)
-  end
-
-  defp process_code(rest, code, indent) do
+  defp process_code([ "", "    " <> line | rest ], code, indent, colors) do
+    process_code(rest, [line, "" | code], indent, colors)
+  end
+
+  defp process_code([ "    " <> line | rest ], code, indent, colors) do
+    process_code(rest, [line|code], indent, colors)
+  end
+
+  defp process_code(rest, code, indent, colors) do
     write_code(code, indent)
-    process(rest, indent)
+    process(rest, indent, colors)
   end
 
   defp write_code(code, indent) do


  ## Text (paragraphs / lists)

  defp process_text(doc=["" | _], para, indent, from_list) do
    write_text(Enum.reverse(para), indent, from_list)
    process(doc, indent)
  end

  defp process_text([], para, indent, from_list) do
    write_text(Enum.reverse(para), indent, from_list)
  end

  defp process_text([line | rest], para, indent, true) do
    { stripped, count } = strip_spaces(line, 0)
    case stripped do
      <<bullet, ?\s, item :: binary>> when bullet in @bullets ->
        write_text(Enum.reverse(para), indent, true)
        process_list(item, rest, count, indent)
      _ ->
        process_text(rest, [line | para], indent, true)
    end
  end

  defp process_text([line | rest], para, indent, from_list) do
    process_text(rest, [line | para], indent, from_list)
  end

  defp write_text(lines, indent, from_list) do

  @doc """
  Prints the documentation body.
  """
  def print(doc, use_ansi // IO.ANSI.terminal?, colors // IEx.Options.get(:colors)) do
    if use_ansi do
      doc
      |> String.split(["\r\n","\n"], trim: false)
      |> Enum.map(&String.rstrip/1)
      |> process("", colors)
    else
      IO.puts doc
    end
    IEx.dont_display_result
  end

  defp process([], _indent, _colors), do: nil

  defp process(["# " <> heading | rest], _indent, colors) do
    write_h1(String.strip(heading))
    process(rest, "", colors)
  end

  defp process(["## " <> heading | rest], _indent, colors) do
    write_h2(String.strip(heading))
    process(rest, "", colors)
  end

  defp process(["### " <> heading | rest], indent, colors) do
    write_h3(String.strip(heading), indent)
    process(rest, indent, colors)
  end

  defp process(["" | rest], indent, colors) do
    process(rest, indent, colors)
  end

  defp process(["    " <> line | rest], indent, colors) do
    process_code(rest, [line], indent, colors)
  end

  defp process([line | rest], indent, colors) do
    { stripped, count } = strip_spaces(line, 0)
    case stripped do
      <<bullet, ?\s, item :: binary >> when bullet in @bullets ->
        process_list(item, rest, count, indent, colors)
      _ ->
        process_text(rest, [line], indent, false, colors)
    end
  end

