Skip to content

Instantly share code, notes, and snippets.

@lunelson
Created February 28, 2014 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lunelson/9273060 to your computer and use it in GitHub Desktop.
Save lunelson/9273060 to your computer and use it in GitHub Desktop.
Sass List Maps 0.9.5 release version
// ----
// libsass (v0.7.0)
// ----
// list helper functions
// 0.9.3 -- "list()" now deprecated in favor of "zip()".
// 0.9.5 -- "zip()" now deprecated as well: single-pair lists are handled automatically
@function list($args...) {
$output: ();
@each $arg in $args { $output: append($output, $arg, 'comma'); }
@return $output;
}
@function slice($list, $start: 1, $end: length($list), $sep: 'comma') {
$output: ();
@for $i from $start through $end {
$output: append($output, nth($list, $i), $sep); }
@return $output;
}
@function set-nth($list, $index, $value, $sep: 'comma') {
$length: length($list); $output: ();
@if $index > $length or $index <= 0 { @return $list; }
@if $index > 1 { @for $i from 1 through $index - 1 { $output: append($output, nth($list, $i), $sep); } }
$output: append($output, $value, $sep);
@if $length > 1 { @for $i from $index + 1 through $length { $output: append($output, nth($list, $i), $sep); } }
@return $output;
}
// list-map helper functions
// 0.9.3 -- key() and value() tentatively added as alternatives to 'tuple-' named funcs
// 0.9.6 -- added better error handling; aliased to single version of each
@function tuple-key($tuple) { @if length($tuple) < 1 { @return null; } @else { @return nth($tuple, 1); } }
@function tuple-value($tuple) { @if length($tuple) < 2 { @return null; } @else { @return nth($tuple, 2); } }
@function key($tuple) { @return tuple-key($tuple); }
@function value($tuple) { @return tuple-value($tuple); }
// 0.9.5 -- added list-map-check()
@function list-map-check($list) { @if length($list) == 2 and length(nth($list, 1)) == 1 { @return append((), $list, 'comma'); } @return $list; }
// list-map versions of list-map-keys(), -values() and -has-key() functions
// 0.9.5 -- now all handle single- or double-wrapped list-maps (single-pair case) automatically
// 0.9.5 -- added map-prev-key() and map-next-key() functions
@function map-keys($list...) {
@if length($list) == 1 { $list: list-map-check($list...); }
@else { $list: list-map-check($list); } $output: ();
@each $tuple in $list { $output: append($output, tuple-key($tuple), 'comma'); }
@return $output;
}
@function map-values($list...) {
@if length($list) == 1 { $list: list-map-check($list...); }
@else { $list: list-map-check($list); } $output: ();
@each $tuple in $list { $output: append($output, tuple-value($tuple), 'comma'); }
@return $output;
}
@function map-has-key($list, $key) {
$list: list-map-check($list);
@each $tuple in $list { @if tuple-key($tuple) == $key { @return true; } }
@return false;
}
@function map-prev-key($list, $key) {
$list: list-map-check($list); $keys: map-keys($list);
@return nth($keys, index($keys, $key) - 1)
}
@function map-next-key($list, $key) {
$list: list-map-check($list); $keys: map-keys($list);
@return nth($keys, index($keys, $key) + 1)
}
// list-map versions of list-map-get(), -merge() and -remove()
// 0.9.5 -- list-map-check() has been integrated to handle single-pair inputs, and give correct outputs
@function map-get($list, $key, $check: true) {
@if $check { $list: list-map-check($list); } @each $tuple in $list {
@if tuple-key($tuple) == $key { @return list-map-check(tuple-value($tuple)); } }
// @if tuple-key($tuple) == $key { @return list-map-check($tuple); } }
@return null;
}
@function map-merge($list1, $list2, $check: true) {
@if $check { $list1: list-map-check($list1); $list2: list-map-check($list2); }
$keys1: map-keys($list1);
@each $tuple in $list2 {
$index: index($keys1, tuple-key($tuple));
@if $index { $list1: set-nth($list1, $index, $tuple); }
@else { $list1: append($list1, $tuple, 'comma'); } }
@return $list1;
}
@function map-remove($list, $key) {
$list: list-map-check($list);
$keys: map-keys($list); $output: ();
@for $n from 1 through length($list) {
@if nth($keys, $n) != $key { $output: append($output, nth($list, $n), 'comma'); } }
@return $output;
}
// deep/nested map functions: list-map-get-z() and list-map-merge-z()
// 0.9.5 -- list-map-check() has been integrated, implicitly or explicitly
@function map-get-z($list, $keys...) {
@if $list == null { @return null; }
$length: length($keys);
$list: map-get($list, nth($keys, 1));
@if $length > 1 {
@for $n from 2 through $length {
@if $list == null { @return null; }
$list: map-get($list, nth($keys, $n), false); }
@return $list; }
@else { @return $list; }
}
@function map-merge-z($list, $keys-and-value...) {
$arg-length: length($keys-and-value);
$value: nth($keys-and-value, $arg-length);
$key-length: $arg-length - 1;
$list: list-map-check($list);
@if $key-length == 0 {
$value: if(type-of($value) == 'list', map-merge($list, list-map-check($value), false), map-merge($list, append((), $value (), 'comma'), false)); }
@else { $start: 1; @if type-of($value) == 'list' { $start: 0; $value: list-map-check($value); }
@for $i from $start through $key-length {
$new-list: (); $old-list: ();
@if $i == 0 { $new-list: $value; } @else { $new-list: append((), nth($keys-and-value, $key-length + 1 - $i) $value, 'comma'); }
@if $i == $key-length { $old-list: $list; } @else { $old-list: map-get-z($list, slice($keys-and-value, 1, $key-length - $i)...) or (); }
$value: map-merge($old-list, $new-list); } }
@return $value;
}
// aliases added as of 0.9.2: unify and replace map-*() and map-*-z() variants
@function get($args...) { @return map-get-z($args...); }
@function merge($args...) { @return map-merge-z($args...); }
@function set($args...) { @return map-merge-z($args...); }
// new as of 0.9.5: map-inspect()
// experimental
@function map-inspect($list...) {
@if length($list) == 1 { $list: list-map-check($list...); }
@else { $list: list-map-check($list); }
$output: '('; $i: 1;
@each $tuple in $list {
@if length($tuple) != 2 {
$output: $output + '#{$tuple}'; }
@else {
$key: nth($tuple, 1);
$value: nth($tuple, 2);
@if type-of($value) == 'list' { $output: $output + '#{$key} #{map-inspect($value)}'; }
@else { $output: $output + '#{$key} #{$value}'; } }
@if $i < length(map-keys($list)) { $output: $output + ', '; }
$i: $i + 1;
}
@return $output + ')';
}
$base-data: ();
.test{
out: map-keys(alpha 1, beta 2);
out: map-keys();
// out: map-inspect(merge($base-data,(
// alpha 1,
// beta 2,
// gamma 3
// )));
// out: map-keys($base-data);
out: type-of($base-data);
out: length($base-data);
type: type-of(list-map-check($base-data));
type: type-of(list-map-check($base-data...));
length: length(list-map-check($base-data));
length: length(list-map-check($base-data...));
out: map-keys(
alpha 1,
beta 2,
gamma 3
);
out: map-merge($base-data,(
alpha 1,
beta 2,
gamma 3
));
}
.test {
out: alpha, beta;
out: list;
out: 0;
type: list;
type: list;
length: 0;
length: 0;
out: alpha, beta, gamma;
out: alpha 1, beta 2, gamma 3; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment