Skip to content

Instantly share code, notes, and snippets.

@jakob-e
Created November 4, 2013 08:52
Show Gist options
  • Save jakob-e/7299875 to your computer and use it in GitHub Desktop.
Save jakob-e/7299875 to your computer and use it in GitHub Desktop.
// Chunks $list into $size large lists
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#chunk
// -------------------------------------------------------------------------------
// @example chunk(a b c d e, 2) => a b, c d, e
// @example chunk(a b c d e, 3) => a b c, d e
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $size [Number] : length of lists
// -------------------------------------------------------------------------------
// @return [List]
@function chunk($list, $size) {
$n-lists: ceil(length($list) / $size);
$tmp-index: 0;
$result: ();
@for $i from 1 through $n-lists {
$tmp-list: ();
@for $j from 1 + $tmp-index through $size + $tmp-index {
@if $j <= length($list) {
$tmp-list: append($tmp-list, nth($list, $j));
}
}
$result: append($result, $tmp-list);
$tmp-index: $tmp-index + $size;
}
@return $result;
}
// Counts the number of occurrences of each value of $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#count-values
// -------------------------------------------------------------------------------
// @dependence `replace-nth()`
// -------------------------------------------------------------------------------
// @example count-values(a b c d e) => a 1, b 1, c 1, d 1, e 1
// @example count-values(a b c a d b a e) => a 3, b 2, c 1, d 1, e 1
// -------------------------------------------------------------------------------
// @param $list [List] : list
// -------------------------------------------------------------------------------
// @return [List]
@function count-values($list) {
$keys : ();
$counts : ();
@each $item in $list {
$index: index($keys, $item);
@if not $index {
$keys : append($keys, $item);
$counts : append($counts, 1);
}
@else {
$count : nth($counts, $index) + 1;
$counts : replace-nth($counts, $index, $count);
}
}
@return zip($keys, $counts);
}
// Returns first element of $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#first
// -------------------------------------------------------------------------------
// @example first(a b c) => a
// -------------------------------------------------------------------------------
// @param $list [List] : list
// -------------------------------------------------------------------------------
// @return [Literal]
@function first($list) {
@return nth($list, 1);
}
// Adds $value at $index in $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#insert-nth
// -------------------------------------------------------------------------------
// @dependence `purge()`
// -------------------------------------------------------------------------------
// @example insert-nth(a b c, 2, z) => a, z, b, c
// @example insert-nth(a b c, 0, z) => error
// @example insert-nth(a b c, -1, z) => error
// @example insert-nth(a b c, 10, z) => error
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $index [Number] : index to add
// @param $value [Literal] : value to add
// -------------------------------------------------------------------------------
// @raise [Error] if $index isn't an integer
// @raise [Error] if $index is strictly lesser than 1
// @raise [Error] if $index is strictly greater than length of $list
// -------------------------------------------------------------------------------
// @return [List] | false
@function insert-nth($list, $index, $value) {
$result: false;
@if type-of($index) != number {
@warn "List index #{quote($index)} is not a number for `insert-nth`.";
@return $result;
}
@else if $index < 1 {
@warn "List index #{quote($index)} must be a non-zero integer for `insert-nth`";
@return $result;
}
@else if $index > length($list) {
@warn "List index is #{quote($index)} but list is only #{length($list)} items long for `insert-nth'.";
@return $result;
}
@else {
$result: ();
@for $i from 1 through length($list) {
@if $i == $index {
$result: append($result, $value);
}
$result: append($result, nth($list, $i));
}
}
@return purge($result);
}
// Checks whether $list is symmetrical (one-level deep)
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#is-symmetrical
// -------------------------------------------------------------------------------
// @dependence `reverse()`
// -------------------------------------------------------------------------------
// @example is-symmetrical(a b c d e) => false
// @example is-symmetrical(a b c b a) => true
// @example is-symmetrical(a (b c d) a) => true
// -------------------------------------------------------------------------------
// @param $list [List] : list
// -------------------------------------------------------------------------------
// @return [Boolean]
@function is-symmetrical($list) {
@return reverse($list) == reverse(reverse($list));
}
// Returns last index of $value in $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#last-index
// -------------------------------------------------------------------------------
// @example last-index(a b c a, a) => 4
// @example last-index(a b c, z) => null
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $value [Literal] : value to be searched for
// -------------------------------------------------------------------------------
// @return [Number] | null
@function last-index($list, $value) {
@for $i from length($list) * -1 through -1 {
$i: abs($i);
@if nth($list, $i) == $value {
@return $i;
}
}
@return null;
}
// Returns last element of $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#last
// -------------------------------------------------------------------------------
// @example last(a b c) => c
// -------------------------------------------------------------------------------
// @param $list [List] : list
// -------------------------------------------------------------------------------
// @return [Literal]
@function last($list) {
@return nth($list, length($list));
}
// Shift indexes from $list of $value
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#loop
// -------------------------------------------------------------------------------
// @example loop(a b c d e) => e, a, b, c, d
// @example loop(a b c d e, 2) => d, e, a, b, c
// @example loop(a b c d e, -2) => c, d, e, a, b
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $value [Number] : number of position between old and new indexes
// -------------------------------------------------------------------------------
// @return [List]
@function loop($list, $value: 1) {
$result: ();
@for $i from 0 to length($list) {
$result: append($result, nth($list, ($i - $value) % length($list) + 1));
}
@return $result;
}
// Adds $value as first index of $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#prepend
// -------------------------------------------------------------------------------
// @dependence `purge()`
// -------------------------------------------------------------------------------
// @example prepend(a b c, z) => z, a, b, c
// @example prepend(a b c, y z) => y z, a, b, c
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $value [Literal] : value to prepend to the list
// -------------------------------------------------------------------------------
// @return [List]
@function prepend($list, $value) {
@return purge(join($value, $list));
}
// Removes all false and null values from $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation.html#purge
// -------------------------------------------------------------------------------
// @example purge(a null b false c) => a, b, c
// @example purge(a b c) => a, b, c
// -------------------------------------------------------------------------------
// @param $list [List] : list
// -------------------------------------------------------------------------------
// @return [List]
@function purge($list) {
$result: ();
@each $item in $list {
@if $item != null and $item != false and $item != "" {
$result: append($result, $item);
}
}
@return $result;
}
// Returns a random value of $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation.html#random-value
// -------------------------------------------------------------------------------
// @dependence `rand` (Ruby)
// -------------------------------------------------------------------------------
// @example random-value(a b c d e) => c
// -------------------------------------------------------------------------------
// @param $list [List] : List
// -------------------------------------------------------------------------------
// @return [Literal]
@function random-value($list) {
@return nth($list, random(length($list)) + 1);
}
// Removes duplicate values from $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#remove-duplicates
// -------------------------------------------------------------------------------
// @example remove-duplicates(a b a c b d c e) => a, b, c, d, e
// @example remove-duplicates(a b (c c c), true) => a, b, c
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $recursive [Boolean] : enable / disable recursivity
// -------------------------------------------------------------------------------
// @return [List]
@function remove-duplicates($list, $recursive: false) {
$result: ();
@each $item in $list {
@if not index($result, $item) {
@if length($item) > 1 and $recursive {
$result: append($result, remove-duplicates($item, $recursive));
}
@else {
$result: append($result, $item);
}
}
}
@return $result;
}
// Removes value from $list at index $index
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#remove-nth
// -------------------------------------------------------------------------------
// @dependence `replace-nth()`
// -------------------------------------------------------------------------------
// @example remove-nth(a b c, 2) => a, c
// @example remove-nth(a b c, 0) => error
// @example remove-nth(a b c, -1) => a, b
// @example remove-nth(a b c, 10) => error
// @example remove-nth(a b c, -10) => error
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $index [Number] : index to remove
// -------------------------------------------------------------------------------
// @raise [Error] if $index isn't an integer
// @raise [Error] if $index is 0
// @raise [Error] if abs value of $index is strictly greater then length of $list
// -------------------------------------------------------------------------------
// @return [List] | false
@function remove-nth($list, $index) {
@return replace-nth($list, $index, "");
}
// Removes value(s) $value from $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#remove
// -------------------------------------------------------------------------------
// @dependence `replace()`
// -------------------------------------------------------------------------------
// @example remove(a b c, b) => a, c
// @example remove(a b c, z) => a, b, c
// @example remove(a b c b, b) => a, c b
// @example remove(a b c b, b, true) => a, c
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $value [Literal] : value to remove
// @param $recursive [Boolean] : enable / disable recursivity
// -------------------------------------------------------------------------------
// @return [List]
@function remove($list, $value, $recursive: false) {
@return replace($list, $value, "", $recursive);
}
// Replaces $old-value by $new-value in $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation.html#replace
// -------------------------------------------------------------------------------
// @dependence `purge()`
// -------------------------------------------------------------------------------
// @example replace( (a, b, c), b, z ) => a, z, c
// @example replace( (a, b, c), y, z ) => a, b, c
// @example replace( (a, b, c a), a, z ) => z, b, c z
// @example replace( (a, b, c a), a, z, true ) => z, b, c z
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $old-value [Literal] : value to replace
// @param $new-value [Literal] : new value for $old-value
// @param $recursive [Boolean] : enable / disable recursivity
// -------------------------------------------------------------------------------
// @return [List]
@function replace($list, $old-value, $new-value, $recursive: false) {
$result: ();
@each $item in $list {
@if length($item) > 1 and $recursive {
$result: append($result, replace($item, $old-value, $new-value, $recursive));
}
@else {
$result: append($result, if($item == $old-value, $new-value, $item));
}
}
@return purge($result);
}
// Reverses the order of $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#reverse
// -------------------------------------------------------------------------------
// @example reverse(a b c) => c, b, a
// @example reverse(a b (c a)) => c a, b, a
// @example reverse(a b (c a), true) => a c, b, a
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $recursive [Boolean] : enable / disable recursivity
// -------------------------------------------------------------------------------
// @return [List]
@function reverse($list, $recursive: false) {
$result: ();
@for $i from length($list) * -1 through -1 {
$item: nth($list, abs($i));
@if length($item) > 1 and $recursive {
$result: append($result, reverse($item, $recursive));
}
@else {
$result: append($result, $item);
}
}
@return $result;
}
// Slices $list between $start and $end
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#slice
// -------------------------------------------------------------------------------
// @example slice(a b c d, 2, 3) => b, c
// @example slice(a b c d, 3, 2) => error
// @example slice(a b c d, 3, 5) => error
// @example slice(a b c d, -1, 3) => error
// @example slice(a b c d, 0, 3) => error
// @example slice(a b c d, 3, 3) => c
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $start [Number] : start index
// @param $end [Number] : end index
// -------------------------------------------------------------------------------
// @raise [Error] if $start or $end aren't integers
// @raise [Error] if $start is greater than $end
// @raise [Error] if $start or $end is strictly lesser than 1
// @raise [Error] if $start is strictly greater than length of $list
// @raise [Error] if $end is strictly greater than length of $list
// -------------------------------------------------------------------------------
// @return [List] | false
@function slice($list, $start: 1, $end: length($list)) {
$result: false;
@if type-of($start) != number or type-of($end) != number {
@warn "List indexes #{quote($start)} and #{quote($end)} must be numbers for `slice`.";
@return $result;
}
@else if $start > $end {
@warn "Start index is #{quote($start)} but has to be lesser than or equals to the end index (#{quote($end)}) for `slice`.";
@return $result;
}
@else if $start < 1 or $end < 1 {
@warn "List indexes must be non-zero integers for `slice`.";
@return $result;
}
@else if $start > length($list) {
@warn "Start index is #{quote($start)} but list is only #{length($list)} items long for `slice`.";
@return $result;
}
@else if $end > length($list) {
@warn "End index is #{quote($end)} but list is only #{length($list)} items long for `slice`.";
@return $result;
}
@else {
$result: ();
@for $i from $start through $end {
$result: append($result, nth($list, $i));
}
}
@return $result;
}
// Sorts numeric values of $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#sort
// -------------------------------------------------------------------------------
// @dependence `last()`
// @dependence `insert-nth()`
// -------------------------------------------------------------------------------
// @example sort(5 12 4.7 6 69 6) => 4.7, 5, 6, 6, 12, 69
// @example sort(5 12 4.7 "8" 6 14px 69 6) => 4.7, 5, 6, 6, 12, 69
// -------------------------------------------------------------------------------
// @param $list [List] : list
// -------------------------------------------------------------------------------
// @raise [Warning] if not unitless number found
// -------------------------------------------------------------------------------
// @return [List]
@function sort($list, $force: false) {
$result : nth($list, 1);
@if length($list) > 1 {
@for $i from 2 through length($list) {
$item: nth($list, $i);
@if type-of($item) == number {
@if unitless($item) and $force {
@if $item > last($result) {
$result: append($result, $item);
}
@else {
$index: 0;
@for $i from length($result) * -1 through -1 {
$i: abs($i);
@if $item <= nth($result, $i) {
$index: $i;
}
}
$result: insert-nth($result, $index, $item);
}
}
@else {
@warn "Not unitless number found. Omitted.";
}
}
@else {
@warn "Not integer value found. Omitted.";
}
}
}
@return $result;
}
// Sums up all unitless values in $list
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#sum
// -------------------------------------------------------------------------------
// @example sum(1 2 3 4 5) => 15
// @example sum(1 a 2 b 3) => 6
// @example sum(10px 3em 5%) => 0
// @example sum(10px 3em 5%, true) => 18
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $force [Boolean] : enable / disable parseInt
// -------------------------------------------------------------------------------
// @return [Number]
@function sum($list, $force: false) {
$result: 0;
@each $item in $list {
@if type-of($item) == number {
@if $force and unit($item) {
$item: $item / ($item * 0 + 1);
}
@if unitless($item) {
$result: $result + $item;
}
}
}
@return $result;
}
// Joins all elements of $list with $glue
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#to-string
// -------------------------------------------------------------------------------
// @example to-string(a b c) => abc
// @example to-string(a (b c) d) => abcd
// @example to-string(a b c, '-') => a-b-c
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $glue [String] : value to use as a join string
// @param $root [Boolean] : strictly internal boolean for recursivity
// -------------------------------------------------------------------------------
// @return [String]
@function to-string($list, $glue: '', $root: true) {
$result: null;
@each $item in $list {
@if length($item) > 1 {
$result: $result#{to-string($item, $glue, false)};
}
@else {
$condition: index($list, $item) != length($list) or not $root;
$result: if($condition, $result#{$item}#{$glue}, $result#{$item});
}
}
@return quote($result);
}
// Returns $list as a string
// -------------------------------------------------------------------------------
// @documentation http://sassylists.com/documentation/#debug
// -------------------------------------------------------------------------------
// @example debug(a b c d e) => [ a, b, c, d, e ]
// @example debug(a b (c d e)) => [ a, b, [ c, d, e ] ]
// -------------------------------------------------------------------------------
// @param $list [List] : list
// @param $pre [Boolean] : enable/disable variables type and proper indentation
// @param $level [Number] : internal variable for recursivity
// -------------------------------------------------------------------------------
// @return [String]
@function debug($list, $pre: false, $level: 1) {
@debug $level;
$tab : " ";
$indent : "";
$break : if($pre, "\A ", "");
@for $i from 1 to $level {
$indent : $indent + $tab;
}
$result: "[" + $break;
@each $item in $list {
$result: $result + if($pre, $indent + $tab, " ");
@if length($item) > 1 {
$result: $result
+ if($pre, "(list: " + length($item) + ") ", "")
+ debug($item, $pre, $level + 1);
}
@else {
$result: $result
+ if($pre, "(" + type-of($item) + ") ", "")
+ $item;
}
@if index($list, $item) != length($list) {
$result: $result + "," + $break;
}
}
$result: $result + $break + if($pre, if($level > 1, $indent, ""), " ") + "]";
@return quote($result);
}
// Mixin displaying clean debug
// -------------------------------------------------------------------------------
// @param $list [List] : list
@mixin debug($list) {
body:before {
content: debug($list, true) !important;
display: block !important;
margin: 1em !important;
padding: .5em !important;
background: #EFEFEF !important;
border: 1px solid #DDD !important;
border-radius: .2em !important;
color: #333 !important;
font: .75em/1.5 "Courier New", monospace !important;
text-shadow: 0 1px white !important;
white-space: pre-wrap !important;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment