A theme as a document (spec/04 §5): stored and shipped as a value, and judged as one.
- the value is
%{version: v, theme: node}(to_map/1), and a store's fragment%{theme: node}(fragment/1), a library entry of kind:theme, reads as the same document; - the JSON form is
{"$version": v, "theme": {…}}(to_json/1), each color a tag (a literal$rgb,$color,$series,$ramp, the transforms by name,$blend,$contrast) and pinned steps$steps, written and read by the JSON adapter (Macaw.Layers.Form,Macaw.Layers.Color.Form), every name inramps,colors,stylesanddefaultsa string, as the theme holds it, and every word (an entry's keys and atom values) read from the library's vocabulary and the registered extensions' words (Macaw.Layers.Theme.Extension.words/0).
from_map/2 judges the value as terms, after the version check, with no form written
or read; from_json/2 reads the JSON form through the adapter's gates (spec/01 §5: the
limits, the version, the migration) to the same value. A name given both as its atom and
as its string in one name map of a value is {:duplicate, :name} at its path. Then: a
node that is a name reads as the built-in theme of that name, any other name is
{:unknown_theme, name}; a variable anywhere is {:unresolved, :var, name}, since
nothing applies a theme; a key the theme does not have is :unknown_key; and every
contract a ramp, color or palette entry breaks is {:contract, message} at
[:theme, :ramps | :colors | :styles, name].
The line is at version 2: a literal color is a term, tagged $rgb in the JSON form.
Version 1 wrote it as CSS text; its step tags each string at a color position that
Macaw.Layers.Color.parse/1 reads, so a version 1 document, or a bundle's entry of one,
reads to the same theme.
As a fragment type (spec/02 §1), ramps, colors, styles and defaults are :union
name maps and every other key :override, so a theme document stacks over a built-in as
Macaw.Layers.Theme.new/1 merges.
iex> theme = Macaw.Layers.Theme.new(name: :house, axis: Macaw.Layers.Color.parse!("#555555"))
iex> Macaw.Layers.Theme.Document.from_map(Macaw.Layers.Theme.Document.to_map(theme))
{:ok, theme}
iex> Macaw.Layers.Theme.Document.from_map(%{theme: :dark})
{:ok, Macaw.Layers.Theme.dark()}Ported from visualize's Visualize.Chart.Theme.
Summary
Functions
%{theme: node}: a store's fragment of kind :theme.
The theme a JSON document holds: read through the JSON adapter (Macaw.Layers.Form.read/3:
every gate, then the value, judged), then built as from_map/2 builds it. limits: as
Macaw.Layers.Form.gates/3 takes them, and extensions: as from_map/2: the reader's
vocabulary is the library's words and these extensions' (Extension.words/0), so an
adopter's words read back only with its extension given, and no other atom is made.
The theme a document value or a theme fragment holds, judged as terms, or every fault.
extensions: the extensions the host registers, which the theme carries and its
contracts hold. No form is written or read, so no limit applies: the limits bound what
reading an encoding costs (from_json/2).
The theme as its node: every field but extensions, an unset counterpart and empty
defaults left out. Its names are strings, as the theme holds them (spec/04 §2.1), and
its words as given.
The JSON document, {:ok, json}, stamped "$version", its words written with the
theme's extensions' (Macaw.Layers.Theme.Extension.words/0).
%{version: current, theme: node}.
Functions
@spec fragment(Macaw.Layers.Theme.t()) :: %{theme: map()}
%{theme: node}: a store's fragment of kind :theme.
@spec from_json(String.t(), keyword()) :: {:ok, Macaw.Layers.Theme.t()} | {:error, [Macaw.Layers.Fault.t(), ...]}
The theme a JSON document holds: read through the JSON adapter (Macaw.Layers.Form.read/3:
every gate, then the value, judged), then built as from_map/2 builds it. limits: as
Macaw.Layers.Form.gates/3 takes them, and extensions: as from_map/2: the reader's
vocabulary is the library's words and these extensions' (Extension.words/0), so an
adopter's words read back only with its extension given, and no other atom is made.
@spec from_map(term(), keyword()) :: {:ok, Macaw.Layers.Theme.t()} | {:error, [Macaw.Layers.Fault.t(), ...]}
The theme a document value or a theme fragment holds, judged as terms, or every fault.
extensions: the extensions the host registers, which the theme carries and its
contracts hold. No form is written or read, so no limit applies: the limits bound what
reading an encoding costs (from_json/2).
@spec node(Macaw.Layers.Theme.t()) :: map()
The theme as its node: every field but extensions, an unset counterpart and empty
defaults left out. Its names are strings, as the theme holds them (spec/04 §2.1), and
its words as given.
@spec to_json(Macaw.Layers.Theme.t()) :: {:ok, String.t()} | {:error, [Macaw.Layers.Fault.t(), ...]}
The JSON document, {:ok, json}, stamped "$version", its words written with the
theme's extensions' (Macaw.Layers.Theme.Extension.words/0).
@spec to_map(Macaw.Layers.Theme.t()) :: %{version: pos_integer(), theme: map()}
%{version: current, theme: node}.