/// Syntax Normalization /// ==================== /// Susy is divided into two layers: /// "Su" provides the core math functions with a stripped-down syntax, /// while "Susy" adds global settings, shorthand syntax, /// and other helpers. /// Each setting (e.g. span, location, columns, spread, etc.) /// has a single canonical syntax in Su. /// /// This normalization module helps translate between those layers, /// transforming parsed Susy input into /// values that Su will understand. /// /// @group _normal /// /// @see susy-normalize /// @see susy-normalize-span /// @see susy-normalize-columns /// @see susy-normalize-spread /// @see susy-normalize-location // Susy Normalize // -------------- /// Normalize the values in a configuration map. /// In addition to the global `$susy` properties, /// this map can include local span-related imformation, /// like `span` and `location`. /// /// Normalization does not check that values are valid, /// which will happen in the Su math layer. /// These functions merely look for known Susy syntax – /// returning a map with those shorthand values /// converted into low-level data for Su. /// For example `span: all` and `location: first` /// will be converted into specific numbers. /// /// @group _normal /// @see $susy /// @see susy-parse /// /// @param {map} $config - /// Map of Susy configuration settings to normalize. /// See `$susy` and `susy-parse()` documentation for details. /// @param {map | null} $context [null] - /// Map of Susy configuration settings to use as global reference, /// or `null` to use global settings. /// /// @return {map} - /// Map of Susy configuration settings, /// with all values normalized for Su math functions. @function susy-normalize( $config, $context: null ) { // Spread @each $setting in ('spread', 'container-spread') { $value: map-get($config, $setting); @if $value { $value: susy-normalize-spread($value); $config: map-merge($config, ($setting: $value)); } } // Columns $columns: map-get($config, 'columns'); @if $columns { $columns: susy-normalize-columns($columns, $context); $config: map-merge($config, ('columns': $columns)); } @if not $columns { $map: type-of($context) == 'map'; $columns: if($map, map-get($context, 'columns'), null); $columns: $columns or susy-get('columns'); } // Span $span: map-get($config, 'span'); @if $span { $span: susy-normalize-span($span, $columns); $config: map-merge($config, ('span': $span)); } // Location $location: map-get($config, 'location'); @if $location { $location: susy-normalize-location($span, $location, $columns); $config: map-merge($config, ('location': $location)); } @return $config; } // Normalize Span // -------------- /// Normalize `span` shorthand for Su. /// Su span syntax allows an explicit length (e.g. `3em`), /// unitless column-span number (e.g. `3` columns), /// or an explicit list of columns (e.g. `(3 5 8)`). /// /// Susy span syntax also allows the `all` keyword, /// which will be converted to a slice of the context /// in normalization. /// /// @group _normal /// /// @param {number | list | 'all'} $span - /// Span value to normalize. /// @param {list} $columns - /// Normalized list of columns in the grid /// /// @return {number | list} - /// Number or list value for `$span` @function susy-normalize-span( $span, $columns: susy-get('columns') ) { @if ($span == 'all') { @return length($columns); } @return $span; } // Normalize Columns // ----------------- /// Normalize `column` shorthand for Su. /// Su column syntax only allows column lists (e.g. `120px 1 1 1 120px`). /// /// Susy span syntax also allows a unitless `slice` number (e.g `of 5`), /// which will be converted to a slice of the context /// in normalization. /// /// @group _normal /// /// @param {list | integer} $columns - /// List of available columns, /// or unitless integer representing a slice of /// the available context. /// @param {map | null} $context [null] - /// Map of Susy configuration settings to use as global reference, /// or `null` to access global settings. /// /// @return {list} - /// Columns list value, normalized for Su input. /// /// @throws /// when attempting to access a slice of asymmetrical context @function susy-normalize-columns( $columns, $context: null ) { $context: $context or susy-settings(); @if type-of($columns) == 'list' { @return _susy-flatten($columns); } @if (type-of($columns) == 'number') and (unitless($columns)) { $span: $columns; $context: map-get($context, 'columns'); $symmetrical: susy-repeat(length($context), nth($context, 1)); @if ($context == $symmetrical) { @return susy-repeat($span, nth($context, 1)); } @else { $actual: 'of `#{$span}`'; $columns: 'grid-columns `#{$context}`'; @return _susy-error( 'context-slice #{$actual} can not be determined based on #{$columns}.', 'susy-normalize-columns'); } } @return $columns; } // Normalize Spread // ---------------- /// Normalize `spread` shorthand for Su. /// Su spread syntax only allows the numbers `-1`, `0`, or `1` – /// representing the number of gutters covered /// in relation to columns spanned. /// /// Susy spread syntax also allows keywords for each value – /// `narrow` for `-1`, `wide` for `0`, or `wider` for `1` – /// which will be converted to their respective integers /// in normalization. /// /// @group _normal /// /// @param {0 | 1 | -1 | 'narrow' | 'wide' | 'wider'} $spread - /// Spread across adjacent gutters, relative to a column-count — /// either `narrow` (-1), `wide` (0), or `wider` (1) /// /// @return {number} - /// Numeric value for `$spread` @function susy-normalize-spread( $spread ) { $normal-spread: ( 'narrow': -1, 'wide': 0, 'wider': 1, ); @return map-get($normal-spread, $spread) or $spread; } // Normalize Location // ------------------ /// Normalize `location` shorthand for Su. /// Su location syntax requires the (1-indexed) number for a column. /// /// Susy also allows the `first` and `last` keywords, /// where `first` is always `1`, /// and `last` is calculated based on span and column values. /// Both keywords are normalized into an integer index /// in normalization. /// /// @group _normal /// /// @param {number} $span - /// Number of grid-columns to be spanned /// @param {integer | 'first' | 'last'} $location - /// Starting (1-indexed) column position of a span, /// or a named location keyword. /// @param {list} $columns - /// Already-normalized list of columns in the grid. /// /// @return {integer} - /// Numeric value for `$location` @function susy-normalize-location( $span, $location, $columns ) { $count: length($columns); $normal-locations: ( 'first': 1, 'alpha': 1, 'last': $count - $span + 1, 'omega': $count - $span + 1, ); @return map-get($normal-locations, $location) or $location; }