Version 0.11.2
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
This document describes the requirements and basic functionality of theme builders. Builders are generally designed for template maintainers' ease of use. Template maintainers SHOULD provide built versions of their template so the end user doesn't need to be aware of builders.
A scheme (or color scheme) is a palette of colors along with some metadata, generally stored in a YAML file. For example: the base16 solarized-dark scheme
A scheme system generally consists of a styling guide and schemes. For example the base16 styling guide and schemes.
A template is a mustache file which acts as a blueprint; it represents how to translate the scheme into an application's desired format. For example: the base16-emacs template is used to convert a base16 scheme into an Emacs theme.
A builder (or theme builder) is a tool which transforms color schemes and templates into application specific configuration. These are primarily targeted at template maintainers or users who build other theme-related tooling.
Building a template is the process of replacing its variables with ones extracted from a scheme; usually outputting it to a file, as defined by the template and template config.
Because the builder spec focuses on what template variables will be provided by the builder, the inputs are defined by the style systems, but must provide certain information to be functional. A common scheme format is provided here for any palette-based scheme systems.
Each scheme system MUST specify a way of obtaining the following information for a given scheme, often by reading from a yaml file or some method of dynamically generating it:
system
- which system this scheme supports. When loading from a yaml file, ifsystem
is not provided, the builder MUST use the provided colors in the palette to determine if this is a legacy scheme in either base16 or base24 format depending on which colors are provided.name
- the scheme's human readable name.slug
- optional. The scheme's machine readable name. The slug SHOULD use dashes rather than underscores. If it is not provided, a builder MUST infer it by slugifying the scheme's name.author
- the scheme's author.description
- optional. A short description of the scheme.variant
- optional, but recommended. Which variant of a given color scheme this qualifies as. Currently only "light" and "dark" are used, but this value could be anything.palette
- all colors used by a scheme, often loaded as HTML hex colors. Some scheme systems may place additional restrictions on the colors in the palette.
Common Scheme Format
The common scheme format is meant to be extensible so additional properties can be added in the future.
The schemes repository provides branches for all backwards incompatible changes, so when a backwards incompatible change is made, the same repository can continue to be used. The main branch will always be the current stable spec. This repository has a separate folder for each scheme system, but it is valid to walk all yaml files and read them directly. All files starting with a .
and the contents of all directories starting with a .
MUST be ignored.
These files have the following structure:
system: "base16"
name: "Scheme Name"
slug: "scheme-name"
author: "Scheme Author"
description: "a short description of the scheme"
variant: "'light' or 'dark'"
palette:
base00: "000000"
base01: "111111"
base02: "222222"
base03: "333333"
base04: "444444"
base05: "555555"
base06: "666666"
base07: "777777"
base08: "888888"
base09: "999999"
base0A: "aaaaaa"
base0B: "bbbbbb"
base0C: "cccccc"
base0D: "dddddd"
base0E: "eeeeee"
base0F: "ffffff"
When scheme is loaded from a common scheme file, the following specifics apply:
- all color values MUST be in HTML hex format and MAY be preceded by a
#
.
Legacy Base16 Scheme Format
This format is deprecated and is included for backwards compatibility reasons. An archived version of all base16 schemes can be found here.
The legacy scheme format is a fallback meant only for the Base16 and Base24 scheme systems.
These files have the following structure:
scheme: "Scheme Name"
author: "Scheme Author"
description: "a short description of the scheme"
base00: "000000"
base01: "111111"
base02: "222222"
base03: "333333"
base04: "444444"
base05: "555555"
base06: "666666"
base07: "777777"
base08: "888888"
base09: "999999"
base0A: "aaaaaa"
base0B: "bbbbbb"
base0C: "cccccc"
base0D: "dddddd"
base0E: "eeeeee"
base0F: "ffffff"
When scheme is loaded from a legacy scheme file, the following specifics apply:
system
will be inferred to be eitherbase16
orbase24
depending on which bases are provided.- all color values MUST be in HTML hex format and MAY be preceded by a
#
. - the
palette
children MUST all be top-level keys. It can be assumed that other thanscheme
,author
, anddescription
arepalette
color values. - the scheme name MUST be specified using
scheme
, notname
.
In order to be built using a standard builder, each template repository MUST have a templates folder containing a config.yaml and any referenced mustache template files.
/templates/*.mustache
- A template file (there may be more than one of these)/templates/config.yaml
- A template configuration file
Template Config Spec
These files have the following structure:
default:
supported-systems: [base16]
filename: "output-directory-name/{{ scheme-system }}-{{ scheme-slug }}.file-extension"
additional:
extension: .another-extension
output: output-directory-name
This example specifies that a Builder is to parse two template files: templates/default.mustache
and templates/additional.mustache
.
supported-systems
defines a list containing all scheme systems this template should be rendered for. This defaults to an array containing only base16
.
filename
defines a mustache template which returns a filename relative to the template repository's root directory. All the template variables listed below are available. Builders MUST error if multiple files will be written with the same name.
extension
and output
are legacy options and SHOULD NOT be used by templates. If filename
is not specified, the output filename will be {{ output }}/{{ scheme-system }}-{{ scheme-slug }}.{{ extension }}
, relative to the template repository's root directory.
As an example, the above config will output the following files for the base16
default-dark
color scheme:
output-directory-name/base16-default-dark.file-extension
, built fromdefault.mustache
.output-directory-name/base16-default-dark.another-extension
, built fromadditional.mustache
.
A builder MUST provide the following variables to template files:
scheme-name
- obtained from thename
key of the scheme inputscheme-author
- obtained from theauthor
key of the scheme inputscheme-description
- obtained from thedescription
key of the scheme inputscheme-slug
- obtained from theslug
key of the scheme input (fallback value: a slugifiedscheme-name
)scheme-slug-underscored
- thescheme-slug
template variable where dashes have been replaced with underscoresscheme-system
- obtained from thesystem
key of the scheme inputscheme-variant
- obtained from thevariant
key of the scheme inputscheme-is-{{variant}}-variant
- dynamic value built from thevariant
key of the scheme file. e.g.variant: "light"
providesscheme-is-light-variant
with a value oftrue
.
Additionally, a builder MUST provide the following template variables for each defined palette token:
{{ token-name }}-hex
- 6-digit hex color value. This does not include a leading#
. e.g "7cafc2".{{ token-name }}-hex-bgr
- built from a reversed version of all the hex values e.g "c2af7c"{{ token-name }}-hex-r
- red component of the hex color value. e.g "7c"{{ token-name }}-hex-g
- green component of the hex color value. e.g "af"{{ token-name }}-hex-b
- blue component of the hex color value. e.g "c2"{{ token-name }}-rgb-r
- red component as a value between0
and255
. e.g "124"{{ token-name }}-rgb-g
- green component as a value between0
and255
. e.g "175"{{ token-name }}-rgb-b
- blue component as a value between0
and255
e.g "194"{{ token-name }}-rgb16-r
- 16 bit red component as a value between0
and65_535
. e.g "15000"{{ token-name }}-rgb16-g
- 16 bit green component as a value between0
and65_535
. e.g "30000"{{ token-name }}-rgb16-b
- 16 bit blue component as a value between0
and65_535
e.g "60000"{{ token-name }}-dec-r
- red component as a value between0
and1.0
. e.g "0.4863"{{ token-name }}-dec-g
- green component as a value between0
and1.0
. e.g "0.6863"{{ token-name }}-dec-b
- blue component as a value between0
and1.0
. e.g "0.7608"
Slugify is simplest to implement in a number of passes:
- Start with your input value, replacing any Unicode characters with their ASCII approximations (as an example
é
would becomee
). On a technical level, this can be done by normalizing the string to the Unicode NFD form (which is the decomposed version), and then dropping any combining characters. - Lowercase all characters. (convert characters
A
toZ
, toa
toz
.) - Replace spaces with the
-
character - Drop all characters that are neither alphanumeric nor dashes
Examples:
Tomorrow Night
->tomorrow-night
Rosé Pine
->rose-pine
Default (Dark)
->default-dark
Mustache was chosen as the templating language due to its simplicity and widespread adoption across languages. YAML was chosen to describe scheme and configuration files for the similar reasons.