defmodule Twix do
alias Twix.DefaultConfig
alias Twix.Mapping
def tw(classes) when is_list(classes) do
Enum.join(classes, " ")
|> tw()
end
def tw(classes) when is_binary(classes) do
classes
|> String.trim()
|> split_classes()
|> Enum.map(&Mapping.new(&1))
|> Enum.reverse()
|> Enum.uniq_by(fn %Mapping{mods: mods, group: group} -> {mods, group} end)
|> handle_conflicts()
|> Enum.reverse()
|> Enum.map(fn %Mapping{base_class: class, mods: mods} ->
(mods ++ [class]) |> Enum.join(":")
end)
|> Enum.join(" ")
end
# -- private functions
defp split_classes(classes) when is_binary(classes) do
Regex.split(~r/\s+/, classes)
end
defp handle_conflicts(mappings) do
mappings
|> Enum.reduce(%{classes: [], conflicts: []}, fn %Mapping{mods: mods, group: group} = data,
acc ->
class = Enum.join(mods ++ [group], ":")
case Enum.member?(acc.conflicts, class) do
true ->
acc
false ->
conflicts =
group
|> get_conflicting_class_group_ids()
%{acc | conflicts: conflicts, classes: acc.classes ++ [data]}
end
end)
|> Map.get(:classes)
end
defp get_conflicting_class_group_ids(class) when is_binary(class) do
String.to_existing_atom(class)
|> get_conflicting_class_group_ids()
end
defp get_conflicting_class_group_ids(class) do
DefaultConfig.conflicting_class_groups()[class] || []
end
end