# Copyright 2025, Matthias Reik # # SPDX-License-Identifier: Apache-2.0 if Mix.env() in [:test, :dev] do defmodule Mix.Tasks.Docs.Fledex.Colors do use Mix.Task require Fledex alias Fledex.Config @shortdoc "Generate documentation for all the available Fledex colors from various known color modules" @requirements ["compile"] @moduledoc """ Generate documentation for all the available Fledex colors from various known color modules See `Fledex.Config.known_color_modules/0` for more details. """ @dir "./pages" @name "colors.md" @switches [ path: :string, name: :string ] @aliases [ o: :path, n: :name ] @doc false @spec run([binary()]) :: any() def run(args) do {cli_opts, _args, _invalid} = OptionParser.parse(args, aliases: @aliases, switches: @switches) out_dir = cli_opts[:path] || @dir out_name = cli_opts[:name] || @name file = Path.join(out_dir, out_name) Mix.shell().info([:green, "Generating Fledex Colors to #{file}"]) content = create_content(Config.known_color_modules()) File.write(file, content, [:utf8, :write]) end defp create_content(modules) do Enum.reduce(modules, create_header(modules), fn {module, type, shortcut}, acc -> acc <> create_section(module, type, shortcut) end) end defp create_header(modules) do header = """ # Color Names This is a list of all the colors that can be found in Fledex. The modules that are marked as `core` are those that will be loaded by default if you `use Fledex` or `use Fledex.Config` and nothing else is mentioned. Those modules that are marked as `optional` are the ones that get shipped with `Fledex` but are not loaded by default. You can still load them through `use Fledex` or `use Fledex.Config` by passing a `:colors` argument (see `Fledex` and `Fledex.Config`) If you specify your own list of color module, you can make use of the alias name (`atom`). ```elixir use Fledex, colors: [:wiki, :css] ``` Therefore the sections are named with the alias instead of the module name. You can also bring your own color name list with your own color modules and load them, but in that case you will need to specify the full color module name. ```elixir use Fledex, colors: [:wiki, MyLibrary.MySuperColors] ``` > #### Info {: .info} > > The colors get loaded by default in the ordered specified here, so if there > is a name conflict the former will win over latter. Once you have specified your color lists, you can access those colors through their alias names (use them through the `Fledex.Color` protocol or the `Fledex.Color.Names` module). When using the `Fledex` DSL the names get by default imported, so you can use them through their function names too (see `Fledex.__using__/1`) This allows to use them in an easy way when defining led sequences like: ```elixir # load our configuration (only Wiki colors) # CAUTION: don't call this several time use Fledex.Config, colors: :wiki # import the Fledex.Leds module to reduce the typing import Fledex.Leds # alias some more modules alias Fledex.Color alias Fledex.Color.Names # create our led sequence with the colors: red, green, blue, purple leds(10) |> light(:red) |> green() |> light(Color.to_colorint(:blue)) |> light(Names.info(:purple)) ``` ### Table of Content """ Enum.reduce(modules, header, fn module, acc -> # long = Atom.to_string(elem(module,0)) type = Atom.to_string(elem(module, 1)) short = Atom.to_string(elem(module, 2)) acc <> """ * [`:#{short}`](##{short}) (#{type}) """ end) end defp create_section(module, type, shortcut) do header = """ ## :#{shortcut} (module: `#{module}`, type: `#{type}`, count: `#{length(module.names())}`) """ module.colors() |> Enum.sort_by(& &1, fn left, right -> left.name < right.name end) |> Enum.reduce(header, fn color, acc -> acc <> create_table_row(color) end) |> close_table() end defp close_table(content) do content <> """
ColorName
""" end @base16 16 defp create_table_row(color) do hex = color.hex |> Integer.to_string(@base16) |> String.pad_leading(6, "0") """
:#{color.name} """ end end end