/// 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 x-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 x-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 x-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 x-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 x-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 x-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;

}