From 867fdece6bc5906176c3cc1d339fc9311a725b20 Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Fri, 26 May 2023 23:11:28 +0000 Subject: [PATCH 01/19] Port modules/index --- eleventy.config.js | 2 + source/documentation/modules/index.liquid | 262 ++++++++++++++++++ .../snippets/built-in-module-status.liquid | 4 + source/helpers/function.ts | 108 ++++++++ 4 files changed, 376 insertions(+) create mode 100644 source/documentation/modules/index.liquid create mode 100644 source/documentation/snippets/built-in-module-status.liquid create mode 100644 source/helpers/function.ts diff --git a/eleventy.config.js b/eleventy.config.js index 11a24dfe7..c38ed5a9b 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -16,6 +16,7 @@ const datesPlugin = require('./source/helpers/dates.ts').default; const { liquidEngine, markdownEngine } = require('./source/helpers/engines.ts'); const pagesPlugin = require('./source/helpers/pages.ts').default; const typePlugin = require('./source/helpers/type.ts').default; +const functionPlugin = require('./source/helpers/function.ts').default; /** @param {import('@11ty/eleventy').UserConfig} eleventyConfig */ module.exports = (eleventyConfig) => { @@ -43,6 +44,7 @@ module.exports = (eleventyConfig) => { eleventyConfig.addPlugin(datesPlugin); eleventyConfig.addPlugin(pagesPlugin); eleventyConfig.addPlugin(typePlugin); + eleventyConfig.addPlugin(functionPlugin); // rss plugin eleventyConfig.addLiquidFilter('absoluteUrl', absoluteUrl); diff --git a/source/documentation/modules/index.liquid b/source/documentation/modules/index.liquid new file mode 100644 index 000000000..bf42ad328 --- /dev/null +++ b/source/documentation/modules/index.liquid @@ -0,0 +1,262 @@ +--- +title: Built-In Modules +eleventyComputed: + before_introduction: > + {% render 'documentation/snippets/built-in-module-status' %} +introduction: > + Sass provides many built-in modules which contain useful functions (and the + occasional mixin). These modules can be loaded with the + [`@use` rule](/documentation/at-rules/use) like any user-defined stylesheet, and their + functions can be called [like any other module + member](/documentation/at-rules/use#loading-members). All built-in module URLs begin with + `sass:` to indicate that they're part of Sass itself. +--- + +{% headsUp %} + Before the Sass module system was introduced, all Sass functions were globally + available at all times. Many functions still have global aliases (these are + listed in their documentation). The Sass team discourages their use and will + eventually deprecate them, but for now they remain available for compatibility + with older Sass versions and with LibSass (which doesn't support the module + system yet). + + [A few functions][] are *only* available globally even in the new module + system, either because they have special evaluation behavior ([`if()`][]) or + because they add extra behavior on top of built-in CSS functions ([`rgb()`][] + and [`hsl()`][]). These will not be deprecated and can be used freely. + + [a few functions]: #global-functions + [`if()`]: #if + [`rgb()`]: #rgb + [`hsl()`]: #hsl +{% endheadsUp %} + +{% codeExample 'modules' %} +@use "sass:color"; + +.button { + $primary-color: #6b717f; + color: $primary-color; + border: 1px solid color.scale($primary-color, $lightness: 20%); +} +=== +@use "sass:color" + +.button + $primary-color: #6b717f + color: $primary-color + border: 1px solid color.scale($primary-color, $lightness: 20%) +=== +.button { + color: #6b717f; + border: 1px solid #878d9a; +} +{% endcodeExample %} + +{% markdown %} +Sass provides the following built-in modules: + +* The [`sass:math` module][] provides functions that operate on [numbers][]. + +* The [`sass:string` module][] makes it easy to combine, search, or split apart + [strings][]. + +* The [`sass:color` module][] generates new [colors][] based on existing ones, + making it easy to build color themes. + +* The [`sass:list` module][] lets you access and modify values in [lists][]. + +* The [`sass:map` module][] makes it possible to look up the value associated + with a key in a [map][], and much more. + +* The [`sass:selector` module][] provides access to Sass's powerful selector + engine. + +* The [`sass:meta` module][] exposes the details of Sass's inner workings. + +[`sass:math` module]: /documentation/modules/math +[numbers]: /documentation/values/numbers +[`sass:string` module]: /documentation/modules/string +[strings]: /documentation/values/strings +[`sass:color` module]: /documentation/modules/color +[colors]: /documentation/values/colors +[`sass:list` module]: /documentation/modules/list +[lists]: /documentation/values/lists +[`sass:map` module]: /documentation/modules/map +[map]: /documentation/values/maps +[`sass:selector` module]: /documentation/modules/selector +[`sass:meta` module]: /documentation/modules/meta + +## Global Functions +{% endmarkdown %} + +{% function 'hsl($hue $saturation $lightness)', 'hsl($hue $saturation $lightness / $alpha)', 'hsl($hue, $saturation, $lightness, $alpha: 1)', 'hsla($hue $saturation $lightness)', 'hsla($hue $saturation $lightness / $alpha)', 'hsla($hue, $saturation, $lightness, $alpha: 1)', 'returns:color' %} +{% compatibility '1.15.0', false, null, false, 'Level 4 Syntax' %} +LibSass and Ruby Sass only support the following signatures: + +* `hsl($hue, $saturation, $lightness)` +* `hsla($hue, $saturation, $lightness, $alpha)` + +Note that for these implementations, the `$alpha` argument is *required* if +the function name `hsla()` is used, and *forbidden* if the function name +`hsl()` is used. +{% endcompatibility %} + +{% compatibility true, false, null, '3.7.0', 'Percent Alpha' %} +LibSass and older versions of Ruby Sass don't support alpha values specified as +percentages. +{% endcompatibility %} + +Returns a color with the given [hue, saturation, and lightness][] and the given +alpha channel. + +[hue, saturation, and lightness]: https://en.wikipedia.org/wiki/HSL_and_HSV + +The hue is a number between `0deg` and `360deg` (inclusive) and may be +unitless. The saturation and lightness are numbers between `0%` and `100%` +(inclusive) and may *not* be unitless. The alpha channel can be specified as +either a unitless number between 0 and 1 (inclusive), or a percentage between +`0%` and `100%` (inclusive). + +[unitless]: values/numbers#units + +{% funFact %} +You can pass [special functions][] like `calc()` or `var()` in place of any +argument to `hsl()`. You can even use `var()` in place of multiple +arguments, since it might be replaced by multiple values! When a color +function is called this way, it returns an unquoted string using the same +signature it was called with. + +[special functions]: /documentation/syntax/special-functions + +{% codeExample 'hsl-special', false %} +@debug hsl(210deg 100% 20% / var(--opacity)); // hsl(210deg 100% 20% / var(--opacity)) +@debug hsla(var(--peach), 20%); // hsla(var(--peach), 20%) +=== +@debug hsl(210deg 100% 20% / var(--opacity)) // hsl(210deg 100% 20% / var(--opacity)) +@debug hsla(var(--peach), 20%) // hsla(var(--peach), 20%) +{% endcodeExample %} +{% endfunFact %} + +{% headsUp %} +Sass's [special parsing rules][] for slash-separated values make it +difficult to pass variables for `$lightness` or `$alpha` when using the +`hsl($hue $saturation $lightness / $alpha)` signature. Consider using +`hsl($hue, $saturation, $lightness, $alpha)` instead. + +[special parsing rules]: /documentation/operators/numeric#slash-separated-values +{% endheadsUp %} + +{% codeExample 'hsl', false %} +@debug hsl(210deg 100% 20%); // #036 +@debug hsl(34, 35%, 92%); // #f2ece4 +@debug hsl(210deg 100% 20% / 50%); // rgba(0, 51, 102, 0.5) +@debug hsla(34, 35%, 92%, 0.2); // rgba(242, 236, 228, 0.2) +=== +@debug hsl(210deg 100% 20%) // #036 +@debug hsl(34, 35%, 92%) // #f2ece4 +@debug hsl(210deg 100% 20% / 50%) // rgba(0, 51, 102, 0.5) +@debug hsla(34, 35%, 92%, 0.2) // rgba(242, 236, 228, 0.2) +{% endcodeExample %} +{% endfunction %} + +{% function 'if($condition, $if-true, $if-false)' %} +Returns `$if-true` if `$condition` is [truthy][], and `$if-false` otherwise. + +This function is special in that it doesn't even evaluate the argument that +isn't returned, so it's safe to call even if the unused argument would throw an +error. + +[truthy]: /documentation/at-rules/control/if#truthiness-and-falsiness + +{% codeExample 'debug', false %} +@debug if(true, 10px, 15px); // 10px +@debug if(false, 10px, 15px); // 15px +@debug if(variable-defined($var), $var, null); // null +=== +@debug if(true, 10px, 15px) // 10px +@debug if(false, 10px, 15px) // 15px +@debug if(variable-defined($var), $var, null) // null +{% endcodeExample %} +{% endfunction %} + +{% function 'rgb($red $green $blue)', 'rgb($red $green $blue / $alpha)', 'rgb($red, $green, $blue, $alpha: 1)', 'rgb($color, $alpha)', 'rgba($red $green $blue)', 'rgba($red $green $blue / $alpha)', 'rgba($red, $green, $blue, $alpha: 1)', 'rgba($color, $alpha)', 'returns:color' %} +{% compatibility '1.15.0', false, null, false, 'Level 4 Syntax' %} +LibSass and Ruby Sass only support the following signatures: + +* `rgb($red, $green, $blue)` +* `rgba($red, $green, $blue, $alpha)` +* `rgba($color, $alpha)` + +Note that for these implementations, the `$alpha` argument is *required* if +the function name `rgba()` is used, and *forbidden* if the function name +`rgb()` is used. +{% endcompatibility %} + +{% compatibility true, false, null, '3.7.0', 'Percent Alpha' %} +LibSass and older versions of Ruby Sass don't support alpha values specified +as percentages. +{% endcompatibility %} + +If `$red`, `$green`, `$blue`, and optionally `$alpha` are passed, returns a +color with the given red, green, blue, and alpha channels. + +Each channel can be specified as either a [unitless][] number between 0 and +255 (inclusive), or a percentage between `0%` and `100%` (inclusive). The +alpha channel can be specified as either a unitless number between 0 and 1 +(inclusive), or a percentage between `0%` and `100%` (inclusive). + +[unitless]: /documentation/values/numbers#units + +{% funFact %} +You can pass [special functions][] like `calc()` or `var()` in place of any +argument to `rgb()`. You can even use `var()` in place of multiple +arguments, since it might be replaced by multiple values! When a color +function is called this way, it returns an unquoted string using the same +signature it was called with. + +[special functions]: /documentation/syntax/special-functions + +{% codeExample 'rgb-special', false %} +@debug rgb(0 51 102 / var(--opacity)); // rgb(0 51 102 / var(--opacity)) +@debug rgba(var(--peach), 0.2); // rgba(var(--peach), 0.2) +=== +@debug rgb(0 51 102 / var(--opacity)) // rgb(0 51 102 / var(--opacity)) +@debug rgba(var(--peach), 0.2) // rgba(var(--peach), 0.2) +{% endcodeExample %} +{% endfunFact %} + +{% headsUp %} +Sass's [special parsing rules][] for slash-separated values make it +difficult to pass variables for `$blue` or `$alpha` when using the +`rgb($red $green $blue / $alpha)` signature. Consider using +`rgb($red, $green, $blue, $alpha)` instead. + +[special parsing rules]: /documentation/operators/numeric#slash-separated-values +{% endheadsUp %} + +{% codeExample 'rgb', false %} +@debug rgb(0 51 102); // #036 +@debug rgb(95%, 92.5%, 89.5%); // #f2ece4 +@debug rgb(0 51 102 / 50%); // rgba(0, 51, 102, 0.5) +@debug rgba(95%, 92.5%, 89.5%, 0.2); // rgba(242, 236, 228, 0.2) +=== +@debug rgb(0 51 102) // #036 +@debug rgb(95%, 92.5%, 89.5%) // #f2ece4 +@debug rgb(0 51 102 / 50%) // rgba(0, 51, 102, 0.5) +@debug rgba(95%, 92.5%, 89.5%, 0.2) // rgba(242, 236, 228, 0.2) +{% endcodeExample %} + +--- + +If `$color` and `$alpha` are passed, this returns `$color` with the given +`$alpha` channel instead of its original alpha channel. + +{% codeExample 'color-and-alpha', false %} +@debug rgb(#f2ece4, 50%); // rgba(242, 236, 228, 0.5); +@debug rgba(rgba(0, 51, 102, 0.5), 1); // #003366 +=== +@debug rgb(#f2ece4, 50%) // rgba(242, 236, 228, 0.5) +@debug rgba(rgba(0, 51, 102, 0.5), 1) // #003366 +{% endcodeExample %} +{% endfunction %} diff --git a/source/documentation/snippets/built-in-module-status.liquid b/source/documentation/snippets/built-in-module-status.liquid new file mode 100644 index 000000000..3856109cf --- /dev/null +++ b/source/documentation/snippets/built-in-module-status.liquid @@ -0,0 +1,4 @@ +{% compatibility '1.23.0', false, null, false %} + Only Dart Sass currently supports loading built-in modules with `@use`. Users + of other implementations must call functions using their global names instead. +{% endcompatibility %} diff --git a/source/helpers/function.ts b/source/helpers/function.ts new file mode 100644 index 000000000..4007da879 --- /dev/null +++ b/source/helpers/function.ts @@ -0,0 +1,108 @@ +import * as cheerio from 'cheerio'; + +import { codeBlock } from './components'; +import { markdown } from './type'; + +const links: Record = { + number: '/documentation/values/numbers', + string: '/documentation/values/strings', + 'quoted string': '/documentation/values/strings#quoted', + 'unquoted string': '/documentation/values/strings#unquoted', + color: '/documentation/values/colors', + list: '/documentation/values/lists', + map: '/documentation/values/maps', + boolean: '/documentation/values/booleans', + null: '/documentation/values/null', + function: '/documentation/values/functions', + selector: '/documentation/modules/selector#selector-values', +}; + +const returnTypeLink = (returnType: string) => + returnType + .split('|') + .map((type) => { + type = type.trim(); + const link = links[type]; + if (!link) { + throw new Error(`Unknown type ${type}`); + } + return `${type}`; + }) + .join(' | '); + +/** Renders API docs for a Sass function (or mixin). + * + * The function's name is parsed from the signature. The API description is + * passed as a Markdown block. If `returns:type` is passed as the last argument, + * it's included as the function's return type. + * + * Multiple signatures may be passed, in which case they're all included in + * sequence. + */ +export function _function(content: string, ...signatures: string[]) { + // Parse the last argument as the return type, if it's present + const returns = signatures.at(-1)?.match(/returns?:\s*(.*)/)?.[1]; + if (returns) signatures.pop(); + + // Highlight each signature + const names: string[] = []; + const highlightedSignatures = signatures.map((signature) => { + const [name] = signature.split('(', 2); + const nameWithoutNamespace = name.split('.').at(-1) || name; + const html = codeBlock(`@function ${signature}`, 'scss'); + const $ = cheerio.load(html); + const signatureElements = $('pre code') + .contents() + .filter((index, element) => $(element).text() !== '@function'); + if (!names.includes(nameWithoutNamespace)) { + names.push(nameWithoutNamespace); + const nameEl = signatureElements + .filter((index, element) => { + return $(element).text() == nameWithoutNamespace; + }) + .eq(0); + nameEl.addClass('docSearch-function'); + nameEl.attr('name', name); + } + return signatureElements + .toArray() + .map((el) => $.html(el)) + .join('') + .trim() + .replace(/\n/g, ' '); + }); + + // Add the return type after the last signature + let mergedSignatures = highlightedSignatures.join(' '); + if (returns) { + mergedSignatures += ` //=> ${returnTypeLink( + returns, + )}`; + } + + // Assemble the final HTML + const $ = cheerio.load(''); + const div = $('
') + .addClass('sl-c-callout sl-c-callout--function') + .attr('id', names[0]); + const pre = $('
').addClass('language-scss');
+  const anchor = $('').addClass('anchor').attr('href', `#${names[0]}`);
+  const code = $('')
+    .addClass('language-scss')
+    .html(mergedSignatures);
+  pre.append(anchor).append(code);
+  div.append(pre).append(markdown(content));
+  $('body').append(div);
+  names.slice(1).forEach((name) => {
+    const div = $('
').attr('id', name); + $('body').append(div); + }); + return $('body').html() || ''; +} + +/* eslint-disable @typescript-eslint/no-unsafe-member-access, + @typescript-eslint/no-unsafe-call, + @typescript-eslint/no-explicit-any */ +export default function typePlugin(eleventyConfig: any) { + eleventyConfig.addPairedLiquidShortcode('function', _function); +} From 446b78b90d0d46ed8d0c69cfd77cf467164d2ce4 Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Sat, 27 May 2023 00:23:55 +0000 Subject: [PATCH 02/19] Port modules/colors --- source/documentation/modules/color.liquid | 834 ++++++++++++++++++++++ source/helpers/function.ts | 6 +- 2 files changed, 837 insertions(+), 3 deletions(-) create mode 100644 source/documentation/modules/color.liquid diff --git a/source/documentation/modules/color.liquid b/source/documentation/modules/color.liquid new file mode 100644 index 000000000..63b5aa1b9 --- /dev/null +++ b/source/documentation/modules/color.liquid @@ -0,0 +1,834 @@ +--- +title: sass:color +--- + +{% render 'documentation/snippets/built-in-module-status' %} + +{% function 'color.adjust($color,!!! $red: null, $green: null, $blue: null,!!! $hue: null, $saturation: null, $lightness: null,!!! $whiteness: null, $blackness: null,!!! $alpha: null)', 'adjust-color(...)', 'returns:color' %} +{% compatibility '1.28.0' false, null, false, '$whiteness and $blackness' %}{% endcompatibility %} + +Increases or decreases one or more properties of `$color` by fixed amounts. + +Adds the value passed for each keyword argument to the corresponding property +of the color, and returns the adjusted color. It's an error to specify an RGB +property (`$red`, `$green`, and/or `$blue`) at the same time as an HSL +property (`$hue`, `$saturation`, and/or `$lightness`), or either of those at +the same time as an [HWB][] property (`$hue`, `$whiteness`, and/or +`$blackness`). + +[HWB]: https://en.wikipedia.org/wiki/HWB_color_model + +All optional arguments must be numbers. The `$red`, `$green`, and `$blue` +arguments must be [unitless][] and between -255 and 255 (inclusive). The +`$hue` argument must have either the unit `deg` or no unit. The `$saturation`, +`$lightness`, `$whiteness`, and `$blackness` arguments must be between `-100%` +and `100%` (inclusive), and may not be unitless. The `$alpha` argument must be +unitless and between -1 and 1 (inclusive). + +[unitless]: /documentation/values/numbers#units + +See also: + +* [`color.scale()`](#scale) for fluidly scaling a color's properties. +* [`color.change()`](#change) for setting a color's properties. + +{% codeExample 'adjust-color', false %} +@debug color.adjust(#6b717f, $red: 15); // #7a717f +@debug color.adjust(#d2e1dd, $red: -10, $blue: 10); // #c8e1e7 +@debug color.adjust(#998099, $lightness: -30%, $alpha: -0.4); // rgba(71, 57, 71, 0.6) +=== +@debug color.adjust(#6b717f, $red: 15) // #7a717f +@debug color.adjust(#d2e1dd, $red: -10, $blue: 10) // #c8e1e7 +@debug color.adjust(#998099, $lightness: -30%, $alpha: -0.4) // rgba(71, 57, 71, 0.6) +{% endcodeExample %} +{% endfunction %} + +{% function 'adjust-hue($color, $degrees)', 'returns:color' %} +Increases or decreases `$color`'s hue. + +The `$hue` must be a number between `-360deg` and `360deg` (inclusive) to add +to `$color`'s hue. It may be [unitless][] but it may not have any unit other +than `deg`. + +[unitless]: /documentation/values/numbers#units + +See also [`color.adjust()`](#adjust), which can adjust any property of a +color. + +{% headsUp %} +Because `adjust-hue()` is redundant with [`adjust()`](#adjust), it's not +included directly in the new module system. Instead of +`adjust-hue($color, $amount)`, you can write +[`color.adjust($color, $hue: $amount)`](#adjust). +{% endheadsUp %} + +{% codeExample 'adjust-hue', false %} +// Hue 222deg becomes 282deg. +@debug adjust-hue(#6b717f, 60deg); // #796b7f + +// Hue 164deg becomes 104deg. +@debug adjust-hue(#d2e1dd, -60deg); // #d6e1d2 + +// Hue 210deg becomes 255deg. +@debug adjust-hue(#036, 45); // #1a0066 +=== +// Hue 222deg becomes 282deg. +@debug adjust-hue(#6b717f, 60deg) // #796b7f + +// Hue 164deg becomes 104deg. +@debug adjust-hue(#d2e1dd, -60deg) // #d6e1d2 + +// Hue 210deg becomes 255deg. +@debug adjust-hue(#036, 45) // #1a0066 +{% endcodeExample %} +{% endfunction %} + +{% function 'color.alpha($color)', 'alpha($color)', 'opacity($color)', 'returns:number' %} +Returns the alpha channel of `$color` as a number between 0 and 1. + +As a special case, this supports the Internet Explorer syntax +`alpha(opacity=20)`, for which it returns an [unquoted string][]. + +[unquoted string]: /documentation/values/strings#unquoted + +See also: + +* [`color.red()`](#red) for getting a color's red channel. +* [`color.green()`](#green) for getting a color's green channel. +* [`color.blue()`](#blue) for getting a color's blue channel. +* [`color.hue()`](#hue) for getting a color's hue. +* [`color.saturation()`](#saturation) for getting a color's saturation. +* [`color.lightness()`](#lightness) for getting a color's lightness. + +{% codeExample 'color-alpha', false %} +@debug color.alpha(#e1d7d2); // 1 +@debug color.opacity(rgb(210, 225, 221, 0.4)); // 0.4 +@debug alpha(opacity=20); // alpha(opacity=20) +=== +@debug color.alpha(#e1d7d2) // 1 +@debug color.opacity(rgb(210, 225, 221, 0.4)) // 0.4 +@debug alpha(opacity=20) // alpha(opacity=20) +{% endcodeExample %} +{% endfunction %} + +{% function 'color.blackness($color)', 'returns:number' %} +{% compatibility '1.28.0', false, null, false %}{% endcompatibility %} + +Returns the [HWB][] blackness of `$color` as a number between `0%` and `100%`. + +[HWB]: https://en.wikipedia.org/wiki/HWB_color_model + +See also: + +* [`color.red()`](#red) for getting a color's red channel. +* [`color.green()`](#green) for getting a color's green channel. +* [`color.hue()`](#hue) for getting a color's hue. +* [`color.saturation()`](#saturation) for getting a color's saturation. +* [`color.lightness()`](#lightness) for getting a color's lightness. +* [`color.whiteness()`](#whiteness) for getting a color's whiteness. +* [`color.alpha()`](#alpha) for getting a color's alpha channel. + +{% codeExample 'color-blackness', false %} +@debug color.blackness(#e1d7d2); // 11.7647058824% +@debug color.blackness(white); // 0% +@debug color.blackness(black); // 100% +=== +@debug color.blackness(#e1d7d2) // 11.7647058824% +@debug color.blackness(white) // 0% +@debug color.blackness(black) // 100% +{% endcodeExample %} +{% endfunction %} + +{% function 'color.blue($color)', 'blue($color)', 'returns:number' %} +Returns the blue channel of `$color` as a number between 0 and 255. + +See also: + +* [`color.red()`](#red) for getting a color's red channel. +* [`color.green()`](#green) for getting a color's green channel. +* [`color.hue()`](#hue) for getting a color's hue. +* [`color.saturation()`](#saturation) for getting a color's saturation. +* [`color.lightness()`](#lightness) for getting a color's lightness. +* [`color.whiteness()`](#whiteness) for getting a color's whiteness. +* [`color.blackness()`](#blackness) for getting a color's blackness. +* [`color.alpha()`](#alpha) for getting a color's alpha channel. + +{% codeExample 'color-blue', false %} +@debug color.blue(#e1d7d2); // 210 +@debug color.blue(white); // 255 +@debug color.blue(black); // 0 +=== +@debug color.blue(#e1d7d2) // 210 +@debug color.blue(white) // 255 +@debug color.blue(black) // 0 +{% endcodeExample %} +{% endfunction %} + +{% function 'color.change($color,!!! $red: null, $green: null, $blue: null,!!! $hue: null, $saturation: null, $lightness: null,!!! $whiteness: null, $blackness: null,!!! $alpha: null)', 'change-color(...)', 'returns:color' %} +{% compatibility '1.28.0', false, null, false, '$whiteness and $blackness' %}{% endcompatibility %} + +Sets one or more properties of a color to new values. + +Uses the value passed for each keyword argument in place of the corresponding +property of the color, and returns the changed color. It's an error to specify +an RGB property (`$red`, `$green`, and/or `$blue`) at the same time as an HSL +property (`$hue`, `$saturation`, and/or `$lightness`), or either of those at +the same time as an [HWB][] property (`$hue`, `$whiteness`, and/or +`$blackness`). + +[HWB]: https://en.wikipedia.org/wiki/HWB_color_model + +All optional arguments must be numbers. The `$red`, `$green`, and `$blue` +arguments must be [unitless][] and between 0 and 255 (inclusive). The `$hue` +argument must have either the unit `deg` or no unit. The `$saturation`, +`$lightness`, `$whiteness`, and `$blackness` arguments must be between `0%` +and `100%` (inclusive), and may not be unitless. The `$alpha` argument must be +unitless and between 0 and 1 (inclusive). + +[unitless]: /documentation/values/numbers#units + +See also: + +* [`color.scale()`](#scale) for fluidly scaling a color's properties. +* [`color.adjust()`](#adjust) for adjusting a color's properties by fixed +amounts. + +{% codeExample 'color-change', false %} +@debug color.change(#6b717f, $red: 100); // #64717f +@debug color.change(#d2e1dd, $red: 100, $blue: 50); // #64e132 +@debug color.change(#998099, $lightness: 30%, $alpha: 0.5); // rgba(85, 68, 85, 0.5) +=== +@debug color.change(#6b717f, $red: 100) // #64717f +@debug color.change(#d2e1dd, $red: 100, $blue: 50) // #64e132 +@debug color.change(#998099, $lightness: 30%, $alpha: 0.5) // rgba(85, 68, 85, 0.5) +{% endcodeExample %} +{% endfunction %} + +{% function 'color.complement($color)', 'complement($color)', 'returns:color' %} +Returns the RGB [complement][] of `$color`. + +This is identical to [`color.adjust($color, $hue: 180deg)`](#adjust). + +[complement]: https://en.wikipedia.org/wiki/Complementary_colors + +{% codeExample 'color-complement', false %} +// Hue 222deg becomes 42deg. +@debug color.complement(#6b717f); // #7f796b + +// Hue 164deg becomes 344deg. +@debug color.complement(#d2e1dd); // #e1d2d6 + +// Hue 210deg becomes 30deg. +@debug color.complement(#036); // #663300 +=== +// Hue 222deg becomes 42deg. +@debug color.complement(#6b717f) // #7f796b + +// Hue 164deg becomes 344deg. +@debug color.complement(#d2e1dd) // #e1d2d6 + +// Hue 210deg becomes 30deg. +@debug color.complement(#036) // #663300 +{% endcodeExample %} +{% endfunction %} + +{% function 'darken($color, $amount)', 'returns:color' %} +Makes `$color` darker. + +The `$amount` must be a number between `0%` and `100%` (inclusive). Decreases +the HSL lightness of `$color` by that amount. + +{% headsUp %} +The `darken()` function decreases lightness by a fixed amount, which is often +not the desired effect. To make a color a certain percentage darker than it was +before, use [`color.scale()`](#scale) instead. + +Because `darken()` is usually not the best way to make a color darker, it's +not included directly in the new module system. However, if you have to +preserve the existing behavior, `darken($color, $amount)` can be written +[`color.adjust($color, $lightness: -$amount)`](#adjust). + +{% codeExample 'color-darken', false %} +// #036 has lightness 20%, so when darken() subtracts 30% it just returns black. +@debug darken(#036, 30%); // black + +// scale() instead makes it 30% darker than it was originally. +@debug color.scale(#036, $lightness: -30%); // #002447 +=== +// #036 has lightness 20%, so when darken() subtracts 30% it just returns black. +@debug darken(#036, 30%) // black + +// scale() instead makes it 30% darker than it was originally. +@debug color.scale(#036, $lightness: -30%) // #002447 +{% endcodeExample %} +{% endheadsUp %} + +{% codeExample 'color-darken-2', false %} +// Lightness 92% becomes 72%. +@debug darken(#b37399, 20%); // #7c4465 + +// Lightness 85% becomes 45%. +@debug darken(#f2ece4, 40%); // #b08b5a + +// Lightness 20% becomes 0%. +@debug darken(#036, 30%); // black +=== +// Lightness 92% becomes 72%. +@debug darken(#b37399, 20%) // #7c4465 + +// Lightness 85% becomes 45%. +@debug darken(#f2ece4, 40%) // #b08b5a + +// Lightness 20% becomes 0%. +@debug darken(#036, 30%) // black +{% endcodeExample %} +{% endfunction %} + +{% function 'desaturate($color, $amount)', 'returns:color' %} +Makes `$color` less saturated. + +The `$amount` must be a number between `0%` and `100%` (inclusive). Decreases +the HSL saturation of `$color` by that amount. + +{% headsUp %} +The `desaturate()` function decreases saturation by a fixed amount, which is +often not the desired effect. To make a color a certain percentage less +saturated than it was before, use [`color.scale()`](#scale) instead. + +Because `desaturate()` is usually not the best way to make a color less +saturated, it's not included directly in the new module system. However, if +you have to preserve the existing behavior, `desaturate($color, $amount)` +can be written [`color.adjust($color, $saturation: -$amount)`](#adjust). + +{% codeExample 'color-desaturate', false %} +// #d2e1dd has saturation 20%, so when desaturate() subtracts 30% it just +// returns gray. +@debug desaturate(#d2e1dd, 30%); // #dadada + +// scale() instead makes it 30% less saturated than it was originally. +@debug color.scale(#6b717f, $saturation: -30%); // #6e727c +=== +// #6b717f has saturation 20%, so when desaturate() subtracts 30% it just +// returns gray. +@debug desaturate(#d2e1dd, 30%) // #dadada + +// scale() instead makes it 30% less saturated than it was originally. +@debug color.scale(#6b717f, $saturation: -30%) // #6e727c +{% endcodeExample %} +{% endheadsUp %} + +{% codeExample 'color-desaturate-2', false %} +// Saturation 100% becomes 80%. +@debug desaturate(#036, 20%); // #0a335c + +// Saturation 35% becomes 15%. +@debug desaturate(#f2ece4, 20%); // #eeebe8 + +// Saturation 20% becomes 0%. +@debug desaturate(#d2e1dd, 30%); // #dadada +=== +// Saturation 100% becomes 80%. +@debug desaturate(#036, 20%) // #0a335c + +// Saturation 35% becomes 15%. +@debug desaturate(#f2ece4, 20%) // #eeebe8 + +// Saturation 20% becomes 0%. +@debug desaturate(#d2e1dd, 30%) // #dadada +{% endcodeExample %} +{% endfunction %} + +{% function 'color.grayscale($color)', 'grayscale($color)', 'returns:color' %} +Returns a gray color with the same lightness as `$color`. + +This is identical to [`color.change($color, $saturation: 0%)`](#change). + +{% codeExample 'color-grayscale', false %} +@debug color.grayscale(#6b717f); // #757575 +@debug color.grayscale(#d2e1dd); // #dadada +@debug color.grayscale(#036); // #333333 +=== +@debug color.grayscale(#6b717f) // #757575 +@debug color.grayscale(#d2e1dd) // #dadada +@debug color.grayscale(#036) // #333333 +{% endcodeExample %} +{% endfunction %} + +{% function 'color.green($color)', 'green($color)', 'returns:number' %} +Returns the green channel of `$color` as a number between 0 and 255. + +See also: + +* [`color.red()`](#red) for getting a color's red channel. +* [`color.blue()`](#blue) for getting a color's blue channel. +* [`color.hue()`](#hue) for getting a color's hue. +* [`color.saturation()`](#saturation) for getting a color's saturation. +* [`color.lightness()`](#lightness) for getting a color's lightness. +* [`color.whiteness()`](#whiteness) for getting a color's whiteness. +* [`color.blackness()`](#blackness) for getting a color's blackness. +* [`color.alpha()`](#alpha) for getting a color's alpha channel. + +{% codeExample 'color-green', false %} +@debug color.green(#e1d7d2); // 215 +@debug color.green(white); // 255 +@debug color.green(black); // 0 +=== +@debug color.green(#e1d7d2) // 215 +@debug color.green(white) // 255 +@debug color.green(black) // 0 +{% endcodeExample %} +{% endfunction %} + +{% function 'color.hue($color)', 'hue($color)', 'returns:number' %} +Returns the hue of `$color` as a number between `0deg` and `360deg`. + +See also: + +* [`color.red()`](#red) for getting a color's red channel. +* [`color.green()`](#green) for getting a color's green channel. +* [`color.blue()`](#blue) for getting a color's blue channel. +* [`color.saturation()`](#saturation) for getting a color's saturation. +* [`color.lightness()`](#lightness) for getting a color's lightness. +* [`color.whiteness()`](#whiteness) for getting a color's whiteness. +* [`color.blackness()`](#blackness) for getting a color's blackness. +* [`color.alpha()`](#alpha) for getting a color's alpha channel. + +{% codeExample 'color-hue', false %} +@debug color.hue(#e1d7d2); // 20deg +@debug color.hue(#f2ece4); // 34.2857142857deg +@debug color.hue(#dadbdf); // 228deg +=== +@debug color.hue(#e1d7d2) // 20deg +@debug color.hue(#f2ece4) // 34.2857142857deg +@debug color.hue(#dadbdf) // 228deg +{% endcodeExample %} +{% endfunction %} + +{% function 'color.hwb($hue $whiteness $blackness)', 'color.hwb($hue $whiteness $blackness / $alpha)', 'color.hwb($hue, $whiteness, $blackness, $alpha: 1)', 'returns:color' %} +{% compatibility '1.28.0', false, null, false %}{% endcompatibility %} + +Returns a color with the given [hue, whiteness, and blackness][] and the given +alpha channel. + +[hue, whiteness, and blackness]: https://en.wikipedia.org/wiki/HWB_color_model + +The hue is a number between `0deg` and `360deg` (inclusive). The whiteness and +blackness are numbers between `0%` and `100%` (inclusive). The hue may be +[unitless][], but the whiteness and blackness must have unit `%`. The alpha +channel can be specified as either a unitless number between 0 and 1 +(inclusive), or a percentage between `0%` and `100%` (inclusive). + +[unitless]: /documentation/values/numbers#units + +{% headsUp %} +Sass's [special parsing rules][] for slash-separated values make it +difficult to pass variables for `$blackness` or `$alpha` when using the +`color.hwb($hue $whiteness $blackness / $alpha)` signature. Consider using +`color.hwb($hue, $whiteness, $blackness, $alpha)` instead. + +[special parsing rules]: /documentation/operators/numeric#slash-separated-values +{% endheadsUp %} + +{% codeExample 'color-hwb', false %} +@debug color.hwb(210, 0%, 60%); // #036 +@debug color.hwb(34, 89%, 5%); // #f2ece4 +@debug color.hwb(210 0% 60% / 0.5); // rgba(0, 51, 102, 0.5) +=== +@debug color.hwb(210, 0%, 60%) // #036 +@debug color.hwb(34, 89%, 5%) // #f2ece4 +@debug color.hwb(210 0% 60% / 0.5) // rgba(0, 51, 102, 0.5) +{% endcodeExample %} +{% endfunction %} + +{% function 'color.ie-hex-str($color)', 'ie-hex-str($color)', 'returns:unquoted string' %} +Returns an unquoted string that represents `$color` in the `#AARRGGBB` format +expected by Internet Explorer's [`-ms-filter`][] property. + +[`-ms-filter`]: https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter + +{% codeExample 'color-ie-hex-str', false %} +@debug color.ie-hex-str(#b37399); // #FFB37399 +@debug color.ie-hex-str(#808c99); // #FF808C99 +@debug color.ie-hex-str(rgba(242, 236, 228, 0.6)); // #99F2ECE4 +=== +@debug color.ie-hex-str(#b37399); // #FFB37399 +@debug color.ie-hex-str(#808c99); // #FF808C99 +@debug color.ie-hex-str(rgba(242, 236, 228, 0.6)); // #99F2ECE4 +{% endcodeExample %} +{% endfunction %} + +{% function 'color.invert($color, $weight: 100%)', 'invert($color, $weight: 100%)', 'returns:color' %} +Returns the inverse or [negative][] of `$color`. + +[negative]: https://en.wikipedia.org/wiki/Negative_(photography) + +The `$weight` must be a number between `0%` and `100%` (inclusive). A higher +weight means the result will be closer to the negative, and a lower weight means +it will be closer to `$color`. Weight `50%` will always produce `#808080`. + +{% codeExample 'color-invert', false %} +@debug color.invert(#b37399); // #4c8c66 +@debug color.invert(black); // white +@debug color.invert(#550e0c, 20%); // #663b3a +=== +@debug color.invert(#b37399) // #4c8c66 +@debug color.invert(black) // white +@debug color.invert(#550e0c, 20%) // #663b3a +{% endcodeExample %} +{% endfunction %} + +{% function 'lighten($color, $amount)', 'returns:color' %} +Makes `$color` lighter. + +The `$amount` must be a number between `0%` and `100%` (inclusive). Increases +the HSL lightness of `$color` by that amount. + +{% headsUp %} +The `lighten()` function increases lightness by a fixed amount, which is often +not the desired effect. To make a color a certain percentage lighter than it was +before, use [`scale()`](#scale) instead. + +Because `lighten()` is usually not the best way to make a color lighter, +it's not included directly in the new module system. However, if you have to +preserve the existing behavior, `lighten($color, $amount)` can be written +[`adjust($color, $lightness: $amount)`](#adjust). + +{% codeExample 'color-lighten', false %} +// #e1d7d2 has lightness 85%, so when lighten() adds 30% it just returns white. +@debug lighten(#e1d7d2, 30%); // white + +// scale() instead makes it 30% lighter than it was originally. +@debug color.scale(#e1d7d2, $lightness: 30%); // #eae3e0 +=== +// #e1d7d2 has lightness 85%, so when lighten() adds 30% it just returns white. +@debug lighten(#e1d7d2, 30%) // white + +// scale() instead makes it 30% lighter than it was originally. +@debug color.scale(#e1d7d2, $lightness: 30%) // #eae3e0 +{% endcodeExample %} +{% endheadsUp %} + +{% codeExample 'color-lighten-2', false %} +// Lightness 46% becomes 66%. +@debug lighten(#6b717f, 20%); // #a1a5af + +// Lightness 20% becomes 80%. +@debug lighten(#036, 60%); // #99ccff + +// Lightness 85% becomes 100%. +@debug lighten(#e1d7d2, 30%); // white +=== +// Lightness 46% becomes 66%. +@debug lighten(#6b717f, 20%) // #a1a5af + +// Lightness 20% becomes 80%. +@debug lighten(#036, 60%) // #99ccff + +// Lightness 85% becomes 100%. +@debug lighten(#e1d7d2, 30%) // white +{% endcodeExample %} +{% endfunction %} + +{% function 'color.lightness($color)', 'lightness($color)', 'returns:number' %} +Returns the HSL lightness of `$color` as a number between `0%` and `100%`. + +See also: + +* [`color.red()`](#red) for getting a color's red channel. +* [`color.green()`](#green) for getting a color's green channel. +* [`color.blue()`](#blue) for getting a color's blue channel. +* [`color.hue()`](#hue) for getting a color's hue. +* [`color.saturation()`](#saturation) for getting a color's saturation. +* [`color.whiteness()`](#whiteness) for getting a color's whiteness. +* [`color.blackness()`](#blackness) for getting a color's blackness. +* [`color.alpha()`](#alpha) for getting a color's alpha channel. + +{% codeExample 'color-lightness', false %} +@debug color.lightness(#e1d7d2); // 85.2941176471% +@debug color.lightness(#f2ece4); // 92.1568627451% +@debug color.lightness(#dadbdf); // 86.4705882353% +=== +@debug color.lightness(#e1d7d2) // 85.2941176471% +@debug color.lightness(#f2ece4) // 92.1568627451% +@debug color.lightness(#dadbdf) // 86.4705882353% +{% endcodeExample %} +{% endfunction %} + +{% function 'color.mix($color1, $color2, $weight: 50%)', 'mix($color1, $color2, $weight: 50%)', 'returns:color' %} +Returns a color that's a mixture of `$color1` and `$color2`. + +Both the `$weight` and the relative opacity of each color determines how much of +each color is in the result. The `$weight` must be a number between `0%` and +`100%` (inclusive). A larger weight indicates that more of `$color1` should be +used, and a smaller weight indicates that more of `$color2` should be used. + +{% codeExample 'color-mix', false %} +@debug color.mix(#036, #d2e1dd); // #698aa2 +@debug color.mix(#036, #d2e1dd, 75%); // #355f84 +@debug color.mix(#036, #d2e1dd, 25%); // #9eb6bf +@debug color.mix(rgba(242, 236, 228, 0.5), #6b717f); // rgba(141, 144, 152, 0.75) +=== +@debug color.mix(#036, #d2e1dd) // #698aa2 +@debug color.mix(#036, #d2e1dd, 75%) // #355f84 +@debug color.mix(#036, #d2e1dd, 25%) // #9eb6bf +@debug color.mix(rgba(242, 236, 228, 0.5), #6b717f) // rgba(141, 144, 152, 0.75) +{% endcodeExample %} +{% endfunction %} + +{% function 'opacify($color, $amount)', 'fade-in($color, $amount)', 'returns:color' %} +Makes `$color` more opaque. + +The `$amount` must be a number between `0` and `1` (inclusive). Increases the +alpha channel of `$color` by that amount. + +{% headsUp %} +The `opacify()` function increases the alpha channel by a fixed amount, which is often +not the desired effect. To make a color a certain percentage more opaque than it was +before, use [`scale()`](#scale) instead. + +Because `opacify()` is usually not the best way to make a color more opaque, +it's not included directly in the new module system. However, if you have to +preserve the existing behavior, `opacify($color, $amount)` can be written +[`adjust($color, $alpha: -$amount)`](#adjust). + +{% codeExample 'color-opacify', false %} +// rgba(#036, 0.7) has alpha 0.7, so when opacify() adds 0.3 it returns a fully +// opaque color. +@debug opacify(rgba(#036, 0.7), 0.3); // #036 + +// scale() instead makes it 30% more opaque than it was originally. +@debug color.scale(rgba(#036, 0.7), $alpha: 30%); // rgba(0, 51, 102, 0.79) +=== +// rgba(#036, 0.7) has alpha 0.7, so when opacify() adds 0.3 it returns a fully +// opaque color. +@debug opacify(rgba(#036, 0.7), 0.3) // #036 + +// scale() instead makes it 30% more opaque than it was originally. +@debug color.scale(rgba(#036, 0.7), $alpha: 30%) // rgba(0, 51, 102, 0.79) +{% endcodeExample %} +{% endheadsUp %} + +{% codeExample 'color-opacify-2', false %} +@debug opacify(rgba(#6b717f, 0.5), 0.2); // rgba(107, 113, 127, 0.7) +@debug fade-in(rgba(#e1d7d2, 0.5), 0.4); // rgba(225, 215, 210, 0.9) +@debug opacify(rgba(#036, 0.7), 0.3); // #036 +=== +@debug opacify(rgba(#6b717f, 0.5), 0.2) // rgba(107, 113, 127, 0.7) +@debug fade-in(rgba(#e1d7d2, 0.5), 0.4) // rgba(225, 215, 210, 0.9) +@debug opacify(rgba(#036, 0.7), 0.3) // #036 +{% endcodeExample %} +{% endfunction %} + +{% function 'color.red($color)', 'red($color)', 'returns:number' %} +Returns the red channel of `$color` as a number between 0 and 255. + +See also: + +* [`color.green()`](#green) for getting a color's green channel. +* [`color.blue()`](#blue) for getting a color's blue channel. +* [`color.hue()`](#hue) for getting a color's hue. +* [`color.saturation()`](#saturation) for getting a color's saturation. +* [`color.lightness()`](#lightness) for getting a color's lightness. +* [`color.whiteness()`](#whiteness) for getting a color's whiteness. +* [`color.blackness()`](#blackness) for getting a color's blackness. +* [`color.alpha()`](#alpha) for getting a color's alpha channel. + +{% codeExample 'color-red', false %} +@debug color.red(#e1d7d2); // 225 +@debug color.red(white); // 255 +@debug color.red(black); // 0 +=== +@debug color.red(#e1d7d2) // 225 +@debug color.red(white) // 255 +@debug color.red(black) // 0 +{% endcodeExample %} +{% endfunction %} + +{% function 'color.saturate($color, $amount)', 'saturate($color, $amount)', 'returns:color' %} +Makes `$color` more saturated. + +The `$amount` must be a number between `0%` and `100%` (inclusive). Increases +the HSL saturation of `$color` by that amount. + +{% headsUp %} +The `saturate()` function increases saturation by a fixed amount, which is often +not the desired effect. To make a color a certain percentage more saturated than +it was before, use [`scale()`](#scale) instead. + +Because `saturate()` is usually not the best way to make a color more +saturated, it's not included directly in the new module system. However, if +you have to preserve the existing behavior, `saturate($color, $amount)` can +be written [`adjust($color, $saturation: $amount)`](#adjust). + +{% codeExample 'color-saturate', false %} +// #0e4982 has saturation 80%, so when saturate() adds 30% it just becomes +// fully saturated. +@debug saturate(#0e4982, 30%); // #004990 + +// scale() instead makes it 30% more saturated than it was originally. +@debug color.scale(#0e4982, $saturation: 30%); // #0a4986 +=== +// #0e4982 has saturation 80%, so when saturate() adds 30% it just becomes +// fully saturated. +@debug saturate(#0e4982, 30%) // #004990 + +// scale() instead makes it 30% more saturated than it was originally. +@debug color.scale(#0e4982, $saturation: 30%) // #0a4986 +{% endcodeExample %} +{% endheadsUp %} + +{% codeExample 'color-saturate-2', false %} +// Saturation 50% becomes 70%. +@debug saturate(#c69, 20%); // #e05299 + +// Saturation 35% becomes 85%. +@debug desaturate(#f2ece4, 50%); // #ebebeb + +// Saturation 80% becomes 100%. +@debug saturate(#0e4982, 30%) // #004990 +=== +// Saturation 50% becomes 70%. +@debug saturate(#c69, 20%); // #e05299 + +// Saturation 35% becomes 85%. +@debug desaturate(#f2ece4, 50%); // #ebebeb + +// Saturation 80% becomes 100%. +@debug saturate(#0e4982, 30%) // #004990 +{% endcodeExample %} +{% endfunction %} + +{% function 'color.saturation($color)', 'saturation($color)', 'returns:number' %} +Returns the HSL saturation of `$color` as a number between `0%` and `100%`. + +See also: + +* [`color.red()`](#red) for getting a color's red channel. +* [`color.green()`](#green) for getting a color's green channel. +* [`color.blue()`](#blue) for getting a color's blue channel. +* [`color.hue()`](#hue) for getting a color's hue. +* [`color.lightness()`](#lightness) for getting a color's lightness. +* [`color.whiteness()`](#whiteness) for getting a color's whiteness. +* [`color.blackness()`](#blackness) for getting a color's blackness. +* [`color.alpha()`](#alpha) for getting a color's alpha channel. + +{% codeExample 'color-saturation', false %} +@debug color.saturation(#e1d7d2); // 20% +@debug color.saturation(#f2ece4); // 30% +@debug color.saturation(#dadbdf); // 7.2463768116% +=== +@debug color.saturation(#e1d7d2) // 20% +@debug color.saturation(#f2ece4) // 30% +@debug color.saturation(#dadbdf) // 7.2463768116% +{% endcodeExample %} +{% endfunction %} + + +{% function 'color.scale($color,!!! $red: null, $green: null, $blue: null,!!! $saturation: null, $lightness: null,!!! $whiteness: null, $blackness: null,!!! $alpha: null)', 'scale-color(...)', 'returns:color' %} +{% compatibility '1.28.0', false, null, false, '$whiteness and $blackness' %}{% endcompatibility %} + +Fluidly scales one or more properties of `$color`. + +Each keyword argument must be a number between `-100%` and `100%` (inclusive). +This indicates how far the corresponding property should be moved from its +original position towards the maximum (if the argument is positive) or the +minimum (if the argument is negative). This means that, for example, +`$lightness: 50%` will make all colors `50%` closer to maximum lightness +without making them fully white. + +It's an error to specify an RGB property (`$red`, `$green`, and/or `$blue`) at +the same time as an HSL property (`$saturation`, and/or `$lightness`), or +either of those at the same time as an [HWB][] property (`$whiteness`, and/or +`$blackness`). + +[HWB]: https://en.wikipedia.org/wiki/HWB_color_model + +See also: + +* [`color.adjust()`](#adjust) for changing a color's properties by fixed + amounts. +* [`color.change()`](#change) for setting a color's properties. + +{% codeExample 'color-scale', false %} +@debug color.scale(#6b717f, $red: 15%); // #81717f +@debug color.scale(#d2e1dd, $lightness: -10%, $saturation: 10%); // #b3d4cb +@debug color.scale(#998099, $alpha: -40%); // rgba(153, 128, 153, 0.6) +=== +@debug color.scale(#6b717f, $red: 15%) // #81717f +@debug color.scale(#d2e1dd, $lightness: -10%, $saturation: 10%) // #b3d4cb +@debug color.scale(#998099, $alpha: -40%) // rgba(153, 128, 153, 0.6) +{% endcodeExample %} +{% endfunction %} + +{% function 'transparentize($color, $amount)', 'fade-out($color, $amount)', 'returns:color' %} +Makes `$color` more transparent. + +The `$amount` must be a number between `0` and `1` (inclusive). Decreases the +alpha channel of `$color` by that amount. + +{% headsUp %} +The `transparentize()` function decreases the alpha channel by a fixed amount, +which is often not the desired effect. To make a color a certain percentage more +transparent than it was before, use [`color.scale()`](#scale) instead. + +Because `transparentize()` is usually not the best way to make a color more +transparent, it's not included directly in the new module system. However, +if you have to preserve the existing behavior, +`transparentize($color, $amount)` can be written +[`color.adjust($color, $alpha: -$amount)`](#adjust). + +{% codeExample 'transparentize', false %} +// rgba(#036, 0.3) has alpha 0.3, so when transparentize() subtracts 0.3 it +// returns a fully transparent color. +@debug transparentize(rgba(#036, 0.3), 0.3); // rgba(0, 51, 102, 0) + +// scale() instead makes it 30% more transparent than it was originally. +@debug color.scale(rgba(#036, 0.3), $alpha: -30%); // rgba(0, 51, 102, 0.21) +=== +// rgba(#036, 0.3) has alpha 0.3, so when transparentize() subtracts 0.3 it +// returns a fully transparent color. +@debug transparentize(rgba(#036, 0.3), 0.3) // rgba(0, 51, 102, 0) + +// scale() instead makes it 30% more transparent than it was originally. +@debug color.scale(rgba(#036, 0.3), $alpha: -30%) // rgba(0, 51, 102, 0.21) +{% endcodeExample %} +{% endheadsUp %} + +{% codeExample 'transparentize-2', false %} +@debug transparentize(rgba(#6b717f, 0.5), 0.2) // rgba(107, 113, 127, 0.3) +@debug fade-out(rgba(#e1d7d2, 0.5), 0.4) // rgba(225, 215, 210, 0.1) +@debug transparentize(rgba(#036, 0.3), 0.3) // rgba(0, 51, 102, 0) +=== +@debug transparentize(rgba(#6b717f, 0.5), 0.2) // rgba(107, 113, 127, 0.3) +@debug fade-out(rgba(#e1d7d2, 0.5), 0.4) // rgba(225, 215, 210, 0.1) +@debug transparentize(rgba(#036, 0.3), 0.3) // rgba(0, 51, 102, 0) +{% endcodeExample %} +{% endfunction %} + +{% function 'color.whiteness($color)', 'returns:number' %} +{% compatibility '1.28.0', false, null, false %}{% endcompatibility %} + +Returns the [HWB][] whiteness of `$color` as a number between `0%` and `100%`. + +[HWB]: https://en.wikipedia.org/wiki/HWB_color_model + +See also: + +* [`color.red()`](#red) for getting a color's red channel. +* [`color.green()`](#green) for getting a color's green channel. +* [`color.hue()`](#hue) for getting a color's hue. +* [`color.saturation()`](#saturation) for getting a color's saturation. +* [`color.lightness()`](#lightness) for getting a color's lightness. +* [`color.blackness()`](#blackness) for getting a color's blackness. +* [`color.alpha()`](#alpha) for getting a color's alpha channel. + +{% codeExample 'color-whiteness', false %} +@debug color.whiteness(#e1d7d2); // 82.3529411765% +@debug color.whiteness(white); // 100% +@debug color.whiteness(black); // 0% +=== +@debug color.whiteness(#e1d7d2) // 82.3529411765% +@debug color.whiteness(white) // 100% +@debug color.whiteness(black) // 0% +{% endcodeExample %} +{% endfunction %} diff --git a/source/helpers/function.ts b/source/helpers/function.ts index 4007da879..cdd392808 100644 --- a/source/helpers/function.ts +++ b/source/helpers/function.ts @@ -47,6 +47,7 @@ export function _function(content: string, ...signatures: string[]) { // Highlight each signature const names: string[] = []; const highlightedSignatures = signatures.map((signature) => { + signature = signature.replace(/!!!/g, '\n'); // Hack to allow newlines in the signature const [name] = signature.split('(', 2); const nameWithoutNamespace = name.split('.').at(-1) || name; const html = codeBlock(`@function ${signature}`, 'scss'); @@ -68,12 +69,11 @@ export function _function(content: string, ...signatures: string[]) { .toArray() .map((el) => $.html(el)) .join('') - .trim() - .replace(/\n/g, ' '); + .trim(); }); // Add the return type after the last signature - let mergedSignatures = highlightedSignatures.join(' '); + let mergedSignatures = highlightedSignatures.join('\n'); if (returns) { mergedSignatures += ` //=> ${returnTypeLink( returns, From e9bce5c301b24a63a938f537ee54602f4ed3fbd6 Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Mon, 29 May 2023 17:22:06 +0000 Subject: [PATCH 03/19] Port modules/list --- .../code-snippets/example-list-index.liquid | 9 + source/code-snippets/example-list-nth.liquid | 7 + source/documentation/modules/list.liquid | 219 ++++++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 source/code-snippets/example-list-index.liquid create mode 100644 source/code-snippets/example-list-nth.liquid create mode 100644 source/documentation/modules/list.liquid diff --git a/source/code-snippets/example-list-index.liquid b/source/code-snippets/example-list-index.liquid new file mode 100644 index 000000000..c2a0a87e4 --- /dev/null +++ b/source/code-snippets/example-list-index.liquid @@ -0,0 +1,9 @@ +{% codeExample 'example-list-index', false %} +@debug list.index(1px solid red, 1px); // 1 +@debug list.index(1px solid red, solid); // 2 +@debug list.index(1px solid red, dashed); // null +=== +@debug list.index(1px solid red, 1px) // 1 +@debug list.index(1px solid red, solid) // 2 +@debug list.index(1px solid red, dashed) // null +{% endcodeExample %} diff --git a/source/code-snippets/example-list-nth.liquid b/source/code-snippets/example-list-nth.liquid new file mode 100644 index 000000000..ead6db832 --- /dev/null +++ b/source/code-snippets/example-list-nth.liquid @@ -0,0 +1,7 @@ +{% codeExample 'example-list-nth', false %} +@debug list.nth(10px 12px 16px, 2); // 12px +@debug list.nth([line1, line2, line3], -1); // line3 +=== +@debug list.nth(10px 12px 16px, 2) // 12px +@debug list.nth([line1, line2, line3], -1) // line3 +{% endcodeExample %} diff --git a/source/documentation/modules/list.liquid b/source/documentation/modules/list.liquid new file mode 100644 index 000000000..e6a2313e0 --- /dev/null +++ b/source/documentation/modules/list.liquid @@ -0,0 +1,219 @@ +--- +title: sass:list +--- + +{% render 'documentation/snippets/built-in-module-status' %} + +{% funFact %} +In Sass, every [map][] counts as a list that contains a two-element list for +each key/value pair. For example, `(1: 2, 3: 4)` counts as `(1 2, 3 4)`. So +all these functions work for maps as well! + +[map]: ../values/maps + +Individual values also count as lists. All these functions treat `1px` as a +list that contains the value `1px`. +{% endfunFact %} + +{% function 'list.append($list, $val, $separator: auto)', 'append($list, $val, $separator: auto)', 'returns:list' %} +Returns a copy of `$list` with `$val` added to the end. + +If `$separator` is `comma`, `space`, or `slash`, the returned list is +comma-separated, space-separated, or slash-separated, respectively. If it's +`auto` (the default), the returned list will use the same separator as `$list` +(or `space` if `$list` doesn't have a separator). Other values aren't allowed. + +[separator]: ../values/lists + +Note that unlike [`list.join()`](#join), if `$val` is a list it's nested +within the returned list rather than having all its elements added to the +returned list. + +{% codeExample 'list-append', false %} +@debug list.append(10px 20px, 30px); // 10px 20px 30px +@debug list.append((blue, red), green); // blue, red, green +@debug list.append(10px 20px, 30px 40px); // 10px 20px (30px 40px) +@debug list.append(10px, 20px, $separator: comma); // 10px, 20px +@debug list.append((blue, red), green, $separator: space); // blue red green +=== +@debug list.append(10px 20px, 30px) // 10px 20px 30px +@debug list.append((blue, red), green) // blue, red, green +@debug list.append(10px 20px, 30px 40px) // 10px 20px (30px 40px) +@debug list.append(10px, 20px, $separator: comma) // 10px, 20px +@debug list.append((blue, red), green, $separator: space) // blue red green +{% endcodeExample %} +{% endfunction %} + +{% function 'list.index($list, $value)', 'index($list, $value)', 'returns:number | null' %} +Returns the [index][] of `$value` in `$list`. + +[index]: ../values/lists#indexes + +If `$value` doesn't appear in `$list`, this returns [`null`][]. If `$value` +appears multiple times in `$list`, this returns the index of its first +appearance. + +[`null`]: ../values/null + +{% render 'code-snippets/example-list-index' %} +{% endfunction %} + +{% function 'list.is-bracketed($list)', 'is-bracketed($list)', 'returns:boolean' %} +Returns whether `$list` has square brackets. + +{% codeExample 'list-is-bracketed', false %} +@debug list.is-bracketed(1px 2px 3px); // false +@debug list.is-bracketed([1px, 2px, 3px]); // true +=== +@debug list.is-bracketed(1px 2px 3px) // false +@debug list.is-bracketed([1px, 2px, 3px]) // true +{% endcodeExample %} +{% endfunction %} + +{% function 'list.join($list1, $list2, $separator: auto, $bracketed: auto)', 'join($list1, $list2, $separator: auto, $bracketed: auto)', 'returns:list' %} +Returns a new list containing the elements of `$list1` followed by the elements +of `$list2`. + +{% headsUp %} +Because individual values count as single-element lists, it's possible to +use `list.join()` to add a value to the end of a list. However, *this is not +recommended*, since if that value is a list it will be concatenated, which +is probably not what you're expecting. + +Use [`list.append()`](#append) instead to add a single value to a list. Only +use `list.join()` to combine two lists together into one. +{% endheadsUp %} + +If `$separator` is `comma`, `space`, or `slash`, the returned list is +comma-separated, space-separated, or slash-separated, respectively. If it's +`auto` (the default), the returned list will use the same separator as +`$list1` if it has a separator, or else `$list2` if it has a separator, or +else `space`. Other values aren't allowed. + +If `$bracketed` is `auto` (the default), the returned list will be bracketed +if `$list1` is. Otherwise, the returned list will have square brackets if +`$bracketed` is [truthy] and no brackets if `$bracketed` is falsey. + +[truthy]: /documentation/values/booleans#truthiness-and-falsiness + +{% codeExample 'list-join', false %} +@debug list.join(10px 20px, 30px 40px); // 10px 20px 30px 40px +@debug list.join((blue, red), (#abc, #def)); // blue, red, #abc, #def +@debug list.join(10px, 20px); // 10px 20px +@debug list.join(10px, 20px, $separator: comma); // 10px, 20px +@debug list.join((blue, red), (#abc, #def), $separator: space); // blue red #abc #def +@debug list.join([10px], 20px); // [10px 20px] +@debug list.join(10px, 20px, $bracketed: true); // [10px 20px] +=== +@debug list.join(10px 20px, 30px 40px) // 10px 20px 30px 40px +@debug list.join((blue, red), (#abc, #def)) // blue, red, #abc, #def +@debug list.join(10px, 20px) // 10px 20px +@debug list.join(10px, 20px, comma) // 10px, 20px +@debug list.join((blue, red), (#abc, #def), space) // blue red #abc #def +@debug list.join([10px], 20px) // [10px 20px] +@debug list.join(10px, 20px, $bracketed: true) // [10px 20px] +{% endcodeExample %} +{% endfunction %} + +{% function 'list.length($list)', 'length($list)', 'returns:number' %} +Returns the length of `$list`. + +This can also return the number of pairs in a map. + +{% codeExample 'list-length', false %} +@debug list.length(10px); // 1 +@debug list.length(10px 20px 30px); // 3 +@debug list.length((width: 10px, height: 20px)); // 2 +=== +@debug list.length(10px) // 1 +@debug list.length(10px 20px 30px) // 3 +@debug list.length((width: 10px, height: 20px)) // 2 +{% endcodeExample %} +{% endfunction %} + +{% function 'list.separator($list)', 'list-separator($list)', 'returns:unquoted string' %} +Returns the name of the separator used by `$list`, either `space`, `comma`, or +`slash`. + +If `$list` doesn't have a separator, returns `space`. + +{% codeExample 'list-separator', false %} +@debug list.separator(1px 2px 3px); // space +@debug list.separator(1px, 2px, 3px); // comma +@debug list.separator('Helvetica'); // space +@debug list.separator(()); // space +=== +@debug list.separator(1px 2px 3px) // space +@debug list.separator(1px, 2px, 3px) // comma +@debug list.separator('Helvetica') // space +@debug list.separator(()) // space +{% endcodeExample %} +{% endfunction %} + +{% function 'list.nth($list, $n)', 'nth($list, $n)' %} +Returns the element of `$list` at [index][] `$n`. + +[index]: ../values/lists#indexes + +If `$n` is negative, it counts from the end of `$list`. Throws an error if +there is no element at index `$n`. + +{% render 'code-snippets/example-list-nth' %} +{% endfunction %} + +{% function 'list.set-nth($list, $n, $value)', 'set-nth($list, $n, $value)', 'returns:list' %} +Returns a copy of `$list` with the element at [index][] `$n` replaced with +`$value`. + +[index]: ../values/lists#indexes + +If `$n` is negative, it counts from the end of `$list`. Throws an error if +there is no existing element at index `$n`. + +{% codeExample 'list-set-nth', false %} +@debug list.set-nth(10px 20px 30px, 1, 2em); // 2em 20px 30px +@debug list.set-nth(10px 20px 30px, -1, 8em); // 10px, 20px, 8em +@debug list.set-nth((Helvetica, Arial, sans-serif), 3, Roboto); // Helvetica, Arial, Roboto +=== +@debug list.set-nth(10px 20px 30px, 1, 2em); // 2em 20px 30px +@debug list.set-nth(10px 20px 30px, -1, 8em); // 10px, 20px, 8em +@debug list.set-nth((Helvetica, Arial, sans-serif), 3, Roboto); // Helvetica, Arial, Roboto +{% endcodeExample %} +{% endfunction %} + +{% function 'list.slash($elements...)', 'returns:list' %} +Returns a slash-separated list that contains `$elements`. + +{% headsUp %} +This function is a temporary solution for creating slash-separated lists. +Eventually, they'll be written literally with slashes, as in +`1px / 2px / solid`, but for the time being [slashes are used for division] +so Sass can't use them for new syntax until the old syntax is removed. + +[slashes are used for division]: ../breaking-changes/slash-div +{% endheadsUp %} + +{% codeExample 'list-slash', false %} +@debug list.slash(1px, 50px, 100px); // 1px / 50px / 100px +=== +@debug list.slash(1px, 50px, 100px) // 1px / 50px / 100px +{% endcodeExample %} +{% endfunction %} + +{% function 'list.zip($lists...)', 'zip($lists...)', 'returns:list' %} +Combines every list in `$lists` into a single list of sub-lists. + +Each element in the returned list contains all the elements at that position +in `$lists`. The returned list is as long as the shortest list in `$lists`. + +The returned list is always comma-separated and the sub-lists are always +space-separated. + +{% codeExample 'list-zip', false %} +@debug list.zip(10px 50px 100px, short mid long); // 10px short, 50px mid, 100px long +@debug list.zip(10px 50px 100px, short mid); // 10px short, 50px mid +=== +@debug list.zip(10px 50px 100px, short mid long) // 10px short, 50px mid, 100px long +@debug list.zip(10px 50px 100px, short mid) // 10px short, 50px mid +{% endcodeExample %} +{% endfunction %} From c6308cbeb1b655bde6e315a33617f1bb8fda3d59 Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Mon, 29 May 2023 17:39:35 +0000 Subject: [PATCH 04/19] Port modules/map --- source/code-snippets/example-map-get.liquid | 11 + source/documentation/modules/map.liquid | 448 ++++++++++++++++++++ 2 files changed, 459 insertions(+) create mode 100644 source/code-snippets/example-map-get.liquid create mode 100644 source/documentation/modules/map.liquid diff --git a/source/code-snippets/example-map-get.liquid b/source/code-snippets/example-map-get.liquid new file mode 100644 index 000000000..ec093f318 --- /dev/null +++ b/source/code-snippets/example-map-get.liquid @@ -0,0 +1,11 @@ +{% codeExample 'map-get', false %} +$font-weights: ("regular": 400, "medium": 500, "bold": 700); + +@debug map.get($font-weights, "medium"); // 500 +@debug map.get($font-weights, "extra-bold"); // null +=== +$font-weights: ("regular": 400, "medium": 500, "bold": 700) + +@debug map.get($font-weights, "medium") // 500 +@debug map.get($font-weights, "extra-bold") // null +{% endcodeExample %} diff --git a/source/documentation/modules/map.liquid b/source/documentation/modules/map.liquid new file mode 100644 index 000000000..0c20960f8 --- /dev/null +++ b/source/documentation/modules/map.liquid @@ -0,0 +1,448 @@ +--- +title: sass:map +--- + +{% render 'documentation/snippets/built-in-module-status' %} + +{% funFact %} +Sass libraries and design systems tend to share and override configurations +that are represented as nested maps (maps that contain maps that contain +maps). + +To help you work with nested maps, some map functions support deep +operations. For example, if you pass multiple keys to `map.get()`, it will +follow those keys to find the desired nested map: + +{% codeExample 'map', false %} +$config: (a: (b: (c: d))); +@debug map.get($config, a, b, c); // d +=== +$config: (a: (b: (c: d))) +@debug map.get($config, a, b, c) // d +{% endcodeExample %} +{% endfunFact %} + +{% function 'map.deep-merge($map1, $map2)', 'returns:map' %} +{% compatibility '1.27.0', false, null, false %}{% endcompatibility %} + +Identical to [`map.merge()`](#merge), except that nested map values are *also* +recursively merged. + +{% codeExample 'map-deep-merge', false %} +$helvetica-light: ( + "weights": ( + "lightest": 100, + "light": 300 + ) +); +$helvetica-heavy: ( + "weights": ( + "medium": 500, + "bold": 700 + ) +); + +@debug map.deep-merge($helvetica-light, $helvetica-heavy); +// ( +// "weights": ( +// "lightest": 100, +// "light": 300, +// "medium": 500, +// "bold": 700 +// ) +// ) +@debug map.merge($helvetica-light, $helvetica-heavy); +// ( +// "weights": ( +// "medium: 500, +// "bold": 700 +// ) +// ) +=== +$helvetica-light: ("weights": ("lightest": 100, "light": 300)) +$helvetica-heavy: ("weights": ("medium": 500, "bold": 700)) + +@debug map.deep-merge($helvetica-light, $helvetica-heavy) +// ( +// "weights": ( +// "lightest": 100, +// "light": 300, +// "medium": 500, +// "bold": 700 +// ) +// ) +@debug map.merge($helvetica-light, $helvetica-heavy); +// ( +// "weights": ( +// "medium: 500, +// "bold": 700 +// ) +// ) +{% endcodeExample %} +{% endfunction %} + +{% function 'map.deep-remove($map, $key, $keys...)', 'returns:map' %} +{% compatibility '1.27.0', false, null, false %}{% endcompatibility %} + +If `$keys` is empty, returns a copy of `$map` without a value associated with +`$key`. + +{% codeExample 'map-deep-remove', false %} +$font-weights: ("regular": 400, "medium": 500, "bold": 700); + +@debug map.deep-remove($font-weights, "regular"); +// ("medium": 500, "bold": 700) +=== +$font-weights: ("regular": 400, "medium": 500, "bold": 700) + +@debug map.deep-remove($font-weights, "regular") +// ("medium": 500, "bold": 700) +{% endcodeExample %} + +--- + +If `$keys` is not empty, follows the set of keys including `$key` and +excluding the last key in `$keys`, from left to right, to find the nested map +targeted for updating. + +Returns a copy of `$map` where the targeted map does not have a value +associated with the last key in `$keys`. + +{% codeExample 'map-deep-remove-2', false %} +$fonts: ( + "Helvetica": ( + "weights": ( + "regular": 400, + "medium": 500, + "bold": 700 + ) + ) +); + +@debug map.deep-remove($fonts, "Helvetica", "weights", "regular"); +// ( +// "Helvetica": ( +// "weights: ( +// "medium": 500, +// "bold": 700 +// ) +// ) +// ) +=== +$fonts: ("Helvetica": ("weights": ("regular": 400, "medium": 500, "bold": 700))) + +@debug map.deep-remove($fonts, "Helvetica", "weights", "regular") +// ( +// "Helvetica": ( +// "weights: ( +// "medium": 500, +// "bold": 700 +// ) +// ) +// ) +{% endcodeExample %} +{% endfunction %} + +{% function 'map.get($map, $key, $keys...)', 'map-get($map, $key, $keys...)' %} +If `$keys` is empty, returns the value in `$map` associated with `$key`. + +If `$map` doesn't have a value associated with `$key`, returns [`null`][]. + +{% render 'code-snippets/example-map-get' %} + +--- + +{% compatibility '1.27.0', false, null, false %} +Only Dart Sass supports calling `map.get()` with more than two arguments. +{% endcompatibility %} + +If `$keys` is not empty, follows the set of keys including `$key` and +excluding the last key in `$keys`, from left to right, to find the nested map +targeted for searching. + +Returns the value in the targeted map associated with the last key in `$keys`. + +Returns [`null`][] if the map does not have a value associated with the key, +or if any key in `$keys` is missing from a map or references a value that is +not a map. + +{% codeExample 'map-deep-remove-2', false %} +$fonts: ( + "Helvetica": ( + "weights": ( + "regular": 400, + "medium": 500, + "bold": 700 + ) + ) +); + +@debug map.get($fonts, "Helvetica", "weights", "regular"); // 400 +@debug map.get($fonts, "Helvetica", "colors"); // null +=== +$fonts: ("Helvetica": ("weights": ("regular": 400, "medium": 500, "bold": 700))) + +@debug map.get($fonts, "Helvetica", "weights", "regular") // 400 +@debug map.get($fonts, "Helvetica", "colors") // null +{% endcodeExample %} + +[`null`]: ../values/null +{% endfunction %} + +{% function 'map.has-key($map, $key, $keys...)', 'map-has-key($map, $key, $keys...)', 'returns:boolean' %} +If `$keys` is empty, returns whether `$map` contains a value associated with +`$key`. + +{% codeExample 'map-has-key', false %} +$font-weights: ("regular": 400, "medium": 500, "bold": 700); + +@debug map.has-key($font-weights, "regular"); // true +@debug map.has-key($font-weights, "bolder"); // false +=== +$font-weights: ("regular": 400, "medium": 500, "bold": 700) + +@debug map.has-key($font-weights, "regular") // true +@debug map.has-key($font-weights, "bolder") // false +{% endcodeExample %} + +--- + +{% compatibility '1.27.0', false, null, false %} +Only Dart Sass supports calling `map.has-key()` with more than two arguments. +{% endcompatibility %} + +If `$keys` is not empty, follows the set of keys including `$key` and +excluding the last key in `$keys`, from left to right, to find the nested map +targeted for searching. + +Returns true if the targeted map contains a value associated with the last key +in `$keys`. + +Returns false if it does not, or if any key in `$keys` is missing from a map +or references a value that is not a map. + +{% codeExample 'map-has-key-2', false %} +$fonts: ( + "Helvetica": ( + "weights": ( + "regular": 400, + "medium": 500, + "bold": 700 + ) + ) +); + +@debug map.has-key($fonts, "Helvetica", "weights", "regular"); // true +@debug map.has-key($fonts, "Helvetica", "colors"); // false +=== +$fonts: ("Helvetica": ("weights": ("regular": 400, "medium": 500, "bold": 700))) + +@debug map.has-key($fonts, "Helvetica", "weights", "regular") // true +@debug map.has-key($fonts, "Helvetica", "colors") // false +{% endcodeExample %} +{% endfunction %} + +{% function 'map.keys($map)', 'map-keys($map)', 'returns:list' %} +Returns a comma-separated list of all the keys in `$map`. + +{% codeExample 'map-keys', false %} +$font-weights: ("regular": 400, "medium": 500, "bold": 700); + +@debug map.keys($font-weights); // "regular", "medium", "bold" +=== +$font-weights: ("regular": 400, "medium": 500, "bold": 700) + +@debug map.keys($font-weights) // "regular", "medium", "bold" +{% endcodeExample %} +{% endfunction %} + +{% function 'map.merge($map1, $map2)', 'map-merge($map1, $map2)', 'map.merge($map1, $keys..., $map2)', 'map-merge($map1, $keys..., $map2)', 'returns:map' %} +{% headsUp %} +In practice, the actual arguments to `map.merge($map1, $keys..., $map2)` +are passed as `map.merge($map1, $args...)`. They are described here as `$map1, +$keys..., $map2` for explanation purposes only. +{% endheadsUp %} + +If no `$keys` are passed, returns a new map with all the keys and values from +both `$map1` and `$map2`. + +If both `$map1` and `$map2` have the same key, `$map2`'s value takes +precedence. + +All keys in the returned map that also appear in `$map1` have the same order +as in `$map1`. New keys from `$map2` appear at the end of the map. + +{% codeExample 'map-merge', false %} +$light-weights: ("lightest": 100, "light": 300); +$heavy-weights: ("medium": 500, "bold": 700); + +@debug map.merge($light-weights, $heavy-weights); +// ("lightest": 100, "light": 300, "medium": 500, "bold": 700) +=== +$light-weights: ("lightest": 100, "light": 300) +$heavy-weights: ("medium": 500, "bold": 700) + +@debug map.merge($light-weights, $heavy-weights) +// ("lightest": 100, "light": 300, "medium": 500, "bold": 700) +{% endcodeExample %} + +--- + +{% compatibility '1.27.0', false, null, false %} +Only Dart Sass supports calling `map.merge()` with more than two arguments. +{% endcompatibility %} + +If `$keys` is not empty, follows the `$keys` to find the nested map targeted +for merging. If any key in `$keys` is missing from a map or references a value +that is not a map, sets the value at that key to an empty map. + +Returns a copy of `$map1` where the targeted map is replaced by a new map that +contains all the keys and values from both the targeted map and `$map2`. + +{% codeExample 'map-merge-2', false %} +$fonts: ( + "Helvetica": ( + "weights": ( + "lightest": 100, + "light": 300 + ) + ) +); +$heavy-weights: ("medium": 500, "bold": 700); + +@debug map.merge($fonts, "Helvetica", "weights", $heavy-weights); +// ( +// "Helvetica": ( +// "weights": ( +// "lightest": 100, +// "light": 300, +// "medium": 500, +// "bold": 700 +// ) +// ) +// ) +=== +$fonts: ("Helvetica": ("weights": ("lightest": 100, "light": 300))) +$heavy-weights: ("medium": 500, "bold": 700) + +@debug map.merge($fonts, "Helvetica", "weights", $heavy-weights) +// ( +// "Helvetica": ( +// "weights": ( +// "lightest": 100, +// "light": 300, +// "medium": 500, +// "bold": 700 +// ) +// ) +// ) +{% endcodeExample %} +{% endfunction %} + +{% function 'map.remove($map, $keys...)', 'map-remove($map, $keys...)', 'returns:map' %} +Returns a copy of `$map` without any values associated with `$keys`. + +If a key in `$keys` doesn't have an associated value in `$map`, it's ignored. + +{% codeExample 'map-remove', false %} +$font-weights: ("regular": 400, "medium": 500, "bold": 700); + +@debug map.remove($font-weights, "regular"); // ("medium": 500, "bold": 700) +@debug map.remove($font-weights, "regular", "bold"); // ("medium": 500) +@debug map.remove($font-weights, "bolder"); +// ("regular": 400, "medium": 500, "bold": 700) +=== +$font-weights: ("regular": 400, "medium": 500, "bold": 700) + +@debug map.remove($font-weights, "regular") // ("medium": 500, "bold": 700) +@debug map.remove($font-weights, "regular", "bold") // ("medium": 500) +@debug map.remove($font-weights, "bolder") +// ("regular": 400, "medium": 500, "bold": 700) +{% endcodeExample %} +{% endfunction %} + +{% function 'map.set($map, $key, $value)', 'map.set($map, $keys..., $key, $value)', 'returns:map' %} +{% headsUp %} +In practice, the actual arguments to `map.set($map, $keys..., $key, $value)` +are passed as `map.set($map, $args...)`. They are described here as `$map, +$keys..., $key, $value` for explanation purposes only. +{% endheadsUp %} + +If `$keys` are not passed, returns a copy of `$map` with the value at `$key` +set to `$value`. + +{% codeExample 'map-set', false %} +$font-weights: ("regular": 400, "medium": 500, "bold": 700); + +@debug map.set($font-weights, "regular", 300); +// ("regular": 300, "medium": 500, "bold": 700) +=== +$font-weights: ("regular": 400, "medium": 500, "bold": 700) + +@debug map.set($font-weights, "regular", 300) +// ("regular": 300, "medium": 500, "bold": 700) +{% endcodeExample %} + +--- + +{% compatibility '1.27.0', false, null, false %} +Only Dart Sass supports calling `map.set()` with more than three arguments. +{% endcompatibility %} + +If `$keys` are passed, follows the `$keys` to find the nested map targeted for +updating. If any key in `$keys` is missing from a map or references a value +that is not a map, sets the value at that key to an empty map. + +Returns a copy of `$map` with the targeted map's value at `$key` set to +`$value`. + +{% codeExample 'map-set-2', false %} +$fonts: ( + "Helvetica": ( + "weights": ( + "regular": 400, + "medium": 500, + "bold": 700 + ) + ) +); + +@debug map.set($fonts, "Helvetica", "weights", "regular", 300); +// ( +// "Helvetica": ( +// "weights": ( +// "regular": 300, +// "medium": 500, +// "bold": 700 +// ) +// ) +// ) +=== +$fonts: ("Helvetica": ("weights": ("regular": 400, "medium": 500, "bold": 700))) + +@debug map.set($fonts, "Helvetica", "weights", "regular", 300) +// ( +// "Helvetica": ( +// "weights": ( +// "regular": 300, +// "medium": 500, +// "bold": 700 +// ) +// ) +// ) +{% endcodeExample %} +{% endfunction %} + +{% function 'map.values($map)', 'map-values($map)', 'returns:list' %} +Returns a comma-separated list of all the values in `$map`. + +{% codeExample 'map-values', false %} +$font-weights: ("regular": 400, "medium": 500, "bold": 700); + +@debug map.values($font-weights); // 400, 500, 700 +=== +$font-weights: ("regular": 400, "medium": 500, "bold": 700) + +@debug map.values($font-weights) // 400, 500, 700 +{% endcodeExample %} +{% endfunction %} From c1ac3ff3072570fb2ab708cd0c75a76b4e5bbc98 Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Mon, 29 May 2023 18:10:30 +0000 Subject: [PATCH 05/19] Port modules/math --- source/documentation/modules/math.liquid | 600 +++++++++++++++++++++++ 1 file changed, 600 insertions(+) create mode 100644 source/documentation/modules/math.liquid diff --git a/source/documentation/modules/math.liquid b/source/documentation/modules/math.liquid new file mode 100644 index 000000000..a33a98756 --- /dev/null +++ b/source/documentation/modules/math.liquid @@ -0,0 +1,600 @@ +--- +title: sass:math +--- + +{% render 'documentation/snippets/built-in-module-status' %} + +{% markdown %} +## Variables +{% endmarkdown %} + +{% function 'math.$e' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +The closest 64-bit floating point approximation of the [mathematical constant +*e*][]. + +[mathematical constant *e*]: https://en.wikipedia.org/wiki/E_(mathematical_constant) + +{% codeExample 'math-e', false %} +@debug math.$e; // 2.7182818285 +=== +@debug math.$e // 2.7182818285 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.$epsilon' %} +{% compatibility '1.55.0', false, null, false %}{% endcompatibility %} + +The difference between 1 and the smallest 64-bit floating point number greater +than 1 according to floating-point comparisons. Because of Sass numbers' [10 +digits of precision](../values/numbers), in many cases this will appear to +be 0. +{% endfunction %} + +{% function 'math.$max-number' %} +{% compatibility '1.55.0', false, null, false %}{% endcompatibility %} + +The maximum finite number that can be represented as a 64-bit floating point +number. + +{% codeExample 'math-max-number', false %} +@debug math.$max-number; // 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +=== +@debug math.$max-number // 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.$max-safe-integer' %} +{% compatibility '1.55.0', false, null, false %}{% endcompatibility %} + +The maximum integer `n` such that both `n` and `n + 1` can be precisely +represented as a 64-bit floating-point number. + +{% codeExample 'math-max-safe-integer', false %} +@debug math.$max-safe-integer; // 9007199254740991 +=== +@debug math.$max-safe-integer // 9007199254740991 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.$min-number' %} +{% compatibility '1.55.0', false, null, false %}{% endcompatibility %} + +The smallest positive number that can be represented as a 64-bit floating +point number. Because of Sass numbers' [10 digits of +precision](../values/numbers), in many cases this will appear to be 0. +{% endfunction %} + +{% function 'math.$min-safe-integer' %} +{% compatibility '1.55.0', false, null, false %}{% endcompatibility %} + +The minimum integer `n` such that both `n` and `n - 1` can be precisely +represented as a 64-bit floating-point number. + +{% codeExample 'math-min-safe-integer', false %} +@debug math.$min-safe-integer; // -9007199254740991 +=== +@debug math.$min-safe-integer // -9007199254740991 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.$pi' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +The closest 64-bit floating point approximation of the [mathematical constant *π*][]. + +[mathematical constant *π*]: https://en.wikipedia.org/wiki/Pi + +{% codeExample 'math-pi', false %} +@debug math.$pi; // 3.1415926536 +=== +@debug math.$pi // 3.1415926536 +{% endcodeExample %} +{% endfunction %} + +{% markdown %} +## Bounding Functions +{% endmarkdown %} + +{% function 'math.ceil($number)', 'ceil($number)', 'returns:number' %} +Rounds `$number` up to the next highest whole number. + +{% codeExample 'math-ceil', false %} +@debug math.ceil(4); // 4 +@debug math.ceil(4.2); // 5 +@debug math.ceil(4.9); // 5 +=== +@debug math.ceil(4) // 4 +@debug math.ceil(4.2) // 5 +@debug math.ceil(4.9) // 5 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.clamp($min, $number, $max)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Restricts `$number` to the range between `$min` and `$max`. If `$number` is +less than `$min` this returns `$min`, and if it's greater than `$max` this +returns `$max`. + +`$min`, `$number`, and `$max` must have compatible units, or all be unitless. + +{% codeExample 'math-clamp', false %} +@debug math.clamp(-1, 0, 1); // 0 +@debug math.clamp(1px, -1px, 10px); // 1px +@debug math.clamp(-1in, 1cm, 10mm); // 10mm +=== +@debug math.clamp(-1, 0, 1) // 0 +@debug math.clamp(1px, -1px, 10px) // 1px +@debug math.clamp(-1in, 1cm, 10mm) // 10mm +{% endcodeExample %} +{% endfunction %} + +{% function 'math.floor($number)', 'floor($number)', 'returns:number' %} +Rounds `$number` down to the next lowest whole number. + +{% codeExample 'math-floor', false %} +@debug math.floor(4); // 4 +@debug math.floor(4.2); // 4 +@debug math.floor(4.9); // 4 +=== +@debug math.floor(4) // 4 +@debug math.floor(4.2) // 4 +@debug math.floor(4.9) // 4 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.max($number...)', 'max($number...)', 'returns:number' %} +Returns the highest of one or more numbers. + +{% codeExample 'math-max', false %} +@debug math.max(1px, 4px); // 4px + +$widths: 50px, 30px, 100px; +@debug math.max($widths...); // 100px +=== +@debug math.max(1px, 4px) // 4px + +$widths: 50px, 30px, 100px +@debug math.max($widths...) // 100px +{% endcodeExample %} +{% endfunction %} + +{% function 'math.min($number...)', 'min($number...)', 'returns:number' %} +Returns the lowest of one or more numbers. + +{% codeExample 'math-min', false %} +@debug math.min(1px, 4px); // 1px + +$widths: 50px, 30px, 100px; +@debug math.min($widths...); // 30px +=== +@debug math.min(1px, 4px) // 1px + +$widths: 50px, 30px, 100px +@debug math.min($widths...) // 30px +{% endcodeExample %} +{% endfunction %} + +{% function 'math.round($number)', 'round($number)', 'returns:number' %} +Rounds `$number` to the nearest whole number. + +{% codeExample 'math-round', false %} +@debug math.round(4); // 4 +@debug math.round(4.2); // 4 +@debug math.round(4.9); // 5 +=== +@debug math.round(4) // 4 +@debug math.round(4.2) // 4 +@debug math.round(4.9) // 5 +{% endcodeExample %} +{% endfunction %} + +{% markdown %} +## Distance Functions +{% endmarkdown %} + +{% function 'math.abs($number)', 'abs($number)', 'returns:number' %} +Returns the [absolute value][] of `$number`. If `$number` is negative, this +returns `-$number`, and if `$number` is positive, it returns `$number` as-is. + +[absolute value]: https://en.wikipedia.org/wiki/Absolute_value + +{% codeExample 'math-abs', false %} +@debug math.abs(10px); // 10px +@debug math.abs(-10px); // 10px +=== +@debug math.abs(10px) // 10px +@debug math.abs(-10px) // 10px +{% endcodeExample %} +{% endfunction %} + +{% function 'math.hypot($number...)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Returns the length of the *n*-dimensional [vector][] that has components equal +to each `$number`. For example, for three numbers *a*, *b*, and *c*, this +returns the square root of *a² + b² + c²*. + +The numbers must either all have compatible units, or all be unitless. And +since the numbers' units may differ, the output takes the unit of the first +number. + +[vector]: https://en.wikipedia.org/wiki/Euclidean_vector + +{% codeExample 'math-hypot', false %} +@debug math.hypot(3, 4); // 5 + +$lengths: 1in, 10cm, 50px; +@debug math.hypot($lengths...); // 4.0952775683in +=== +@debug math.hypot(3, 4) // 5 + +$lengths: 1in, 10cm, 50px +@debug math.hypot($lengths...) // 4.0952775683in +{% endcodeExample %} +{% endfunction %} + +{% markdown %} +## Exponential Functions +{% endmarkdown %} + +{% function 'math.log($number, $base: null)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Returns the [logarithm][] of `$number` with respect to `$base`. If `$base` is +`null`, the [natural log][] is calculated. + +`$number` and `$base` must be unitless. + +[logarithm]: https://en.wikipedia.org/wiki/Logarithm +[natural log]: https://en.wikipedia.org/wiki/Natural_logarithm + +{% codeExample 'math-log', false %} +@debug math.log(10); // 2.302585093 +@debug math.log(10, 10); // 1 +=== +@debug math.log(10) // 2.302585093 +@debug math.log(10, 10) // 1 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.pow($base, $exponent)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Raises `$base` [to the power of][] `$exponent`. + +`$base` and `$exponent` must be unitless. + +[to the power of]: https://en.wikipedia.org/wiki/Exponentiation + +{% codeExample 'math-pow', false %} +@debug math.pow(10, 2); // 100 +@debug math.pow(100, math.div(1, 3)); // 4.6415888336 +@debug math.pow(5, -2); // 0.04 +=== +@debug math.pow(10, 2) // 100 +@debug math.pow(100, math.div(1, 3)) // 4.6415888336 +@debug math.pow(5, -2) // 0.04 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.sqrt($number)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Returns the [square root][] of `$number`. + +`$number` must be unitless. + +[square root]: https://en.wikipedia.org/wiki/Square_root + +{% codeExample 'math-sqrt', false %} +@debug math.sqrt(100); // 10 +@debug math.sqrt(math.div(1, 3)); // 0.5773502692 +@debug math.sqrt(-1); // NaN +=== +@debug math.sqrt(100) // 10 +@debug math.sqrt(math.div(1, 3)) // 0.5773502692 +@debug math.sqrt(-1) // NaN +{% endcodeExample %} +{% endfunction %} + +{% markdown %} +## Trigonometric Functions +{% endmarkdown %} + +{% function 'math.cos($number)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Returns the [cosine][] of `$number`. + +`$number` must be an angle (its units must be compatible with `deg`) or +unitless. If `$number` has no units, it is assumed to be in `rad`. + +[cosine]: https://en.wikipedia.org/wiki/Trigonometric_functions#Right-angled_triangle_definitions + +{% codeExample 'math-cos', false %} +@debug math.cos(100deg); // -0.1736481777 +@debug math.cos(1rad); // 0.5403023059 +@debug math.cos(1); // 0.5403023059 +=== +@debug math.cos(100deg) // -0.1736481777 +@debug math.cos(1rad) // 0.5403023059 +@debug math.cos(1) // 0.5403023059 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.sin($number)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Returns the [sine][] of `$number`. + +`$number` must be an angle (its units must be compatible with `deg`) or +unitless. If `$number` has no units, it is assumed to be in `rad`. + +[sine]: https://en.wikipedia.org/wiki/Trigonometric_functions#Right-angled_triangle_definitions + +{% codeExample 'math-sin', false %} +@debug math.sin(100deg); // 0.984807753 +@debug math.sin(1rad); // 0.8414709848 +@debug math.sin(1); // 0.8414709848 +=== +@debug math.sin(100deg) // 0.984807753 +@debug math.sin(1rad) // 0.8414709848 +@debug math.sin(1) // 0.8414709848 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.tan($number)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Returns the [tangent][] of `$number`. + +`$number` must be an angle (its units must be compatible with `deg`) or +unitless. If `$number` has no units, it is assumed to be in `rad`. + +[tangent]: https://en.wikipedia.org/wiki/Trigonometric_functions#Right-angled_triangle_definitions + +{% codeExample 'math-tan', false %} +@debug math.tan(100deg); // -5.6712818196 +@debug math.tan(1rad); // 1.5574077247 +@debug math.tan(1); // 1.5574077247 +=== +@debug math.tan(100deg) // -5.6712818196 +@debug math.tan(1rad) // 1.5574077247 +@debug math.tan(1) // 1.5574077247 +{% endcodeExample %} +{% endfunction %} + +{% function 'math.acos($number)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Returns the [arccosine][] of `$number` in `deg`. + +`$number` must be unitless. + +[arccosine]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Basic_properties + +{% codeExample 'math-acos', false %} +@debug math.acos(0.5); // 60deg +@debug math.acos(2); // NaNdeg +=== +@debug math.acos(0.5) // 60deg +@debug math.acos(2) // NaNdeg +{% endcodeExample %} +{% endfunction %} + +{% function 'math.asin($number)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Returns the [arcsine][] of `$number` in `deg`. + +`$number` must be unitless. + +[arcsine]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Basic_properties + +{% codeExample 'math-asin', false %} +@debug math.asin(0.5); // 30deg +@debug math.asin(2); // NaNdeg +=== +@debug math.asin(0.5) // 30deg +@debug math.asin(2) // NaNdeg +{% endcodeExample %} +{% endfunction %} + +{% function 'math.atan($number)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Returns the [arctangent][] of `$number` in `deg`. + +`$number` must be unitless. + +[arctangent]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Basic_properties + +{% codeExample 'math-atan', false %} +@debug math.atan(10); // 84.2894068625deg +=== +@debug math.atan(10) // 84.2894068625deg +{% endcodeExample %} +{% endfunction %} + +{% function 'math.atan2($y, $x)', 'returns:number' %} +{% compatibility '1.25.0', false, null, false %}{% endcompatibility %} + +Returns the [2-argument arctangent][] of `$y` and `$x` in `deg`. + +`$y` and `$x` must have compatible units or be unitless. + +[2-argument arctangent]: https://en.wikipedia.org/wiki/Atan2 + +{% funFact %} +`math.atan2($y, $x)` is distinct from `atan(math.div($y, $x))` because it preserves the +quadrant of the point in question. For example, `math.atan2(1, -1)` corresponds +to the point `(-1, 1)` and returns `135deg`. In contrast, `math.atan(math.div(1, -1))` and +`math.atan(math.div(-1, 1))` resolve first to `atan(-1)`, so both return `-45deg`. +{% endfunFact %} + +{% codeExample 'math-atan2', false %} +@debug math.atan2(-1, 1); // 135deg +=== +@debug math.atan2(-1, 1) // 135deg +{% endcodeExample %} +{% endfunction %} + +{% markdown %} +## Unit Functions +{% endmarkdown %} + +{% function 'math.compatible($number1, $number2)', 'comparable($number1, $number2)', 'returns:boolean' %} +Returns whether `$number1` and `$number2` have compatible units. + +If this returns `true`, `$number1` and `$number2` can safely be [added][], +[subtracted][], and [compared][]. Otherwise, doing so will produce errors. + +[added]: ../operators/numeric +[subtracted]: ../operators/numeric +[compared]: ../operators/relational + +{% headsUp %} +The global name of this function +is comparable, but when it was added to the +`sass:math` module the name was changed +to compatible to more clearly convey what the +function does. +{% endheadsUp %} + +{% codeExample 'math-compatible', false %} +@debug math.compatible(2px, 1px); // true +@debug math.compatible(100px, 3em); // false +@debug math.compatible(10cm, 3mm); // true +=== +@debug math.compatible(2px, 1px) // true +@debug math.compatible(100px, 3em) // false +@debug math.compatible(10cm, 3mm) // true +{% endcodeExample %} +{% endfunction %} + +{% function 'math.is-unitless($number)', 'unitless($number)', 'returns:boolean' %} +Returns whether `$number` has no units. + +{% codeExample 'math-is-unitless', false %} +@debug math.is-unitless(100); // true +@debug math.is-unitless(100px); // false +=== +@debug math.is-unitless(100) // true +@debug math.is-unitless(100px) // false +{% endcodeExample %} +{% endfunction %} + +{% function 'math.unitless($number)', 'unit($number)', 'returns:quoted string' %} +Returns a string representation of `$number`'s units. + +{% headsUp %} +This function is intended for debugging; its output format is not guaranteed +to be consistent across Sass versions or implementations. +{% endheadsUp %} + +{% codeExample 'math-unitless', false %} +@debug math.unit(100); // "" +@debug math.unit(100px); // "px" +@debug math.unit(5px * 10px); // "px*px" +@debug math.unit(math.div(5px, 1s)); // "px/s" +=== +@debug math.unit(100) // "" +@debug math.unit(100px) // "px" +@debug math.unit(5px * 10px) // "px*px" +@debug math.unit(math.div(5px, 1s)) // "px/s" +{% endcodeExample %} +{% endfunction %} + +{% markdown %} +## Other Functions +{% endmarkdown %} + +{% function 'math.div($number1, $number2)', 'returns:number' %} +{% compatibility '1.33.0', false, null, false %}{% endcompatibility %} + +Returns the result of dividing `$number1` by `$number2`. + +Any units shared by both numbers will be canceled out. Units in `$number1` +that aren't in `$number2` will end up in the return value's numerator, and +units in `$number2` that aren't in `$number1` will end up in its denominator. + +{% headsUp %} +For backwards-compatibility purposes, this returns the *exact same result* +as [the deprecated `/` operator], including concatenating two strings with a +`/` character between them. However, this behavior will be removed +eventually and shouldn't be used in new stylesheets. + +[the deprecated `/` operator]: ../breaking-changes/slash-div +{% endheadsUp %} + +{% codeExample 'math-div', false %} +@debug math.div(1, 2); // 0.5 +@debug math.div(100px, 5px); // 20 +@debug math.div(100px, 5); // 20px +@debug math.div(100px, 5s); // 20px/s +=== +@debug math.div(1, 2) // 0.5 +@debug math.div(100px, 5px) // 20 +@debug math.div(100px, 5) // 20px +@debug math.div(100px, 5s) // 20px/s +{% endcodeExample %} +{% endfunction %} + +{% function 'math.percentage($number)', 'percentage($number)', 'returns:number' %} +Converts a unitless `$number` (usually a decimal between 0 and 1) to a +percentage. + +{% funFact %} +This function is identical to `$number * 100%`. +{% endfunFact %} + +{% codeExample 'math-percentage', false %} +@debug math.percentage(0.2); // 20% +@debug math.percentage(math.div(100px, 50px)); // 200% +=== +@debug math.percentage(0.2) // 20% +@debug math.percentage(math.div(100px, 50px)) // 200% +{% endcodeExample %} +{% endfunction %} + +{% function 'math.random($limit: null)', 'random($limit: null)', 'returns:number' %} +If `$limit` is `null`, returns a random decimal number between 0 and 1. + +{% codeExample 'math-random', false %} +@debug math.random(); // 0.2821251858 +@debug math.random(); // 0.6221325814 +=== +@debug math.random() // 0.2821251858 +@debug math.random() // 0.6221325814 +{% endcodeExample %} + +* * * + +If `$limit` is a number greater than or equal to 1, returns a random whole +number between 1 and `$limit`. + +{% headsUp %} +`random()` ignores units in `$limit`. [This behavior is deprecated] and +`random($limit)` will return a random integer with the same units as the +`$limit` argument. + +[This behavior is deprecated]: ../breaking-changes/random-with-units + +{% codeExample 'math-random-warning', false %} +@debug math.random(100px); // 42 +=== +@debug math.random(100px) // 42 +{% endcodeExample %} +{% endheadsUp %} + +{% codeExample 'math-random-limit', false %} +@debug math.random(10); // 4 +@debug math.random(10000); // 5373 +=== +@debug math.random(10) // 4 +@debug math.random(10000) // 5373 +{% endcodeExample %} +{% endfunction %} From a87be92c8036d47223499f4ec014379ca54e6748 Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Mon, 29 May 2023 20:19:19 +0000 Subject: [PATCH 06/19] Port modules/meta --- .../example-first-class-function.liquid | 58 ++ ...e-mixin-arbitrary-keyword-arguments.liquid | 47 ++ source/documentation/modules/meta.liquid | 543 ++++++++++++++++++ .../snippets/call-impl-status.liquid | 11 + .../module-system-function-status.liquid | 3 + 5 files changed, 662 insertions(+) create mode 100644 source/code-snippets/example-first-class-function.liquid create mode 100644 source/code-snippets/example-mixin-arbitrary-keyword-arguments.liquid create mode 100644 source/documentation/modules/meta.liquid create mode 100644 source/documentation/snippets/call-impl-status.liquid create mode 100644 source/documentation/snippets/module-system-function-status.liquid diff --git a/source/code-snippets/example-first-class-function.liquid b/source/code-snippets/example-first-class-function.liquid new file mode 100644 index 000000000..ba1c955dc --- /dev/null +++ b/source/code-snippets/example-first-class-function.liquid @@ -0,0 +1,58 @@ +{# TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass #} + +{% codeExample 'first-class-function' %} +@use "sass:list"; +@use "sass:meta"; +@use "sass:string"; + +/// Return a copy of $list with all elements for which $condition returns `true` +/// removed. +@function remove-where($list, $condition) { + $new-list: (); + $separator: list.separator($list); + @each $element in $list { + @if not meta.call($condition, $element) { + $new-list: list.append($new-list, $element, $separator: $separator); + } + } + @return $new-list; +} + +$fonts: Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif; + +content { + @function contains-helvetica($string) { + @return string.index($string, "Helvetica"); + } + font-family: remove-where($fonts, meta.get-function("contains-helvetica")); +} +=== +@use "sass:list" +@use "sass:meta" +@use "sass:string" + +/// Return a copy of $list with all elements for which $condition returns `true` +/// removed. +@function remove-where($list, $condition) + $new-list: () + $separator: list.separator($list) + @each $element in $list + @if not meta.call($condition, $element) + $new-list: list.append($new-list, $element, $separator: $separator) + + + @return $new-list + + +$fonts: Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif + +.content + @function contains-helvetica($string) + @return string.index($string, "Helvetica") + + font-family: remove-where($fonts, meta.get-function("contains-helvetica")) +=== +.content { + font-family: Tahoma, Geneva, Arial, sans-serif; +} +{% endcodeExample %} diff --git a/source/code-snippets/example-mixin-arbitrary-keyword-arguments.liquid b/source/code-snippets/example-mixin-arbitrary-keyword-arguments.liquid new file mode 100644 index 000000000..fad4b0d38 --- /dev/null +++ b/source/code-snippets/example-mixin-arbitrary-keyword-arguments.liquid @@ -0,0 +1,47 @@ +{% codeExample 'arbitrary-kwargs' %} +@use "sass:meta"; + +@mixin syntax-colors($args...) { + @debug meta.keywords($args); + // (string: #080, comment: #800, variable: #60b) + + @each $name, $color in meta.keywords($args) { + pre span.stx-#{$name} { + color: $color; + } + } +} + +@include syntax-colors( + $string: #080, + $comment: #800, + $variable: #60b, +) +=== +@use "sass:meta" + +@mixin syntax-colors($args...) + @debug meta.keywords($args) + // (string: #080, comment: #800, variable: #60b) + + @each $name, $color in meta.keywords($args) + pre span.stx-#{$name} + color: $color + + + + +@include syntax-colors($string: #080, $comment: #800, $variable: #60b) +=== +pre span.stx-string { + color: #080; +} + +pre span.stx-comment { + color: #800; +} + +pre span.stx-variable { + color: #60b; +} +{% endcodeExample %} diff --git a/source/documentation/modules/meta.liquid b/source/documentation/modules/meta.liquid new file mode 100644 index 000000000..b4d7c6f5f --- /dev/null +++ b/source/documentation/modules/meta.liquid @@ -0,0 +1,543 @@ +--- +title: sass:meta +--- + +{% render 'documentation/snippets/built-in-module-status' %} + +{% markdown %} +## Mixins +{% endmarkdown %} + +{% function 'meta.load-css($url, $with: null)' %} +{% compatibility '1.23.0', false, null, false %} +Only Dart Sass currently supports this mixin. +{% endcompatibility %} + +Loads the [module][] at `$url` and includes its CSS as though it were written +as the contents of this mixin. The `$with` parameter provides +[configuration][] for the modules; if it's passed, it must be a map from +variable names (without `$`) to the values of those variables to use in the +loaded module. + +[module]: /documentation/at-rules/use +[configuration]: /documentation/at-rules/use#configuration + +If `$url` is relative, it's interpreted as relative to the file in which +`meta.load-css()` is included. + +**Like the [`@use` rule][]**: + +[`@use` rule]: /documentation/at-rules/use + +* This will only evaluate the given module once, even if it's loaded multiple +times in different ways. + +* This cannot provide configuration to a module that's already been loaded, +whether or not it was already loaded with configuration. + +**Unlike the [`@use` rule][]**: + +* This doesn't make any members from the loaded module available in the +current module. + +* This can be used anywhere in a stylesheet. It can even be nested within +style rules to create nested styles! + +* The module URL being loaded can come from a variable and include +[interpolation][]. + +[interpolation]: /documentation/interpolation + +{% headsUp %} +The `$url` parameter should be a string containing a URL like you'd pass to +the `@use` rule. It shouldn't be a CSS `url()`! +{% endheadsUp %} + +{% codeExample 'load-css', false %} +// dark-theme/_code.scss +$border-contrast: false !default; + +code { + background-color: #6b717f; + color: #d2e1dd; + @if $border-contrast { + border-color: #dadbdf; + } +} +--- +// style.scss +@use "sass:meta"; + +body.dark { + @include meta.load-css("dark-theme/code", + $with: ("border-contrast": true)); +} +=== +// dark-theme/_code.sass +$border-contrast: false !default + +code + background-color: #6b717f + color: #d2e1dd + @if $border-contrast + border-color: #dadbdf +--- +// style.sass +@use "sass:meta" + +body.dark + $configuration: ("border-contrast": true) + @include meta.load-css("dark-theme/code", $with: $configuration) +=== +body.dark code { + background-color: #6b717f; + color: #d2e1dd; + border-color: #dadbdf; +} +{% endcodeExample %} +{% endfunction %} + +{% markdown %} +## Functions +{% endmarkdown %} + +{% function 'meta.calc-args($calc)', 'returns:list' %} +{% compatibility '1.40.0', false, null, false %}{% endcompatibility %} + +Returns the arguments for the given [calculation]. + +[calculation]: /documentation/values/calculations + +If an argument is a number or a nested calculation, it's returned as that +type. Otherwise, it's returned as an unquoted string. + +{% codeExample 'calc-args', false %} +@debug meta.calc-args(calc(100px + 10%)); // unquote("100px + 10%") +@debug meta.calc-args(clamp(50px, var(--width), 1000px)); // 50px, unquote("var(--width)"), 1000px +=== +@debug meta.calc-args(calc(100px + 10%)) // unquote("100px + 10%") +@debug meta.calc-args(clamp(50px, var(--width), 1000px)) // 50px, unquote("var(--width)"), 1000px +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.calc-name($calc)', 'returns:quoted string' %} +{% compatibility '1.40.0', false, null, false %}{% endcompatibility %} + +Returns the name of the given [calculation]. + +[calculation]: /documentation/values/calculations + +{% codeExample 'calc-name', false %} +@debug meta.calc-name(calc(100px + 10%)); // "calc" +@debug meta.calc-name(clamp(50px, var(--width), 1000px)); // "clamp" +=== +@debug meta.calc-name(calc(100px + 10%)) // "calc" +@debug meta.calc-name(clamp(50px, var(--width), 1000px)) // "clamp" +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.call($function, $args...)', 'call($function, $args...)' %} +{% render 'documentation/snippets/call-impl-status' %} + +Invokes `$function` with `$args` and returns the result. + +The `$function` should be a [function][] returned by +[`meta.get-function()`][]. + +[function]: /documentation/values/functions +[`meta.get-function()`]: #get-function + +{% render 'code-snippets/example-first-class-function' %} +{% endfunction %} + +{% function 'meta.content-exists()', 'content-exists()', 'returns:boolean' %} +Returns whether the current mixin was passed a [`@content` block][]. + +[`@content` block]: /documentation/at-rules/mixin#content-blocks + +Throws an error if called outside of a mixin. + +{% codeExample 'content-exists', false %} +@mixin debug-content-exists { + @debug meta.content-exists(); + @content; +} + +@include debug-content-exists; // false +@include debug-content-exists { // true + // Content! +} +=== +@mixin debug-content-exists + @debug meta.content-exists() + @content + + +@include debug-content-exists // false +@include debug-content-exists // true + // Content! +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.feature-exists($feature)', 'feature-exists($feature)', 'returns:boolean' %} +Returns whether the current Sass implementation supports `$feature`. + +The `$feature` must be a string. The currently recognized features are: + +* `global-variable-shadowing`, which means that a local variable will + [shadow][] a global variable unless it has the `!global` flag. +* `extend-selector-pseudoclass`, which means that the [`@extend` rule][] will + affect selectors nested in pseudo-classes like `:not()`. +* `units-level3`, which means that [unit arithmetic][] supports units defined + in [CSS Values and Units Level 3][]. +* `at-error`, which means that the [`@error` rule][] is supported. +* `custom-property`, which means that [custom property declaration][] values + don't support any [expressions][] other than [interpolation][]. + +[shadow]: /documentation/variables#shadowing +[`@extend` rule]: /documentation/at-rules/extend +[unit arithmetic]: /documentation/values/numbers#units +[CSS Values and Units Level 3]: http://www.w3.org/TR/css3-values +[`@error` rule]: /documentation/at-rules/error +[custom property declaration]: /documentation/style-rules/declarations#custom-properties +[expressions]: /documentation/syntax/structure#expressions +[interpolation]: /documentation/interpolation + +Returns `false` for any unrecognized `$feature`. + +{% codeExample 'feature-exists', false %} +@debug meta.feature-exists("at-error"); // true +@debug meta.feature-exists("unrecognized"); // false +=== +@debug meta.feature-exists("at-error") // true +@debug meta.feature-exists("unrecognized") // false +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.function-exists($name, $module: null)', 'function-exists($name)', 'returns:boolean' %} +Returns whether a function named `$name` is defined, either as a built-in +function or a user-defined function. + +If `$module` is passed, this also checks the module named `$module` for the +function definition. `$module` must be a string matching the namespace of a +[`@use` rule][] in the current file. + +[`@use` rule]: /documentation/at-rules/use + +{% codeExample 'function-exists', false %} +@use "sass:math"; + +@debug meta.function-exists("div", "math"); // true +@debug meta.function-exists("scale-color"); // true +@debug meta.function-exists("add"); // false + +@function add($num1, $num2) { + @return $num1 + $num2; +} +@debug meta.function-exists("add"); // true +=== +@use "sass:math" + +@debug meta.function-exists("div", "math") // true +@debug meta.function-exists("scale-color") // true +@debug meta.function-exists("add") // false + +@function add($num1, $num2) + @return $num1 + $num2 + +@debug meta.function-exists("add") // true +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.get-function($name, $css: false, $module: null)', 'get-function($name, $css: false, $module: null)', 'returns:function' %} +Returns the [function][] named `$name`. + +[function]: /documentation/values/functions + +If `$module` is `null`, this returns the function named `$name` without a +namespace (including [global built-in functions][]). Otherwise, `$module` must +be a string matching the namespace of a [`@use` rule][] in the current file, +in which case this returns the function in that module named `$name`. + +[global built-in functions]: /documentation/modules#global-functions +[`@use` rule]: /documentation/at-rules/use + +By default, this throws an error if `$name` doesn't refer to Sass function. +However, if `$css` is `true`, it instead returns a [plain CSS function][]. + +[user-defined]: /documentation/at-rules/function +[plain CSS function]: /documentation/at-rules/function#plain-css-functions + +The returned function can be called using [`meta.call()`](#call). + +{% render 'code-snippets/example-first-class-function' %} +{% endfunction %} + +{% function 'meta.global-variable-exists($name, $module: null)', 'global-variable-exists($name, $module: null)', 'returns:boolean' %} +Returns whether a [global variable][] named `$name` (without the `$`) exists. + +[global variable]: /documentation/variables#scope + +If `$module` is `null`, this returns whether a variable named `$name` without +a namespace exists. Otherwise, `$module` must be a string matching the +namespace of a [`@use` rule][] in the current file, in which case this returns +whether that module has a variable named `$name`. + +[`@use` rule]: /documentation/at-rules/use + +See also [`meta.variable-exists()`](#variable-exists). + +{% codeExample 'global-variable-exists', false %} +@debug meta.global-variable-exists("var1"); // false + +$var1: value; +@debug meta.global-variable-exists("var1"); // true + +h1 { + // $var2 is local. + $var2: value; + @debug meta.global-variable-exists("var2"); // false +} +=== +@debug meta.global-variable-exists("var1") // false + +$var1: value +@debug meta.global-variable-exists("var1") // true + +h1 + // $var2 is local. + $var2: value + @debug meta.global-variable-exists("var2") // false +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.inspect($value)', 'inspect($value)', 'returns:unquoted string' %} +Returns a string representation of `$value`. + +Returns a representation of *any* Sass value, not just those that can be +represented in CSS. As such, its return value is not guaranteed to be valid +CSS. + +{% headsUp %} +This function is intended for debugging; its output format is not guaranteed +to be consistent across Sass versions or implementations. +{% endheadsUp %} + +{% codeExample 'inspect', false %} +@debug meta.inspect(10px 20px 30px); // unquote("10px 20px 30px") +@debug meta.inspect(("width": 200px)); // unquote('("width": 200px)') +@debug meta.inspect(null); // unquote("null") +@debug meta.inspect("Helvetica"); // unquote('"Helvetica"') +=== +@debug meta.inspect(10px 20px 30px) // unquote("10px 20px 30px") +@debug meta.inspect(("width": 200px)) // unquote('("width": 200px)') +@debug meta.inspect(null) // unquote("null") +@debug meta.inspect("Helvetica") // unquote('"Helvetica"') +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.keywords($args)', 'keywords($args)', 'returns:map' %} +Returns the keywords passed to a mixin or function that takes [arbitrary +arguments][]. The `$args` argument must be an [argument list][]. + +[arbitrary arguments]: /documentation/at-rules/mixin#taking-arbitrary-arguments +[argument list]: /documentation/values/lists#argument-lists + +The keywords are returned as a map from argument names as unquoted strings (not +including `$`) to the values of those arguments. + +{% render 'code-snippets/example-mixin-arbitrary-keyword-arguments' %} +{% endfunction %} + +{% function 'meta.mixin-exists($name, $module: null)', 'mixin-exists($name, $module: null)', 'returns:boolean' %} +Returns whether a [mixin][] named `$name` exists. + +[mixin]: /documentation/at-rules/mixin + +If `$module` is `null`, this returns whether a mixin named `$name` without a +namespace exists. Otherwise, `$module` must be a string matching the namespace +of a [`@use` rule][] in the current file, in which case this returns whether +that module has a mixin named `$name`. + +[`@use` rule]: /documentation/at-rules/use + +{% codeExample 'mixin-exists', false %} +@debug meta.mixin-exists("shadow-none"); // false + +@mixin shadow-none { + box-shadow: none; +} + +@debug meta.mixin-exists("shadow-none"); // true +=== +@debug meta.mixin-exists("shadow-none") // false + +@mixin shadow-none + box-shadow: none + + +@debug meta.mixin-exists("shadow-none") // true +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.module-functions($module)', 'returns:map' %} +{% render 'documentation/snippets/module-system-function-status' %} + +Returns all the functions defined in a module, as a map from function names to +[function values][]. + +[function values]: /documentation/values/functions + +The `$module` parameter must be a string matching the namespace of a [`@use` +rule][] in the current file. + +[`@use` rule]: /documentation/at-rules/use + +{% codeExample 'module-functions', false %} +// _functions.scss +@function pow($base, $exponent) { + $result: 1; + @for $_ from 1 through $exponent { + $result: $result * $base; + } + @return $result; +} +--- +@use "sass:map"; +@use "sass:meta"; + +@use "functions"; + +@debug meta.module-functions("functions"); // ("pow": get-function("pow")) + +@debug meta.call(map.get(meta.module-functions("functions"), "pow"), 3, 4); // 81 +=== +// _functions.sass +@function pow($base, $exponent) + $result: 1 + @for $_ from 1 through $exponent + $result: $result * $base + + @return $result +--- +@use "sass:map" +@use "sass:meta" + +@use "functions" + +@debug meta.module-functions("functions") // ("pow": get-function("pow")) + +@debug meta.call(map.get(meta.module-functions("functions"), "pow"), 3, 4) // 81 +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.module-variables($module)', 'returns:map' %} +{% render 'documentation/snippets/module-system-function-status' %} + +Returns all the variables defined in a module, as a map from variable names +(without `$`) to the values of those variables. + +The `$module` parameter must be a string matching the namespace of a [`@use` +rule][] in the current file. + +[`@use` rule]: /documentation/at-rules/use + +{% codeExample 'module-variables', false %} +// _variables.scss +$hopbush: #c69; +$midnight-blue: #036; +$wafer: #e1d7d2; +--- +@use "sass:meta"; + +@use "variables"; + +@debug meta.module-variables("variables"); +// ( +// "hopbush": #c69, +// "midnight-blue": #036, +// "wafer": #e1d7d2 +// ) +=== +// _variables.sass +$hopbush: #c69 +$midnight-blue: #036 +$wafer: #e1d7d2 +--- +@use "sass:meta" + +@use "variables" + +@debug meta.module-variables("variables") +// ( +// "hopbush": #c69, +// "midnight-blue": #036, +// "wafer": #e1d7d2 +// ) +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.type-of($value)', 'type-of($value)', 'returns:unquoted string' %} +Returns the type of `$value`. + +This can return the following values: + +* [`number`](/documentation/values/numbers) +* [`string`](/documentation/values/strings) +* [`color`](/documentation/values/colors) +* [`list`](/documentation/values/lists) +* [`map`](/documentation/values/maps) +* [`calculation`](/documentation/values/calculations) +* [`bool`](/documentation/values/booleans) +* [`null`](/documentation/values/null) +* [`function`](/documentation/values/functions) +* [`arglist`](/documentation/values/lists#argument-lists) + +New possible values may be added in the future. It may return either `list` or +`map` for `()`, depending on whether or not it was returned by a +[map function][]. + +[map function]: /documentation/modules/map + +{% codeExample 'type-of', false %} +@debug meta.type-of(10px); // number +@debug meta.type-of(10px 20px 30px); // list +@debug meta.type-of(()); // list +=== +@debug meta.type-of(10px) // number +@debug meta.type-of(10px 20px 30px) // list +@debug meta.type-of(()) // list +{% endcodeExample %} +{% endfunction %} + +{% function 'meta.variable-exists($name)', 'variable-exists($name)', 'returns:boolean' %} +Returns whether a variable named `$name` (without the `$`) exists in the +current [scope][]. + +[scope]: /documentation/variables#scope + +See also [`meta.global-variable-exists()`](#global-variable-exists). + +{% codeExample 'variable-exists', false %} +@debug meta.variable-exists("var1"); // false + +$var1: value; +@debug meta.variable-exists("var1"); // true + +h1 { + // $var2 is local. + $var2: value; + @debug meta.variable-exists("var2"); // true +} +=== +@debug meta.variable-exists("var1") // false + +$var1: value +@debug meta.variable-exists("var1") // true + +h1 + // $var2 is local. + $var2: value + @debug meta.variable-exists("var2") // true +{% endcodeExample %} +{% endfunction %} diff --git a/source/documentation/snippets/call-impl-status.liquid b/source/documentation/snippets/call-impl-status.liquid new file mode 100644 index 000000000..ce56ccf02 --- /dev/null +++ b/source/documentation/snippets/call-impl-status.liquid @@ -0,0 +1,11 @@ +{% compatibility true, '3.5.0', null, '3.5.0', 'Argument type' %} +In older versions of LibSass and Ruby Sass, the [`call()` function][] took a +string representing a function's name. This was changed to take a function +value instead in preparation for a new module system where functions are no +longer global and so a given name may not always refer to the same function. + +[`call()` function]: /documentation/modules/meta#call + +Passing a string to `call()` still works in all implementations, but it's +deprecated and will be disallowed in future versions. +{% endcompatibility %} diff --git a/source/documentation/snippets/module-system-function-status.liquid b/source/documentation/snippets/module-system-function-status.liquid new file mode 100644 index 000000000..dad5db1cd --- /dev/null +++ b/source/documentation/snippets/module-system-function-status.liquid @@ -0,0 +1,3 @@ +{% compatibility '1.23.0', false, null, false %} +Only Dart Sass currently supports this function. +{% endcompatibility %} From 0babc895743c6397791e0e433a47545f6e3929b3 Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Mon, 29 May 2023 20:26:14 +0000 Subject: [PATCH 07/19] Fix links --- source/documentation/modules/list.liquid | 14 +++++++------- source/documentation/modules/map.liquid | 2 +- source/documentation/modules/math.liquid | 16 ++++++++-------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/source/documentation/modules/list.liquid b/source/documentation/modules/list.liquid index e6a2313e0..e3766dc42 100644 --- a/source/documentation/modules/list.liquid +++ b/source/documentation/modules/list.liquid @@ -9,7 +9,7 @@ In Sass, every [map][] counts as a list that contains a two-element list for each key/value pair. For example, `(1: 2, 3: 4)` counts as `(1 2, 3 4)`. So all these functions work for maps as well! -[map]: ../values/maps +[map]: /documentation/values/maps Individual values also count as lists. All these functions treat `1px` as a list that contains the value `1px`. @@ -23,7 +23,7 @@ comma-separated, space-separated, or slash-separated, respectively. If it's `auto` (the default), the returned list will use the same separator as `$list` (or `space` if `$list` doesn't have a separator). Other values aren't allowed. -[separator]: ../values/lists +[separator]: /documentation/values/lists Note that unlike [`list.join()`](#join), if `$val` is a list it's nested within the returned list rather than having all its elements added to the @@ -47,13 +47,13 @@ returned list. {% function 'list.index($list, $value)', 'index($list, $value)', 'returns:number | null' %} Returns the [index][] of `$value` in `$list`. -[index]: ../values/lists#indexes +[index]: /documentation/values/lists#indexes If `$value` doesn't appear in `$list`, this returns [`null`][]. If `$value` appears multiple times in `$list`, this returns the index of its first appearance. -[`null`]: ../values/null +[`null`]: /documentation/values/null {% render 'code-snippets/example-list-index' %} {% endfunction %} @@ -153,7 +153,7 @@ If `$list` doesn't have a separator, returns `space`. {% function 'list.nth($list, $n)', 'nth($list, $n)' %} Returns the element of `$list` at [index][] `$n`. -[index]: ../values/lists#indexes +[index]: /documentation/values/lists#indexes If `$n` is negative, it counts from the end of `$list`. Throws an error if there is no element at index `$n`. @@ -165,7 +165,7 @@ there is no element at index `$n`. Returns a copy of `$list` with the element at [index][] `$n` replaced with `$value`. -[index]: ../values/lists#indexes +[index]: /documentation/values/lists#indexes If `$n` is negative, it counts from the end of `$list`. Throws an error if there is no existing element at index `$n`. @@ -190,7 +190,7 @@ Eventually, they'll be written literally with slashes, as in `1px / 2px / solid`, but for the time being [slashes are used for division] so Sass can't use them for new syntax until the old syntax is removed. -[slashes are used for division]: ../breaking-changes/slash-div +[slashes are used for division]: /documentation/breaking-changes/slash-div {% endheadsUp %} {% codeExample 'list-slash', false %} diff --git a/source/documentation/modules/map.liquid b/source/documentation/modules/map.liquid index 0c20960f8..969af2f6d 100644 --- a/source/documentation/modules/map.liquid +++ b/source/documentation/modules/map.liquid @@ -186,7 +186,7 @@ $fonts: ("Helvetica": ("weights": ("regular": 400, "medium": 500, "bold": 700))) @debug map.get($fonts, "Helvetica", "colors") // null {% endcodeExample %} -[`null`]: ../values/null +[`null`]: /documentation/values/null {% endfunction %} {% function 'map.has-key($map, $key, $keys...)', 'map-has-key($map, $key, $keys...)', 'returns:boolean' %} diff --git a/source/documentation/modules/math.liquid b/source/documentation/modules/math.liquid index a33a98756..c61b771b0 100644 --- a/source/documentation/modules/math.liquid +++ b/source/documentation/modules/math.liquid @@ -28,7 +28,7 @@ The closest 64-bit floating point approximation of the [mathematical constant The difference between 1 and the smallest 64-bit floating point number greater than 1 according to floating-point comparisons. Because of Sass numbers' [10 -digits of precision](../values/numbers), in many cases this will appear to +digits of precision](/documentation/values/numbers), in many cases this will appear to be 0. {% endfunction %} @@ -63,7 +63,7 @@ represented as a 64-bit floating-point number. The smallest positive number that can be represented as a 64-bit floating point number. Because of Sass numbers' [10 digits of -precision](../values/numbers), in many cases this will appear to be 0. +precision](/documentation/values/numbers), in many cases this will appear to be 0. {% endfunction %} {% function 'math.$min-safe-integer' %} @@ -452,9 +452,9 @@ Returns whether `$number1` and `$number2` have compatible units. If this returns `true`, `$number1` and `$number2` can safely be [added][], [subtracted][], and [compared][]. Otherwise, doing so will produce errors. -[added]: ../operators/numeric -[subtracted]: ../operators/numeric -[compared]: ../operators/relational +[added]: /documentation/operators/numeric +[subtracted]: /documentation/operators/numeric +[compared]: /documentation/operators/relational {% headsUp %} The global name of this function @@ -487,7 +487,7 @@ Returns whether `$number` has no units. {% endcodeExample %} {% endfunction %} -{% function 'math.unitless($number)', 'unit($number)', 'returns:quoted string' %} +{% function 'math.unit($number)', 'unit($number)', 'returns:quoted string' %} Returns a string representation of `$number`'s units. {% headsUp %} @@ -527,7 +527,7 @@ as [the deprecated `/` operator], including concatenating two strings with a `/` character between them. However, this behavior will be removed eventually and shouldn't be used in new stylesheets. -[the deprecated `/` operator]: ../breaking-changes/slash-div +[the deprecated `/` operator]: /documentation/breaking-changes/slash-div {% endheadsUp %} {% codeExample 'math-div', false %} @@ -581,7 +581,7 @@ number between 1 and `$limit`. `random($limit)` will return a random integer with the same units as the `$limit` argument. -[This behavior is deprecated]: ../breaking-changes/random-with-units +[This behavior is deprecated]: /documentation/breaking-changes/random-with-units {% codeExample 'math-random-warning', false %} @debug math.random(100px); // 42 From b26f496017caa2fdd44d99d377741da8bec42ade Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Mon, 29 May 2023 20:37:50 +0000 Subject: [PATCH 08/19] Port modules/selector --- source/documentation/modules/selector.liquid | 238 +++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 source/documentation/modules/selector.liquid diff --git a/source/documentation/modules/selector.liquid b/source/documentation/modules/selector.liquid new file mode 100644 index 000000000..3e0ea6a1b --- /dev/null +++ b/source/documentation/modules/selector.liquid @@ -0,0 +1,238 @@ +--- +title: sass:selector +--- + +{% render 'documentation/snippets/built-in-module-status' %} + +{% markdown %} +## Selector Values + +The functions in this module inspect and manipulate selectors. Whenever they +return a selector, it's always a comma-separated [list][] (the selector list) +that contains space-separated lists (the complex selectors) that contain +[unquoted strings][] (the compound selectors). For example, the selector `.main +aside:hover, .sidebar p` would be returned as: + +[list]: /documentation/values/lists +[unquoted strings]: /documentation/values/strings#unquoted + +```scss +@debug ((unquote(".main") unquote("aside:hover")), + (unquote(".sidebar") unquote("p"))); +// .main aside:hover, .sidebar p +``` + +Selector arguments to these functions may be in the same format, but they can +also just be normal strings (quoted or unquoted), or a combination. For example, +`".main aside:hover, .sidebar p"` is a valid selector argument. +{% endmarkdown %} + +{% function 'selector.is-superselector($super, $sub)', 'is-superselector($super, $sub)', 'returns:boolean' %} +Returns whether the selector `$super` matches all the elements that the +selector `$sub` matches. + +Still returns true even if `$super` matches *more* elements than `$sub`. + +The `$super` and `$sub` selectors may contain [placeholder selectors][], but +not [parent selectors][]. + +[placeholder selectors]: /documentation/style-rules/placeholder-selectors +[parent selectors]: /documentation/style-rules/parent-selector + +{% codeExample 'is-superselector', false %} +@debug selector.is-superselector("a", "a.disabled"); // true +@debug selector.is-superselector("a.disabled", "a"); // false +@debug selector.is-superselector("a", "sidebar a"); // true +@debug selector.is-superselector("sidebar a", "a"); // false +@debug selector.is-superselector("a", "a"); // true +=== +@debug selector.is-superselector("a", "a.disabled") // true +@debug selector.is-superselector("a.disabled", "a") // false +@debug selector.is-superselector("a", "sidebar a") // true +@debug selector.is-superselector("sidebar a", "a") // false +@debug selector.is-superselector("a", "a") // true +{% endcodeExample %} +{% endfunction %} + +{% function 'selector.append($selectors...)', 'selector-append($selectors...)', 'returns:selector' %} +Combines `$selectors` without [descendant combinators][]—that is, without +whitespace between them. + +[descendant combinators]: https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_selectors + +If any selector in `$selectors` is a selector list, each complex selector is +combined separately. + +The `$selectors` may contain [placeholder selectors][], but not [parent +selectors][]. + +[placeholder selectors]: /documentation/style-rules/placeholder-selectors +[parent selectors]: /documentation/style-rules/parent-selector + +See also [`selector.nest()`](#nest). + +{% codeExample 'append', false %} +@debug selector.append("a", ".disabled"); // a.disabled +@debug selector.append(".accordion", "__copy"); // .accordion__copy +@debug selector.append(".accordion", "__copy, __image"); +// .accordion__copy, .accordion__image +=== +@debug selector.append("a", ".disabled") // a.disabled +@debug selector.append(".accordion", "__copy") // .accordion__copy +@debug selector.append(".accordion", "__copy, __image") +// .accordion__copy, .accordion__image +{% endcodeExample %} +{% endfunction %} + +{% function 'selector.extend($selector, $extendee, $extender)', 'selector-extend($selector, $extendee, $extender)', 'returns:selector' %} +Extends `$selector` as with the [`@extend` rule][]. + +[`@extend` rule]: /documentation/at-rules/extend + +Returns a copy of `$selector` modified with the following `@extend` rule: + +```scss +#{$extender} { + @extend #{$extendee}; +} +``` + +In other words, replaces all instances of `$extendee` in `$selector` with +`$extendee, $extender`. If `$selector` doesn't contain `$extendee`, returns it +as-is. + +The `$selector`, `$extendee`, and `$extender` selectors may contain +[placeholder selectors][], but not [parent selectors][]. + +[placeholder selectors]: /documentation/style-rules/placeholder-selectors +[parent selectors]: /documentation/style-rules/parent-selector + +See also [`selector.replace()`](#replace). + +{% codeExample 'extend', false %} +@debug selector.extend("a.disabled", "a", ".link"); // a.disabled, .link.disabled +@debug selector.extend("a.disabled", "h1", "h2"); // a.disabled +@debug selector.extend(".guide .info", ".info", ".content nav.sidebar"); +// .guide .info, .guide .content nav.sidebar, .content .guide nav.sidebar +=== +@debug selector.extend("a.disabled", "a", ".link") // a.disabled, .link.disabled +@debug selector.extend("a.disabled", "h1", "h2") // a.disabled +@debug selector.extend(".guide .info", ".info", ".content nav.sidebar") +// .guide .info, .guide .content nav.sidebar, .content .guide nav.sidebar +{% endcodeExample %} +{% endfunction %} + +{% function 'selector.nest($selectors...)', 'selector-nest($selectors...)', 'returns:selector' %} +Combines `$selectors` as though they were nested within one another in the +stylesheet. + +The `$selectors` may contain [placeholder selectors][]. Unlike other selector +functions, all of them except the first may also contain [parent selectors][]. + +[placeholder selectors]: /documentation/style-rules/placeholder-selectors +[parent selectors]: /documentation/style-rules/parent-selector + +See also [`selector.append()`](#append). + +{% codeExample 'nest', false %} +@debug selector.nest("ul", "li"); // ul li +@debug selector.nest(".alert, .warning", "p"); // .alert p, .warning p +@debug selector.nest(".alert", "&:hover"); // .alert:hover +@debug selector.nest(".accordion", "&__copy"); // .accordion__copy +=== +@debug selector.nest("ul", "li") // ul li +@debug selector.nest(".alert, .warning", "p") // .alert p, .warning p +@debug selector.nest(".alert", "&:hover") // .alert:hover +@debug selector.nest(".accordion", "&__copy") // .accordion__copy +{% endcodeExample %} +{% endfunction %} + +{% function 'selector.parse($selector)', 'selector-parse($selector)', 'returns:selector' %} +Returns `$selector` in the [selector value](#selector-values) format. + +{% codeExample 'parse', false %} +@debug selector.parse(".main aside:hover, .sidebar p"); +// ((unquote(".main") unquote("aside:hover")), +// (unquote(".sidebar") unquote("p"))) +=== +@debug selector.parse(".main aside:hover, .sidebar p") +// ((unquote(".main") unquote("aside:hover")), +// (unquote(".sidebar") unquote("p"))) +{% endcodeExample %} +{% endfunction %} + +{% function 'selector.replace($selector, $original, $replacement)', 'selector-replace($selector, $original, $replacement)', 'returns:selector' %} +Returns a copy of `$selector` with all instances of `$original` replaced by +`$replacement`. + +This uses the [`@extend` rule][]'s [intelligent unification][] to make sure +`$replacement` is seamlessly integrated into `$selector`. If `$selector` +doesn't contain `$original`, returns it as-is. + +[`@extend` rule]: /documentation/at-rules/extend +[intelligent unification]: /documentation/at-rules/extend#how-it-works + +The `$selector`, `$original`, and `$replacement` selectors may contain +[placeholder selectors][], but not [parent selectors][]. + +[placeholder selectors]: /documentation/style-rules/placeholder-selectors +[parent selectors]: /documentation/style-rules/parent-selector + +See also [`selector.extend()`](#extend). + +{% codeExample 'replace', false %} +@debug selector.replace("a.disabled", "a", ".link"); // .link.disabled +@debug selector.replace("a.disabled", "h1", "h2"); // a.disabled +@debug selector.replace(".guide .info", ".info", ".content nav.sidebar"); +// .guide .content nav.sidebar, .content .guide nav.sidebar +=== +@debug selector.replace("a.disabled", "a", ".link") // .link.disabled +@debug selector.replace("a.disabled", "h1", "h2") // a.disabled +@debug selector.replace(".guide .info", ".info", ".content nav.sidebar") +// .guide .content nav.sidebar, .content .guide nav.sidebar +{% endcodeExample %} +{% endfunction %} + +{% function 'selector.unify($selector1, $selector2)', 'selector-unify($selector1, $selector2)', 'returns:selector | null' %} +Returns a selector that matches only elements matched by *both* `$selector1` +and `$selector2`. + +Returns `null` if `$selector1` and `$selector2` don't match any of the same +elements, or if there's no selector that can express their overlap. + +Like selectors generated by the [`@extend` rule][], the returned selector +isn't guaranteed to match *all* the elements matched by both `$selector1` and +`$selector2` if they're both complex selectors. + +[`@extend` rule]: /documentation/at-rules/extend#html-heuristics + +{% codeExample 'unify', false %} +@debug selector.unify("a", ".disabled"); // a.disabled +@debug selector.unify("a.disabled", "a.outgoing"); // a.disabled.outgoing +@debug selector.unify("a", "h1"); // null +@debug selector.unify(".warning a", "main a"); // .warning main a, main .warning a +=== +@debug selector.unify("a", ".disabled") // a.disabled +@debug selector.unify("a.disabled", "a.outgoing") // a.disabled.outgoing +@debug selector.unify("a", "h1") // null +@debug selector.unify(".warning a", "main a") // .warning main a, main .warning a +{% endcodeExample %} +{% endfunction %} + +{% function 'selector.simple-selectors($selector)', 'simple-selectors($selector)', 'returns:list' %} +Returns a list of simple selectors in `$selector`. + +The `$selector` must be a single string that contains a compound selector. +This means it may not contain combinators (including spaces) or commas. + +The returned list is comma-separated, and the simple selectors are unquoted +strings. + +{% codeExample 'simple-selectors', false %} +@debug selector.simple-selectors("a.disabled"); // a, .disabled +@debug selector.simple-selectors("main.blog:after"); // main, .blog, :after +=== +@debug selector.simple-selectors("a.disabled") // a, .disabled +@debug selector.simple-selectors("main.blog:after") // main, .blog, :after +{% endcodeExample %} +{% endfunction %} From ab9e9dd92c360474626805f69826861468101839 Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Mon, 29 May 2023 20:46:09 +0000 Subject: [PATCH 09/19] Port modules/string --- source/documentation/modules/string.liquid | 164 +++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 source/documentation/modules/string.liquid diff --git a/source/documentation/modules/string.liquid b/source/documentation/modules/string.liquid new file mode 100644 index 000000000..764902309 --- /dev/null +++ b/source/documentation/modules/string.liquid @@ -0,0 +1,164 @@ +--- +title: sass:string +--- + +{% render 'documentation/snippets/built-in-module-status' %} + +{% function 'string.quote($string)', 'quote($string)', 'returns:string' %} +Returns `$string` as a quoted string. + +{% codeExample 'quote', false %} +@debug string.quote(Helvetica); // "Helvetica" +@debug string.quote("Helvetica"); // "Helvetica" +=== +@debug string.quote(Helvetica) // "Helvetica" +@debug string.quote("Helvetica") // "Helvetica" +{% endcodeExample %} +{% endfunction %} + +{% function 'string.index($string, $substring)', 'str-index($string, $substring)', 'returns:number' %} +Returns the first [index][] of `$substring` in `$string`, or `null` if +`$string` doesn't contain `$substring`. + +[index]: /documentation/values/strings#string-indexes + +{% codeExample 'index', false %} +@debug string.index("Helvetica Neue", "Helvetica"); // 1 +@debug string.index("Helvetica Neue", "Neue"); // 11 +=== +@debug string.index("Helvetica Neue", "Helvetica") // 1 +@debug string.index("Helvetica Neue", "Neue") // 11 +{% endcodeExample %} +{% endfunction %} + +{% function 'string.insert($string, $insert, $index)', 'str-insert($string, $insert, $index)', 'returns:string' %} +Returns a copy of `$string` with `$insert` inserted at [`$index`][]. + +[`$index`]: /documentation/values/strings#string-indexes + +{% codeExample 'insert', false %} +@debug string.insert("Roboto Bold", " Mono", 7); // "Roboto Mono Bold" +@debug string.insert("Roboto Bold", " Mono", -6); // "Roboto Mono Bold" +=== +@debug string.insert("Roboto Bold", " Mono", 7) // "Roboto Mono Bold" +@debug string.insert("Roboto Bold", " Mono", -6) // "Roboto Mono Bold" +{% endcodeExample %} + +If `$index` is higher than the length of `$string`, `$insert` is added to +the end. If `$index` is smaller than the negative length of the string, +`$insert` is added to the beginning. + +{% codeExample 'insert-2', false %} +@debug string.insert("Roboto", " Bold", 100); // "Roboto Bold" +@debug string.insert("Bold", "Roboto ", -100); // "Roboto Bold" +=== +@debug string.insert("Roboto", " Bold", 100) // "Roboto Bold" +@debug string.insert("Bold", "Roboto ", -100) // "Roboto Bold" +{% endcodeExample %} +{% endfunction %} + +{% function 'string.length($string)', 'str-length($string)', 'returns:number' %} +Returns the number of characters in `$string`. + +{% codeExample 'length', false %} +@debug string.length("Helvetica Neue"); // 14 +@debug string.length(bold); // 4 +@debug string.length(""); // 0 +=== +@debug string.length("Helvetica Neue") // 14 +@debug string.length(bold) // 4 +@debug string.length("") // 0 +{% endcodeExample %} +{% endfunction %} + +{% function 'string.slice($string, $start-at, $end-at: -1)', 'str-slice($string, $start-at, $end-at: -1)', 'returns:string' %} +Returns the slice of `$string` starting at [index][] `$start-at` and ending at +index `$end-at` (both inclusive). + +[index]: /documentation/values/strings#string-indexes + +{% codeExample 'slice', false %} +@debug string.slice("Helvetica Neue", 11); // "Neue" +@debug string.slice("Helvetica Neue", 1, 3); // "Hel" +@debug string.slice("Helvetica Neue", 1, -6); // "Helvetica" +=== +@debug string.slice("Helvetica Neue", 11) // "Neue" +@debug string.slice("Helvetica Neue", 1, 3) // "Hel" +@debug string.slice("Helvetica Neue", 1, -6) // "Helvetica" +{% endcodeExample %} +{% endfunction %} + +{% function 'string.split($string, $separator, $limit: null)', 'returns:list' %} +{% compatibility '1.57.0', false, null, false %}{% endcompatibility %} + +Returns a bracketed, comma-separated list of substrings of `$string` that are +separated by `$separator`. The `$separator`s aren't included in these +substrings. + +If `$limit` is a number `1` or higher, this splits on at most that many +`$separator`s (and so returns at most `$limit + 1` strings). The last +substring contains the rest of the string, including any remaining +`$separator`s. + +{% codeExample 'split', false %} +@debug string.split("Segoe UI Emoji", " "); // ["Segoe", "UI", "Emoji"] +@debug string.split("Segoe UI Emoji", " ", $limit: 1); // ["Segoe", "UI Emoji"] +=== +@debug string.split("Segoe UI Emoji", " ") // ["Segoe", "UI", "Emoji"] +@debug string.split("Segoe UI Emoji", " ", $limit: 1) // ["Segoe", "UI Emoji"] +{% endcodeExample %} +{% endfunction %} + +{% function 'string.to-upper-case($string)', 'to-upper-case($string)', 'returns:string' %} +Returns a copy of `$string` with the [ASCII][] letters converted to upper case. + +[ASCII]: https://en.wikipedia.org/wiki/ASCII + +{% codeExample 'to-upper-case', false %} +@debug string.to-upper-case("Bold"); // "BOLD" +@debug string.to-upper-case(sans-serif); // SANS-SERIF +=== +@debug string.to-upper-case("Bold") // "BOLD" +@debug string.to-upper-case(sans-serif) // SANS-SERIF +{% endcodeExample %} +{% endfunction %} + +{% function 'string.to-lower-case($string)', 'to-lower-case($string)', 'returns:string' %} +Returns a copy of `$string` with the [ASCII][] letters converted to lower case. + +[ASCII]: https://en.wikipedia.org/wiki/ASCII + +{% codeExample 'to-lower-case', false %} +@debug string.to-lower-case("Bold"); // "bold" +@debug string.to-lower-case(SANS-SERIF); // sans-serif +=== +@debug string.to-lower-case("Bold") // "bold" +@debug string.to-lower-case(SANS-SERIF) // sans-serif +{% endcodeExample %} +{% endfunction %} + +{% function 'string.unique-id()', 'unique-id()', 'returns:string' %} +Returns a randomly-generated unquoted string that's guaranteed to be a valid +CSS identifier and to be unique within the current Sass compilation. + +{% codeExample 'unique-id', false %} +@debug string.unique-id(); // uabtrnzug +@debug string.unique-id(); // u6w1b1def +=== +@debug string.unique-id(); // uabtrnzug +@debug string.unique-id(); // u6w1b1def +{% endcodeExample %} +{% endfunction %} + +{% function 'string.unquote($string)', 'unquote($string)', 'returns:string' %} +Returns `$string` as an unquoted string. This can produce strings that aren't +valid CSS, so use with caution. + +{% codeExample 'unquote', false %} +@debug string.unquote("Helvetica"); // Helvetica +@debug string.unquote(".widget:hover"); // .widget:hover +=== +@debug string.unquote("Helvetica") // Helvetica +@debug string.unquote(".widget:hover") // .widget:hover +{% endcodeExample %} +{% endfunction %} From 44c854d214bd83a5ffc922d3064371def5728c1b Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Tue, 30 May 2023 15:49:58 +0000 Subject: [PATCH 10/19] Add missing class --- source/helpers/function.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/helpers/function.ts b/source/helpers/function.ts index cdd392808..732680ae8 100644 --- a/source/helpers/function.ts +++ b/source/helpers/function.ts @@ -85,7 +85,7 @@ export function _function(content: string, ...signatures: string[]) { const div = $('
') .addClass('sl-c-callout sl-c-callout--function') .attr('id', names[0]); - const pre = $('
').addClass('language-scss');
+  const pre = $('
').addClass('signature language-scss');
   const anchor = $('').addClass('anchor').attr('href', `#${names[0]}`);
   const code = $('')
     .addClass('language-scss')

From 85ef810781c366995aebb166f76d2128eb211bd6 Mon Sep 17 00:00:00 2001
From: Jonny Gerig Meyer 
Date: Tue, 30 May 2023 16:49:15 -0400
Subject: [PATCH 11/19] start review

---
 source/documentation/modules/index.liquid        | 16 +++++++++++-----
 .../snippets/built-in-module-status.liquid       |  1 +
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/source/documentation/modules/index.liquid b/source/documentation/modules/index.liquid
index 259481f24..739f12302 100644
--- a/source/documentation/modules/index.liquid
+++ b/source/documentation/modules/index.liquid
@@ -5,11 +5,11 @@ eleventyComputed:
     {% render 'documentation/snippets/built-in-module-status' %}
 introduction: >
   Sass provides many built-in modules which contain useful functions (and the
-  occasional mixin). These modules can be loaded with the
-  [`@use` rule](/documentation/at-rules/use) like any user-defined stylesheet, and their
+  occasional mixin). These modules can be loaded with the [`@use`
+  rule](/documentation/at-rules/use) like any user-defined stylesheet, and their
   functions can be called [like any other module
-  member](/documentation/at-rules/use#loading-members). All built-in module URLs begin with
-  `sass:` to indicate that they're part of Sass itself.
+  member](/documentation/at-rules/use#loading-members). All built-in module URLs
+  begin with `sass:` to indicate that they're part of Sass itself.
 ---
 
 {% headsUp %}
@@ -91,6 +91,7 @@ Sass provides the following built-in modules:
 {% endmarkdown %}
 
 {% function 'hsl($hue $saturation $lightness)', 'hsl($hue $saturation $lightness / $alpha)', 'hsl($hue, $saturation, $lightness, $alpha: 1)', 'hsla($hue $saturation $lightness)', 'hsla($hue $saturation $lightness / $alpha)', 'hsla($hue, $saturation, $lightness, $alpha: 1)', 'returns:color' %}
+{% # Arguments are (in order): `dart`, `libsass`, `node`, `ruby`, optional feature name, additional details within %}
 {% compatibility '1.15.0', false, null, false, 'Level 4 Syntax' %}
 LibSass and Ruby Sass only support the following signatures:
 
@@ -102,6 +103,7 @@ the function name `hsla()` is used, and *forbidden* if the function name
 `hsl()` is used.
 {% endcompatibility %}
 
+{% # Arguments are (in order): `dart`, `libsass`, `node`, `ruby`, optional feature name, additional details within %}
 {% compatibility true, false, null, '3.7.0', 'Percent Alpha' %}
 LibSass and older versions of Ruby Sass don't support alpha values specified as
 percentages.
@@ -183,6 +185,7 @@ error.
 {% endfunction %}
 
 {% function 'rgb($red $green $blue)', 'rgb($red $green $blue / $alpha)', 'rgb($red, $green, $blue, $alpha: 1)', 'rgb($color, $alpha)', 'rgba($red $green $blue)', 'rgba($red $green $blue / $alpha)', 'rgba($red, $green, $blue, $alpha: 1)', 'rgba($color, $alpha)', 'returns:color' %}
+{% # Arguments are (in order): `dart`, `libsass`, `node`, `ruby`, optional feature name, additional details within %}
 {% compatibility '1.15.0', false, null, false, 'Level 4 Syntax' %}
 LibSass and Ruby Sass only support the following signatures:
 
@@ -195,6 +198,7 @@ the function name `rgba()` is used, and *forbidden* if the function name
 `rgb()` is used.
 {% endcompatibility %}
 
+{% # Arguments are (in order): `dart`, `libsass`, `node`, `ruby`, optional feature name, additional details within %}
 {% compatibility true, false, null, '3.7.0', 'Percent Alpha' %}
 LibSass and older versions of Ruby Sass don't support alpha values specified
 as percentages.
@@ -210,7 +214,8 @@ alpha channel can be specified as either a unitless number between 0 and 1
 
 [unitless]: /documentation/values/numbers#units
 
-{% funFact %}
+{% funFact false %}
+{% markdown %}
 You can pass [special functions][] like `calc()` or `var()` in place of any
 argument to `rgb()`. You can even use `var()` in place of multiple
 arguments, since it might be replaced by multiple values! When a color
@@ -218,6 +223,7 @@ function is called this way, it returns an unquoted string using the same
 signature it was called with.
 
 [special functions]: /documentation/syntax/special-functions
+{% endmarkdown %}
 
 {% codeExample 'rgb-special', false %}
 @debug rgb(0 51 102 / var(--opacity)); // rgb(0 51 102 / var(--opacity))
diff --git a/source/documentation/snippets/built-in-module-status.liquid b/source/documentation/snippets/built-in-module-status.liquid
index 3856109cf..cfed103c6 100644
--- a/source/documentation/snippets/built-in-module-status.liquid
+++ b/source/documentation/snippets/built-in-module-status.liquid
@@ -1,3 +1,4 @@
+{% # Arguments are (in order): `dart`, `libsass`, `node`, `ruby`, optional feature name, additional details within %}
 {% compatibility '1.23.0', false, null, false %}
   Only Dart Sass currently supports loading built-in modules with `@use`. Users
   of other implementations must call functions using their global names instead.

From 48dc4801c1303c25bf34af220e776f81410303b2 Mon Sep 17 00:00:00 2001
From: Ed Rivas 
Date: Tue, 30 May 2023 21:11:38 +0000
Subject: [PATCH 12/19] Add explicit markdown blocks to modules/colors

---
 source/documentation/modules/color.liquid | 81 +++++++++++++++++++----
 source/helpers/function.ts                |  3 +-
 2 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/source/documentation/modules/color.liquid b/source/documentation/modules/color.liquid
index 63b5aa1b9..a032a48bd 100644
--- a/source/documentation/modules/color.liquid
+++ b/source/documentation/modules/color.liquid
@@ -6,7 +6,7 @@ title: sass:color
 
 {% function 'color.adjust($color,!!!  $red: null, $green: null, $blue: null,!!!  $hue: null, $saturation: null, $lightness: null,!!!  $whiteness: null, $blackness: null,!!!  $alpha: null)', 'adjust-color(...)', 'returns:color' %}
 {% compatibility '1.28.0' false, null, false, '$whiteness and $blackness' %}{% endcompatibility %}
-
+{% markdown %}
 Increases or decreases one or more properties of `$color` by fixed amounts.
 
 Adds the value passed for each keyword argument to the corresponding property
@@ -31,6 +31,7 @@ See also:
 
 * [`color.scale()`](#scale) for fluidly scaling a color's properties.
 * [`color.change()`](#change) for setting a color's properties.
+{% endmarkdown %}
 
 {% codeExample 'adjust-color', false %}
 @debug color.adjust(#6b717f, $red: 15); // #7a717f
@@ -44,6 +45,7 @@ See also:
 {% endfunction %}
 
 {% function 'adjust-hue($color, $degrees)', 'returns:color' %}
+{% markdown %}
 Increases or decreases `$color`'s hue.
 
 The `$hue` must be a number between `-360deg` and `360deg` (inclusive) to add
@@ -54,6 +56,7 @@ than `deg`.
 
 See also [`color.adjust()`](#adjust), which can adjust any property of a
 color.
+{% endmarkdown %}
 
 {% headsUp %}
 Because `adjust-hue()` is redundant with [`adjust()`](#adjust), it's not
@@ -84,6 +87,7 @@ included directly in the new module system. Instead of
 {% endfunction %}
 
 {% function 'color.alpha($color)', 'alpha($color)', 'opacity($color)', 'returns:number' %}
+{% markdown %}
 Returns the alpha channel of `$color` as a number between 0 and 1.
 
 As a special case, this supports the Internet Explorer syntax
@@ -99,6 +103,7 @@ See also:
 * [`color.hue()`](#hue) for getting a color's hue.
 * [`color.saturation()`](#saturation) for getting a color's saturation.
 * [`color.lightness()`](#lightness) for getting a color's lightness.
+{% endmarkdown %}
 
 {% codeExample 'color-alpha', false %}
 @debug color.alpha(#e1d7d2); // 1
@@ -113,7 +118,7 @@ See also:
 
 {% function 'color.blackness($color)', 'returns:number' %}
 {% compatibility '1.28.0', false, null, false %}{% endcompatibility %}
-
+{% markdown %}
 Returns the [HWB][] blackness of `$color` as a number between `0%` and `100%`.
 
 [HWB]: https://en.wikipedia.org/wiki/HWB_color_model
@@ -127,6 +132,7 @@ See also:
 * [`color.lightness()`](#lightness) for getting a color's lightness.
 * [`color.whiteness()`](#whiteness) for getting a color's whiteness.
 * [`color.alpha()`](#alpha) for getting a color's alpha channel.
+{% endmarkdown %}
 
 {% codeExample 'color-blackness', false %}
 @debug color.blackness(#e1d7d2); // 11.7647058824%
@@ -140,6 +146,7 @@ See also:
 {% endfunction %}
 
 {% function 'color.blue($color)', 'blue($color)', 'returns:number' %}
+{% markdown %}
 Returns the blue channel of `$color` as a number between 0 and 255.
 
 See also:
@@ -152,6 +159,7 @@ See also:
 * [`color.whiteness()`](#whiteness) for getting a color's whiteness.
 * [`color.blackness()`](#blackness) for getting a color's blackness.
 * [`color.alpha()`](#alpha) for getting a color's alpha channel.
+{% endmarkdown %}
 
 {% codeExample 'color-blue', false %}
 @debug color.blue(#e1d7d2); // 210
@@ -166,7 +174,7 @@ See also:
 
 {% function 'color.change($color,!!!  $red: null, $green: null, $blue: null,!!!  $hue: null, $saturation: null, $lightness: null,!!!  $whiteness: null, $blackness: null,!!!  $alpha: null)', 'change-color(...)', 'returns:color' %}
 {% compatibility '1.28.0', false, null, false, '$whiteness and $blackness' %}{% endcompatibility %}
-
+{% markdown %}
 Sets one or more properties of a color to new values.
 
 Uses the value passed for each keyword argument in place of the corresponding
@@ -192,6 +200,7 @@ See also:
 * [`color.scale()`](#scale) for fluidly scaling a color's properties.
 * [`color.adjust()`](#adjust) for adjusting a color's properties by fixed
 amounts.
+{% endmarkdown %}
 
 {% codeExample 'color-change', false %}
 @debug color.change(#6b717f, $red: 100); // #64717f
@@ -205,11 +214,13 @@ amounts.
 {% endfunction %}
 
 {% function 'color.complement($color)', 'complement($color)', 'returns:color' %}
+{% markdown %}
 Returns the RGB [complement][] of `$color`.
 
 This is identical to [`color.adjust($color, $hue: 180deg)`](#adjust).
 
 [complement]: https://en.wikipedia.org/wiki/Complementary_colors
+{% endmarkdown %}
 
 {% codeExample 'color-complement', false %}
 // Hue 222deg becomes 42deg.
@@ -233,12 +244,15 @@ This is identical to [`color.adjust($color, $hue: 180deg)`](#adjust).
 {% endfunction %}
 
 {% function 'darken($color, $amount)', 'returns:color' %}
+{% markdown %}
 Makes `$color` darker.
 
 The `$amount` must be a number between `0%` and `100%` (inclusive). Decreases
 the HSL lightness of `$color` by that amount.
+{% endmarkdown %}
 
-{% headsUp %}
+{% headsUp false %}
+{% markdown %}
 The `darken()` function decreases lightness by a fixed amount, which is often
 not the desired effect. To make a color a certain percentage darker than it was
 before, use [`color.scale()`](#scale) instead.
@@ -247,6 +261,7 @@ Because `darken()` is usually not the best way to make a color darker, it's
 not included directly in the new module system. However, if you have to
 preserve the existing behavior, `darken($color, $amount)` can be written
 [`color.adjust($color, $lightness: -$amount)`](#adjust).
+{% endmarkdown %}
 
 {% codeExample 'color-darken', false %}
 // #036 has lightness 20%, so when darken() subtracts 30% it just returns black.
@@ -285,12 +300,15 @@ preserve the existing behavior, `darken($color, $amount)` can be written
 {% endfunction %}
 
 {% function 'desaturate($color, $amount)', 'returns:color' %}
+{% markdown %}
 Makes `$color` less saturated.
 
 The `$amount` must be a number between `0%` and `100%` (inclusive). Decreases
 the HSL saturation of `$color` by that amount.
+{% endmarkdown %}
 
-{% headsUp %}
+{% headsUp false %}
+{% markdown %}
 The `desaturate()` function decreases saturation by a fixed amount, which is
 often not the desired effect. To make a color a certain percentage less
 saturated than it was before, use [`color.scale()`](#scale) instead.
@@ -299,6 +317,7 @@ Because `desaturate()` is usually not the best way to make a color less
 saturated, it's not included directly in the new module system. However, if
 you have to preserve the existing behavior, `desaturate($color, $amount)`
 can be written [`color.adjust($color, $saturation: -$amount)`](#adjust).
+{% endmarkdown %}
 
 {% codeExample 'color-desaturate', false %}
 // #d2e1dd has saturation 20%, so when desaturate() subtracts 30% it just
@@ -339,9 +358,11 @@ can be written [`color.adjust($color, $saturation: -$amount)`](#adjust).
 {% endfunction %}
 
 {% function 'color.grayscale($color)', 'grayscale($color)', 'returns:color' %}
+{% markdown %}
 Returns a gray color with the same lightness as `$color`.
 
 This is identical to [`color.change($color, $saturation: 0%)`](#change).
+{% endmarkdown %}
 
 {% codeExample 'color-grayscale', false %}
 @debug color.grayscale(#6b717f); // #757575
@@ -355,6 +376,7 @@ This is identical to [`color.change($color, $saturation: 0%)`](#change).
 {% endfunction %}
 
 {% function 'color.green($color)', 'green($color)', 'returns:number' %}
+{% markdown %}
 Returns the green channel of `$color` as a number between 0 and 255.
 
 See also:
@@ -367,6 +389,7 @@ See also:
 * [`color.whiteness()`](#whiteness) for getting a color's whiteness.
 * [`color.blackness()`](#blackness) for getting a color's blackness.
 * [`color.alpha()`](#alpha) for getting a color's alpha channel.
+{% endmarkdown %}
 
 {% codeExample 'color-green', false %}
 @debug color.green(#e1d7d2); // 215
@@ -380,6 +403,7 @@ See also:
 {% endfunction %}
 
 {% function 'color.hue($color)', 'hue($color)', 'returns:number' %}
+{% markdown %}
 Returns the hue of `$color` as a number between `0deg` and `360deg`.
 
 See also:
@@ -392,6 +416,7 @@ See also:
 * [`color.whiteness()`](#whiteness) for getting a color's whiteness.
 * [`color.blackness()`](#blackness) for getting a color's blackness.
 * [`color.alpha()`](#alpha) for getting a color's alpha channel.
+{% endmarkdown %}
 
 {% codeExample 'color-hue', false %}
 @debug color.hue(#e1d7d2); // 20deg
@@ -406,7 +431,7 @@ See also:
 
 {% function 'color.hwb($hue $whiteness $blackness)', 'color.hwb($hue $whiteness $blackness / $alpha)', 'color.hwb($hue, $whiteness, $blackness, $alpha: 1)', 'returns:color' %}
 {% compatibility '1.28.0', false, null, false %}{% endcompatibility %}
-
+{% markdown %}
 Returns a color with the given [hue, whiteness, and blackness][] and the given
 alpha channel.
 
@@ -419,6 +444,7 @@ channel can be specified as either a unitless number between 0 and 1
 (inclusive), or a percentage between `0%` and `100%` (inclusive).
 
 [unitless]: /documentation/values/numbers#units
+{% endmarkdown %}
 
 {% headsUp %}
 Sass's [special parsing rules][] for slash-separated values make it
@@ -441,10 +467,12 @@ difficult to pass variables for `$blackness` or `$alpha` when using the
 {% endfunction %}
 
 {% function 'color.ie-hex-str($color)', 'ie-hex-str($color)', 'returns:unquoted string' %}
+{% markdown %}
 Returns an unquoted string that represents `$color` in the `#AARRGGBB` format
 expected by Internet Explorer's [`-ms-filter`][] property.
 
 [`-ms-filter`]: https://developer.mozilla.org/en-US/docs/Web/CSS/-ms-filter
+{% endmarkdown %}
 
 {% codeExample 'color-ie-hex-str', false %}
 @debug color.ie-hex-str(#b37399); // #FFB37399
@@ -458,6 +486,7 @@ expected by Internet Explorer's [`-ms-filter`][] property.
 {% endfunction %}
 
 {% function 'color.invert($color, $weight: 100%)', 'invert($color, $weight: 100%)', 'returns:color' %}
+{% markdown %}
 Returns the inverse or [negative][] of `$color`.
 
 [negative]: https://en.wikipedia.org/wiki/Negative_(photography)
@@ -465,6 +494,7 @@ Returns the inverse or [negative][] of `$color`.
 The `$weight` must be a number between `0%` and `100%` (inclusive). A higher
 weight means the result will be closer to the negative, and a lower weight means
 it will be closer to `$color`. Weight `50%` will always produce `#808080`.
+{% endmarkdown %}
 
 {% codeExample 'color-invert', false %}
 @debug color.invert(#b37399); // #4c8c66
@@ -478,12 +508,15 @@ it will be closer to `$color`. Weight `50%` will always produce `#808080`.
 {% endfunction %}
 
 {% function 'lighten($color, $amount)', 'returns:color' %}
+{% markdown %}
 Makes `$color` lighter.
 
 The `$amount` must be a number between `0%` and `100%` (inclusive). Increases
 the HSL lightness of `$color` by that amount.
+{% endmarkdown %}
 
-{% headsUp %}
+{% headsUp false %}
+{% markdown %}
 The `lighten()` function increases lightness by a fixed amount, which is often
 not the desired effect. To make a color a certain percentage lighter than it was
 before, use [`scale()`](#scale) instead.
@@ -492,6 +525,7 @@ Because `lighten()` is usually not the best way to make a color lighter,
 it's not included directly in the new module system. However, if you have to
 preserve the existing behavior, `lighten($color, $amount)` can be written
 [`adjust($color, $lightness: $amount)`](#adjust).
+{% endmarkdown %}
 
 {% codeExample 'color-lighten', false %}
 // #e1d7d2 has lightness 85%, so when lighten() adds 30% it just returns white.
@@ -530,6 +564,7 @@ preserve the existing behavior, `lighten($color, $amount)` can be written
 {% endfunction %}
 
 {% function 'color.lightness($color)', 'lightness($color)', 'returns:number' %}
+{% markdown %}
 Returns the HSL lightness of `$color` as a number between `0%` and `100%`.
 
 See also:
@@ -542,6 +577,7 @@ See also:
 * [`color.whiteness()`](#whiteness) for getting a color's whiteness.
 * [`color.blackness()`](#blackness) for getting a color's blackness.
 * [`color.alpha()`](#alpha) for getting a color's alpha channel.
+{% endmarkdown %}
 
 {% codeExample 'color-lightness', false %}
 @debug color.lightness(#e1d7d2); // 85.2941176471%
@@ -555,12 +591,14 @@ See also:
 {% endfunction %}
 
 {% function 'color.mix($color1, $color2, $weight: 50%)', 'mix($color1, $color2, $weight: 50%)', 'returns:color' %}
+{% markdown %}
 Returns a color that's a mixture of `$color1` and `$color2`.
 
 Both the `$weight` and the relative opacity of each color determines how much of
 each color is in the result. The `$weight` must be a number between `0%` and
 `100%` (inclusive). A larger weight indicates that more of `$color1` should be
 used, and a smaller weight indicates that more of `$color2` should be used.
+{% endmarkdown %}
 
 {% codeExample 'color-mix', false %}
 @debug color.mix(#036, #d2e1dd); // #698aa2
@@ -576,12 +614,15 @@ used, and a smaller weight indicates that more of `$color2` should be used.
 {% endfunction %}
 
 {% function 'opacify($color, $amount)', 'fade-in($color, $amount)', 'returns:color' %}
+{% markdown %}
 Makes `$color` more opaque.
 
 The `$amount` must be a number between `0` and `1` (inclusive). Increases the
 alpha channel of `$color` by that amount.
+{% endmarkdown %}
 
-{% headsUp %}
+{% headsUp false %}
+{% markdown %}
 The `opacify()` function increases the alpha channel by a fixed amount, which is often
 not the desired effect. To make a color a certain percentage more opaque than it was
 before, use [`scale()`](#scale) instead.
@@ -590,6 +631,7 @@ Because `opacify()` is usually not the best way to make a color more opaque,
 it's not included directly in the new module system. However, if you have to
 preserve the existing behavior, `opacify($color, $amount)` can be written
 [`adjust($color, $alpha: -$amount)`](#adjust).
+{% endmarkdown %}
 
 {% codeExample 'color-opacify', false %}
 // rgba(#036, 0.7) has alpha 0.7, so when opacify() adds 0.3 it returns a fully
@@ -620,6 +662,7 @@ preserve the existing behavior, `opacify($color, $amount)` can be written
 {% endfunction %}
 
 {% function 'color.red($color)', 'red($color)', 'returns:number' %}
+{% markdown %}
 Returns the red channel of `$color` as a number between 0 and 255.
 
 See also:
@@ -632,6 +675,7 @@ See also:
 * [`color.whiteness()`](#whiteness) for getting a color's whiteness.
 * [`color.blackness()`](#blackness) for getting a color's blackness.
 * [`color.alpha()`](#alpha) for getting a color's alpha channel.
+{% endmarkdown %}
 
 {% codeExample 'color-red', false %}
 @debug color.red(#e1d7d2); // 225
@@ -645,12 +689,15 @@ See also:
 {% endfunction %}
 
 {% function 'color.saturate($color, $amount)', 'saturate($color, $amount)', 'returns:color' %}
+{% markdown %}
 Makes `$color` more saturated.
 
 The `$amount` must be a number between `0%` and `100%` (inclusive). Increases
 the HSL saturation of `$color` by that amount.
+{% endmarkdown %}
 
-{% headsUp %}
+{% headsUp false %}
+{% markdown %}
 The `saturate()` function increases saturation by a fixed amount, which is often
 not the desired effect. To make a color a certain percentage more saturated than
 it was before, use [`scale()`](#scale) instead.
@@ -659,6 +706,7 @@ Because `saturate()` is usually not the best way to make a color more
 saturated, it's not included directly in the new module system. However, if
 you have to preserve the existing behavior, `saturate($color, $amount)` can
 be written [`adjust($color, $saturation: $amount)`](#adjust).
+{% endmarkdown %}
 
 {% codeExample 'color-saturate', false %}
 // #0e4982 has saturation 80%, so when saturate() adds 30% it just becomes
@@ -699,6 +747,7 @@ be written [`adjust($color, $saturation: $amount)`](#adjust).
 {% endfunction %}
 
 {% function 'color.saturation($color)', 'saturation($color)', 'returns:number' %}
+{% markdown %}
 Returns the HSL saturation of `$color` as a number between `0%` and `100%`.
 
 See also:
@@ -711,6 +760,7 @@ See also:
 * [`color.whiteness()`](#whiteness) for getting a color's whiteness.
 * [`color.blackness()`](#blackness) for getting a color's blackness.
 * [`color.alpha()`](#alpha) for getting a color's alpha channel.
+{% endmarkdown %}
 
 {% codeExample 'color-saturation', false %}
 @debug color.saturation(#e1d7d2); // 20%
@@ -723,10 +773,9 @@ See also:
 {% endcodeExample %}
 {% endfunction %}
 
-
 {% function 'color.scale($color,!!!  $red: null, $green: null, $blue: null,!!!  $saturation: null, $lightness: null,!!!  $whiteness: null, $blackness: null,!!!  $alpha: null)', 'scale-color(...)', 'returns:color' %}
 {% compatibility '1.28.0', false, null, false, '$whiteness and $blackness' %}{% endcompatibility %}
-
+{% markdown %}
 Fluidly scales one or more properties of `$color`.
 
 Each keyword argument must be a number between `-100%` and `100%` (inclusive).
@@ -748,6 +797,7 @@ See also:
 * [`color.adjust()`](#adjust) for changing a color's properties by fixed
   amounts.
 * [`color.change()`](#change) for setting a color's properties.
+{% endmarkdown %}
 
 {% codeExample 'color-scale', false %}
 @debug color.scale(#6b717f, $red: 15%); // #81717f
@@ -761,12 +811,15 @@ See also:
 {% endfunction %}
 
 {% function 'transparentize($color, $amount)', 'fade-out($color, $amount)', 'returns:color' %}
+{% markdown %}
 Makes `$color` more transparent.
 
 The `$amount` must be a number between `0` and `1` (inclusive). Decreases the
 alpha channel of `$color` by that amount.
+{% endmarkdown %}
 
-{% headsUp %}
+{% headsUp false %}
+{% markdown %}
 The `transparentize()` function decreases the alpha channel by a fixed amount,
 which is often not the desired effect. To make a color a certain percentage more
 transparent than it was before, use [`color.scale()`](#scale) instead.
@@ -776,6 +829,7 @@ transparent, it's not included directly in the new module system. However,
 if you have to preserve the existing behavior,
 `transparentize($color, $amount)` can be written
 [`color.adjust($color, $alpha: -$amount)`](#adjust).
+{% endmarkdown %}
 
 {% codeExample 'transparentize', false %}
 // rgba(#036, 0.3) has alpha 0.3, so when transparentize() subtracts 0.3 it
@@ -807,7 +861,7 @@ if you have to preserve the existing behavior,
 
 {% function 'color.whiteness($color)', 'returns:number' %}
 {% compatibility '1.28.0', false, null, false %}{% endcompatibility %}
-
+{% markdown %}
 Returns the [HWB][] whiteness of `$color` as a number between `0%` and `100%`.
 
 [HWB]: https://en.wikipedia.org/wiki/HWB_color_model
@@ -821,6 +875,7 @@ See also:
 * [`color.lightness()`](#lightness) for getting a color's lightness.
 * [`color.blackness()`](#blackness) for getting a color's blackness.
 * [`color.alpha()`](#alpha) for getting a color's alpha channel.
+{% endmarkdown %}
 
 {% codeExample 'color-whiteness', false %}
 @debug color.whiteness(#e1d7d2); // 82.3529411765%
diff --git a/source/helpers/function.ts b/source/helpers/function.ts
index 732680ae8..5887ffda1 100644
--- a/source/helpers/function.ts
+++ b/source/helpers/function.ts
@@ -1,7 +1,6 @@
 import * as cheerio from 'cheerio';
 
 import { codeBlock } from './components';
-import { markdown } from './type';
 
 const links: Record = {
   number: '/documentation/values/numbers',
@@ -91,7 +90,7 @@ export function _function(content: string, ...signatures: string[]) {
     .addClass('language-scss')
     .html(mergedSignatures);
   pre.append(anchor).append(code);
-  div.append(pre).append(markdown(content));
+  div.append(pre).append(content);
   $('body').append(div);
   names.slice(1).forEach((name) => {
     const div = $('
').attr('id', name); From 270796b012cdb2b12c6499c5e06bff5e4ec4b39d Mon Sep 17 00:00:00 2001 From: Ed Rivas Date: Tue, 30 May 2023 23:39:56 +0000 Subject: [PATCH 13/19] Add explicit markdown docs to the rest of modules/* --- .../example-first-class-function.liquid | 5 +- source/documentation/modules/list.liquid | 22 ++++++ source/documentation/modules/map.liquid | 40 +++++++++-- source/documentation/modules/math.liquid | 68 ++++++++++++++++++- source/documentation/modules/meta.liquid | 32 +++++++++ source/documentation/modules/selector.liquid | 16 +++++ source/documentation/modules/string.liquid | 22 ++++++ 7 files changed, 197 insertions(+), 8 deletions(-) diff --git a/source/code-snippets/example-first-class-function.liquid b/source/code-snippets/example-first-class-function.liquid index ba1c955dc..8ce4097a2 100644 --- a/source/code-snippets/example-first-class-function.liquid +++ b/source/code-snippets/example-first-class-function.liquid @@ -1,5 +1,6 @@ -{# TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass #} - +{%- comment -%} +TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass +{%- endcomment -%} {% codeExample 'first-class-function' %} @use "sass:list"; @use "sass:meta"; diff --git a/source/documentation/modules/list.liquid b/source/documentation/modules/list.liquid index e3766dc42..cbcd71cd0 100644 --- a/source/documentation/modules/list.liquid +++ b/source/documentation/modules/list.liquid @@ -16,6 +16,7 @@ list that contains the value `1px`. {% endfunFact %} {% function 'list.append($list, $val, $separator: auto)', 'append($list, $val, $separator: auto)', 'returns:list' %} +{% markdown %} Returns a copy of `$list` with `$val` added to the end. If `$separator` is `comma`, `space`, or `slash`, the returned list is @@ -28,6 +29,7 @@ comma-separated, space-separated, or slash-separated, respectively. If it's Note that unlike [`list.join()`](#join), if `$val` is a list it's nested within the returned list rather than having all its elements added to the returned list. +{% endmarkdown %} {% codeExample 'list-append', false %} @debug list.append(10px 20px, 30px); // 10px 20px 30px @@ -45,6 +47,7 @@ returned list. {% endfunction %} {% function 'list.index($list, $value)', 'index($list, $value)', 'returns:number | null' %} +{% markdown %} Returns the [index][] of `$value` in `$list`. [index]: /documentation/values/lists#indexes @@ -54,12 +57,15 @@ appears multiple times in `$list`, this returns the index of its first appearance. [`null`]: /documentation/values/null +{% endmarkdown %} {% render 'code-snippets/example-list-index' %} {% endfunction %} {% function 'list.is-bracketed($list)', 'is-bracketed($list)', 'returns:boolean' %} +{% markdown %} Returns whether `$list` has square brackets. +{% endmarkdown %} {% codeExample 'list-is-bracketed', false %} @debug list.is-bracketed(1px 2px 3px); // false @@ -71,8 +77,10 @@ Returns whether `$list` has square brackets. {% endfunction %} {% function 'list.join($list1, $list2, $separator: auto, $bracketed: auto)', 'join($list1, $list2, $separator: auto, $bracketed: auto)', 'returns:list' %} +{% markdown %} Returns a new list containing the elements of `$list1` followed by the elements of `$list2`. +{% endmarkdown %} {% headsUp %} Because individual values count as single-element lists, it's possible to @@ -84,6 +92,7 @@ Use [`list.append()`](#append) instead to add a single value to a list. Only use `list.join()` to combine two lists together into one. {% endheadsUp %} +{% markdown %} If `$separator` is `comma`, `space`, or `slash`, the returned list is comma-separated, space-separated, or slash-separated, respectively. If it's `auto` (the default), the returned list will use the same separator as @@ -95,6 +104,7 @@ if `$list1` is. Otherwise, the returned list will have square brackets if `$bracketed` is [truthy] and no brackets if `$bracketed` is falsey. [truthy]: /documentation/values/booleans#truthiness-and-falsiness +{% endmarkdown %} {% codeExample 'list-join', false %} @debug list.join(10px 20px, 30px 40px); // 10px 20px 30px 40px @@ -116,9 +126,11 @@ if `$list1` is. Otherwise, the returned list will have square brackets if {% endfunction %} {% function 'list.length($list)', 'length($list)', 'returns:number' %} +{% markdown %} Returns the length of `$list`. This can also return the number of pairs in a map. +{% endmarkdown %} {% codeExample 'list-length', false %} @debug list.length(10px); // 1 @@ -132,10 +144,12 @@ This can also return the number of pairs in a map. {% endfunction %} {% function 'list.separator($list)', 'list-separator($list)', 'returns:unquoted string' %} +{% markdown %} Returns the name of the separator used by `$list`, either `space`, `comma`, or `slash`. If `$list` doesn't have a separator, returns `space`. +{% endmarkdown %} {% codeExample 'list-separator', false %} @debug list.separator(1px 2px 3px); // space @@ -151,17 +165,20 @@ If `$list` doesn't have a separator, returns `space`. {% endfunction %} {% function 'list.nth($list, $n)', 'nth($list, $n)' %} +{% markdown %} Returns the element of `$list` at [index][] `$n`. [index]: /documentation/values/lists#indexes If `$n` is negative, it counts from the end of `$list`. Throws an error if there is no element at index `$n`. +{% endmarkdown %} {% render 'code-snippets/example-list-nth' %} {% endfunction %} {% function 'list.set-nth($list, $n, $value)', 'set-nth($list, $n, $value)', 'returns:list' %} +{% markdown %} Returns a copy of `$list` with the element at [index][] `$n` replaced with `$value`. @@ -169,6 +186,7 @@ Returns a copy of `$list` with the element at [index][] `$n` replaced with If `$n` is negative, it counts from the end of `$list`. Throws an error if there is no existing element at index `$n`. +{% endmarkdown %} {% codeExample 'list-set-nth', false %} @debug list.set-nth(10px 20px 30px, 1, 2em); // 2em 20px 30px @@ -182,7 +200,9 @@ there is no existing element at index `$n`. {% endfunction %} {% function 'list.slash($elements...)', 'returns:list' %} +{% markdown %} Returns a slash-separated list that contains `$elements`. +{% endmarkdown %} {% headsUp %} This function is a temporary solution for creating slash-separated lists. @@ -201,6 +221,7 @@ so Sass can't use them for new syntax until the old syntax is removed. {% endfunction %} {% function 'list.zip($lists...)', 'zip($lists...)', 'returns:list' %} +{% markdown %} Combines every list in `$lists` into a single list of sub-lists. Each element in the returned list contains all the elements at that position @@ -208,6 +229,7 @@ in `$lists`. The returned list is as long as the shortest list in `$lists`. The returned list is always comma-separated and the sub-lists are always space-separated. +{% endmarkdown %} {% codeExample 'list-zip', false %} @debug list.zip(10px 50px 100px, short mid long); // 10px short, 50px mid, 100px long diff --git a/source/documentation/modules/map.liquid b/source/documentation/modules/map.liquid index 969af2f6d..4143a644e 100644 --- a/source/documentation/modules/map.liquid +++ b/source/documentation/modules/map.liquid @@ -4,7 +4,8 @@ title: sass:map {% render 'documentation/snippets/built-in-module-status' %} -{% funFact %} +{% funFact false %} +{% markdown %} Sass libraries and design systems tend to share and override configurations that are represented as nested maps (maps that contain maps that contain maps). @@ -12,6 +13,7 @@ maps). To help you work with nested maps, some map functions support deep operations. For example, if you pass multiple keys to `map.get()`, it will follow those keys to find the desired nested map: +{% endmarkdown %} {% codeExample 'map', false %} $config: (a: (b: (c: d))); @@ -24,9 +26,10 @@ $config: (a: (b: (c: d))) {% function 'map.deep-merge($map1, $map2)', 'returns:map' %} {% compatibility '1.27.0', false, null, false %}{% endcompatibility %} - +{% markdown %} Identical to [`map.merge()`](#merge), except that nested map values are *also* recursively merged. +{% endmarkdown %} {% codeExample 'map-deep-merge', false %} $helvetica-light: ( @@ -83,9 +86,10 @@ $helvetica-heavy: ("weights": ("medium": 500, "bold": 700)) {% function 'map.deep-remove($map, $key, $keys...)', 'returns:map' %} {% compatibility '1.27.0', false, null, false %}{% endcompatibility %} - +{% markdown %} If `$keys` is empty, returns a copy of `$map` without a value associated with `$key`. +{% endmarkdown %} {% codeExample 'map-deep-remove', false %} $font-weights: ("regular": 400, "medium": 500, "bold": 700); @@ -99,6 +103,7 @@ $font-weights: ("regular": 400, "medium": 500, "bold": 700) // ("medium": 500, "bold": 700) {% endcodeExample %} +{% markdown %} --- If `$keys` is not empty, follows the set of keys including `$key` and @@ -107,6 +112,7 @@ targeted for updating. Returns a copy of `$map` where the targeted map does not have a value associated with the last key in `$keys`. +{% endmarkdown %} {% codeExample 'map-deep-remove-2', false %} $fonts: ( @@ -144,12 +150,17 @@ $fonts: ("Helvetica": ("weights": ("regular": 400, "medium": 500, "bold": 700))) {% endfunction %} {% function 'map.get($map, $key, $keys...)', 'map-get($map, $key, $keys...)' %} +{% markdown %} If `$keys` is empty, returns the value in `$map` associated with `$key`. If `$map` doesn't have a value associated with `$key`, returns [`null`][]. +[`null`]: /documentation/values/null +{% endmarkdown %} + {% render 'code-snippets/example-map-get' %} +{% markdown %} --- {% compatibility '1.27.0', false, null, false %} @@ -166,6 +177,9 @@ Returns [`null`][] if the map does not have a value associated with the key, or if any key in `$keys` is missing from a map or references a value that is not a map. +[`null`]: /documentation/values/null +{% endmarkdown %} + {% codeExample 'map-deep-remove-2', false %} $fonts: ( "Helvetica": ( @@ -185,13 +199,13 @@ $fonts: ("Helvetica": ("weights": ("regular": 400, "medium": 500, "bold": 700))) @debug map.get($fonts, "Helvetica", "weights", "regular") // 400 @debug map.get($fonts, "Helvetica", "colors") // null {% endcodeExample %} - -[`null`]: /documentation/values/null {% endfunction %} {% function 'map.has-key($map, $key, $keys...)', 'map-has-key($map, $key, $keys...)', 'returns:boolean' %} +{% markdown %} If `$keys` is empty, returns whether `$map` contains a value associated with `$key`. +{% endmarkdown %} {% codeExample 'map-has-key', false %} $font-weights: ("regular": 400, "medium": 500, "bold": 700); @@ -205,6 +219,7 @@ $font-weights: ("regular": 400, "medium": 500, "bold": 700) @debug map.has-key($font-weights, "bolder") // false {% endcodeExample %} +{% markdown %} --- {% compatibility '1.27.0', false, null, false %} @@ -220,6 +235,7 @@ in `$keys`. Returns false if it does not, or if any key in `$keys` is missing from a map or references a value that is not a map. +{% endmarkdown %} {% codeExample 'map-has-key-2', false %} $fonts: ( @@ -243,7 +259,9 @@ $fonts: ("Helvetica": ("weights": ("regular": 400, "medium": 500, "bold": 700))) {% endfunction %} {% function 'map.keys($map)', 'map-keys($map)', 'returns:list' %} +{% markdown %} Returns a comma-separated list of all the keys in `$map`. +{% endmarkdown %} {% codeExample 'map-keys', false %} $font-weights: ("regular": 400, "medium": 500, "bold": 700); @@ -263,6 +281,7 @@ are passed as `map.merge($map1, $args...)`. They are described here as `$map1, $keys..., $map2` for explanation purposes only. {% endheadsUp %} +{% markdown %} If no `$keys` are passed, returns a new map with all the keys and values from both `$map1` and `$map2`. @@ -271,6 +290,7 @@ precedence. All keys in the returned map that also appear in `$map1` have the same order as in `$map1`. New keys from `$map2` appear at the end of the map. +{% endmarkdown %} {% codeExample 'map-merge', false %} $light-weights: ("lightest": 100, "light": 300); @@ -286,6 +306,7 @@ $heavy-weights: ("medium": 500, "bold": 700) // ("lightest": 100, "light": 300, "medium": 500, "bold": 700) {% endcodeExample %} +{% markdown %} --- {% compatibility '1.27.0', false, null, false %} @@ -298,6 +319,7 @@ that is not a map, sets the value at that key to an empty map. Returns a copy of `$map1` where the targeted map is replaced by a new map that contains all the keys and values from both the targeted map and `$map2`. +{% endmarkdown %} {% codeExample 'map-merge-2', false %} $fonts: ( @@ -340,9 +362,11 @@ $heavy-weights: ("medium": 500, "bold": 700) {% endfunction %} {% function 'map.remove($map, $keys...)', 'map-remove($map, $keys...)', 'returns:map' %} +{% markdown %} Returns a copy of `$map` without any values associated with `$keys`. If a key in `$keys` doesn't have an associated value in `$map`, it's ignored. +{% endmarkdown %} {% codeExample 'map-remove', false %} $font-weights: ("regular": 400, "medium": 500, "bold": 700); @@ -368,8 +392,10 @@ are passed as `map.set($map, $args...)`. They are described here as `$map, $keys..., $key, $value` for explanation purposes only. {% endheadsUp %} +{% markdown %} If `$keys` are not passed, returns a copy of `$map` with the value at `$key` set to `$value`. +{% endmarkdown %} {% codeExample 'map-set', false %} $font-weights: ("regular": 400, "medium": 500, "bold": 700); @@ -383,6 +409,7 @@ $font-weights: ("regular": 400, "medium": 500, "bold": 700) // ("regular": 300, "medium": 500, "bold": 700) {% endcodeExample %} +{% markdown %} --- {% compatibility '1.27.0', false, null, false %} @@ -395,6 +422,7 @@ that is not a map, sets the value at that key to an empty map. Returns a copy of `$map` with the targeted map's value at `$key` set to `$value`. +{% endmarkdown %} {% codeExample 'map-set-2', false %} $fonts: ( @@ -434,7 +462,9 @@ $fonts: ("Helvetica": ("weights": ("regular": 400, "medium": 500, "bold": 700))) {% endfunction %} {% function 'map.values($map)', 'map-values($map)', 'returns:list' %} +{% markdown %} Returns a comma-separated list of all the values in `$map`. +{% endmarkdown %} {% codeExample 'map-values', false %} $font-weights: ("regular": 400, "medium": 500, "bold": 700); diff --git a/source/documentation/modules/math.liquid b/source/documentation/modules/math.liquid index c61b771b0..e93a1306e 100644 --- a/source/documentation/modules/math.liquid +++ b/source/documentation/modules/math.liquid @@ -11,10 +11,12 @@ title: sass:math {% function 'math.$e' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} The closest 64-bit floating point approximation of the [mathematical constant *e*][]. [mathematical constant *e*]: https://en.wikipedia.org/wiki/E_(mathematical_constant) +{% endmarkdown %} {% codeExample 'math-e', false %} @debug math.$e; // 2.7182818285 @@ -26,17 +28,21 @@ The closest 64-bit floating point approximation of the [mathematical constant {% function 'math.$epsilon' %} {% compatibility '1.55.0', false, null, false %}{% endcompatibility %} +{% markdown %} The difference between 1 and the smallest 64-bit floating point number greater than 1 according to floating-point comparisons. Because of Sass numbers' [10 digits of precision](/documentation/values/numbers), in many cases this will appear to be 0. +{% endmarkdown %} {% endfunction %} {% function 'math.$max-number' %} {% compatibility '1.55.0', false, null, false %}{% endcompatibility %} +{% markdown %} The maximum finite number that can be represented as a 64-bit floating point number. +{% endmarkdown %} {% codeExample 'math-max-number', false %} @debug math.$max-number; // 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -48,8 +54,10 @@ number. {% function 'math.$max-safe-integer' %} {% compatibility '1.55.0', false, null, false %}{% endcompatibility %} +{% markdown %} The maximum integer `n` such that both `n` and `n + 1` can be precisely represented as a 64-bit floating-point number. +{% endmarkdown %} {% codeExample 'math-max-safe-integer', false %} @debug math.$max-safe-integer; // 9007199254740991 @@ -61,16 +69,20 @@ represented as a 64-bit floating-point number. {% function 'math.$min-number' %} {% compatibility '1.55.0', false, null, false %}{% endcompatibility %} +{% markdown %} The smallest positive number that can be represented as a 64-bit floating point number. Because of Sass numbers' [10 digits of precision](/documentation/values/numbers), in many cases this will appear to be 0. +{% endmarkdown %} {% endfunction %} {% function 'math.$min-safe-integer' %} {% compatibility '1.55.0', false, null, false %}{% endcompatibility %} +{% markdown %} The minimum integer `n` such that both `n` and `n - 1` can be precisely represented as a 64-bit floating-point number. +{% endmarkdown %} {% codeExample 'math-min-safe-integer', false %} @debug math.$min-safe-integer; // -9007199254740991 @@ -82,9 +94,11 @@ represented as a 64-bit floating-point number. {% function 'math.$pi' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} The closest 64-bit floating point approximation of the [mathematical constant *π*][]. [mathematical constant *π*]: https://en.wikipedia.org/wiki/Pi +{% endmarkdown %} {% codeExample 'math-pi', false %} @debug math.$pi; // 3.1415926536 @@ -98,7 +112,9 @@ The closest 64-bit floating point approximation of the [mathematical constant * {% endmarkdown %} {% function 'math.ceil($number)', 'ceil($number)', 'returns:number' %} +{% markdown %} Rounds `$number` up to the next highest whole number. +{% endmarkdown %} {% codeExample 'math-ceil', false %} @debug math.ceil(4); // 4 @@ -114,11 +130,13 @@ Rounds `$number` up to the next highest whole number. {% function 'math.clamp($min, $number, $max)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Restricts `$number` to the range between `$min` and `$max`. If `$number` is less than `$min` this returns `$min`, and if it's greater than `$max` this returns `$max`. `$min`, `$number`, and `$max` must have compatible units, or all be unitless. +{% endmarkdown %} {% codeExample 'math-clamp', false %} @debug math.clamp(-1, 0, 1); // 0 @@ -132,7 +150,9 @@ returns `$max`. {% endfunction %} {% function 'math.floor($number)', 'floor($number)', 'returns:number' %} +{% markdown %} Rounds `$number` down to the next lowest whole number. +{% endmarkdown %} {% codeExample 'math-floor', false %} @debug math.floor(4); // 4 @@ -146,7 +166,9 @@ Rounds `$number` down to the next lowest whole number. {% endfunction %} {% function 'math.max($number...)', 'max($number...)', 'returns:number' %} +{% markdown %} Returns the highest of one or more numbers. +{% endmarkdown %} {% codeExample 'math-max', false %} @debug math.max(1px, 4px); // 4px @@ -162,7 +184,9 @@ $widths: 50px, 30px, 100px {% endfunction %} {% function 'math.min($number...)', 'min($number...)', 'returns:number' %} +{% markdown %} Returns the lowest of one or more numbers. +{% endmarkdown %} {% codeExample 'math-min', false %} @debug math.min(1px, 4px); // 1px @@ -178,7 +202,9 @@ $widths: 50px, 30px, 100px {% endfunction %} {% function 'math.round($number)', 'round($number)', 'returns:number' %} +{% markdown %} Rounds `$number` to the nearest whole number. +{% endmarkdown %} {% codeExample 'math-round', false %} @debug math.round(4); // 4 @@ -196,10 +222,12 @@ Rounds `$number` to the nearest whole number. {% endmarkdown %} {% function 'math.abs($number)', 'abs($number)', 'returns:number' %} +{% markdown %} Returns the [absolute value][] of `$number`. If `$number` is negative, this returns `-$number`, and if `$number` is positive, it returns `$number` as-is. [absolute value]: https://en.wikipedia.org/wiki/Absolute_value +{% endmarkdown %} {% codeExample 'math-abs', false %} @debug math.abs(10px); // 10px @@ -213,6 +241,7 @@ returns `-$number`, and if `$number` is positive, it returns `$number` as-is. {% function 'math.hypot($number...)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the length of the *n*-dimensional [vector][] that has components equal to each `$number`. For example, for three numbers *a*, *b*, and *c*, this returns the square root of *a² + b² + c²*. @@ -222,6 +251,7 @@ since the numbers' units may differ, the output takes the unit of the first number. [vector]: https://en.wikipedia.org/wiki/Euclidean_vector +{% endmarkdown %} {% codeExample 'math-hypot', false %} @debug math.hypot(3, 4); // 5 @@ -243,6 +273,7 @@ $lengths: 1in, 10cm, 50px {% function 'math.log($number, $base: null)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the [logarithm][] of `$number` with respect to `$base`. If `$base` is `null`, the [natural log][] is calculated. @@ -250,6 +281,7 @@ Returns the [logarithm][] of `$number` with respect to `$base`. If `$base` is [logarithm]: https://en.wikipedia.org/wiki/Logarithm [natural log]: https://en.wikipedia.org/wiki/Natural_logarithm +{% endmarkdown %} {% codeExample 'math-log', false %} @debug math.log(10); // 2.302585093 @@ -263,11 +295,13 @@ Returns the [logarithm][] of `$number` with respect to `$base`. If `$base` is {% function 'math.pow($base, $exponent)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Raises `$base` [to the power of][] `$exponent`. `$base` and `$exponent` must be unitless. [to the power of]: https://en.wikipedia.org/wiki/Exponentiation +{% endmarkdown %} {% codeExample 'math-pow', false %} @debug math.pow(10, 2); // 100 @@ -283,11 +317,13 @@ Raises `$base` [to the power of][] `$exponent`. {% function 'math.sqrt($number)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the [square root][] of `$number`. `$number` must be unitless. [square root]: https://en.wikipedia.org/wiki/Square_root +{% endmarkdown %} {% codeExample 'math-sqrt', false %} @debug math.sqrt(100); // 10 @@ -307,12 +343,14 @@ Returns the [square root][] of `$number`. {% function 'math.cos($number)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the [cosine][] of `$number`. `$number` must be an angle (its units must be compatible with `deg`) or unitless. If `$number` has no units, it is assumed to be in `rad`. [cosine]: https://en.wikipedia.org/wiki/Trigonometric_functions#Right-angled_triangle_definitions +{% endmarkdown %} {% codeExample 'math-cos', false %} @debug math.cos(100deg); // -0.1736481777 @@ -328,12 +366,14 @@ unitless. If `$number` has no units, it is assumed to be in `rad`. {% function 'math.sin($number)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the [sine][] of `$number`. `$number` must be an angle (its units must be compatible with `deg`) or unitless. If `$number` has no units, it is assumed to be in `rad`. [sine]: https://en.wikipedia.org/wiki/Trigonometric_functions#Right-angled_triangle_definitions +{% endmarkdown %} {% codeExample 'math-sin', false %} @debug math.sin(100deg); // 0.984807753 @@ -349,12 +389,14 @@ unitless. If `$number` has no units, it is assumed to be in `rad`. {% function 'math.tan($number)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the [tangent][] of `$number`. `$number` must be an angle (its units must be compatible with `deg`) or unitless. If `$number` has no units, it is assumed to be in `rad`. [tangent]: https://en.wikipedia.org/wiki/Trigonometric_functions#Right-angled_triangle_definitions +{% endmarkdown %} {% codeExample 'math-tan', false %} @debug math.tan(100deg); // -5.6712818196 @@ -370,11 +412,13 @@ unitless. If `$number` has no units, it is assumed to be in `rad`. {% function 'math.acos($number)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the [arccosine][] of `$number` in `deg`. `$number` must be unitless. [arccosine]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Basic_properties +{% endmarkdown %} {% codeExample 'math-acos', false %} @debug math.acos(0.5); // 60deg @@ -388,11 +432,13 @@ Returns the [arccosine][] of `$number` in `deg`. {% function 'math.asin($number)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the [arcsine][] of `$number` in `deg`. `$number` must be unitless. [arcsine]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Basic_properties +{% endmarkdown %} {% codeExample 'math-asin', false %} @debug math.asin(0.5); // 30deg @@ -406,11 +452,13 @@ Returns the [arcsine][] of `$number` in `deg`. {% function 'math.atan($number)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the [arctangent][] of `$number` in `deg`. `$number` must be unitless. [arctangent]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Basic_properties +{% endmarkdown %} {% codeExample 'math-atan', false %} @debug math.atan(10); // 84.2894068625deg @@ -422,11 +470,13 @@ Returns the [arctangent][] of `$number` in `deg`. {% function 'math.atan2($y, $x)', 'returns:number' %} {% compatibility '1.25.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the [2-argument arctangent][] of `$y` and `$x` in `deg`. `$y` and `$x` must have compatible units or be unitless. [2-argument arctangent]: https://en.wikipedia.org/wiki/Atan2 +{% endmarkdown %} {% funFact %} `math.atan2($y, $x)` is distinct from `atan(math.div($y, $x))` because it preserves the @@ -447,6 +497,7 @@ to the point `(-1, 1)` and returns `135deg`. In contrast, `math.atan(math.div(1, {% endmarkdown %} {% function 'math.compatible($number1, $number2)', 'comparable($number1, $number2)', 'returns:boolean' %} +{% markdown %} Returns whether `$number1` and `$number2` have compatible units. If this returns `true`, `$number1` and `$number2` can safely be [added][], @@ -455,6 +506,7 @@ If this returns `true`, `$number1` and `$number2` can safely be [added][], [added]: /documentation/operators/numeric [subtracted]: /documentation/operators/numeric [compared]: /documentation/operators/relational +{% endmarkdown %} {% headsUp %} The global name of this function @@ -476,7 +528,9 @@ function does. {% endfunction %} {% function 'math.is-unitless($number)', 'unitless($number)', 'returns:boolean' %} +{% markdown %} Returns whether `$number` has no units. +{% endmarkdown %} {% codeExample 'math-is-unitless', false %} @debug math.is-unitless(100); // true @@ -488,7 +542,9 @@ Returns whether `$number` has no units. {% endfunction %} {% function 'math.unit($number)', 'unit($number)', 'returns:quoted string' %} +{% markdown %} Returns a string representation of `$number`'s units. +{% endmarkdown %} {% headsUp %} This function is intended for debugging; its output format is not guaranteed @@ -515,11 +571,13 @@ to be consistent across Sass versions or implementations. {% function 'math.div($number1, $number2)', 'returns:number' %} {% compatibility '1.33.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the result of dividing `$number1` by `$number2`. Any units shared by both numbers will be canceled out. Units in `$number1` that aren't in `$number2` will end up in the return value's numerator, and units in `$number2` that aren't in `$number1` will end up in its denominator. +{% endmarkdown %} {% headsUp %} For backwards-compatibility purposes, this returns the *exact same result* @@ -544,8 +602,10 @@ eventually and shouldn't be used in new stylesheets. {% endfunction %} {% function 'math.percentage($number)', 'percentage($number)', 'returns:number' %} +{% markdown %} Converts a unitless `$number` (usually a decimal between 0 and 1) to a percentage. +{% endmarkdown %} {% funFact %} This function is identical to `$number * 100%`. @@ -561,7 +621,9 @@ This function is identical to `$number * 100%`. {% endfunction %} {% function 'math.random($limit: null)', 'random($limit: null)', 'returns:number' %} +{% markdown %} If `$limit` is `null`, returns a random decimal number between 0 and 1. +{% endmarkdown %} {% codeExample 'math-random', false %} @debug math.random(); // 0.2821251858 @@ -571,17 +633,21 @@ If `$limit` is `null`, returns a random decimal number between 0 and 1. @debug math.random() // 0.6221325814 {% endcodeExample %} +{% markdown %} * * * If `$limit` is a number greater than or equal to 1, returns a random whole number between 1 and `$limit`. +{% endmarkdown %} -{% headsUp %} +{% headsUp false %} +{% markdown %} `random()` ignores units in `$limit`. [This behavior is deprecated] and `random($limit)` will return a random integer with the same units as the `$limit` argument. [This behavior is deprecated]: /documentation/breaking-changes/random-with-units +{% endmarkdown %} {% codeExample 'math-random-warning', false %} @debug math.random(100px); // 42 diff --git a/source/documentation/modules/meta.liquid b/source/documentation/modules/meta.liquid index b4d7c6f5f..9890c2777 100644 --- a/source/documentation/modules/meta.liquid +++ b/source/documentation/modules/meta.liquid @@ -13,6 +13,7 @@ title: sass:meta Only Dart Sass currently supports this mixin. {% endcompatibility %} +{% markdown %} Loads the [module][] at `$url` and includes its CSS as though it were written as the contents of this mixin. The `$with` parameter provides [configuration][] for the modules; if it's passed, it must be a map from @@ -47,6 +48,7 @@ style rules to create nested styles! [interpolation][]. [interpolation]: /documentation/interpolation +{% endmarkdown %} {% headsUp %} The `$url` parameter should be a string containing a URL like you'd pass to @@ -104,12 +106,14 @@ body.dark code { {% function 'meta.calc-args($calc)', 'returns:list' %} {% compatibility '1.40.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the arguments for the given [calculation]. [calculation]: /documentation/values/calculations If an argument is a number or a nested calculation, it's returned as that type. Otherwise, it's returned as an unquoted string. +{% endmarkdown %} {% codeExample 'calc-args', false %} @debug meta.calc-args(calc(100px + 10%)); // unquote("100px + 10%") @@ -123,9 +127,11 @@ type. Otherwise, it's returned as an unquoted string. {% function 'meta.calc-name($calc)', 'returns:quoted string' %} {% compatibility '1.40.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns the name of the given [calculation]. [calculation]: /documentation/values/calculations +{% endmarkdown %} {% codeExample 'calc-name', false %} @debug meta.calc-name(calc(100px + 10%)); // "calc" @@ -139,6 +145,7 @@ Returns the name of the given [calculation]. {% function 'meta.call($function, $args...)', 'call($function, $args...)' %} {% render 'documentation/snippets/call-impl-status' %} +{% markdown %} Invokes `$function` with `$args` and returns the result. The `$function` should be a [function][] returned by @@ -146,16 +153,19 @@ The `$function` should be a [function][] returned by [function]: /documentation/values/functions [`meta.get-function()`]: #get-function +{% endmarkdown %} {% render 'code-snippets/example-first-class-function' %} {% endfunction %} {% function 'meta.content-exists()', 'content-exists()', 'returns:boolean' %} +{% markdown %} Returns whether the current mixin was passed a [`@content` block][]. [`@content` block]: /documentation/at-rules/mixin#content-blocks Throws an error if called outside of a mixin. +{% endmarkdown %} {% codeExample 'content-exists', false %} @mixin debug-content-exists { @@ -180,6 +190,7 @@ Throws an error if called outside of a mixin. {% endfunction %} {% function 'meta.feature-exists($feature)', 'feature-exists($feature)', 'returns:boolean' %} +{% markdown %} Returns whether the current Sass implementation supports `$feature`. The `$feature` must be a string. The currently recognized features are: @@ -204,6 +215,7 @@ The `$feature` must be a string. The currently recognized features are: [interpolation]: /documentation/interpolation Returns `false` for any unrecognized `$feature`. +{% endmarkdown %} {% codeExample 'feature-exists', false %} @debug meta.feature-exists("at-error"); // true @@ -215,6 +227,7 @@ Returns `false` for any unrecognized `$feature`. {% endfunction %} {% function 'meta.function-exists($name, $module: null)', 'function-exists($name)', 'returns:boolean' %} +{% markdown %} Returns whether a function named `$name` is defined, either as a built-in function or a user-defined function. @@ -223,6 +236,7 @@ function definition. `$module` must be a string matching the namespace of a [`@use` rule][] in the current file. [`@use` rule]: /documentation/at-rules/use +{% endmarkdown %} {% codeExample 'function-exists', false %} @use "sass:math"; @@ -250,6 +264,7 @@ function definition. `$module` must be a string matching the namespace of a {% endfunction %} {% function 'meta.get-function($name, $css: false, $module: null)', 'get-function($name, $css: false, $module: null)', 'returns:function' %} +{% markdown %} Returns the [function][] named `$name`. [function]: /documentation/values/functions @@ -269,11 +284,13 @@ However, if `$css` is `true`, it instead returns a [plain CSS function][]. [plain CSS function]: /documentation/at-rules/function#plain-css-functions The returned function can be called using [`meta.call()`](#call). +{% endmarkdown %} {% render 'code-snippets/example-first-class-function' %} {% endfunction %} {% function 'meta.global-variable-exists($name, $module: null)', 'global-variable-exists($name, $module: null)', 'returns:boolean' %} +{% markdown %} Returns whether a [global variable][] named `$name` (without the `$`) exists. [global variable]: /documentation/variables#scope @@ -286,6 +303,7 @@ whether that module has a variable named `$name`. [`@use` rule]: /documentation/at-rules/use See also [`meta.variable-exists()`](#variable-exists). +{% endmarkdown %} {% codeExample 'global-variable-exists', false %} @debug meta.global-variable-exists("var1"); // false @@ -312,11 +330,13 @@ h1 {% endfunction %} {% function 'meta.inspect($value)', 'inspect($value)', 'returns:unquoted string' %} +{% markdown %} Returns a string representation of `$value`. Returns a representation of *any* Sass value, not just those that can be represented in CSS. As such, its return value is not guaranteed to be valid CSS. +{% endmarkdown %} {% headsUp %} This function is intended for debugging; its output format is not guaranteed @@ -337,6 +357,7 @@ to be consistent across Sass versions or implementations. {% endfunction %} {% function 'meta.keywords($args)', 'keywords($args)', 'returns:map' %} +{% markdown %} Returns the keywords passed to a mixin or function that takes [arbitrary arguments][]. The `$args` argument must be an [argument list][]. @@ -345,11 +366,13 @@ arguments][]. The `$args` argument must be an [argument list][]. The keywords are returned as a map from argument names as unquoted strings (not including `$`) to the values of those arguments. +{% endmarkdown %} {% render 'code-snippets/example-mixin-arbitrary-keyword-arguments' %} {% endfunction %} {% function 'meta.mixin-exists($name, $module: null)', 'mixin-exists($name, $module: null)', 'returns:boolean' %} +{% markdown %} Returns whether a [mixin][] named `$name` exists. [mixin]: /documentation/at-rules/mixin @@ -360,6 +383,7 @@ of a [`@use` rule][] in the current file, in which case this returns whether that module has a mixin named `$name`. [`@use` rule]: /documentation/at-rules/use +{% endmarkdown %} {% codeExample 'mixin-exists', false %} @debug meta.mixin-exists("shadow-none"); // false @@ -383,6 +407,7 @@ that module has a mixin named `$name`. {% function 'meta.module-functions($module)', 'returns:map' %} {% render 'documentation/snippets/module-system-function-status' %} +{% markdown %} Returns all the functions defined in a module, as a map from function names to [function values][]. @@ -392,6 +417,7 @@ The `$module` parameter must be a string matching the namespace of a [`@use` rule][] in the current file. [`@use` rule]: /documentation/at-rules/use +{% endmarkdown %} {% codeExample 'module-functions', false %} // _functions.scss @@ -434,6 +460,7 @@ rule][] in the current file. {% function 'meta.module-variables($module)', 'returns:map' %} {% render 'documentation/snippets/module-system-function-status' %} +{% markdown %} Returns all the variables defined in a module, as a map from variable names (without `$`) to the values of those variables. @@ -441,6 +468,7 @@ The `$module` parameter must be a string matching the namespace of a [`@use` rule][] in the current file. [`@use` rule]: /documentation/at-rules/use +{% endmarkdown %} {% codeExample 'module-variables', false %} // _variables.scss @@ -478,6 +506,7 @@ $wafer: #e1d7d2 {% endfunction %} {% function 'meta.type-of($value)', 'type-of($value)', 'returns:unquoted string' %} +{% markdown %} Returns the type of `$value`. This can return the following values: @@ -498,6 +527,7 @@ New possible values may be added in the future. It may return either `list` or [map function][]. [map function]: /documentation/modules/map +{% endmarkdown %} {% codeExample 'type-of', false %} @debug meta.type-of(10px); // number @@ -511,12 +541,14 @@ New possible values may be added in the future. It may return either `list` or {% endfunction %} {% function 'meta.variable-exists($name)', 'variable-exists($name)', 'returns:boolean' %} +{% markdown %} Returns whether a variable named `$name` (without the `$`) exists in the current [scope][]. [scope]: /documentation/variables#scope See also [`meta.global-variable-exists()`](#global-variable-exists). +{% endmarkdown %} {% codeExample 'variable-exists', false %} @debug meta.variable-exists("var1"); // false diff --git a/source/documentation/modules/selector.liquid b/source/documentation/modules/selector.liquid index 3e0ea6a1b..b67564198 100644 --- a/source/documentation/modules/selector.liquid +++ b/source/documentation/modules/selector.liquid @@ -28,6 +28,7 @@ also just be normal strings (quoted or unquoted), or a combination. For example, {% endmarkdown %} {% function 'selector.is-superselector($super, $sub)', 'is-superselector($super, $sub)', 'returns:boolean' %} +{% markdown %} Returns whether the selector `$super` matches all the elements that the selector `$sub` matches. @@ -38,6 +39,7 @@ not [parent selectors][]. [placeholder selectors]: /documentation/style-rules/placeholder-selectors [parent selectors]: /documentation/style-rules/parent-selector +{% endmarkdown %} {% codeExample 'is-superselector', false %} @debug selector.is-superselector("a", "a.disabled"); // true @@ -55,6 +57,7 @@ not [parent selectors][]. {% endfunction %} {% function 'selector.append($selectors...)', 'selector-append($selectors...)', 'returns:selector' %} +{% markdown %} Combines `$selectors` without [descendant combinators][]—that is, without whitespace between them. @@ -70,6 +73,7 @@ selectors][]. [parent selectors]: /documentation/style-rules/parent-selector See also [`selector.nest()`](#nest). +{% endmarkdown %} {% codeExample 'append', false %} @debug selector.append("a", ".disabled"); // a.disabled @@ -85,6 +89,7 @@ See also [`selector.nest()`](#nest). {% endfunction %} {% function 'selector.extend($selector, $extendee, $extender)', 'selector-extend($selector, $extendee, $extender)', 'returns:selector' %} +{% markdown %} Extends `$selector` as with the [`@extend` rule][]. [`@extend` rule]: /documentation/at-rules/extend @@ -108,6 +113,7 @@ The `$selector`, `$extendee`, and `$extender` selectors may contain [parent selectors]: /documentation/style-rules/parent-selector See also [`selector.replace()`](#replace). +{% endmarkdown %} {% codeExample 'extend', false %} @debug selector.extend("a.disabled", "a", ".link"); // a.disabled, .link.disabled @@ -123,6 +129,7 @@ See also [`selector.replace()`](#replace). {% endfunction %} {% function 'selector.nest($selectors...)', 'selector-nest($selectors...)', 'returns:selector' %} +{% markdown %} Combines `$selectors` as though they were nested within one another in the stylesheet. @@ -133,6 +140,7 @@ functions, all of them except the first may also contain [parent selectors][]. [parent selectors]: /documentation/style-rules/parent-selector See also [`selector.append()`](#append). +{% endmarkdown %} {% codeExample 'nest', false %} @debug selector.nest("ul", "li"); // ul li @@ -148,7 +156,9 @@ See also [`selector.append()`](#append). {% endfunction %} {% function 'selector.parse($selector)', 'selector-parse($selector)', 'returns:selector' %} +{% markdown %} Returns `$selector` in the [selector value](#selector-values) format. +{% endmarkdown %} {% codeExample 'parse', false %} @debug selector.parse(".main aside:hover, .sidebar p"); @@ -162,6 +172,7 @@ Returns `$selector` in the [selector value](#selector-values) format. {% endfunction %} {% function 'selector.replace($selector, $original, $replacement)', 'selector-replace($selector, $original, $replacement)', 'returns:selector' %} +{% markdown %} Returns a copy of `$selector` with all instances of `$original` replaced by `$replacement`. @@ -179,6 +190,7 @@ The `$selector`, `$original`, and `$replacement` selectors may contain [parent selectors]: /documentation/style-rules/parent-selector See also [`selector.extend()`](#extend). +{% endmarkdown %} {% codeExample 'replace', false %} @debug selector.replace("a.disabled", "a", ".link"); // .link.disabled @@ -194,6 +206,7 @@ See also [`selector.extend()`](#extend). {% endfunction %} {% function 'selector.unify($selector1, $selector2)', 'selector-unify($selector1, $selector2)', 'returns:selector | null' %} +{% markdown %} Returns a selector that matches only elements matched by *both* `$selector1` and `$selector2`. @@ -205,6 +218,7 @@ isn't guaranteed to match *all* the elements matched by both `$selector1` and `$selector2` if they're both complex selectors. [`@extend` rule]: /documentation/at-rules/extend#html-heuristics +{% endmarkdown %} {% codeExample 'unify', false %} @debug selector.unify("a", ".disabled"); // a.disabled @@ -220,6 +234,7 @@ isn't guaranteed to match *all* the elements matched by both `$selector1` and {% endfunction %} {% function 'selector.simple-selectors($selector)', 'simple-selectors($selector)', 'returns:list' %} +{% markdown %} Returns a list of simple selectors in `$selector`. The `$selector` must be a single string that contains a compound selector. @@ -227,6 +242,7 @@ This means it may not contain combinators (including spaces) or commas. The returned list is comma-separated, and the simple selectors are unquoted strings. +{% endmarkdown %} {% codeExample 'simple-selectors', false %} @debug selector.simple-selectors("a.disabled"); // a, .disabled diff --git a/source/documentation/modules/string.liquid b/source/documentation/modules/string.liquid index 764902309..c3956ca32 100644 --- a/source/documentation/modules/string.liquid +++ b/source/documentation/modules/string.liquid @@ -5,7 +5,9 @@ title: sass:string {% render 'documentation/snippets/built-in-module-status' %} {% function 'string.quote($string)', 'quote($string)', 'returns:string' %} +{% markdown %} Returns `$string` as a quoted string. +{% endmarkdown %} {% codeExample 'quote', false %} @debug string.quote(Helvetica); // "Helvetica" @@ -17,10 +19,12 @@ Returns `$string` as a quoted string. {% endfunction %} {% function 'string.index($string, $substring)', 'str-index($string, $substring)', 'returns:number' %} +{% markdown %} Returns the first [index][] of `$substring` in `$string`, or `null` if `$string` doesn't contain `$substring`. [index]: /documentation/values/strings#string-indexes +{% endmarkdown %} {% codeExample 'index', false %} @debug string.index("Helvetica Neue", "Helvetica"); // 1 @@ -32,9 +36,11 @@ Returns the first [index][] of `$substring` in `$string`, or `null` if {% endfunction %} {% function 'string.insert($string, $insert, $index)', 'str-insert($string, $insert, $index)', 'returns:string' %} +{% markdown %} Returns a copy of `$string` with `$insert` inserted at [`$index`][]. [`$index`]: /documentation/values/strings#string-indexes +{% endmarkdown %} {% codeExample 'insert', false %} @debug string.insert("Roboto Bold", " Mono", 7); // "Roboto Mono Bold" @@ -44,9 +50,11 @@ Returns a copy of `$string` with `$insert` inserted at [`$index`][]. @debug string.insert("Roboto Bold", " Mono", -6) // "Roboto Mono Bold" {% endcodeExample %} +{% markdown %} If `$index` is higher than the length of `$string`, `$insert` is added to the end. If `$index` is smaller than the negative length of the string, `$insert` is added to the beginning. +{% endmarkdown %} {% codeExample 'insert-2', false %} @debug string.insert("Roboto", " Bold", 100); // "Roboto Bold" @@ -58,7 +66,9 @@ the end. If `$index` is smaller than the negative length of the string, {% endfunction %} {% function 'string.length($string)', 'str-length($string)', 'returns:number' %} +{% markdown %} Returns the number of characters in `$string`. +{% endmarkdown %} {% codeExample 'length', false %} @debug string.length("Helvetica Neue"); // 14 @@ -72,10 +82,12 @@ Returns the number of characters in `$string`. {% endfunction %} {% function 'string.slice($string, $start-at, $end-at: -1)', 'str-slice($string, $start-at, $end-at: -1)', 'returns:string' %} +{% markdown %} Returns the slice of `$string` starting at [index][] `$start-at` and ending at index `$end-at` (both inclusive). [index]: /documentation/values/strings#string-indexes +{% endmarkdown %} {% codeExample 'slice', false %} @debug string.slice("Helvetica Neue", 11); // "Neue" @@ -91,6 +103,7 @@ index `$end-at` (both inclusive). {% function 'string.split($string, $separator, $limit: null)', 'returns:list' %} {% compatibility '1.57.0', false, null, false %}{% endcompatibility %} +{% markdown %} Returns a bracketed, comma-separated list of substrings of `$string` that are separated by `$separator`. The `$separator`s aren't included in these substrings. @@ -99,6 +112,7 @@ If `$limit` is a number `1` or higher, this splits on at most that many `$separator`s (and so returns at most `$limit + 1` strings). The last substring contains the rest of the string, including any remaining `$separator`s. +{% endmarkdown %} {% codeExample 'split', false %} @debug string.split("Segoe UI Emoji", " "); // ["Segoe", "UI", "Emoji"] @@ -110,9 +124,11 @@ substring contains the rest of the string, including any remaining {% endfunction %} {% function 'string.to-upper-case($string)', 'to-upper-case($string)', 'returns:string' %} +{% markdown %} Returns a copy of `$string` with the [ASCII][] letters converted to upper case. [ASCII]: https://en.wikipedia.org/wiki/ASCII +{% endmarkdown %} {% codeExample 'to-upper-case', false %} @debug string.to-upper-case("Bold"); // "BOLD" @@ -124,9 +140,11 @@ Returns a copy of `$string` with the [ASCII][] letters converted to upper case. {% endfunction %} {% function 'string.to-lower-case($string)', 'to-lower-case($string)', 'returns:string' %} +{% markdown %} Returns a copy of `$string` with the [ASCII][] letters converted to lower case. [ASCII]: https://en.wikipedia.org/wiki/ASCII +{% endmarkdown %} {% codeExample 'to-lower-case', false %} @debug string.to-lower-case("Bold"); // "bold" @@ -138,8 +156,10 @@ Returns a copy of `$string` with the [ASCII][] letters converted to lower case. {% endfunction %} {% function 'string.unique-id()', 'unique-id()', 'returns:string' %} +{% markdown %} Returns a randomly-generated unquoted string that's guaranteed to be a valid CSS identifier and to be unique within the current Sass compilation. +{% endmarkdown %} {% codeExample 'unique-id', false %} @debug string.unique-id(); // uabtrnzug @@ -151,8 +171,10 @@ CSS identifier and to be unique within the current Sass compilation. {% endfunction %} {% function 'string.unquote($string)', 'unquote($string)', 'returns:string' %} +{% markdown %} Returns `$string` as an unquoted string. This can produce strings that aren't valid CSS, so use with caution. +{% endmarkdown %} {% codeExample 'unquote', false %} @debug string.unquote("Helvetica"); // Helvetica From 1013ee0cc4409defc140f7c1aa125f90c8708d4f Mon Sep 17 00:00:00 2001 From: Jonny Gerig Meyer Date: Fri, 2 Jun 2023 17:44:40 -0400 Subject: [PATCH 14/19] fix build --- source/code-snippets/example-first-class-function.liquid | 2 +- source/documentation/at-rules/mixin.liquid | 4 ++-- source/documentation/style-rules/declarations.liquid | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/code-snippets/example-first-class-function.liquid b/source/code-snippets/example-first-class-function.liquid index 9edfe0be3..71886bff0 100644 --- a/source/code-snippets/example-first-class-function.liquid +++ b/source/code-snippets/example-first-class-function.liquid @@ -1,4 +1,4 @@ -{% # TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass -%} +{% comment %}TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass{% endcomment -%} {% codeExample 'first-class-function' %} @use "sass:list"; @use "sass:meta"; diff --git a/source/documentation/at-rules/mixin.liquid b/source/documentation/at-rules/mixin.liquid index 949d1ba74..0baee5f66 100644 --- a/source/documentation/at-rules/mixin.liquid +++ b/source/documentation/at-rules/mixin.liquid @@ -279,7 +279,7 @@ introduction: > [map]: /documentation/values/maps {% endmarkdown %} -{% # TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass -%} +{% comment %}TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass{% endcomment -%} {% render 'code-snippets/example-mixin-arbitrary-keyword-arguments' %} {% funFact %} @@ -407,7 +407,7 @@ introduction: > [map]: /documentation/values/maps {% endheadsUp %} -{% # TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass -%} +{% comment %}TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass{% endcomment -%} {% codeExample 'passing-arguments-to-content-blocks', false %} @mixin media($types...) { @each $type in $types { diff --git a/source/documentation/style-rules/declarations.liquid b/source/documentation/style-rules/declarations.liquid index 87828b3b4..10d0bece8 100644 --- a/source/documentation/style-rules/declarations.liquid +++ b/source/documentation/style-rules/declarations.liquid @@ -168,7 +168,7 @@ introduction: > [interpolation]: /documentation/interpolation {% endmarkdown %} -{% # TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass -%} +{% comment %}TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass{% endcomment -%} {% codeExample 'custom-properties' %} $primary: #81899b; $accent: #302e24; From bc0cb322039d7d24fa6b966a586b3e2436ab5c58 Mon Sep 17 00:00:00 2001 From: Jonny Gerig Meyer Date: Fri, 2 Jun 2023 18:02:34 -0400 Subject: [PATCH 15/19] fix a few markdown issues --- source/documentation/modules/index.liquid | 4 +- source/documentation/modules/list.liquid | 18 +++++---- source/documentation/modules/map.liquid | 48 +++++++++++------------ 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/source/documentation/modules/index.liquid b/source/documentation/modules/index.liquid index f06f2e730..e04d324cc 100644 --- a/source/documentation/modules/index.liquid +++ b/source/documentation/modules/index.liquid @@ -255,9 +255,9 @@ introduction: > @debug rgba(95%, 92.5%, 89.5%, 0.2) // rgba(242, 236, 228, 0.2) {% endcodeExample %} - {% markdown %} - --- + {{ '---' | markdown }} + {% markdown %} If `$color` and `$alpha` are passed, this returns `$color` with the given `$alpha` channel instead of its original alpha channel. {% endmarkdown %} diff --git a/source/documentation/modules/list.liquid b/source/documentation/modules/list.liquid index 8b5a53003..d15b709e0 100644 --- a/source/documentation/modules/list.liquid +++ b/source/documentation/modules/list.liquid @@ -81,17 +81,19 @@ title: sass:list {% markdown %} Returns a new list containing the elements of `$list1` followed by the elements of `$list2`. + {% endmarkdown %} - {% headsUp %} - Because individual values count as single-element lists, it's possible to - use `list.join()` to add a value to the end of a list. However, *this is - not recommended*, since if that value is a list it will be concatenated, - which is probably not what you're expecting. + {% headsUp %} + Because individual values count as single-element lists, it's possible to + use `list.join()` to add a value to the end of a list. However, *this is not + recommended*, since if that value is a list it will be concatenated, which + is probably not what you're expecting. - Use [`list.append()`](#append) instead to add a single value to a list. - Only use `list.join()` to combine two lists together into one. - {% endheadsUp %} + Use [`list.append()`](#append) instead to add a single value to a list. Only + use `list.join()` to combine two lists together into one. + {% endheadsUp %} + {% markdown %} If `$separator` is `comma`, `space`, or `slash`, the returned list is comma-separated, space-separated, or slash-separated, respectively. If it's `auto` (the default), the returned list will use the same separator as diff --git a/source/documentation/modules/map.liquid b/source/documentation/modules/map.liquid index 358ed1883..b0592be2e 100644 --- a/source/documentation/modules/map.liquid +++ b/source/documentation/modules/map.liquid @@ -105,9 +105,9 @@ title: sass:map // ("medium": 500, "bold": 700) {% endcodeExample %} - {% markdown %} - --- + {{ '---' | markdown }} + {% markdown %} If `$keys` is not empty, follows the set of keys including `$key` and excluding the last key in `$keys`, from left to right, to find the nested map targeted for updating. @@ -162,13 +162,13 @@ title: sass:map {% render 'code-snippets/example-map-get' %} - {% markdown %} - --- + {{ '---' | markdown }} - {% compatibility 'dart: "1.27.0"', 'libsass: false', 'ruby: false' %} - Only Dart Sass supports calling `map.get()` with more than two arguments. - {% endcompatibility %} + {% compatibility 'dart: "1.27.0"', 'libsass: false', 'ruby: false' %} + Only Dart Sass supports calling `map.get()` with more than two arguments. + {% endcompatibility %} + {% markdown %} If `$keys` is not empty, follows the set of keys including `$key` and excluding the last key in `$keys`, from left to right, to find the nested map targeted for searching. @@ -222,14 +222,14 @@ title: sass:map @debug map.has-key($font-weights, "bolder") // false {% endcodeExample %} - {% markdown %} - --- + {{ '---' | markdown }} - {% compatibility 'dart: "1.27.0"', 'libsass: false', 'ruby: false' %} - Only Dart Sass supports calling `map.has-key()` with more than two - arguments. - {% endcompatibility %} + {% compatibility 'dart: "1.27.0"', 'libsass: false', 'ruby: false' %} + Only Dart Sass supports calling `map.has-key()` with more than two + arguments. + {% endcompatibility %} + {% markdown %} If `$keys` is not empty, follows the set of keys including `$key` and excluding the last key in `$keys`, from left to right, to find the nested map targeted for searching. @@ -310,14 +310,13 @@ title: sass:map // ("lightest": 100, "light": 300, "medium": 500, "bold": 700) {% endcodeExample %} - {% markdown %} - --- + {{ '---' | markdown }} - {% compatibility 'dart: "1.27.0"', 'libsass: false', 'ruby: false' %} - Only Dart Sass supports calling `map.merge()` with more than two - arguments. - {% endcompatibility %} + {% compatibility 'dart: "1.27.0"', 'libsass: false', 'ruby: false' %} + Only Dart Sass supports calling `map.merge()` with more than two arguments. + {% endcompatibility %} + {% markdown %} If `$keys` is not empty, follows the `$keys` to find the nested map targeted for merging. If any key in `$keys` is missing from a map or references a value that is not a map, sets the value at that key to an empty map. @@ -416,14 +415,13 @@ title: sass:map // ("regular": 300, "medium": 500, "bold": 700) {% endcodeExample %} - {% markdown %} - --- + {{ '---' | markdown }} - {% compatibility 'dart: "1.27.0"', 'libsass: false', 'ruby: false' %} - Only Dart Sass supports calling `map.set()` with more than three - arguments. - {% endcompatibility %} + {% compatibility 'dart: "1.27.0"', 'libsass: false', 'ruby: false' %} + Only Dart Sass supports calling `map.set()` with more than three arguments. + {% endcompatibility %} + {% markdown %} If `$keys` are passed, follows the `$keys` to find the nested map targeted for updating. If any key in `$keys` is missing from a map or references a value that is not a map, sets the value at that key to an empty map. From 9f8fbce7afab7ac92fac9009020f3f7b652a8009 Mon Sep 17 00:00:00 2001 From: Jonny Gerig Meyer Date: Fri, 2 Jun 2023 18:06:43 -0400 Subject: [PATCH 16/19] update comments --- source/code-snippets/example-first-class-function.liquid | 4 +++- source/documentation/at-rules/mixin.liquid | 8 ++++++-- source/documentation/style-rules/declarations.liquid | 4 +++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/source/code-snippets/example-first-class-function.liquid b/source/code-snippets/example-first-class-function.liquid index 71886bff0..2681d856a 100644 --- a/source/code-snippets/example-first-class-function.liquid +++ b/source/code-snippets/example-first-class-function.liquid @@ -1,4 +1,6 @@ -{% comment %}TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass{% endcomment -%} +{% comment -%} + TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass +{%- endcomment -%} {% codeExample 'first-class-function' %} @use "sass:list"; @use "sass:meta"; diff --git a/source/documentation/at-rules/mixin.liquid b/source/documentation/at-rules/mixin.liquid index 0baee5f66..d611f4b20 100644 --- a/source/documentation/at-rules/mixin.liquid +++ b/source/documentation/at-rules/mixin.liquid @@ -279,7 +279,9 @@ introduction: > [map]: /documentation/values/maps {% endmarkdown %} -{% comment %}TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass{% endcomment -%} +{% comment -%} + TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass +{%- endcomment -%} {% render 'code-snippets/example-mixin-arbitrary-keyword-arguments' %} {% funFact %} @@ -407,7 +409,9 @@ introduction: > [map]: /documentation/values/maps {% endheadsUp %} -{% comment %}TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass{% endcomment -%} +{% comment -%} + TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass +{%- endcomment -%} {% codeExample 'passing-arguments-to-content-blocks', false %} @mixin media($types...) { @each $type in $types { diff --git a/source/documentation/style-rules/declarations.liquid b/source/documentation/style-rules/declarations.liquid index 10d0bece8..80ebd7c25 100644 --- a/source/documentation/style-rules/declarations.liquid +++ b/source/documentation/style-rules/declarations.liquid @@ -168,7 +168,9 @@ introduction: > [interpolation]: /documentation/interpolation {% endmarkdown %} -{% comment %}TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass{% endcomment -%} +{% comment -%} + TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass +{%- endcomment -%} {% codeExample 'custom-properties' %} $primary: #81899b; $accent: #302e24; From 32b1a508e8720b132f2a89fe47dae266081fd187 Mon Sep 17 00:00:00 2001 From: Jonny Gerig Meyer Date: Fri, 2 Jun 2023 18:18:43 -0400 Subject: [PATCH 17/19] Do not include snippets in built site. --- .../code_snippets}/example-advanced-nesting.liquid | 0 .../code_snippets}/example-each-list.liquid | 0 .../code_snippets}/example-each-map.liquid | 0 .../example-first-class-function.liquid | 0 .../example-if-parent-selector.liquid | 0 .../code_snippets}/example-if.liquid | 0 .../code_snippets}/example-list-index.liquid | 0 .../code_snippets}/example-list-nth.liquid | 0 .../code_snippets}/example-map-get.liquid | 0 ...xample-mixin-arbitrary-keyword-arguments.liquid | 0 .../code_snippets}/example-module-migrator.liquid | 0 .../code_snippets}/example-nesting.liquid | 0 .../code_snippets}/example-placeholder.liquid | 0 .../code_snippets}/example-use-with.liquid | 0 .../doc_snippets}/built-in-module-status.liquid | 0 .../doc_snippets}/call-impl-status.liquid | 0 .../module-system-function-status.liquid | 0 .../doc_snippets}/module-system-status.liquid | 0 .../doc_snippets}/operator-list.liquid | 0 .../doc_snippets}/silence-deprecations.liquid | 0 .../doc_snippets}/source-maps.liquid | 0 .../doc_snippets}/truthiness-and-falsiness.liquid | 0 source/documentation/at-rules/at-root.liquid | 2 +- source/documentation/at-rules/control/each.liquid | 4 ++-- source/documentation/at-rules/control/if.liquid | 4 ++-- source/documentation/at-rules/control/while.liquid | 2 +- source/documentation/at-rules/extend.liquid | 2 +- source/documentation/at-rules/import.liquid | 2 +- source/documentation/at-rules/mixin.liquid | 2 +- source/documentation/at-rules/use.liquid | 4 ++-- .../breaking-changes/bogus-combinators.liquid | 2 +- .../breaking-changes/slash-div.liquid | 2 +- .../breaking-changes/strict-unary.liquid | 2 +- source/documentation/cli/dart-sass.md | 2 +- source/documentation/cli/migrator.md | 4 ++-- source/documentation/modules/color.liquid | 2 +- source/documentation/modules/index.liquid | 2 +- source/documentation/modules/list.liquid | 6 +++--- source/documentation/modules/map.liquid | 4 ++-- source/documentation/modules/math.liquid | 2 +- source/documentation/modules/meta.liquid | 14 +++++++------- source/documentation/modules/selector.liquid | 2 +- source/documentation/modules/string.liquid | 2 +- source/documentation/style-rules/index.liquid | 2 +- .../style-rules/parent-selector.liquid | 4 ++-- .../style-rules/placeholder-selectors.liquid | 2 +- source/documentation/syntax/structure.md | 2 +- source/documentation/variables.liquid | 4 ++-- source/guide.liquid | 2 +- 49 files changed, 42 insertions(+), 42 deletions(-) rename source/{code-snippets => _includes/code_snippets}/example-advanced-nesting.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-each-list.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-each-map.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-first-class-function.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-if-parent-selector.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-if.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-list-index.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-list-nth.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-map-get.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-mixin-arbitrary-keyword-arguments.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-module-migrator.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-nesting.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-placeholder.liquid (100%) rename source/{code-snippets => _includes/code_snippets}/example-use-with.liquid (100%) rename source/{documentation/snippets => _includes/doc_snippets}/built-in-module-status.liquid (100%) rename source/{documentation/snippets => _includes/doc_snippets}/call-impl-status.liquid (100%) rename source/{documentation/snippets => _includes/doc_snippets}/module-system-function-status.liquid (100%) rename source/{documentation/snippets => _includes/doc_snippets}/module-system-status.liquid (100%) rename source/{documentation/snippets => _includes/doc_snippets}/operator-list.liquid (100%) rename source/{documentation/snippets => _includes/doc_snippets}/silence-deprecations.liquid (100%) rename source/{documentation/snippets => _includes/doc_snippets}/source-maps.liquid (100%) rename source/{documentation/snippets => _includes/doc_snippets}/truthiness-and-falsiness.liquid (100%) diff --git a/source/code-snippets/example-advanced-nesting.liquid b/source/_includes/code_snippets/example-advanced-nesting.liquid similarity index 100% rename from source/code-snippets/example-advanced-nesting.liquid rename to source/_includes/code_snippets/example-advanced-nesting.liquid diff --git a/source/code-snippets/example-each-list.liquid b/source/_includes/code_snippets/example-each-list.liquid similarity index 100% rename from source/code-snippets/example-each-list.liquid rename to source/_includes/code_snippets/example-each-list.liquid diff --git a/source/code-snippets/example-each-map.liquid b/source/_includes/code_snippets/example-each-map.liquid similarity index 100% rename from source/code-snippets/example-each-map.liquid rename to source/_includes/code_snippets/example-each-map.liquid diff --git a/source/code-snippets/example-first-class-function.liquid b/source/_includes/code_snippets/example-first-class-function.liquid similarity index 100% rename from source/code-snippets/example-first-class-function.liquid rename to source/_includes/code_snippets/example-first-class-function.liquid diff --git a/source/code-snippets/example-if-parent-selector.liquid b/source/_includes/code_snippets/example-if-parent-selector.liquid similarity index 100% rename from source/code-snippets/example-if-parent-selector.liquid rename to source/_includes/code_snippets/example-if-parent-selector.liquid diff --git a/source/code-snippets/example-if.liquid b/source/_includes/code_snippets/example-if.liquid similarity index 100% rename from source/code-snippets/example-if.liquid rename to source/_includes/code_snippets/example-if.liquid diff --git a/source/code-snippets/example-list-index.liquid b/source/_includes/code_snippets/example-list-index.liquid similarity index 100% rename from source/code-snippets/example-list-index.liquid rename to source/_includes/code_snippets/example-list-index.liquid diff --git a/source/code-snippets/example-list-nth.liquid b/source/_includes/code_snippets/example-list-nth.liquid similarity index 100% rename from source/code-snippets/example-list-nth.liquid rename to source/_includes/code_snippets/example-list-nth.liquid diff --git a/source/code-snippets/example-map-get.liquid b/source/_includes/code_snippets/example-map-get.liquid similarity index 100% rename from source/code-snippets/example-map-get.liquid rename to source/_includes/code_snippets/example-map-get.liquid diff --git a/source/code-snippets/example-mixin-arbitrary-keyword-arguments.liquid b/source/_includes/code_snippets/example-mixin-arbitrary-keyword-arguments.liquid similarity index 100% rename from source/code-snippets/example-mixin-arbitrary-keyword-arguments.liquid rename to source/_includes/code_snippets/example-mixin-arbitrary-keyword-arguments.liquid diff --git a/source/code-snippets/example-module-migrator.liquid b/source/_includes/code_snippets/example-module-migrator.liquid similarity index 100% rename from source/code-snippets/example-module-migrator.liquid rename to source/_includes/code_snippets/example-module-migrator.liquid diff --git a/source/code-snippets/example-nesting.liquid b/source/_includes/code_snippets/example-nesting.liquid similarity index 100% rename from source/code-snippets/example-nesting.liquid rename to source/_includes/code_snippets/example-nesting.liquid diff --git a/source/code-snippets/example-placeholder.liquid b/source/_includes/code_snippets/example-placeholder.liquid similarity index 100% rename from source/code-snippets/example-placeholder.liquid rename to source/_includes/code_snippets/example-placeholder.liquid diff --git a/source/code-snippets/example-use-with.liquid b/source/_includes/code_snippets/example-use-with.liquid similarity index 100% rename from source/code-snippets/example-use-with.liquid rename to source/_includes/code_snippets/example-use-with.liquid diff --git a/source/documentation/snippets/built-in-module-status.liquid b/source/_includes/doc_snippets/built-in-module-status.liquid similarity index 100% rename from source/documentation/snippets/built-in-module-status.liquid rename to source/_includes/doc_snippets/built-in-module-status.liquid diff --git a/source/documentation/snippets/call-impl-status.liquid b/source/_includes/doc_snippets/call-impl-status.liquid similarity index 100% rename from source/documentation/snippets/call-impl-status.liquid rename to source/_includes/doc_snippets/call-impl-status.liquid diff --git a/source/documentation/snippets/module-system-function-status.liquid b/source/_includes/doc_snippets/module-system-function-status.liquid similarity index 100% rename from source/documentation/snippets/module-system-function-status.liquid rename to source/_includes/doc_snippets/module-system-function-status.liquid diff --git a/source/documentation/snippets/module-system-status.liquid b/source/_includes/doc_snippets/module-system-status.liquid similarity index 100% rename from source/documentation/snippets/module-system-status.liquid rename to source/_includes/doc_snippets/module-system-status.liquid diff --git a/source/documentation/snippets/operator-list.liquid b/source/_includes/doc_snippets/operator-list.liquid similarity index 100% rename from source/documentation/snippets/operator-list.liquid rename to source/_includes/doc_snippets/operator-list.liquid diff --git a/source/documentation/snippets/silence-deprecations.liquid b/source/_includes/doc_snippets/silence-deprecations.liquid similarity index 100% rename from source/documentation/snippets/silence-deprecations.liquid rename to source/_includes/doc_snippets/silence-deprecations.liquid diff --git a/source/documentation/snippets/source-maps.liquid b/source/_includes/doc_snippets/source-maps.liquid similarity index 100% rename from source/documentation/snippets/source-maps.liquid rename to source/_includes/doc_snippets/source-maps.liquid diff --git a/source/documentation/snippets/truthiness-and-falsiness.liquid b/source/_includes/doc_snippets/truthiness-and-falsiness.liquid similarity index 100% rename from source/documentation/snippets/truthiness-and-falsiness.liquid rename to source/_includes/doc_snippets/truthiness-and-falsiness.liquid diff --git a/source/documentation/at-rules/at-root.liquid b/source/documentation/at-rules/at-root.liquid index 05f2827f9..7dadf17e6 100644 --- a/source/documentation/at-rules/at-root.liquid +++ b/source/documentation/at-rules/at-root.liquid @@ -10,7 +10,7 @@ introduction: > [selector functions](/documentation/modules/selector). --- -{% render 'code-snippets/example-advanced-nesting' %} +{% render 'code_snippets/example-advanced-nesting' %} {% markdown %} The `@at-root` rule is necessary here because Sass doesn't know what diff --git a/source/documentation/at-rules/control/each.liquid b/source/documentation/at-rules/control/each.liquid index 0957b176e..d31f65a8a 100644 --- a/source/documentation/at-rules/control/each.liquid +++ b/source/documentation/at-rules/control/each.liquid @@ -11,7 +11,7 @@ introduction: > the given variable name. --- -{% render 'code-snippets/example-each-list' %} +{% render 'code_snippets/example-each-list' %} {% markdown %} ## With Maps @@ -22,7 +22,7 @@ introduction: > second. {% endmarkdown %} -{% render 'code-snippets/example-each-map' %} +{% render 'code_snippets/example-each-map' %} {% markdown %} ## Destructuring diff --git a/source/documentation/at-rules/control/if.liquid b/source/documentation/at-rules/control/if.liquid index e921eb336..9ca2bf9d8 100644 --- a/source/documentation/at-rules/control/if.liquid +++ b/source/documentation/at-rules/control/if.liquid @@ -10,7 +10,7 @@ introduction: > it’s not. --- -{% render 'code-snippets/example-if' %} +{% render 'code_snippets/example-if' %} {% markdown %} ## `@else` @@ -146,4 +146,4 @@ introduction: > } {% endcodeExample %} -{% render 'documentation/snippets/truthiness-and-falsiness' %} +{% render 'doc_snippets/truthiness-and-falsiness' %} diff --git a/source/documentation/at-rules/control/while.liquid b/source/documentation/at-rules/control/while.liquid index 8fe572482..0778329f6 100644 --- a/source/documentation/at-rules/control/while.liquid +++ b/source/documentation/at-rules/control/while.liquid @@ -52,4 +52,4 @@ introduction: > [`@for`]: /documentation/at-rules/control/for {% endheadsUp %} -{% render 'documentation/snippets/truthiness-and-falsiness' %} +{% render 'doc_snippets/truthiness-and-falsiness' %} diff --git a/source/documentation/at-rules/extend.liquid b/source/documentation/at-rules/extend.liquid index 2910f2147..20a9af74d 100644 --- a/source/documentation/at-rules/extend.liquid +++ b/source/documentation/at-rules/extend.liquid @@ -204,7 +204,7 @@ introduction: > [placeholder selectors]: /documentation/style-rules/placeholder-selectors {% endmarkdown %} -{% render 'code-snippets/example-placeholder' %} +{% render 'code_snippets/example-placeholder' %} {% markdown %} ### Private Placeholders diff --git a/source/documentation/at-rules/import.liquid b/source/documentation/at-rules/import.liquid index f60495929..543d17188 100644 --- a/source/documentation/at-rules/import.liquid +++ b/source/documentation/at-rules/import.liquid @@ -484,7 +484,7 @@ introduction: > {% markdown %} ## Import and Modules - {% render 'documentation/snippets/module-system-status' %} + {% render 'doc_snippets/module-system-status' %} Sass's [module system][] integrates seamlessly with `@import`, whether you're importing a file that contains `@use` rules or loading a file that contains diff --git a/source/documentation/at-rules/mixin.liquid b/source/documentation/at-rules/mixin.liquid index d611f4b20..b7ef1905d 100644 --- a/source/documentation/at-rules/mixin.liquid +++ b/source/documentation/at-rules/mixin.liquid @@ -282,7 +282,7 @@ introduction: > {% comment -%} TODO(nweiz): auto-generate this CSS once we're compiling with Dart Sass {%- endcomment -%} -{% render 'code-snippets/example-mixin-arbitrary-keyword-arguments' %} +{% render 'code_snippets/example-mixin-arbitrary-keyword-arguments' %} {% funFact %} If you don't ever pass an argument list to the [`meta.keywords()` function][], diff --git a/source/documentation/at-rules/use.liquid b/source/documentation/at-rules/use.liquid index d41f71f82..ac1a115b2 100644 --- a/source/documentation/at-rules/use.liquid +++ b/source/documentation/at-rules/use.liquid @@ -3,7 +3,7 @@ title: "@use" table_of_contents: true eleventyComputed: before_introduction: > - {% render 'documentation/snippets/module-system-status' %} + {% render 'doc_snippets/module-system-status' %} introduction: > The `@use` rule loads [mixins](/documentation/at-rules/mixin), [functions](/documentation/at-rules/function), and @@ -298,7 +298,7 @@ introduction: > [`!default` flag]: /documentation/variables#default-values {% endmarkdown %} -{% render 'code-snippets/example-use-with' %} +{% render 'code_snippets/example-use-with' %} {% markdown %} ### With Mixins diff --git a/source/documentation/breaking-changes/bogus-combinators.liquid b/source/documentation/breaking-changes/bogus-combinators.liquid index a037f137f..37cd2ce79 100644 --- a/source/documentation/breaking-changes/bogus-combinators.liquid +++ b/source/documentation/breaking-changes/bogus-combinators.liquid @@ -57,7 +57,7 @@ introduction: > leading or trailing combinators that end up in selectors after nesting is resolved. - {% render 'documentation/snippets/silence-deprecations' %} + {% render 'doc_snippets/silence-deprecations' %} In addition, we'll immediately start omitting selectors that we know to be invalid CSS from the compiled CSS, with one exception: we _won't_ omit diff --git a/source/documentation/breaking-changes/slash-div.liquid b/source/documentation/breaking-changes/slash-div.liquid index 611d42882..c6d359c06 100644 --- a/source/documentation/breaking-changes/slash-div.liquid +++ b/source/documentation/breaking-changes/slash-div.liquid @@ -61,7 +61,7 @@ introduction: > instead. {% endmarkdown %} -{% render 'documentation/snippets/silence-deprecations' %} +{% render 'doc_snippets/silence-deprecations' %} {% codeExample 'math-div', false %} @use "sass:math"; diff --git a/source/documentation/breaking-changes/strict-unary.liquid b/source/documentation/breaking-changes/strict-unary.liquid index 59b02c8d8..8776734e5 100644 --- a/source/documentation/breaking-changes/strict-unary.liquid +++ b/source/documentation/breaking-changes/strict-unary.liquid @@ -51,7 +51,7 @@ introduction: > We'll make this an error in Dart Sass 2.0.0, but until then it'll just emit a deprecation warning. - {% render 'documentation/snippets/silence-deprecations' %} + {% render 'doc_snippets/silence-deprecations' %} ## Automatic Migration diff --git a/source/documentation/cli/dart-sass.md b/source/documentation/cli/dart-sass.md index 69385753a..7761fa443 100644 --- a/source/documentation/cli/dart-sass.md +++ b/source/documentation/cli/dart-sass.md @@ -223,7 +223,7 @@ Compiled themes/light.scss to public/css/light.css. {% compatibility 'dart: "1.3.0"' %}{% endcompatibility %} -{% render 'documentation/snippets/source-maps' %} +{% render 'doc_snippets/source-maps' %} Dart Sass generates source maps by default for every CSS file it emits. diff --git a/source/documentation/cli/migrator.md b/source/documentation/cli/migrator.md index 9d77497f9..58b98040d 100644 --- a/source/documentation/cli/migrator.md +++ b/source/documentation/cli/migrator.md @@ -33,7 +33,7 @@ see what changes will be made without actually saving them, you can pass [--dry-run]: #dry-run [--verbose]: #verbose -{% render 'code-snippets/example-module-migrator' %} +{% render 'code_snippets/example-module-migrator' %} ## Installation @@ -259,7 +259,7 @@ before, including: [`--migrate-deps` option]: #migrate-deps {% endheadsUp %} -{% render 'code-snippets/example-module-migrator' %} +{% render 'code_snippets/example-module-migrator' %} #### Loading Dependencies diff --git a/source/documentation/modules/color.liquid b/source/documentation/modules/color.liquid index a8db13eaa..7b433cb2e 100644 --- a/source/documentation/modules/color.liquid +++ b/source/documentation/modules/color.liquid @@ -2,7 +2,7 @@ title: sass:color --- -{% render 'documentation/snippets/built-in-module-status' %} +{% render 'doc_snippets/built-in-module-status' %} {% function 'color.adjust($color,!!! $red: null, $green: null, $blue: null,!!! $hue: null, $saturation: null, $lightness: null,!!! $whiteness: null, $blackness: null,!!! $alpha: null)', 'adjust-color(...)', 'returns:color' %} {% compatibility 'dart: "1.28.0"', 'libsass: false', 'ruby: false', 'feature: "$whiteness and $blackness"' %}{% endcompatibility %} diff --git a/source/documentation/modules/index.liquid b/source/documentation/modules/index.liquid index e04d324cc..47c3e74bb 100644 --- a/source/documentation/modules/index.liquid +++ b/source/documentation/modules/index.liquid @@ -2,7 +2,7 @@ title: Built-In Modules eleventyComputed: before_introduction: > - {% render 'documentation/snippets/built-in-module-status' %} + {% render 'doc_snippets/built-in-module-status' %} introduction: > Sass provides many built-in modules which contain useful functions (and the occasional mixin). These modules can be loaded with the [`@use` diff --git a/source/documentation/modules/list.liquid b/source/documentation/modules/list.liquid index d15b709e0..3efaaf993 100644 --- a/source/documentation/modules/list.liquid +++ b/source/documentation/modules/list.liquid @@ -2,7 +2,7 @@ title: sass:list --- -{% render 'documentation/snippets/built-in-module-status' %} +{% render 'doc_snippets/built-in-module-status' %} {% funFact %} In Sass, every [map][] counts as a list that contains a two-element list for @@ -60,7 +60,7 @@ title: sass:list [`null`]: /documentation/values/null {% endmarkdown %} - {% render 'code-snippets/example-list-index' %} + {% render 'code_snippets/example-list-index' %} {% endfunction %} {% function 'list.is-bracketed($list)', 'is-bracketed($list)', 'returns:boolean' %} @@ -175,7 +175,7 @@ title: sass:list there is no element at index `$n`. {% endmarkdown %} - {% render 'code-snippets/example-list-nth' %} + {% render 'code_snippets/example-list-nth' %} {% endfunction %} {% function 'list.set-nth($list, $n, $value)', 'set-nth($list, $n, $value)', 'returns:list' %} diff --git a/source/documentation/modules/map.liquid b/source/documentation/modules/map.liquid index b0592be2e..bc1f99040 100644 --- a/source/documentation/modules/map.liquid +++ b/source/documentation/modules/map.liquid @@ -2,7 +2,7 @@ title: sass:map --- -{% render 'documentation/snippets/built-in-module-status' %} +{% render 'doc_snippets/built-in-module-status' %} {% funFact false %} {% markdown %} @@ -160,7 +160,7 @@ title: sass:map [`null`]: /documentation/values/null {% endmarkdown %} - {% render 'code-snippets/example-map-get' %} + {% render 'code_snippets/example-map-get' %} {{ '---' | markdown }} diff --git a/source/documentation/modules/math.liquid b/source/documentation/modules/math.liquid index 10309e31d..7556ffd7c 100644 --- a/source/documentation/modules/math.liquid +++ b/source/documentation/modules/math.liquid @@ -2,7 +2,7 @@ title: sass:math --- -{% render 'documentation/snippets/built-in-module-status' %} +{% render 'doc_snippets/built-in-module-status' %} {{ '## Variables' | markdown }} diff --git a/source/documentation/modules/meta.liquid b/source/documentation/modules/meta.liquid index 07b8151a9..86b7436de 100644 --- a/source/documentation/modules/meta.liquid +++ b/source/documentation/modules/meta.liquid @@ -2,7 +2,7 @@ title: sass:meta --- -{% render 'documentation/snippets/built-in-module-status' %} +{% render 'doc_snippets/built-in-module-status' %} {{ '## Mixins' | markdown }} @@ -139,7 +139,7 @@ title: sass:meta {% endfunction %} {% function 'meta.call($function, $args...)', 'call($function, $args...)' %} - {% render 'documentation/snippets/call-impl-status' %} + {% render 'doc_snippets/call-impl-status' %} {% markdown %} Invokes `$function` with `$args` and returns the result. @@ -151,7 +151,7 @@ title: sass:meta [`meta.get-function()`]: #get-function {% endmarkdown %} - {% render 'code-snippets/example-first-class-function' %} + {% render 'code_snippets/example-first-class-function' %} {% endfunction %} {% function 'meta.content-exists()', 'content-exists()', 'returns:boolean' %} @@ -282,7 +282,7 @@ title: sass:meta The returned function can be called using [`meta.call()`](#call). {% endmarkdown %} - {% render 'code-snippets/example-first-class-function' %} + {% render 'code_snippets/example-first-class-function' %} {% endfunction %} {% function 'meta.global-variable-exists($name, $module: null)', 'global-variable-exists($name, $module: null)', 'returns:boolean' %} @@ -365,7 +365,7 @@ title: sass:meta (not including `$`) to the values of those arguments. {% endmarkdown %} - {% render 'code-snippets/example-mixin-arbitrary-keyword-arguments' %} + {% render 'code_snippets/example-mixin-arbitrary-keyword-arguments' %} {% endfunction %} {% function 'meta.mixin-exists($name, $module: null)', 'mixin-exists($name, $module: null)', 'returns:boolean' %} @@ -402,7 +402,7 @@ title: sass:meta {% endfunction %} {% function 'meta.module-functions($module)', 'returns:map' %} - {% render 'documentation/snippets/module-system-function-status' %} + {% render 'doc_snippets/module-system-function-status' %} {% markdown %} Returns all the functions defined in a module, as a map from function names @@ -455,7 +455,7 @@ title: sass:meta {% endfunction %} {% function 'meta.module-variables($module)', 'returns:map' %} - {% render 'documentation/snippets/module-system-function-status' %} + {% render 'doc_snippets/module-system-function-status' %} {% markdown %} Returns all the variables defined in a module, as a map from variable names diff --git a/source/documentation/modules/selector.liquid b/source/documentation/modules/selector.liquid index b7c37ecbd..abd5df783 100644 --- a/source/documentation/modules/selector.liquid +++ b/source/documentation/modules/selector.liquid @@ -2,7 +2,7 @@ title: sass:selector --- -{% render 'documentation/snippets/built-in-module-status' %} +{% render 'doc_snippets/built-in-module-status' %} {% markdown %} ## Selector Values diff --git a/source/documentation/modules/string.liquid b/source/documentation/modules/string.liquid index ab4b7d2c9..505871cf4 100644 --- a/source/documentation/modules/string.liquid +++ b/source/documentation/modules/string.liquid @@ -2,7 +2,7 @@ title: sass:string --- -{% render 'documentation/snippets/built-in-module-status' %} +{% render 'doc_snippets/built-in-module-status' %} {% function 'string.quote($string)', 'quote($string)', 'returns:string' %} {% markdown %} diff --git a/source/documentation/style-rules/index.liquid b/source/documentation/style-rules/index.liquid index 5a15b5d48..54b8522ce 100644 --- a/source/documentation/style-rules/index.liquid +++ b/source/documentation/style-rules/index.liquid @@ -32,7 +32,7 @@ introduction: > rule's. {% endmarkdown %} -{% render 'code-snippets/example-nesting' %} +{% render 'code_snippets/example-nesting' %} {% headsUp %} Nested rules are super helpful, but they can also make it hard to visualize diff --git a/source/documentation/style-rules/parent-selector.liquid b/source/documentation/style-rules/parent-selector.liquid index 8b2f4a265..24f38bbe8 100644 --- a/source/documentation/style-rules/parent-selector.liquid +++ b/source/documentation/style-rules/parent-selector.liquid @@ -154,7 +154,7 @@ introduction: > [falsey]: /documentation/at-rules/control/if#truthiness-and-falsiness {% endmarkdown %} -{% render 'code-snippets/example-if-parent-selector' %} +{% render 'code_snippets/example-if-parent-selector' %} {% markdown %} ### Advanced Nesting @@ -168,7 +168,7 @@ introduction: > [`@at-root` rule]: /documentation/at-rules/at-root {% endmarkdown %} -{% render 'code-snippets/example-advanced-nesting' %} +{% render 'code_snippets/example-advanced-nesting' %} {% headsUp %} When Sass is nesting selectors, it doesn't know what interpolation was used to diff --git a/source/documentation/style-rules/placeholder-selectors.liquid b/source/documentation/style-rules/placeholder-selectors.liquid index b6b14691e..2e6471f0e 100644 --- a/source/documentation/style-rules/placeholder-selectors.liquid +++ b/source/documentation/style-rules/placeholder-selectors.liquid @@ -8,7 +8,7 @@ introduction: > CSS, nor is any style rule whose selectors all contain placeholders. --- -{% render 'code-snippets/example-placeholder' %} +{% render 'code_snippets/example-placeholder' %} {% markdown %} What's the use of a selector that isn't emitted? It can still be [extended][]! diff --git a/source/documentation/syntax/structure.md b/source/documentation/syntax/structure.md index d9dc6eb66..845949619 100644 --- a/source/documentation/syntax/structure.md +++ b/source/documentation/syntax/structure.md @@ -95,7 +95,7 @@ The simplest expressions just represent static values: Sass defines syntax for a number of operations: -{% render 'documentation/snippets/operator-list', parens: true %} +{% render 'doc_snippets/operator-list', parens: true %} ### Other Expressions diff --git a/source/documentation/variables.liquid b/source/documentation/variables.liquid index 0d1d9b390..e59aec7db 100644 --- a/source/documentation/variables.liquid +++ b/source/documentation/variables.liquid @@ -99,7 +99,7 @@ introduction: > ### Configuring Modules - {% render 'documentation/snippets/module-system-status' %} + {% render 'doc_snippets/module-system-status' %} Variables defined with `!default` can be configured when loading a module with the [`@use` rule][]. Sass libraries often use `!default` variables to allow @@ -113,7 +113,7 @@ introduction: > stylesheet with a `!default` flag can be configured. {% endmarkdown %} -{% render 'code-snippets/example-use-with' %} +{% render 'code_snippets/example-use-with' %} {% markdown %} ## Built-in Variables diff --git a/source/guide.liquid b/source/guide.liquid index 2cf37ac8a..638e2efaf 100644 --- a/source/guide.liquid +++ b/source/guide.liquid @@ -207,7 +207,7 @@ navigation: | {% markdown %} ## Modules - {% render 'documentation/snippets/module-system-status' %} + {% render 'doc_snippets/module-system-status' %} You don't have to write all your Sass in a single file. You can split it up however you want with the `@use` rule. This rule loads another Sass file as From 48e4b547013501d096cb7960a175a4c24701d1ef Mon Sep 17 00:00:00 2001 From: Jonny Gerig Meyer Date: Wed, 7 Jun 2023 15:44:07 -0400 Subject: [PATCH 18/19] Use `{% capture %}` blocks for args with newlines. --- source/documentation/modules/color.liquid | 30 ++++++++++++++++++++--- source/helpers/function.ts | 8 ++++-- source/helpers/type.ts | 8 ++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/source/documentation/modules/color.liquid b/source/documentation/modules/color.liquid index 7b433cb2e..488e8ce85 100644 --- a/source/documentation/modules/color.liquid +++ b/source/documentation/modules/color.liquid @@ -4,7 +4,15 @@ title: sass:color {% render 'doc_snippets/built-in-module-status' %} -{% function 'color.adjust($color,!!! $red: null, $green: null, $blue: null,!!! $hue: null, $saturation: null, $lightness: null,!!! $whiteness: null, $blackness: null,!!! $alpha: null)', 'adjust-color(...)', 'returns:color' %} +{% capture color_adjust %} + color.adjust($color, + $red: null, $green: null, $blue: null, + $hue: null, $saturation: null, $lightness: null, + $whiteness: null, $blackness: null, + $alpha: null) +{% endcapture %} + +{% function color_adjust, 'adjust-color(...)', 'returns:color' %} {% compatibility 'dart: "1.28.0"', 'libsass: false', 'ruby: false', 'feature: "$whiteness and $blackness"' %}{% endcompatibility %} {% markdown %} @@ -174,7 +182,15 @@ title: sass:color {% endcodeExample %} {% endfunction %} -{% function 'color.change($color,!!! $red: null, $green: null, $blue: null,!!! $hue: null, $saturation: null, $lightness: null,!!! $whiteness: null, $blackness: null,!!! $alpha: null)', 'change-color(...)', 'returns:color' %} +{% capture color_change %} + color.change($color, + $red: null, $green: null, $blue: null, + $hue: null, $saturation: null, $lightness: null, + $whiteness: null, $blackness: null, + $alpha: null) +{% endcapture %} + +{% function color_change, 'change-color(...)', 'returns:color' %} {% compatibility 'dart: "1.28.0"', 'libsass: false', 'ruby: false', 'feature: "$whiteness and $blackness"' %}{% endcompatibility %} {% markdown %} @@ -781,7 +797,15 @@ title: sass:color {% endcodeExample %} {% endfunction %} -{% function 'color.scale($color,!!! $red: null, $green: null, $blue: null,!!! $saturation: null, $lightness: null,!!! $whiteness: null, $blackness: null,!!! $alpha: null)', 'scale-color(...)', 'returns:color' %} +{% capture color_scale %} + color.scale($color, + $red: null, $green: null, $blue: null, + $saturation: null, $lightness: null, + $whiteness: null, $blackness: null, + $alpha: null) +{% endcapture %} + +{% function color_scale, 'scale-color(...)', 'returns:color' %} {% compatibility 'dart: "1.28.0"', 'libsass: false', 'ruby: false', 'feature: "$whiteness and $blackness"' %}{% endcompatibility %} {% markdown %} diff --git a/source/helpers/function.ts b/source/helpers/function.ts index 5887ffda1..941662d44 100644 --- a/source/helpers/function.ts +++ b/source/helpers/function.ts @@ -1,4 +1,5 @@ import * as cheerio from 'cheerio'; +import stripIndent from 'strip-indent'; import { codeBlock } from './components'; @@ -41,12 +42,14 @@ const returnTypeLink = (returnType: string) => export function _function(content: string, ...signatures: string[]) { // Parse the last argument as the return type, if it's present const returns = signatures.at(-1)?.match(/returns?:\s*(.*)/)?.[1]; - if (returns) signatures.pop(); + if (returns) { + signatures.pop(); + } // Highlight each signature const names: string[] = []; const highlightedSignatures = signatures.map((signature) => { - signature = signature.replace(/!!!/g, '\n'); // Hack to allow newlines in the signature + signature = stripIndent(signature).trim(); const [name] = signature.split('(', 2); const nameWithoutNamespace = name.split('.').at(-1) || name; const html = codeBlock(`@function ${signature}`, 'scss'); @@ -54,6 +57,7 @@ export function _function(content: string, ...signatures: string[]) { const signatureElements = $('pre code') .contents() .filter((index, element) => $(element).text() !== '@function'); + // Add a class to make it easier to index function documentation. if (!names.includes(nameWithoutNamespace)) { names.push(nameWithoutNamespace); const nameEl = signatureElements diff --git a/source/helpers/type.ts b/source/helpers/type.ts index cb3b030d9..ffe86919c 100644 --- a/source/helpers/type.ts +++ b/source/helpers/type.ts @@ -66,6 +66,13 @@ export const replaceInternalLinks = (content: string, url: string) => */ export const startsWith = (str: string, check: string) => str.startsWith(check); +/** + * Strips leading whitespace from each line in a string. + * + * @see https://github.com/sindresorhus/strip-indent + */ +export const stripInd = (str: string) => stripIndent(str); + /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any */ @@ -77,6 +84,7 @@ export default function typePlugin(eleventyConfig: any) { eleventyConfig.addLiquidFilter('typogr', typogr); eleventyConfig.addLiquidFilter('replaceInternalLinks', replaceInternalLinks); eleventyConfig.addLiquidFilter('startsWith', startsWith); + eleventyConfig.addLiquidFilter('stripIndent', stripInd); // shortcodes... eleventyConfig.addLiquidShortcode('lorem', getLorem); From 1a89e8fa4614a7f3c379a969164949bb357106d0 Mon Sep 17 00:00:00 2001 From: Jonny Gerig Meyer Date: Wed, 7 Jun 2023 16:36:06 -0400 Subject: [PATCH 19/19] Use LiquidJS template instead of constructing HTML in JS. --- source/_includes/function.liquid | 5 +++++ source/helpers/function.ts | 34 ++++++++------------------------ 2 files changed, 13 insertions(+), 26 deletions(-) create mode 100644 source/_includes/function.liquid diff --git a/source/_includes/function.liquid b/source/_includes/function.liquid new file mode 100644 index 000000000..264025584 --- /dev/null +++ b/source/_includes/function.liquid @@ -0,0 +1,5 @@ +{% for name in names offset: 1 %}
{% endfor -%} +
{{ signatures }}{% if returns %} //=> {{ returns }}{% endif %}
+ {{ content }} +
+{%- for name in names offset: 1 %}
{% endfor %} diff --git a/source/helpers/function.ts b/source/helpers/function.ts index 941662d44..168781075 100644 --- a/source/helpers/function.ts +++ b/source/helpers/function.ts @@ -2,6 +2,7 @@ import * as cheerio from 'cheerio'; import stripIndent from 'strip-indent'; import { codeBlock } from './components'; +import { liquidEngine } from './engines'; const links: Record = { number: '/documentation/values/numbers', @@ -33,7 +34,7 @@ const returnTypeLink = (returnType: string) => /** Renders API docs for a Sass function (or mixin). * * The function's name is parsed from the signature. The API description is - * passed as a Markdown block. If `returns:type` is passed as the last argument, + * passed as an HTML block. If `returns:type` is passed as the last argument, * it's included as the function's return type. * * Multiple signatures may be passed, in which case they're all included in @@ -75,32 +76,13 @@ export function _function(content: string, ...signatures: string[]) { .trim(); }); - // Add the return type after the last signature - let mergedSignatures = highlightedSignatures.join('\n'); - if (returns) { - mergedSignatures += ` //=> ${returnTypeLink( - returns, - )}`; - } - - // Assemble the final HTML - const $ = cheerio.load(''); - const div = $('
') - .addClass('sl-c-callout sl-c-callout--function') - .attr('id', names[0]); - const pre = $('
').addClass('signature language-scss');
-  const anchor = $('').addClass('anchor').attr('href', `#${names[0]}`);
-  const code = $('')
-    .addClass('language-scss')
-    .html(mergedSignatures);
-  pre.append(anchor).append(code);
-  div.append(pre).append(content);
-  $('body').append(div);
-  names.slice(1).forEach((name) => {
-    const div = $('
').attr('id', name); - $('body').append(div); + // Render the final HTML + return liquidEngine.renderFile('function', { + names, + signatures: highlightedSignatures.join('\n'), + content, + returns: returns ? returnTypeLink(returns) : null, }); - return $('body').html() || ''; } /* eslint-disable @typescript-eslint/no-unsafe-member-access,