Current section
Files
Jump to
Current section
Files
lib/pote/format/atom.ex
defmodule Pote.Format.Atom do
@moduledoc """
Atom format for colours by name.
Supports custom colours defined in the default palette:
primary, secondary, ternary, quaternary, success, warning, error, info,
debug, happy, critical, alert, background, menu,
no_color, gradient_1 through gradient_6
"""
@behaviour Pote.Format
alias Pote.Conversions
@type parsed :: atom()
@spec parse(any()) :: {:ok, parsed()} | :error
def parse(color) when is_atom(color) do
if Map.has_key?(Pote.default_colors(), color) do
{:ok, color}
else
:error
end
end
def parse(color) when is_binary(color), do: parse_binary_color(color)
def parse(_), do: :error
defp parse_binary_color(color) do
atom_color = String.to_existing_atom(color)
parse(atom_color)
rescue
ArgumentError -> :error
end
@spec valid?(any()) :: boolean()
def valid?(color) when is_atom(color) do
Map.has_key?(Pote.default_colors(), color)
end
def valid?(color) when is_binary(color), do: valid_binary_color?(color)
def valid?(_), do: false
defp valid_binary_color?(color) do
atom_color = String.to_existing_atom(color)
Map.has_key?(Pote.default_colors(), atom_color)
rescue
ArgumentError -> false
end
@spec to_rgb(parsed()) :: {0..255, 0..255, 0..255}
def to_rgb(color) do
case Pote.default_colors() do
%{^color => rgb} -> rgb
_ -> {128, 128, 128}
end
end
@spec to_hex(parsed()) :: String.t()
def to_hex(color) do
color |> to_rgb() |> Conversions.rgb_to_hex()
end
@spec to_argb(parsed()) :: {0..255, 0..255, 0..255, 0..255}
def to_argb(color) do
{r, g, b} = to_rgb(color)
{255, r, g, b}
end
@spec to_hsl(parsed()) :: {float(), float(), float()}
def to_hsl(color) do
color |> to_rgb() |> Conversions.rgb_to_hsl()
end
@spec to_hsv(parsed()) :: {float(), float(), float()}
def to_hsv(color) do
color |> to_rgb() |> Conversions.rgb_to_hsv()
end
@spec to_cmyk(parsed()) :: {float(), float(), float(), float()}
def to_cmyk(color) do
color |> to_rgb() |> Conversions.rgb_to_cmyk()
end
@spec to_xterm256(parsed()) :: non_neg_integer()
def to_xterm256(color) do
color |> to_rgb() |> Conversions.rgb_to_xterm256()
end
@spec name(parsed()) :: String.t() | nil
def name(color), do: color
@spec from_rgb({0..255, 0..255, 0..255}) :: parsed()
def from_rgb(rgb) do
Pote.default_colors()
|> Enum.min_by(fn {_name, color_rgb} ->
Conversions.color_distance(rgb, color_rgb)
end)
|> elem(0)
end
@spec info(parsed()) :: map()
def info(parsed) do
%{
format: :atom,
original: parsed,
parsed: parsed,
rgb: to_rgb(parsed),
hex: to_hex(parsed),
argb: to_argb(parsed),
hsl: to_hsl(parsed),
hsv: to_hsv(parsed),
cmyk: to_cmyk(parsed),
xterm256: to_xterm256(parsed),
name: name(parsed)
}
end
end