From 860421ca545009620ea88fdffcd9f8d175084263 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 28 Oct 2022 17:04:33 -0700 Subject: [PATCH] [Function Units] Flush the proposal to the spec (#3437) See #3374 --- spec/built-in-modules/color.md | 67 +++++++++++++++++++++++++++++++--- spec/built-in-modules/list.md | 21 +++++++++++ spec/types/list.md | 31 ++++++++++++++++ 3 files changed, 114 insertions(+), 5 deletions(-) diff --git a/spec/built-in-modules/color.md b/spec/built-in-modules/color.md index 7bf966afee..226ebbbb59 100644 --- a/spec/built-in-modules/color.md +++ b/spec/built-in-modules/color.md @@ -86,7 +86,13 @@ This function is also available as a global function named `adjust-color()`. * If `$alpha` isn't null: - * If `$alpha` isn't a number between -1 and 1 (inclusive), throw an error. + * If `$alpha` isn't a number, throw an error. + + * If `$alpha` has units other than `%`, throw an error. + + * If `$alpha` has unit `%`, set it to `math.div($alpha, 100%)`. + + * If `$alpha < -1` or `$alpha > 1`, throw an error. * Set `alpha` to `alpha + $alpha` clamped between 0 and 1. @@ -239,11 +245,17 @@ This function is also available as a global function named `change-color()`. * If `$color` isn't a color, throw an error. -* If `$alpha` isn't either null or a number between 0 and 1 (inclusive), throw - an error. +* If `$alpha` is null, let `alpha` be `$color`'s alpha channel. Otherwise: + + * If `$alpha` isn't a number, throw an error. + + * If `$alpha` has units other than `%`, throw an error. + + * If `$alpha` has unit `%`, set it to `math.div($alpha, 100%)`. + + * If `$alpha < 0` or `$alpha > 1`, throw an error. -* Let `alpha` be `$color`'s alpha channel if `$alpha` is null or `$alpha` - without units otherwise. + * Let `alpha` be `$alpha` clamped between 0 and 1. * If `$hue` isn't a number or null, throw an error. @@ -509,6 +521,51 @@ This function is also available as a global function named `lightness()`. mix($color1, $color2, $weight: 50%) ``` +* If either `$color1` or `$color2` is not a color, throw an error. + +* If `$weight` isn't a number with unit `%`, throw an error. + +* Let `normal-weight` be `$weight / 50% - 1`. + +* Let `alpha1` and `alpha2` be the alpha values of `$color1` and `$color2` + respectively. + +* Let `alpha-distance` be `alpha1 - alpha2`. + +* Let `weight-by-distance` be `normal-weight * alpha-distance`. + +* If `weight-by-distance == -1`, let `combined-weight1` be `normal-weight`. + +* Otherwise: + + * Let `weight-distance-sum` be `normal-weight + alpha-distance`. + + * Let `combined-weight1` be `weight-distance-sum / (1 + weight-by-distance)`. + +* Let `weight1` be `(combined-weight1 + 1) / 2`. + +* Let `weight2` be `1 - weight1`. + +* Let `red1` and `red2` be the red channels of `$color1` and `$color2` + respectively. + +* Let `red` be `red1 * weight1 + red2 * weight2`. + +* Let `green1` and `green2` be the green channels of `$color1` and `$color2` + respectively. + +* Let `green` be `green1 * weight1 + green2 * weight2`. + +* Let `blue1` and `blue2` be the blue channels of `$color1` and `$color2` + respectively. + +* Let `blue` be `blue1 * weight1 + blue2 * weight2`. + +* Let `alpha` be `alpha1 * weight-scale + alpha2 * (1 - weight-scale)`. + +* Return a color with the given `red`, `green`, and `blue` channels, and `alpha` + value. + ### `opacify()` ``` diff --git a/spec/built-in-modules/list.md b/spec/built-in-modules/list.md index eacc375996..0f06c9d0d5 100644 --- a/spec/built-in-modules/list.md +++ b/spec/built-in-modules/list.md @@ -83,6 +83,17 @@ nth($list, $n) This function is also available as a global function named `nth()`. +* If `$n` isn't a unitless [integer], throw an error. + +* If `$n` is an [invalid index] for `$list`'s [list value], throw an error. + +* Return the value [indexed by] `$n` in `$list`'s list value. + +[integer]: ../types/number.md#integer +[invalid index]: ../types/list.md#index +[indexed by]: ../types/list.md#index +[list value]: ../types/list.md#list-value + ### `set-nth()` ``` @@ -91,6 +102,16 @@ set-nth($list, $n, $value) This function is also available as a global function named `set-nth()`. +* If `$n` isn't a unitless [integer], throw an error. + +* Let `list` be a copy of `$list`'s [list value]. + +* If `$n` is an [invalid index] for `list`, throw an error. + +* Replace the value indexed by `$n` in `list` with `$value`. + +* Return `list`. + ### `zip()` ``` diff --git a/spec/types/list.md b/spec/types/list.md index c855b4d1d7..fff3d3e1a4 100644 --- a/spec/types/list.md +++ b/spec/types/list.md @@ -4,6 +4,8 @@ * [Definitions](#definitions) * [List](#list) + * [List Value](#list-value) + * [Index](#index) ## Definitions @@ -13,3 +15,32 @@ A *SassScript list* (usually referred to as just a *list*) is an ordered sequence of SassScript values. A list may or may not be *bracketed*, and a list has a *separator* which is one of "space", "comma", "slash", or "undecided". Only lists with zero or one elements may have an "undecided" separator. + +### List Value + +A SassScript value's *list value* is the interpretation of that value as a +SassScript list. This differs from type to type: + +* The list value of a list is the list itself. +* The list value of a map is an unbracketed comma-separated list whose elements + are the key/value pairs in the map as two-element unbracketed space-separated + lists. +* The list value of any other value is an unbracketed undecided-separator list + containing only that value. + +### Index + +An *index* is a unitless [integer] that refers to a specific location in a list. +Positive integers count from the beginning of the list, and negative integers +count from the end of the list. The referenced value is said to be *indexed by* +the index. An integer is an *invalid index* for a given list if it's 0 or if its +absolute value is larger than the length of that list. + +> For example, in the values in the list `["a", "b", "c"]` are referred to by +> the following indices: +> +> * `"a"`: 1, -3 +> * `"b"`: 2, -2 +> * `"c"`: 3, -1 + +[integer]: number.md#integer