   end
 
   defp downcase("", acc), do: acc
+
+  # Sigma handling
+
+  for {first, last} <- rangify.(letters) do
+    if first == last do
+      defp letter?(unquote(first)), do: true
+    else
+      defp letter?(codepoint)
+           when codepoint >= unquote(first) and codepoint <= unquote(last),
+           do: true
+    end
+  end
+
+  defp letter?(_), do: false
 
   # Upcase
 


  def downcase(string) when is_binary(string), do: downcase(string, "")

  for codepoint <- letters do
    defp downcase(<<0x03A3::utf8, unquote(codepoint), rest::bits>>, acc) do
      downcase(<<unquote(codepoint), rest::bits>>, <<acc::binary, 0x03C3::utf8>>)
    end
  end
  defp downcase(<<0x03A3::utf8, rest::bits>>, acc) do
    downcase(rest, <<acc::binary, 0x03C2::utf8>>)
  end

    |> IO.iodata_to_binary()
end

rangify = fn [head | tail] ->
  {first, last, acc} =
    Enum.reduce(tail, {head, head, []}, fn
      number, {first, last, acc} when number == first - 1 ->
        {number, last, acc}

      number, {first, last, acc} ->
        {number, number, [{first, last} | acc]}
    end)

  [{first, last} | acc]
end

acc = {[], [], [], %{}, %{}}

{codes, letters, non_breakable, decompositions, combining_classes} =
  Enum.reduce(File.stream!(data_path), acc, fn line, {cacc, lacc, wacc, dacc, kacc} ->
    [
      codepoint,
      _name,
