1PYSCSS(1) pyScss PYSCSS(1)
2
3
4
6 pyscss - pyScss Documentation
7
8 build-status coverage
9
10 pyScss is a Python implementation of Sass, a CSS preprocessing language
11 that adds variables, expressions, nested rules, mixins, inheritance,
12 and other features that help ease the maintenance of large stylesheets.
13
14 pyScss also includes support for Compass, and has an extension mecha‐
15 nism for adding your own custom behavior.
16
17 pyScss is not yet fully compatible with the canonical Ruby implementa‐
18 tion, but we're getting there and constantly improving. Please feel
19 free to file a GitHub issue for anything pyScss gets wrong. Click here
20 to lend your support to pyScss and make a donation at pledgie.com!
21
22 Contents:
23
25 Installation
26 pyScss requires only Python 2.6 or later, including Python 3.x. PyPy
27 is also known to work. Install with pip:
28
29 pip install pyScss
30
31 It has a handful of pure-Python dependencies, which pip should install
32 for you:
33
34 · six
35
36 · enum34 (for Python 3.3 and below)
37
38 · pathlib (for Python 3.3 and below)
39
40 There's also an optional C speedup module, which requires having
41 libpcre and its development headers installed, with UTF-8 support
42 enabled (which it is by default).
43
44 Usage
45 Run from the command line by using -m:
46
47 python -m scss < file.scss
48
49 Specify directories to search for imports with -I. See python -mscss
50 --help for more options.
51
52 NOTE:
53 -mscss will only work in Python 2.7 and above. In Python 2.6, -m
54 doesn't work with packages, and you need to invoke this instead:
55
56 python -m scss.tool
57
58 Interactive mode
59 To get a REPL:
60
61 python -mscss --interactive
62
63 Example session:
64
65 $ python scss.py --interactive
66 >>> @import "compass/css3"
67 >>> show()
68 ['functions', 'mixins', 'options', 'vars']
69 >>> show(mixins)
70 ['apply-origin',
71 'apply-transform',
72 ...
73 'transparent']
74 >>> show(mixins, transparent)
75 @mixin transparent() {
76 @include opacity(0);
77 }
78 >>> 1px + 5px
79 6px
80 >>> _
81
82 Compass example
83 With --load-path set to Compass and Blueprint roots, you can compile
84 with Compass like with the following:
85
86 @option compress: no;
87
88 $blueprint-grid-columns : 24;
89 $blueprint-grid-width : 30px;
90 $blueprint-grid-margin : 10px;
91 $font-color : #333;
92
93 @import "compass/reset";
94 @import "compass/utilities";
95 @import "blueprint";
96
97 // your code...
98
100 Legacy API
101 WARNING:
102 This API is still supported while the new API below is worked out,
103 but it's slated for deprecation and eventual removal. If you don't
104 need any of the features not yet available with the new API, con‐
105 sider porting as soon as possible.
106
107 Compiling files
108 Very basic usage is simple enough:
109
110 from scss import Scss
111 css = Scss()
112 css.compile("a { color: red + green; }")
113
114 Configuration
115 There are several configuration variables in the scss.config module
116 that you may wish to change.
117
118 PROJECT_ROOT: Root of your entire project. Used only to construct
119 defaults for other variables. Defaults to the root of the pyScss
120 installation, which is probably not what you want.
121
122 LOAD_PATHS: An iterable of paths to search when using``@import``.
123
124 STATIC_ROOT: Used for finding sprite files. Defaults to
125 $PROJECT_ROOT/static.
126
127 ASSETS_ROOT: Generated sprites are saved here. Defaults to
128 $STATIC_ROOT/assets.
129
130 CACHE_ROOT: Used for storing cached sprite information. Defaults to
131 ASSETS_ROOT.
132
133 STATIC_URL: URL equivalent to STATIC_ROOT. Defaults to static/.
134
135 ASSETS_URL: URL equivalent to ASSETS_ROOT. Defaults to static/assets/.
136
137 SPRTE_MAP_DIRECTION: Direction in which to arrange sprites in a
138 spritesheet. Defaults to vertical; may be changed to horizontal, diag‐
139 onal, or smart.
140
141 VERBOSITY: Increase spew from the compiler. Defaults to 1.
142
143 DEBUG: Set to true to make parse errors fatal. Defaults to false.
144
145 Django example
146 A rough example of using pyScss with Django:
147
148 import os
149 import fnmatch
150
151 import scss
152
153 from django.conf import settings
154 from django.utils.datastructures import SortedDict
155 from django.contrib.staticfiles import finders
156
157
158 def finder(glob):
159 """
160 Finds all files in the django finders for a given glob,
161 returns the file path, if available, and the django storage object.
162 storage objects must implement the File storage API:
163 https://docs.djangoproject.com/en/dev/ref/files/storage/
164 """
165 for finder in finders.get_finders():
166 for path, storage in finder.list([]):
167 if fnmatch.fnmatchcase(path, glob):
168 yield path, storage
169
170
171 # STATIC_ROOT is where pyScss looks for images and static data.
172 # STATIC_ROOT can be either a fully qualified path name or a "finder"
173 # iterable function that receives a filename or glob and returns a tuple
174 # of the file found and its file storage object for each matching file.
175 # (https://docs.djangoproject.com/en/dev/ref/files/storage/)
176 scss.config.STATIC_ROOT = finder
177 scss.config.STATIC_URL = settings.STATIC_URL
178
179 # ASSETS_ROOT is where the pyScss outputs the generated files such as spritemaps
180 # and compile cache:
181 scss.config.ASSETS_ROOT = os.path.join(settings.MEDIA_ROOT, 'assets/')
182 scss.config.ASSETS_URL = settings.MEDIA_URL + 'assets/'
183
184 # These are the paths pyScss will look ".scss" files on. This can be the path to
185 # the compass framework or blueprint or compass-recepies, etc.
186 scss.config.LOAD_PATHS = [
187 '/usr/local/www/sass/frameworks/',
188 '/Library/Ruby/Gems/1.8/gems/compass-0.11.5/frameworks/compass/stylesheets/',
189 '/Library/Ruby/Gems/1.8/gems/compass-0.11.5/frameworks/blueprint/stylesheets/',
190 ]
191
192 # This creates the Scss object used to compile SCSS code. In this example,
193 # _scss_vars will hold the context variables:
194 _scss_vars = {}
195 _scss = scss.Scss(
196 scss_vars=_scss_vars,
197 scss_opts={
198 'compress': True,
199 'debug_info': True,
200 }
201 )
202
203 # 1. Compile from a string:
204 compiled_css_from_string = _scss.compile('@import "file2"; a {color: red + green; }')
205
206 # 2. Compile from a file:
207 compiled_css_from_file = _scss.compile(scss_file='file1.scss')
208
209 # 3. Compile from a set of files (use SortedDict or collections.OrderedDict to
210 # maintain the compile order):
211 _scss._scss_files = SortedDict((
212 ('file2.scss', open('file2.scss').read()),
213 ('file3.scss', open('file3.scss').read()),
214 ('file4.scss', open('file4.scss').read()),
215 ))
216 compiled_css_from_files = _scss.compile()
217
218 NOTE:
219 The API here is likely to be improved in 1.3, to avoid the need for
220 calling underscored functions.
221
222 New API
223 The simplest example:
224
225 from scss.compiler import compile_string
226
227 print(compile_string("a { color: red + green; }"))
228
229 scss.compiler.compile_string() is just a simple wrapper around the
230 scss.compiler.Compiler class:
231
232 from scss.compiler import Compiler
233
234 compiler = Compiler()
235 print(compiler.compile_string("a { color: red + green; }"))
236
237 The most common arguments passed to Compiler are:
238
239 search_path
240 A list of paths to search for @imports. May be either strings
241 or pathlib.Path objects.
242
243 Extending pyScss
244 A significant advantage to using pyScss is that you can inject Python
245 values and code into the Sass compilation process.
246
247 Injecting values
248 You can define Sass values by creating and populating a scss.names‐
249 pace.Namespace:
250
251 from scss.namespace import Namespace
252 from scss.types import String
253
254 namespace = Namespace()
255 namespace.set_variable('$base-url', String('http://localhost/'))
256 compiler = Compiler(namespace=namespace)
257 compiler.compile_string('div { background: url($base-url); }')
258
259 Now, $base-url will be available to the compiled Sass code, just like
260 any other variable. Note that the value given must be one of the Sass
261 types defined in scss.types.
262
263 Injecting functions
264 You can inject functions the same way:
265
266 def square(x):
267 return x * x
268
269 namespace.set_function('square', 1, square)
270
271 This creates a function square for use in your Sass source. Optional
272 arguments, keyword arguments, and slurpy arguments are all supported
273 automatically. The arguments are Sass types, and the return value must
274 be one as well.
275
276 The second argument is the arity — the number of required arguments, or
277 None if any number of arguments is allowed. Sass functions can be
278 overloaded by arity, so this is required. For functions with optional
279 arguments, adding the same function multiple times can be tedious and
280 error-prone, so the declare decorator is also available:
281
282 @namespace.declare
283 def square(x):
284 return x * x
285
286 This will inspect the arguments for you and register the function with
287 all arities it accepts. The function name is determined from the
288 Python name: underscores become hyphens, and trailing underscores are
289 removed. If you'd prefer to be more explicit, there's also a
290 declare_alias:
291
292 @namespace.declare_alias('square')
293 def square(x):
294 return x * x
295
296 API reference
297 scss.compiler
298 scss.namespace
299 scss.extension
301 Supported Sass features
302 pyScss is mostly compatible with Sass 3.2 and has partial support for
303 the upcoming Sass 3.3. The canonical syntax reference is in the Sass
304 documentation:
305 http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html
306
307 Both syntaxes
308 SCSS (CSS3 superset) is the primary syntax, but there's experimental
309 support for the SASS (YAML-like) syntax.
310
311 Built-in functions
312 All of the Sass 3.2 functions described in the Sass documentation are
313 supported.
314
315 Rule nesting
316 Rule/selector nesting and the & parent-reference selector are both sup‐
317 ported.
318
319 Example:
320
321 .selector {
322 a {
323 display: block;
324 }
325 strong {
326 color: blue;
327 }
328 }
329
330 Produces:
331
332 .selector a {
333 display: block;
334 }
335 .selector strong {
336 color: blue;
337 }
338
339 Variables, data types
340 Variables are supported. All of the Sass data types—strings, numbers,
341 booleans, colors, lists, maps, and null—are supported.
342
343 Example:
344
345 $main-color: #ce4dd6;
346 $style: solid;
347 $side: bottom;
348 #navbar {
349 border-#{$side}: {
350 color: $main-color;
351 style: $style;
352 }
353 }
354
355 Produces:
356
357 #navbar {
358 border-bottom-color: #ce4dd6;
359 border-bottom-style: solid;
360 }
361
362 Functions and mixins
363 @function, @mixin, and @include (optionally with @content) are sup‐
364 ported.
365
366 Named arguments (foo($name: value)) and slurpy arguments
367 (foo($args...)) are also supported.
368
369 Example:
370
371 @mixin rounded($side, $radius: 10px) {
372 border-#{$side}-radius: $radius;
373 -moz-border-radius-#{$side}: $radius;
374 -webkit-border-#{$side}-radius: $radius;
375 }
376 #navbar li { @include rounded(top); }
377 #footer { @include rounded(top, 5px); }
378 #sidebar { @include rounded(left, 8px); }
379
380 Produces:
381
382 #navbar li {
383 border-top-radius: 10px;
384 -moz-border-radius-top: 10px;
385 -webkit-border-top-radius: 10px;
386 }
387 #footer {
388 border-top-radius: 5px;
389 -moz-border-radius-top: 5px;
390 -webkit-border-top-radius: 5px;
391 }
392 #sidebar {
393 border-left-radius: 8px;
394 -moz-border-radius-left: 8px;
395 -webkit-border-left-radius: 8px;
396 }
397
398 Rule extension
399 @extend is supported, though some particularly thorny edge cases may
400 not produce output identical to the reference compiler.
401
402 Example:
403
404 .error {
405 border: 1px #f00;
406 background-color: #fdd;
407 }
408 .error.intrusion {
409 background-image: url("/image/hacked.png");
410 }
411 .seriousError {
412 @extend .error;
413 border-width: 3px;
414 }
415
416 Produces:
417
418 .error,
419 .seriousError {
420 border: 1px red;
421 background-color: #fdd;
422 }
423 .error.intrusion,
424 .seriousError.intrusion {
425 background-image: url("/image/hacked.png");
426 }
427 .seriousError {
428 border-width: 3px;
429 }
430
431 Conditions
432 @if, @else if, and @else are supported.
433
434 Loops
435 Both types of iteration are supported:
436
437 @for $n from 1 through 9 {
438 .span-#{$n} { width: $n * 10%; }
439 }
440
441 @each $color in red, blue, yellow {
442 .button-#{$color} {
443 background-color: $color;
444 }
445 }
446
447 Additionally, the unpacking-iteration syntax in Sass trunk is supposed;
448 see Maps.
449
450 Maps
451 pyScss has experimental support for maps, a data type recently added to
452 Sass trunk. Maps are defined with colons inside parentheses:
453
454 $colors: (
455 text: black,
456 background: white
457 );
458
459 Keys may be any Sass expression, not just strings.
460
461 Maps are manipulated with a handful of map functions:
462
463 a {
464 color: map-get($colors, text);
465 background-color: map-get($colors, background);
466 }
467
468 A map is semantically equivalent to a list of 2-lists, stored in the
469 order they appeared when the map was defined. Any list operation will
470 work on a map:
471
472 div {
473 // I don't know why you'd do this :)
474 margin: nth($colors, 1); // => text, black
475 }
476
477 Maps may be iterated over with @each, of course, but each item will be
478 a somewhat clumsy 2-list. Instead, you can give multiple variables to
479 do an unpacking iteration:
480
481 @each $key, $value in $colors {
482 // I don't know why you'd do this either!
483 [data-style=$key] {
484 color: $value;
485 }
486 }
487
488 This syntax works on any list-of-lists.
489
490 Everything is a list
491 Another change borrowed from Sass trunk: any scalar type (string, num‐
492 ber, boolean, etc.) will also act as a list of one element when used
493 where a list is expected. This is most useful when writing Python
494 extensions, but may also save you from checking type-of in a complex
495 API.
496
497 Compass support
498 An arbitrary cross-section of Compass 0.11 is supported:
499
500 · Math functions: sin, cos, tan, round, ceil, floor, pi, e
501
502 · Images: image-url, image-width, image-height...
503
504 · Embedded (inline) images: inline-image
505
506 NOTE:
507 Currently, Compass support is provided by default, which has led to
508 some surprising behavior since parts of Compass conflict with parts
509 of CSS3. In the future, Compass will become an extension like it is
510 for Ruby, and you will have to opt in.
511
512 Sprites
513 Example:
514
515 $icons: sprite-map("sociable/*.png"); // contains sociable/facebook.png among others.
516 div {
517 background: $icons;
518 }
519 @each $icon in sprites($icons) {
520 div .#{$icon} {
521 width: image-width(sprite-file($icons, $icon));
522 height: image-height(sprite-file($icons, $icon));
523 background-position: sprite-position($icons, $icon);
524 }
525 }
526
527 ...generates a new sprite file and produces something like:
528
529 div {
530 background: url("/static/assets/u8Y7yEQL0UffAVw5rX7yhw.png?_=1298240989") 0px 0px no-repeat;
531 }
532 div .facebook {
533 width: 32px;
534 height: 32px;
535 background-position: 0px 0px;
536 }
537 div .twitter {
538 width: 32px;
539 height: 32px;
540 background-position: 0px -32px;
541 }
542 ...
543
544 pyScss-specific extensions
545 pyScss supports some constructs that upstream Sass does not, for vari‐
546 ous reasons. Listed here are "blessed" features in no danger of being
547 removed, though you should avoid them if you're at all interested in
548 working with the reference compiler.
549
550 There are also some deviations that only exist for backwards compati‐
551 bility; you should not rely on them, they will start spewing warnings
552 at some point in the future, and eventually they will disappear. They
553 are listed separately in Deprecated features.
554
555 @option
556 Compiler options may be toggled at runtime with @option. At the moment
557 the only supported option is compress, to control whether the output is
558 compressed:
559
560 @option compress: true;
561
562 Multiplying strings by numbers
563 Much like in Python, this works:
564
565 content: "foo" * 3; // => "foofoofoo"
566
567 This is a runtime error in the reference compiler.
568
569 Deprecated features
570 Brackets to delimit expressions
571 In an expression, square brackets are equivalent to parentheses:
572
573 margin-top: [1px + 2px] * 3; // => 9px
574
575 This is a holdover from xCSS and will be removed in the future.
576
577 extends
578 There's an alternative syntax for @extend:
579
580 a extends b {
581 ...
582 }
583
584 This is identical to:
585
586 a {
587 @extend b;
588 ...
589 }
590
591 This is a holdover from xCSS and will be removed in the future.
592
593 self selector
594 self is an alias for &:
595
596 a {
597 self:hover {
598 text-decoration: underline;
599 }
600 }
601
602 This is a holdover from xCSS and will be removed in the future.
603
604 @variables block
605 Variables may be declared in a dedicated block:
606
607 @variables {
608 $color: red;
609 }
610
611 @vars is an alias for @variables.
612
613 This is a holdover from xCSS and will be removed in the future.
614
615 +foo to include a mixin
616 This:
617
618 div {
619 +border-radius 3px;
620 }
621
622 Is equivalent to this:
623
624 div {
625 @include border-radius(3px);
626 }
627
628 This is the same as the Sass syntax, but causes some parsing ambiguity,
629 since +foo with a block could be either a nested CSS block with a sib‐
630 ling selector or a mixin call. Its future is uncertain, but you should
631 probably avoid using it in SCSS files.
632
633 Soft errors
634 pyScss is much more liberal in what it accepts than the reference com‐
635 piler; for example, rules at the top level and missing closing braces
636 are accepted without complaint, and attempting to use a non-existent
637 mixin only results in a warning.
638
639 pyScss 2.0 is likely to be much stricter; don't rely on any particular
640 abuse of syntax to work in the future.
641
642 Operations on lists
643 Binary operations with a list on the left-hand side are performed ele‐
644 ment-wise:
645
646 p {
647 margin: (1em 0 3em) * 0.5; // => 0.5em 0 1.5em
648 }
649
650 Given that future versions of the reference compiler are likely to
651 introduce built-in list operations, the future of this feature is
652 unclear.
653
654 Mixin injection
655 A mixin defined like this:
656
657 @mixin foo(...) {
658 // ...
659 }
660
661 will accept any keyword arguments, which will be available as variables
662 within the mixin.
663
664 This behavior exists for historical reasons and due to the lack of a
665 **kwargs equivalent within Sass. Its usage makes mixin behavior harder
666 to understand and you should not use it.
667
668 Unsupported Sass features
669 Some Sass features are not supported or have some gaps. Each of these
670 may be considered a bug.
671
672 CLI
673 pyScss's command-line arguments are not entirely compatible with those
674 of the reference compiler.
675
676 Sass 3.3
677 The following Sass 3.3 improvements are not yet implemented, but are
678 planned for the near future:
679
680 · Use of & in expressions.
681
682 · @at-root
683
684 · Source map support.
685
686 · Using ... multiple times in a function call, or passing a map of
687 arguments with .... Likewise, keywords() is not implemented.
688
689 · unique-id(), call(), and the various *-exists() functions are not
690 implemented.
691
693 Reporting bugs
694 If you have any suggestions, bug reports, or minor annoyances, please
695 report them to the issue tracker on GitHub:
696 http://github.com/Kronuz/pyScss/issues
697
698 Contributing
699 Please send us pull requests on GitHub!
700 https://github.com/Kronuz/pyScss
701
702 Running the test suite
703 The test suite is built atop the excellent py.test library, and can be
704 run with:
705
706 py.test
707
708 from the root of a source checkout.
709
710 Most of the tests are pairs of input/output files in scss/tests/files;
711 the test suite scans for these, compiles all the .scss files, and com‐
712 pares the output with the .css file of the same name. To run only par‐
713 ticular tests, you can pass them directly as filenames:
714
715 py.test scss/tests/files/general/000-smoketest.scss
716
717 There are also several tests borrowed from the Ruby and C implementa‐
718 tions. Many of these don't work (due to missing features, different
719 error messages, slightly different formatting, etc.), so to reduce the
720 useless noise produced by a test run, you must explicitly opt into them
721 with --include-ruby, even when using a file filter. These files are in
722 the from-ruby/ and from-sassc/ subdirectories.
723
724 Other than the borrowed tests, the directory names are arbitrary.
725
726 License and copyright
727 Copyright © 2012 German M. Bravo (Kronuz), with additional heavy con‐
728 tributions by Eevee (Lexy Munroe). Licensed under the MIT license.
729
730 pyScss is inspired by and partially derived from various projects:
731
732 · Compass © 2009 Christopher M. Eppstein
733
734 · Sass © 2006-2009 Hampton Catlin and Nathan Weizenbaum
735
736 · xCSS © 2010 Anton Pawlik
737
738 Special thanks to Yelp for allowing Eevee to contribute to pyScss dur‐
739 ing working hours. Yelp does not claim copyright.
740
741 Changelog
742 1.3.5 (June 8, 2016)
743 · The new less2scss module attempts to convert Less syntax to SCSS.
744
745 · The *-exists functions from Sass 3.3 are now supported.
746
747 · The contents of a file @import-ed in the middle of an input file now
748 appears in the expected place, not at the end of the output.
749
750 · Double-slashes within URLs, as often happens with base64-encoded data
751 URLs, are no longer stripped as comments.
752
753 · Nesting selectors that end with a combinator, e.g. div > { p { ... }
754 }, now works correctly.
755
756 · invert() is now left alone when the argument is a number, indicating
757 the CSS filter rather than the Sass function.
758
759 · if() now evaluates its arguments lazily.
760
761 · str-slice() now silently corrects out-of-bounds indices.
762
763 · append() now defaults to returning a space-delimited list, when the
764 given list has fewer than two elements.
765
766 · -moz-calc and -webkit-calc are recognized as variants of the calc()
767 CSS function.
768
769 · Filenames containing dots can now be imported.
770
771 · Properties with a computed value of null are now omitted from the
772 output.
773
774 · The opacity token in IE's strange alpha(opacity=N) construct is now
775 recognized case-insensitively.
776
777 · The Compass gradient functions now recognize currentColor as a color.
778
779 · The fonts extension should now work under Python 3.
780
781 · Escaped astral plane characters no longer crash narrow Python 2
782 builds.
783
784 · The alpha value in rgba(...) is no longer truncated to only two deci‐
785 mal places.
786
787 · Some edge cases with float precision were fixed, so 742px - 40px is
788 no longer 701.99999999px.
789
790 1.3.4 (Dec 15, 2014)
791 · The modulus (%) operator is now supported.
792
793 · / and - inside an expression work correctly; this fixes some cases of
794 using vanilla CSS's / syntax.
795
796 · Relative imports have been more fixed.
797
798 · Line numbers in error messages are... more likely to be correct.
799
800 · Sass at-blocks now parse correctly even when there's no space after
801 the block name, e.g. @if(foo){...}.
802
803 · A few more cases of #{...} being replaced lexically have been
804 switched to real parsing.
805
806 With these changes, pyScss can now successfully compile Zurb Foundation
807 5.
808
809 1.3.3 (Nov 18, 2014)
810 · URLs with quotes now parse as the Url type, not as generic functions.
811 Fixes some uses of @import.
812
813 · A return got lost in the Compass gradient code, which would break
814 some uses of gradients.
815
816 · Some API work in an attempt to get django-pyscss working against 1.3.
817
818 1.3.2 (Oct 17, 2014)
819 · Fix another couple embarrassing bugs, this time with the CLI.
820
821 · Fix the auto behavior of join() to match Ruby.
822
823 · Fully allow arbitrary expressions as map keys; previously, this only
824 worked for the first key. LL(1) is hard.
825
826 · Restore Python 3.2 compatibility.
827
828 · Travis CI and Coveralls are now enabled.
829
830 1.3.1 (Oct 16, 2014)
831 Fixes an embarrassing crash when compiling multiple files together.
832
833 1.3.0 (Oct 15, 2014)
834 This is a somewhat transitional release along the road to 2.0, which
835 will remove a lot of deprecated features.
836
837 Sass/CSS compatibility
838 · Importing files from a parent directory with ../ now works (as long
839 as the imported file is still on the search path).
840
841 · Multiple CSS imports on the same line are now left unchanged. (Pre‐
842 viously, the line would be repeated once for each import.)
843
844 · CSS 3 character set detection is supported.
845
846 · CSS escapes within strings are supported (though, unlike Sass, are
847 usually printed literally rather than escaped).
848
849 · Map keys may now be arbitrary expressions.
850
851 · Slurpy named arguments are now supported.
852
853 · !global on variable assignments is now supported (and does nothing,
854 as in Sass).
855
856 · rebeccapurple is understood as a color name.
857
858 Additionally, a great many more constructs should now parse correctly.
859 By default, when pyScss encounters a parse error, it replaces any
860 interpolations and variables, and treats the result as a single opaque
861 string.
862
863 This was the only way syntax like url(http://foo/bar) was recognized,
864 since a colon is usually not allowed in the middle of a bareword. As a
865 result, code like background: url(...) scale-color(...); didn't work,
866 because the url would fail to parse and so pyScss would never even know
867 that scale-color is supposed to be a function call.
868
869 Now, the parser understands most of the unusual quirks of CSS syntax:
870
871 · () is recognized as an empty list.
872
873 · url() is fully supported.
874
875 · expression(), alpha(opacity=...), and calc() are supported (and left
876 alone, except for interpolation).
877
878 · Interpolation is part of the parser, rather than being applied before
879 parsing, so there should be far fewer bugs with it.
880
881 · CSS escapes within barewords are recognized (and ignored).
882
883 · !important may have whitespace after the !.
884
885 Glossing over a bad parse now spits out a deprecation warning, and will
886 be removed entirely in 2.0.
887
888 Bug fixes
889 · Old-style pseudo-element selectors (:before and friends, written with
890 only one colon) always stay at the end of the selector.
891
892 · The CSS3 grayscale(90%) function is now left alone, rather than being
893 treated as a Sass function. (Previously, only unitless numbers would
894 trigger this behavior.)
895
896 · Placeholder selectors (%foo) no longer end up in the output.
897
898 · Iterating over a list of lists with a single variable works (again).
899
900 · File path handling is much more polite with Windows directory separa‐
901 tors.
902
903 · At-rules broken across several lines are now recognized correctly.
904
905 · @for ... to now excludes the upper bound.
906
907 · @extend no longer shuffles rules around, and should now produce rules
908 in the same order as Ruby Sass. It also produces rules in the cor‐
909 rect order when extending from the same rule more than once. Hope‐
910 fully it's now correct, once and for all.
911
912 · Fixed a couple more Compass gradient bugs. Probably.
913
914 New features
915 · Compatibility with Python 3.2, allegedly.
916
917 · Support for building SVG font sheets from within stylesheets.
918
919 · Error messages have been improved once again: parse errors should be
920 somewhat less cryptic, the source of mixins is included in a trace‐
921 back, and missing closing braces are reported.
922
923 Backwards-incompatible changes
924 · Missing imports are now fatal.
925
926 · Much sloppy behavior or reliance on old xCSS features will now pro‐
927 duce deprecation warnings. All such behaviors will be removed in
928 pyScss 2.0.
929
930 Internals
931 · The C speedups module is now Unicode-aware, and works under CPython
932 3.
933
934 · There's no longer a runtime warning if the speedups module is not
935 found.
936
937 · pyScss is now (a lot more) Unicode-clean; everything internally is
938 treated as text, not bytes.
939
940 · Compiling the grammar is now much less painful, and doesn't require
941 copy-pasting anything.
942
943 · Several large modules have been broken up further. __init__ is, at
944 last, virtually empty.
945
946 · All the built-in functions have been moved into built-in extensions.
947
948 1.2.0 (Oct 8, 2013)
949 This is a significant release that greatly increases compatibility with
950 the reference compiler; in particular, the Sass port of Bootstrap now
951 compiles.
952
953 There are a lot of changes here, so please feel free to report any bugs
954 you see! The goal is 100% compatibility with the Ruby project.
955
956 Missing Sass features
957 · Dashes and underscores are treated as interchangeable in variable,
958 function, and mixin names.
959
960 · Rule blocks in the form background: red { ... } are now supported.
961
962 · Colors are output as their shortest representation, and never as
963 hsl(). The separate compiler options for compressing colors have
964 been removed.
965
966 · The color modification functions (adjust-color, etc.) now work reli‐
967 ably.
968
969 · transparent is recognized as a color.
970
971 · Unrecognized units are now supported and treated as opaque.
972
973 · Arbitrary combinations of units (e.g., px * px) are supported for
974 intermediate values. Unit cancellation now works reliably.
975
976 · Comparison and addition are now more in line with the Ruby behavior.
977
978 · / is now left untouched when it appears between literals, as in font:
979 0 / 0.
980
981 · null is supported.
982
983 · zip() is supported.
984
985 · grayscale() now knows it's also a CSS3 filter function, and won't be
986 evaluated if its argument is a number.
987
988 · Slurpy arguments (some-function($args...)) are supported.
989
990 · @extend has been greatly improved: it eliminates common ancestors and
991 works in many complex cases that used to produce strange results.
992
993 · Several Compass functions now adhere more closely to Compass's behav‐
994 ior. linear-gradient() is less likely to wreck valid CSS3 syntax.
995
996 · Compass's e(), pow(), log(), and sqrt() are now supported.
997
998 Bug fixes
999 · Interactive mode works. Again.
1000
1001 · Color names in strings and selectors are no longer replaced with hex
1002 equivalents.
1003
1004 · Unrecognized @-rule blocks such as @keyframes are left alone, rather
1005 than being treated like selectors.
1006
1007 · @media blocks aren't repeated for every rule inside.
1008
1009 · Pound-interpolation always drops quotes on strings.
1010
1011 · Single quoted strings no longer lose their quotes when rendered.
1012
1013 · + foo { ... } is now recognized as a nested block, not an include.
1014
1015 · color-stop() and several proposed CSS4 functions no longer produce
1016 "unrecognized function" warnings.
1017
1018 · Several obscure bugs with variable scoping have been fixed, though a
1019 couple others remain.
1020
1021 · Several bugfixes to the C speedups module to bring it in line with
1022 the behavior of the pure-Python scanner.
1023
1024 New features
1025 · Python 3 support. As a result, Python 2.5 no longer works; whether
1026 this is a bug or a feature is not yet clear.
1027
1028 · It's possible to write custom Sass functions in Python, though the
1029 API for this is not final.
1030
1031 · Experimental support for the map type and destructuring @each, both
1032 unreleased additions to the Ruby project.
1033
1034 · Support for the new string and list functions in Sass 3.3.
1035
1036 · Added background-brushed.
1037
1038 Backwards-incompatible changes
1039 · Configuration via monkeypatching the scss module no longer works.
1040 Monkeypatch scss.config instead.
1041
1042 · em and px are no longer compatible.
1043
1044 · Unrecognized variable names are now a fatal error.
1045
1046 Internals
1047 · No longer a single 5000-line file!
1048
1049 · Vastly expanded test suite, including some experimental tests bor‐
1050 rowed from the Ruby and C implementations.
1051
1052 · Parser now produces an AST rather than evaluating expressions during
1053 the parse, which allows for heavier caching and fixes some existing
1054 cache bugs.
1055
1056 · The type system has been virtually rewritten; types now act much less
1057 like Python types, and compilation uses Sass types throughout rather
1058 than mixing Python types with Sass types.
1059
1060 1.1.5 (Feb 15, 2013)
1061 · debug_info now properly produces rules that can be used by FireSass
1062 and Google Chrome SASS Source Maps.
1063
1064 · Improved memory usage for large sets of files to be used as sprites.
1065
1066 · Warns about IE 4095 maximum number of selectors.
1067
1068 · debug_info prints info as comments if specified as comments.
1069
1070 · Better handling of undefined variables.
1071
1072 · Added CSS filter functions and skewX skewY.
1073
1074 · Command line tool and entry point fixed.
1075
1076 · Fix cache buster URLs when paths already include queries or frag‐
1077 ments.
1078
1079 · Hashable Values.
1080
1081 1.1.4 (Aug 8, 2012)
1082 · Added --debug-info command line option (for FireSass output).
1083
1084 · Added compass helper function reject().
1085
1086 · Added undefined keyword for undefined variables.
1087
1088 1.1.3 (Jan 9, 2012)
1089 · Support for the new Sass 3.2.0 features (@content and placeholder
1090 selectors)
1091
1092 · Fixed bug with line numbers throwing an exception.
1093
1094 1.1.2 (Jan 3, 2012)
1095 · Regression bug fixed from 1.1.1
1096
1097 1.1.1 (Jan 2, 2012)
1098 · Added optional C speedup module for an amazing boost in scanning
1099 speed!
1100
1101 · Added headings, stylesheet-url, font-url, font-files,
1102 inline-font-files and sprite-names.
1103
1104 1.1.0 (Dec 22, 2011)
1105 · Added min() and max() for lists.
1106
1107 · Removed exception raise.
1108
1109 1.0.9 (Dec 22, 2011)
1110 · Optimizations in the scanner.
1111
1112 · Added background-noise() for compass-recipes support.
1113
1114 · enumerate() and range() can go backwards. Ex.: range(3, 0) goes from
1115 3 to 0.
1116
1117 · Added line numbers and files for errors.
1118
1119 · Added support for Firebug with FireSass.
1120
1121 · nth(n) is round (returns the nth mod len item of the list).
1122
1123 · --watch added to the command line.
1124
1125 · Several bugs fixed.
1126
1127 1.0.8 (May 13, 2011)
1128 · Changed source color ($src-color) default to black.
1129
1130 · Moved the module filename to __init__.py and module renamed back to
1131 scss.
1132
1133 · genindex
1134
1135 · modindex
1136
1137 · search
1138
1140 German M. Bravo (Kronuz)
1141
1143 2013, German M. Bravo (Kronuz)
1144
1145
1146
1147
11481.3 Jul 15, 2018 PYSCSS(1)