sass-list-maps 0.9.9 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +30 -16
  3. data/_sass-list-maps.scss +434 -87
  4. metadata +8 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 85bcf7214f40042aadd55fa5398155b44c7d6082
4
- data.tar.gz: 144f031bb7e12acb9d541603da96652be0296ac6
3
+ metadata.gz: 4cdb2fd397cd4a3805836350c1e574d9956b3c8c
4
+ data.tar.gz: 544594422b60254ab7f37371d94cad608d9f74f8
5
5
  SHA512:
6
- metadata.gz: 7dfa1543f07dc9011a7ffeca5e7bf861c8b34ee0ea165063abc86e040d9f5495fbe492c58ae5b8d5d7b38f04a999bea18aba0305dd1726094d6523aeec0e3508
7
- data.tar.gz: 126beea1c3b5b2b5c43cbe144b1be70bde50e03651590c6d6b3a77e3ea7f2f8d8aecece338bc83b21fcb8f46b9abd2bddc591bcb0dc9e0522e5a856f8ba0a86c
6
+ metadata.gz: d20eb2fa1bec7f96d1e9f618754f6ec4ae21595826f6556109bbc87dd2cae4cf9c213e7688d93c697af0753e1e3a3abc2aab5ff97f5f47d471e6102deaef731a
7
+ data.tar.gz: 3252ce935c5396903ff6324e02e37b92a00964bf6537e66a0cf149ddede15410112760a00c7101f5a6259b4ad49ef1bc10d026a43e919e6fbd025ea686b61e4d
data/README.md CHANGED
@@ -1,11 +1,16 @@
1
1
  ## Sass List–Maps
2
2
 
