 defmodule EEx.Tokenizer do
   @moduledoc false
 
-  @type content :: IO.chardata
+  @type content :: IO.chardata()
   @type line :: non_neg_integer
   @type marker :: '=' | '/' | '|' | ''
-  @type token :: {:text, content} |
-                 {:expr | :start_expr | :middle_expr | :end_expr, line, marker, content}
+  @type token ::
+          {:text, content}
+          | {:expr | :start_expr | :middle_expr | :end_expr, line, marker, content}
 
   @doc """
   Tokenizes the given charlist or binary.

  # including the line break following it if there is one.
  defp trim_if_needed(rest, line, opts, buffer, acc) do
    original = {rest, line, buffer}
    if opts[:trim] do
      case {trim_left(buffer, acc), trim_right(rest, line)} do
        {{true, new_buffer}, {true, new_rest, new_line}} ->
          {new_rest, new_line, new_buffer}
        _ ->
          original
      end

  end

  defp tokenize('<%%' ++ t, line, opts, buffer, acc) do
    tokenize(t, line, opts, [?%, ?< | buffer], acc)
  end

  defp tokenize('<%#' ++ t, line, opts, buffer, acc) do
    case expr(t, line, []) do
      {:error, _, _} = error ->
        error

      {:ok, _, new_line, rest} ->
        {rest, new_line, buffer} = trim_if_needed(rest, new_line, opts, buffer, acc)
        tokenize(rest, new_line, opts, buffer, acc)
    end
  end