3
- These functions provide forward-compatible map (hash) data-type functionality for [libsass](http://libsass.org/) and [ruby-sass](http://sass-lang.com/) 3.2.x using the SassScript `list` data-type. They are a polyfill for the `map` data-type introduced in ruby-sass 3.3.x. They feature-match all the current native (ruby-sass) `map` functions, and add nested (or 'chained') `get()`, `set()` and `merge()` functions and inspection / debugging functions as well.
3
+ These functions provide a forward-compatible polyfill for SassScript `map` (hash) data-type functionality in [libsass](http://libsass.org/) and [ruby-sass](http://sass-lang.com/) 3.2.x using the `list` data-type. They feature-match all the current native (ruby-sass) `map` functions, and add nested (or 'chained') `get()`, `set()` and `merge()` functions and inspection / debugging functions as well.
4
4
 
5
- ![](/sass-hash.jpg)
5
+ #### NB: these functions may soon be obsolete, as [SassScript Maps may soon land in libsass](https://github.com/sass/libsass/pull/481). At that point I will put up a new library that offers the same advanced functions for the native implementation as for this polyfill.
6
+
7
+ ![](sass-hash.jpg)
6
8
 
7
9
  #### Updates
8
10
 
11
+ * 1.0.0-b3 -- altered use of `list-map-check()` in `map-get()` and `map-get-z()` functions, to avoid double-wrapped-output edge case
12
+ * 1.0.0-b2 -- updated `map-remove()` function to allow removing multiple keys; conformant to ruby-sass 3.4.
13
+ * 1.0.0-b -- preparing for 1.0; added npm distribution and newly commented source code thanks to Hugo Giraudel. Next version will use SassDoc-style comments.
9
14
  * 0.9.9 -- added `map-pretty()` function to inspect/debug list-maps in pretty-printed form
10
15
  * 0.9.6-0.9.8 -- argument-handling enhancements; typo fixes
11
16
  * 0.9.3-0.9.5 -- handling single-pair lists automatically. This means no more need for `list()` or `zip()` functions, which are now deprecated.
@@ -14,17 +19,21 @@ These functions provide forward-compatible map (hash) data-type functionality fo
14
19
 
15
20
  #### Try it
16
21
 
17
- You can test-drive these functions at [Sassmeister, in this pre-loaded gist](http://sassmeister.com/gist/8645654)—but note that the libsass version at Sassmeister might be a couple of point-releases behind this repo.
22
+ You can test-drive these functions at [Sassmeister, in this pre-loaded gist](http://sassmeister.com/gist/4787415116ed1adbc8d9)—but note that the libsass version at Sassmeister might be a couple of point-releases behind this repo.
18
23
 
19
24
  #### Install it
20
25
 
21
- 'Sass List-Maps' can be installed as a Bower component for non-ruby setups (see [node-sass options](http://github.com/sindresorhus/grunt-sass#includepaths) if you are using libsass via node) or as a gem-based Compass extension for ruby setups:
26
+ 'Sass List-Maps' can be installed as a Bower component or NPM module for non-ruby setups (see [node-sass options](http://github.com/sindresorhus/grunt-sass#includepaths) if you are using libsass via node) or as a gem-based Compass extension for ruby setups:
22
27
 
23
28
  ```sh
29
+ # installation with npm
30
+ npm install sass-list-maps
31
+
24
32
  # installation with bower
25
33
  bower install sass-list-maps
26
34
 
27
- # if using grunt-sass, you need to set 'includePaths' option
35
+ # if using grunt-sass, you might want to set 'includePaths'
36
+ # to match install location of bower or npm.
28
37
  options: {
29
38
  includePaths: [
30
39
  './bower_components/sass-list-maps'
@@ -42,15 +51,17 @@ You can of course also just fork or download this repo or copy-and-paste, as the
42
51
 
43
52
  ### Introduction
44
53
 
45
- Maps (known in programming as hashes, dictionaries, or objects<sup>1</sup>) allow dynamic creating, setting, merging and retrieving of data. They are native to ruby-sass as of version 3.3.x, but for earlier ruby-sass versions, and for the libsass C-based compiler (until the point at which maps are integrated there natively), this is an alternative solution which feature-matches ruby-sass' 3.3.x map functionality using the `list` data-type. Additional functions are also provided to allow nested (chained) getting and merging/setting, and inspection for debugging.
54
+ Maps (known in programming as hashes, dictionaries, or objects<sup>1</sup>) allow dynamic creating, setting, merging and retrieving of data. They are native to ruby-sass as of version 3.3.x, but for earlier ruby-sass versions, and for the libsass C-based compiler (until the point at which maps are integrated there natively), this is an alternative solution which feature-matches ruby-sass' 3.3.x map functionality using the `list` data-type.
55
+
56
+ Some additional functions are also provided to allow nested (chained) getting and merging/setting, and inspection for debugging.
46
57
 
47
58
  *<sup>1</sup>objects (as in javascript) are not exactly the same thing as maps and hashes, but for these purposes close enough.*
48
59
 
49
60
  #### Syntax
50
61
 
51
- Compared to ruby-sass' native maps, 'list-maps' are lists like any other list in Sass, but they are *lists of pairs*, formatted in such a way as to be interpreted like a map. To this purpose, the first item in each pair is interpreted as the 'key' (usually a string), while the second is interpreted as the correspondent 'value'. This 'value' can be any Sass-script data-type, including a list—which means list-maps can contain other list-maps, allowing them to form nested data structures.
62
+ Compared to ruby-sass' native maps, 'list-maps' are lists like any other list in Sass, but they are *lists of pairs*, formatted in such a way as to be interpreted like a map. To this purpose, the first item in each pair is interpreted as the 'key', while the second is interpreted as the correspondent 'value'. This 'value' can be any Sass-script data-type, including a list—which means list-maps can contain other list-maps, allowing them to form nested data structures. The formatting used here keeps as close as possible to the syntax of native maps, with the difference that there no colons (`:`) used.
52
63
 
53
- The formatting used here keeps as close as possible to the syntax of native maps, with the difference that there no colons (`:`) used, and the placement of commas is more critical (e.g. a comma after the last item is not allowed):
64
+ *NB: in ruby-sass 3.2.x or lower, the placement of commas is also very critical (no comma after the last item); but in libsass as of 2.0 you can put commas after each item if you wish.*
54
65
 
55
66
  ```scss
56
67
  /* a single-line list-map -- compatible with any
@@ -81,11 +92,11 @@ s$native-map-z: (
81
92
  );
82
93
  ```
83
94
 
84
- It should be clear that these 'list-maps' and ruby-sass' native maps are very similar—in fact they are in principle the same (native maps are a special type of list). For this reason it was possible to reverse engineer the map functions of ruby-sass' 3.3+ to use the SassScript 'list' data-type.
95
+ It should be clear that 'list-maps' and ruby-sass 'native' maps are very similar—in fact, they are in principle the same. For this reason it was possible to reverse engineer the map functions of ruby-sass' 3.3+ to use the SassScript `list` data-type. Moreover, as with native maps in ruby-sass, list functions (e.g. `nth()`, `index()`) can be used on list-maps, since they are still lists.
85
96
 
86
97
  ### The Functions
87
98
 
88
- These functions have the same names as the map functions in ruby-sass >= 3.3.x, which means that if they were used in ruby-sass 3.3.x or higher they would conflict. Therefore, the following code assume a sass environment of either ruby-sass < 3.3.x or libsass. Also, as with native maps in ruby-sass, native list functions (e.g. `nth()`, `index()`) can also be used on list-maps since they are still lists.
99
+ These functions have the same names as the built-in map functions in ruby-sass >= 3.3.x, which means that if they were used in ruby-sass 3.3.x or higher they would conflict with (or at least overwrite) the built-in ones. Therefore, the following code assume you are using either ruby-sass 3.2.x or earlier, or libsass (currently 2.1b).
89
100
 
90
101
  #### Core (matching the ruby-sass 3.3.x native map functions)
91
102
 
@@ -132,7 +143,7 @@ $short-map: map-remove($list-map, alpha);
132
143
  // -> $short-map = ( beta 2, gamma 3)
133
144
  ```
134
145
 
135
- **NB**: you might notice in the second example above, that the second argument to map-merge isn't really a 'list-map' it's just a list of two items. This is the so-called "single item" list conundrum in Sass which is a bit tricky, but these functions as of 0.9.5 handle this case automatically.
146
+ **NB**: you might notice in the second example above, that the second argument to map-merge isn't really a 'list-map' it's just a list of two items. This is the so-called "single item" list conundrum in Sass. As of v0.9.5 these functions handle this type of input so the API can mimic the native syntax as closely as possible.
136
147
 
137
148
  #### Advanced (beyond the ruby-sass 3.3.x native map functions)
138
149
 
@@ -262,17 +273,20 @@ Since the 'advanced' nested/chained `map-get-z()` and `map-merge-z()` take a var
262
273
 
263
274
  There are a few points that bear mentioning/repeating:
264
275
 
265
- * operating on global variables in libsass and in ruby-sass 3.2.x or earlier, works differently than in 3.3.x+: You can make changes to global variables from inside a mixin scope but you can't create them from there. There is no `!global` flag. This has implications for mixins that operate on global list-maps.
266
- * as noted, the 'list-map' syntax is less forgiving than that of native maps (watch your commas). Also, it lacks any error-checking (e.g. native maps will produce a warning if you have duplicate keys). And obviously fancy features of native maps such as passing a map to a function in the form `my-function($map...)` whereupon you can reference the key/value elements inside the function as if they were named variables, doesn't work with list-maps.
267
- * as of this writing, this code contains no test-suites or inline error-catches or warnings of any kind. I've been using it in my own work but there are surely edge-cases I haven't seen. I welcome reports and contributions!
276
+ * operating on global variables in libsass and in ruby-sass 3.2.x or earlier works differently than in 3.3.x and later: You can make changes to global variables from inside a mixin scope but you can't create them from there. There is no `!global` flag. This has implications for how you declare and change global variables.
277
+ * there is no error-checking for the data-type itself (e.g. native maps will produce a warning if you have duplicate keys).
278
+ * special features of native maps in ruby-sass, such as passing a map to a function in the form `my-function($map...)` whereupon you can reference the key/value pairs inside the function as if they were named variables, doesn't work here.
279
+ * as noted, the 'list-map' syntax is in ruby-sass 3.2.x or earlier is still less forgiving than that of native maps (watch your commas), but it's a bit more easygoing in libsass, which is the more likely use-case.
280
+ * as of this writing, this code contains no test-suites or inline error-catches or warnings of any kind. I've been using it in my own work and incrementally optimizing it, but I welcome reports and contributions!
268
281
 
269
282
  ### To-Dos
270
283
 
271
- * Make a depth-based version of `map-remove()`
284
+ * Push a SassDoc documented version (this will be 1.0.0 final)
285
+ * Implement an error/warning system (probably 1.1.0)
272
286
  * Push a native maps version of the 'advanced' functions above
273
287
 
274
288
  ### Acknowledgements
275
289
 
276
290
  First and foremost, gratitude to the core Sass devs (@nex3 and @chriseppstein) for their tireless advancement of the gold-standard of CSS pre-processing, and secondly to @jedfoster and @anotheruiguy for [Sassmeister](http://sassmeister.com/), which makes developing complex functions and mixins relatively painless.
277
291
 
278
- Also acknowledgements to @HugoGiraudel for [SassyLists](http://sassylists.com/), from which I adapted some early functions, and especially for his list `debug()` function, without which I would not have been able to figure out what was going on (and going wrong) in ruby-sass 3.2.x and libsass.
292
+ Also acknowledgements to @HugoGiraudel for [SassyLists](http://sassylists.com/), from which I adapted some early functions, and especially for his list `debug()` function, without which I would not have been able to figure out what was going on (and going wrong) in ruby-sass 3.2.x and libsass.
@@ -1,175 +1,522 @@
1
- // list helper functions
2
- // 0.9.3 -- "list()" now deprecated in favor of "zip()".
3
- // 0.9.5 -- "zip()" now deprecated as well: single-pair lists are handled automatically
1
+ // Sass List-Maps 1.0.0-b3
2
+ // a libsass polyfill for rubysass "maps" data-type -- using lists
3
+ // by @lunelson
4
+ // MIT License
4
5
 
5
- @function list($args...) {
6
- $output: ();
7
- @each $arg in $args { $output: append($output, $arg, 'comma'); }
8
- @return $output;
9
- }
10
- @function slice($list, $start: 1, $end: length($list), $sep: 'comma') {
6
+ // 88 88 88 88
7
+ // ,d "" 88 "" ,d ""
8
+ // 88 88 88
9
+ // 88 88 MM88MMM 88 88 88 MM88MMM 88 ,adPPYba, ,adPPYba,
10
+ // 88 88 88 88 88 88 88 88 a8P_____88 I8[ ""
11
+ // 88 88 88 88 88 88 88 88 8PP""""""" `"Y8ba,
12
+ // "8a, ,a88 88, 88 88 88 88, 88 "8b, ,aa aa ]8I
13
+ // `"YbbdP'Y8 "Y888 88 88 88 "Y888 88 `"Ybbd8"' `"YbbdP"'
14
+ //
15
+
16
+ ///////////////////////////
17
+ // list helper functions //
18
+ ///////////////////////////
19
+
20
+ // list-slice(): return a sub-list from a list, 'sliced' from/to given indices
21
+ // ---
22
+ // @alias slice()
23
+ // ---
24
+ // @param [list] $list: list to slice
25
+ // @param [number] $start (1): start index
26
+ // @param [number] $end (length($list)): end index
27
+ // @param [string] $sep ('comma'): default list separator
28
+ // ---
29
+ // @return [list]
30
+ @function list-slice($list, $start: 1, $end: length($list), $sep: 'comma') {
11
31
  $output: ();
12
32
  @for $i from $start through $end {
13
33
  $output: append($output, nth($list, $i), $sep); }
14
34
  @return $output;
15
35
  }
16
- @function set-nth($list, $index, $value, $sep: 'comma') {
17
- $length: length($list); $output: ();
18
- @if $index > $length or $index <= 0 { @return $list; }
19
- @if $index > 1 { @for $i from 1 through $index - 1 { $output: append($output, nth($list, $i), $sep); } }
36
+ // alias
37
+ @function slice($args...) { @return list-slice($args...); }
38
+
39
+ // list-set-nth(): return a list with value at index set/updated to new value
40
+ // ---
41
+ // @alias set-nth()
42
+ // ---
43
+ // @param [list] $list: list to set
44
+ // @param [number] $index: index to set
45
+ // @param [literal] $value: new value
46
+ // @param [string] $sep ('comma'): list separator
47
+ // ---
48
+ // @return [list]
49
+ @function list-set-nth($list, $index, $value, $sep: 'comma') {
50
+ $length: length($list);
51
+ $output: ();
52
+ @if $index > $length or $index <= 0 {
53
+ @return $list;
54
+ }
55
+ @if $index > 1 {
56
+ @for $i from 1 through $index - 1 {
57
+ $output: append($output, nth($list, $i), $sep);
58
+ }
59
+ }
20
60
  $output: append($output, $value, $sep);
21
- @if $length > 1 { @for $i from $index + 1 through $length { $output: append($output, nth($list, $i), $sep); } }
61
+ @if $length > 1 {
62
+ @for $i from $index + 1 through $length {
63
+ $output: append($output, nth($list, $i), $sep);
64
+ }
65
+ }
22
66
  @return $output;
23
67
  }
68
+ // alias
69
+ @function set-nth($args...) { @return list-set-nth($args...); }
24
70
 
25
- // list-map helper functions
26
- // 0.9.3 -- key() and value() tentatively added as alternatives to 'tuple-' named funcs
27
- // 0.9.6 -- added better error handling; aliased to single version of each
71
+ ///////////////////////////////
72
+ // list-map helper functions //
73
+ ///////////////////////////////
28
74
 
29
- @function tuple-key($tuple) { @if length($tuple) < 1 { @return null; } @else { @return nth($tuple, 1); } }
30
- @function tuple-value($tuple) { @if length($tuple) < 2 { @return null; } @else { @return nth($tuple, 2); } }
75
+ // tuple-key(): return the key (first value) from a tuple (pair)
76
+ // ---
77
+ // @alias key()
78
+ // ---
79
+ // [0.9.3] added alias
80
+ // ---
81
+ // @param [list] $tuple: pair (list of length 2), to extract key from
82
+ // ---
83
+ // @return [literal]
84
+ @function tuple-key($tuple) {
85
+ @if length($tuple) < 1 { @return null; }
86
+ @return nth($tuple, 1);
87
+ }
88
+ // alias
31
89
  @function key($tuple) { @return tuple-key($tuple); }
90
+
91
+ // tuple-value(): return the value (second value) from a tuple (pair)
92
+ // ---
93
+ // @alias value()
94
+ // ---
95
+ // [0.9.3] added alias
96
+ // ---
97
+ // @param [list] $tuple: pair (list of length 2), to extract value from
98
+ // ---
99
+ // @return [literal]
100
+ @function tuple-value($tuple) {
101
+ @if length($tuple) < 2 { @return null; }
102
+ @return nth($tuple, 2);
103
+ }
104
+ // alias
32
105
  @function value($tuple) { @return tuple-value($tuple); }
33
106
 
34
- // 0.9.5 -- added list-map-check()
107
+ // list-map-check(): return list-map from list; ensure input list-maps are lists-of-lists
108
+ // ---
109
+ // [0.9.5] added; replaces use of 'list()' function
110
+ // @param [list] $list: list-map to check
111
+ // ---
112
+ // @return [list]
113
+ @function list-map-check($list) {
114
+ @if length($list) == 2 and length(nth($list, 1)) == 1 {
115
+ @return append((), $list, 'comma');
116
+ }
117
+ @return $list;
118
+ }
35
119
 
36
- @function list-map-check($list) { @if length($list) == 2 and length(nth($list, 1)) == 1 { @return append((), $list, 'comma'); } @return $list; }
120
+ //
121
+ // ,adPPYba, ,adPPYba, 8b,dPPYba, ,adPPYba,
122
+ // a8" "" a8" "8a 88P' "Y8 a8P_____88
123
+ // 8b 8b d8 88 8PP"""""""
124
+ // "8a, ,aa "8a, ,a8" 88 "8b, ,aa
125
+ // `"Ybbd8"' `"YbbdP"' 88 `"Ybbd8"'
126
+ //
37
127
 
38
- // list-map versions of list-map-keys(), -values() and -has-key() functions
39
- // 0.9.5 -- now all handle single- or double-wrapped list-maps (single-pair case) automatically
40
- // 0.9.5 -- added map-prev-key() and map-next-key() functions
128
+ /////////////////////////////////////////////////////////////////////////
129
+ // list-map versions of map-keys(), -values() and -has-key() functions //
130
+ /////////////////////////////////////////////////////////////////////////
41
131
 
132
+ // map-keys(): return comma-separated list of keys from map [conformant with rubysass map-keys()]
133
+ // ---
134
+ // @alias keys()
135
+ // ---
136
+ // [0.9.5] use list-map-check to handle single pairs automatically
137
+ // ---
138
+ // @param [argList] $list: list to retrieve keys from
139
+ // ---
140
+ // @return [list]
42
141
  @function map-keys($list...) {
43
- @if length($list) == 1 { $list: list-map-check($list...); }
44
- @else { $list: list-map-check($list); } $output: ();
45
- @each $tuple in $list { $output: append($output, tuple-key($tuple), 'comma'); }
142
+ $list: if(length($list) == 1, list-map-check($list...), list-map-check($list));
143
+ $output: ();
144
+ @each $tuple in $list {
145
+ $output: append($output, tuple-key($tuple), 'comma');
146
+ }
46
147
  @return $output;
47
148
  }
149
+ // alias
150
+ @function keys($list...) { @return map-keys($list...); }
151
+
152
+ // map-values(): return comma-separated list of values from map [conformant with rubysass map-values()]
153
+ // ---
154
+ // @alias values()
155
+ // ---
156
+ // [0.9.5] use list-map-check to handle single pairs automatically
157
+ // ---
158
+ // @param [argList] $list: list to retrieve values from
159
+ // ---
160
+ // @return [list]
48
161
  @function map-values($list...) {
49
- @if length($list) == 1 { $list: list-map-check($list...); }
50
- @else { $list: list-map-check($list); } $output: ();
51
- @each $tuple in $list { $output: append($output, tuple-value($tuple), 'comma'); }
162
+ $list: if(length($list) == 1, list-map-check($list...), list-map-check($list));
163
+ $output: ();
164
+ @each $tuple in $list {
165
+ $output: append($output, tuple-value($tuple), 'comma');
166
+ }
52
167
  @return $output;
53
168
  }
169
+ // alias
170
+ @function values($list...) { @return map-values($list...); }
171
+
172
+ // map-has-key(): check whether key exists in map at root level [conformant with rubysass map-has-key()]
173
+ // ---
174
+ // @alias has-key()
175
+ // ---
176
+ // @param [list] $list: list to check
177
+ // @param [literal] $key: key to check in list
178
+ // ---
179
+ // @return [bool]
54
180
  @function map-has-key($list, $key) {
55
181
  $list: list-map-check($list);
56
- @each $tuple in $list { @if tuple-key($tuple) == $key { @return true; } }
182
+ @each $tuple in $list {
183
+ @if tuple-key($tuple) == $key {
184
+ @return true;
185
+ }
186
+ }
57
187
  @return false;
58
188
  }
59
- @function map-prev-key($list, $key) {
60
- $list: list-map-check($list); $keys: map-keys($list);
61
- @return nth($keys, index($keys, $key) - 1);
62
- }
63
- @function map-next-key($list, $key) {
64
- $list: list-map-check($list); $keys: map-keys($list);
65
- @return nth($keys, index($keys, $key) + 1);
66
- }
189
+ // alias
190
+ @function has-key($list, $key) { @return map-has-key($list, $key); }
67
191
 
68
- // list-map versions of list-map-get(), -merge() and -remove()
69
- // 0.9.5 -- list-map-check() has been integrated to handle single-pair inputs, and give correct outputs
192
+ ////////////////////////////////////////////////////////////
193
+ // list-map versions of map-get(), -merge() and -remove() //
194
+ ////////////////////////////////////////////////////////////
70
195
 
71
- @function map-get($list, $key, $check: true) {
72
- @if $check { $list: list-map-check($list); } @each $tuple in $list {
73
- @if tuple-key($tuple) == $key { @return list-map-check(tuple-value($tuple)); } }
74
- // @if tuple-key($tuple) == $key { @return list-map-check($tuple); } }
196
+ // map-get(): return value corresponding to key in map; conformant to rubysass map-get()
197
+ // ---
198
+ // [0.9.5] list-map-check() now handles single-pair inputs / outputs
199
+ // ---
200
+ // @param [list] $list: map
201
+ // @param [literal] $key: key by which to look up value
202
+ // @param [bool] $check (true): whether or not to check the map format first
203
+ // ---
204
+ // @return [literal] | [null]
205
+ @function map-get($list, $key) {
206
+ $list: list-map-check($list);
207
+ @each $tuple in $list {
208
+ @if tuple-key($tuple) == $key {
209
+ @return tuple-value($tuple);
210
+ }
211
+ }
75
212
  @return null;
76
213
  }
214
+
215
+ // map-merge(): return a merge of second map in to first map; conformant to rubysass map-merge()
216
+ // ---
217
+ // [0.9.5] list-map-check() handles single pairs; $check param for internal use
218
+ // ---
219
+ // @param [list] $list1: first map
220
+ // @param [list] $list2: second map
221
+ // @param [bool] $check (true): whether or not to check the map first
222
+ // ---
223
+ // @return [list]
77
224
  @function map-merge($list1, $list2, $check: true) {
78
- @if $check { $list1: list-map-check($list1); $list2: list-map-check($list2); }
225
+ @if $check {
226
+ $list1: list-map-check($list1);
227
+ $list2: list-map-check($list2);
228
+ }
79
229
  $keys1: map-keys($list1);
80
230
  @each $tuple in $list2 {
81
231
  $index: index($keys1, tuple-key($tuple));
82
232
  @if $index { $list1: set-nth($list1, $index, $tuple); }
83
- @else { $list1: append($list1, $tuple, 'comma'); } }
233
+ @else { $list1: append($list1, $tuple, 'comma'); }
234
+ }
84
235
  @return $list1;
85
236
  }
86
- @function map-remove($list, $key) {
237
+
238
+ // map-remove(): return map with tuples removed, according to keys (if found); conformant to rubysass 3.4 map-remove()
239
+ // ---
240
+ // @param [list] $list: map
241
+ // @param [literal] $key: key
242
+ // ---
243
+ // @return [list]
244
+ @function map-remove($list, $keys...) {
87
245
  $list: list-map-check($list);
88
- $keys: map-keys($list); $output: ();
89
- @for $n from 1 through length($list) {
90
- @if nth($keys, $n) != $key { $output: append($output, nth($list, $n), 'comma'); } }
246
+ $output: ();
247
+ @each $tuple in $list {
248
+ @if index($keys, tuple-key($tuple)) == false {
249
+ $output: append($output, $tuple, 'comma');
250
+ }
251
+ }
91
252
  @return $output;
92
253
  }
93
254
 
94
- // deep/nested map functions: list-map-get-z() and list-map-merge-z()
95
- // 0.9.5 -- list-map-check() has been integrated, implicitly or explicitly
255
+ //
256
+ // 88 88
257
+ // 88 88
258
+ // 88 88
259
+ // ,adPPYYba, ,adPPYb,88 8b d8 ,adPPYYba, 8b,dPPYba, ,adPPYba, ,adPPYba, ,adPPYb,88
260
+ // "" `Y8 a8" `Y88 `8b d8' "" `Y8 88P' `"8a a8" "" a8P_____88 a8" `Y88
261
+ // ,adPPPPP88 8b 88 `8b d8' ,adPPPPP88 88 88 8b 8PP""""""" 8b 88
262
+ // 88, ,88 "8a, ,d88 `8b,d8' 88, ,88 88 88 "8a, ,aa "8b, ,aa "8a, ,d88
263
+ // `"8bbdP"Y8 `"8bbdP"Y8 "8" `"8bbdP"Y8 88 88 `"Ybbd8"' `"Ybbd8"' `"8bbdP"Y8
264
+ //
265
+
266
+ //////////////////////////////////////////////////////////////
267
+ // deep/nested map functions: map-get-z() and map-merge-z() //
268
+ //////////////////////////////////////////////////////////////
96
269
 
270
+ // map-get-z(): a 'deep', nested or chained version of `map-get` (see above); unique
271
+ // ---
272
+ // [0.9.5] now uses list-map-check to handle single-pair list-maps
273
+ // [0.9.2] aliased to get(); can replace map-get() and map-get-z() in usage
274
+ // ---
275
+ // @alias get()
276
+ // ---
277
+ // @param [list] $list: map
278
+ // @param [argList] $keys: nested / chained key list (where to get value)
279
+ // ---
280
+ // @return [literal] | [null]
97
281
  @function map-get-z($list, $keys...) {
98
- @if $list == null { @return null; }
282
+ @if $list == null { @return $list; }
99
283
  $length: length($keys);
100
284
  $list: map-get($list, nth($keys, 1));
101
285
  @if $length > 1 {
102
286
  @for $n from 2 through $length {
103
- @if $list == null { @return null; }
104
- $list: map-get($list, nth($keys, $n), false); }
105
- @return $list; }
106
- @else { @return $list; }
287
+ @if $list == null { @return $list; }
288
+ $list: map-get($list, nth($keys, $n));
289
+ }
290
+ @return $list;
291
+ }
292
+ @return $list;
107
293
  }
294
+ // alias
295
+ @function get($args...) { @return map-get-z($args...); }
296
+
297
+ // map-merge-z(): a 'deep', nested or chained version of `map-merge`; offers `map-set` syntax too
298
+ // ---
299
+ // [0.9.5] now uses list-map-check to handle single-pair list-maps
300
+ // [0.9.2] aliased to merge() and set(); can replace map-merge() and map-merge-z() in usage
301
+ // ---
302
+ // @alias merge(), set()
303
+ // ---
304
+ // @param [list] $list: map
305
+ // @param [argList] $keys-and-values: nested / chained key list (where to merge value); final item in list is the value to be merged
306
+ // ---
307
+ // @return [list]
108
308
  @function map-merge-z($list, $keys-and-value...) {
109
309
  $arg-length: length($keys-and-value);
110
310
  $value: nth($keys-and-value, $arg-length);
111
311
  $key-length: $arg-length - 1;
112
312
  $list: list-map-check($list);
113
313
  @if $key-length == 0 {
114
- $value: if(type-of($value) == 'list', map-merge($list, list-map-check($value), false), map-merge($list, append((), $value (), 'comma'), false)); }
115
- @else { $start: 1; @if type-of($value) == 'list' { $start: 0; $value: list-map-check($value); }
314
+ $value: if(type-of($value) == 'list', map-merge($list, list-map-check($value), false), map-merge($list, append((), $value (), 'comma'), false));
315
+ }
316
+ @else {
317
+ $start: 1;
318
+ @if type-of($value) == 'list' {
319
+ $start: 0;
320
+ $value: list-map-check($value);
321
+ }
116
322
  @for $i from $start through $key-length {
117
323
  $new-list: (); $old-list: ();
118
- @if $i == 0 { $new-list: $value; } @else { $new-list: append((), nth($keys-and-value, $key-length + 1 - $i) $value, 'comma'); }
119
- @if $i == $key-length { $old-list: $list; } @else { $old-list: map-get-z($list, slice($keys-and-value, 1, $key-length - $i)...) or (); }
120
- $value: map-merge($old-list, $new-list); } }
324
+ @if $i == 0 { $new-list: $value; }
325
+ @else { $new-list: append((), nth($keys-and-value, $key-length + 1 - $i) $value, 'comma'); }
326
+ @if $i == $key-length { $old-list: $list; }
327
+ @else { $old-list: map-get-z($list, slice($keys-and-value, 1, $key-length - $i)...) or (); }
328
+ $value: map-merge($old-list, $new-list);
329
+ }
330
+ }
121
331
  @return $value;
122
332
  }
123
-
124
- // aliases added as of 0.9.2: unify and replace map-*() and map-*-z() variants
125
-
126
- @function get($args...) { @return map-get-z($args...); }
333
+ // aliases
127
334
  @function merge($args...) { @return map-merge-z($args...); }
128
335
  @function set($args...) { @return map-merge-z($args...); }
129
336
 
130
- // new as of 0.9.5: map-inspect()
337
+ //
338
+ // ,d
339
+ // 88
340
+ // ,adPPYba, 8b, ,d8 MM88MMM 8b,dPPYba, ,adPPYYba, ,adPPYba,
341
+ // a8P_____88 `Y8, ,8P' 88 88P' "Y8 "" `Y8 I8[ ""
342
+ // 8PP""""""" )888( 88 88 ,adPPPPP88 `"Y8ba,
343
+ // "8b, ,aa ,d8" "8b, 88, 88 88, ,88 aa ]8I
344
+ // `"Ybbd8"' 8P' `Y8 "Y888 88 `"8bbdP"Y8 `"YbbdP"'
345
+ //
346
+
347
+ /////////////////////////////////////
348
+ // additional map helper functions //
349
+ /////////////////////////////////////
350
+
351
+ // map-prev-key(): return previous key from map
352
+ // ---
353
+ // [0.9.5] added
354
+ // ---
355
+ // @alias prev-key()
356
+ // ---
357
+ // @param [list] $list: map
358
+ // @param [literal] $key: pivot key
359
+ // ---
360
+ // @return [literal]
361
+ @function map-prev-key($list, $key) {
362
+ $list: list-map-check($list);
363
+ $keys: map-keys($list);
364
+ @return nth($keys, index($keys, $key) - 1);
365
+ }
366
+ // alias
367
+ @function prev-key($list, $key) { @return map-prev-key($list, $key); }
131
368
 
369
+ // map-next-key(): return next key from map
370
+ // ---
371
+ // [0.9.5] added
372
+ // ---
373
+ // @alias next-key()
374
+ // ---
375
+ // @param [list] $list: map
376
+ // @param [literal] $key: pivot key
377
+ // ---
378
+ // @return [literal]
379
+ @function map-next-key($list, $key) {
380
+ $list: list-map-check($list);
381
+ $keys: map-keys($list);
382
+ @return nth($keys, index($keys, $key) + 1);
383
+ }
384
+ // alias
385
+ @function next-key($list, $key) { @return map-next-key($list, $key); }
386
+
387
+ // map-inspect(): return the string representation of a map
388
+ // ---
389
+ // [0.9.5] added
390
+ // ---
391
+ // @param [argList] $list: map
392
+ // ---
393
+ // @return [string]
132
394
  @function map-inspect($list...) {
133
- @if length($list) == 1 { $list: list-map-check($list...); }
134
- @else { $list: list-map-check($list); }
135
- $output: '('; $i: 1;
395
+ $list: if(length($list) == 1, list-map-check($list...), list-map-check($list));
396
+ $output: '(';
397
+ $i: 1;
136
398
  @each $tuple in $list {
137
399
  @if length($tuple) != 2 {
138
- $output: $output + '#{$tuple}'; }
400
+ $output: $output + '#{$tuple}';
401
+ }
139
402
  @else {
140
- $key: nth($tuple, 1);
141
- $value: nth($tuple, 2);
142
- @if type-of($value) == 'list' { $output: $output + '#{$key} #{map-inspect($value)}'; }
143
- @else { $output: $output + '#{$key} #{$value}'; } }
144
- @if $i < length(map-keys($list)) { $output: $output + ', '; }
403
+ $key: tuple-key($tuple);
404
+ $value: tuple-value($tuple);
405
+ $output: $output + '#{$key} ' + if(type-of($value) == 'list', '#{map-inspect($value)}', '#{$value}');
406
+ }
407
+ @if $i < length(map-keys($list)) {
408
+ $output: $output + ', ';
409
+ }
145
410
  $i: $i + 1;
146
411
  }
147
412
  @return $output + ')';
148
413
  }
149
414
 
150
- // new as of 0.9.9: map-pretty()
151
-
415
+ // map-pretty(): return the string representation of a map with indents and line breaks
416
+ // ---
417
+ // [0.9.9] added
418
+ // ---
419
+ // @alias map-inspect-pretty()
420
+ // ---
421
+ // @param [list] $list: map
422
+ // @param [number] $level (1): internal variable, do not touch
423
+ // ---
424
+ // @return [string]
152
425
  @function map-pretty($list, $level: 1) {
153
- @if length($list) == 1 { $list: list-map-check($list...); }
154
- @else { $list: list-map-check($list); }
426
+ $tab: ' ';
427
+ $cr: '
428
+ ';
429
+ $list: if(length($list) == 1, list-map-check($list...), list-map-check($list));
155
430
  $indent: $tab; $outdent: $tab;
156
431
  @for $n from 1 through $level { $indent: $indent + $tab; }
157
432
  @for $n from 1 through $level - 1 { $outdent: $outdent + $tab; }
158
- $output: '(' + $cr + $indent; $i: 1;
433
+ $output: '(' + $cr + $indent;
434
+ $i: 1;
159
435
  @each $tuple in $list {
160
436
  @if length($tuple) != 2 {
161
- $output: $output + '#{$tuple}'; }
437
+ $output: $output + '#{$tuple}';
438
+ }
162
439
  @else {
163
440
  $key: nth($tuple, 1); $value: nth($tuple, 2);
164
441
  @if type-of($value) == 'list' { $output: $output + '#{$key} #{map-pretty($value, $level+1)}'; }
165
- @else { $output: $output + '#{$key} #{$value}'; } }
442
+ @else { $output: $output + '#{$key} #{$value}'; }
443
+ }
166
444
  @if $i < length(map-keys($list)) { $output: $output + ',' + $cr + $indent; }
167
445
  $i: $i + 1;
168
446
  }
169
- // @return unquote($output + $cr + $outdent + ')'); // replace last line with this one for unquoted output in libsass
170
447
  @return $output + $cr + $outdent + ')';
171
448
  }
172
- // aliases of above
449
+ // aliases
173
450
  @function map-inspect-pretty($list...) { @return map-pretty($list...); }
174
- @function map-inspect-p($list...) { @return map-pretty($list...); }
175
451
 
452
+ // map-sort(): return sorted list-map, based on values at given key(s)
453
+ // ---
454
+ // [0.9.9] added
455
+ //
456
+ // @param [list] $list: map
457
+ // @param [argList] $keys: nested / chained key list
458
+ // ---
459
+ // @return [list]
460
+ $list-map-sort-dir: 'asc'; // global sort dir variable
461
+ @function map-sort($list-map, $keys...) {
462
+ @if length($keys) < 1 { @return $list-map; }
463
+ $list-map: list-map-check($list-map);
464
+ @if length($list-map) > 1 {
465
+ $less: (); $equal: (); $greater: ();
466
+ $seed: nth($list-map, ceil(length($list-map) / 2));
467
+ $seed-value: map-get-z(nth($seed, 2), $keys...);
468
+ @each $item in $list-map {
469
+ $item-value: map-get-z(nth($item, 2), $keys...);
470
+ @if $list-map-sort-dir == 'asc' {
471
+ @if $item-value == $seed-value { $equal: append($equal, $item, 'comma'); }
472
+ @else if $item-value < $seed-value { $less: append($less, $item, 'comma'); }
473
+ @else { $greater: append($greater, $item, 'comma'); }
474
+ }
475
+ @else {
476
+ @if $item-value == $seed-value { $equal: append($equal, $item, 'comma'); }
477
+ @else if $item-value > $seed-value { $less: append($less, $item, 'comma'); }
478
+ @else { $greater: append($greater, $item, 'comma'); }
479
+ }
480
+ }
481
+ @return join(join(map-sort($less, $keys...), $equal), map-sort($greater, $keys...));
482
+ }
483
+ @return $list-map;
484
+ }
485
+
486
+ // map-json(): return json string representation of a map
487
+ // ---
488
+ // [1.0.0] added
489
+ // ---
490
+ // @param [list] $list: map
491
+ // @param [number] $level (1): internal variable, do not touch
492
+ // ---
493
+ // @return [string]
494
+ @function map-json($list...) {
495
+ $list: if(length($list) == 1, list-map-check($list...), list-map-check($list));
496
+ $output: '{ '; $i: 1;
497
+ @each $tuple in $list {
498
+ @if length($tuple) != 2 {
499
+ $output: $output + '#{$tuple}';
500
+ }
501
+ @else {
502
+ $key: nth($tuple, 1);
503
+ $value: nth($tuple, 2);
504
+ @if type-of($value) == 'list' {
505
+ $output: $output + '"#{$key}": #{map-json($value)}';
506
+ }
507
+ @else if type-of($value) == 'number' {
508
+ $value: if(unitless($value), $value, '"#{$value}"');
509
+ $output: $output + '"#{$key}": #{$value}';
510
+ }
511
+ @else {
512
+ $value: if(type-of($value) == 'bool', $value, '"#{$value}"');
513
+ $output: $output + '"#{$key}": #{$value}';
514
+ }
515
+ }
516
+ @if $i < length(map-keys($list)) {
517
+ $output: $output + ', ';
518
+ }
519
+ $i: $i + 1;
520
+ }
521
+ @return $output + ' }';
522
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass-list-maps
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.9
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lu Nelson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-29 00:00:00.000000000 Z
11
+ date: 2014-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: compass
@@ -38,15 +38,15 @@ dependencies:
38
38
  - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: 3.2.0
41
- description: Forward-compatible map (hash) manipulation functions for libsass and
42
- ruby-sass < 3.3
41
+ description: Polyfill for map (hash/object) data functionality in libsass and ruby-sass
42
+ < 3.3.x.
43
43
  email: lunelson@gmail.com
44
44
  executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
- - LICENSE
49
48
  - README.md
49
+ - LICENSE
50
50
  - _sass-list-maps.scss
51
51
  - lib/sass-list-maps.rb
52
52
  homepage: https://github.com/lunelson/sass-list-maps
@@ -69,8 +69,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
69
  version: '0'
70
70
  requirements: []
71
71
  rubyforge_project:
72
- rubygems_version: 2.2.1
72
+ rubygems_version: 2.0.14
73
73
  signing_key:
74
74
  specification_version: 4
75
- summary: Map (hash) data in libsass and ruby-sass < 3.3
75
+ summary: Polyfill for map (hash/object) data functionality in libsass and ruby-sass
76
+ < 3.3.x.
76
77
  test_files: []