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 en‐
42 abled (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 de‐
119 faults for other variables. Defaults to the root of the pyScss instal‐
120 lation, 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.name‐
249 space.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 de‐
290 clare_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 ex‐
494 tensions, but may also save you from checking type-of in a complex API.
495
496 Compass support
497 An arbitrary cross-section of Compass 0.11 is supported:
498
499 • Math functions: sin, cos, tan, round, ceil, floor, pi, e
500
501 • Images: image-url, image-width, image-height...
502
503 • Embedded (inline) images: inline-image
504
505 NOTE:
506 Currently, Compass support is provided by default, which has led to
507 some surprising behavior since parts of Compass conflict with parts
508 of CSS3. In the future, Compass will become an extension like it is
509 for Ruby, and you will have to opt in.
510
511 Sprites
512 Example:
513
514 $icons: sprite-map("sociable/*.png"); // contains sociable/facebook.png among others.
515 div {
516 background: $icons;
517 }
518 @each $icon in sprites($icons) {
519 div .#{$icon} {
520 width: image-width(sprite-file($icons, $icon));
521 height: image-height(sprite-file($icons, $icon));
522 background-position: sprite-position($icons, $icon);
523 }
524 }
525
526 ...generates a new sprite file and produces something like:
527
528 div {
529 background: url("/static/assets/u8Y7yEQL0UffAVw5rX7yhw.png?_=1298240989") 0px 0px no-repeat;
530 }
531 div .facebook {
532 width: 32px;
533 height: 32px;
534 background-position: 0px 0px;
535 }
536 div .twitter {
537 width: 32px;
538 height: 32px;
539 background-position: 0px -32px;
540 }
541 ...
542
543 pyScss-specific extensions
544 pyScss supports some constructs that upstream Sass does not, for vari‐
545 ous reasons. Listed here are "blessed" features in no danger of being
546 removed, though you should avoid them if you're at all interested in
547 working with the reference compiler.
548
549 There are also some deviations that only exist for backwards compati‐
550 bility; you should not rely on them, they will start spewing warnings
551 at some point in the future, and eventually they will disappear. They
552 are listed separately in Deprecated features.
553
554 @option
555 Compiler options may be toggled at runtime with @option. At the moment
556 the only supported option is compress, to control whether the output is
557 compressed:
558
559 @option compress: true;
560
561 Multiplying strings by numbers
562 Much like in Python, this works:
563
564 content: "foo" * 3; // => "foofoofoo"
565
566 This is a runtime error in the reference compiler.
567
568 Deprecated features
569 Brackets to delimit expressions
570 In an expression, square brackets are equivalent to parentheses:
571
572 margin-top: [1px + 2px] * 3; // => 9px
573
574 This is a holdover from xCSS and will be removed in the future.
575
576 extends
577 There's an alternative syntax for @extend:
578
579 a extends b {
580 ...
581 }
582
583 This is identical to:
584
585 a {
586 @extend b;
587 ...
588 }
589
590 This is a holdover from xCSS and will be removed in the future.
591
592 self selector
593 self is an alias for &:
594
595 a {
596 self:hover {
597 text-decoration: underline;
598 }
599 }
600
601 This is a holdover from xCSS and will be removed in the future.
602
603 @variables block
604 Variables may be declared in a dedicated block:
605
606 @variables {
607 $color: red;
608 }
609
610 @vars is an alias for @variables.
611
612 This is a holdover from xCSS and will be removed in the future.
613
614 +foo to include a mixin
615 This:
616
617 div {
618 +border-radius 3px;
619 }
620
621 Is equivalent to this:
622
623 div {
624 @include border-radius(3px);
625 }
626
627 This is the same as the Sass syntax, but causes some parsing ambiguity,
628 since +foo with a block could be either a nested CSS block with a sib‐
629 ling selector or a mixin call. Its future is uncertain, but you should
630 probably avoid using it in SCSS files.
631
632 Soft errors
633 pyScss is much more liberal in what it accepts than the reference com‐
634 piler; for example, rules at the top level and missing closing braces
635 are accepted without complaint, and attempting to use a non-existent
636 mixin only results in a warning.
637
638 pyScss 2.0 is likely to be much stricter; don't rely on any particular
639 abuse of syntax to work in the future.
640
641 Operations on lists
642 Binary operations with a list on the left-hand side are performed ele‐
643 ment-wise:
644
645 p {
646 margin: (1em 0 3em) * 0.5; // => 0.5em 0 1.5em
647 }
648
649 Given that future versions of the reference compiler are likely to in‐
650 troduce built-in list operations, the future of this feature is un‐
651 clear.
652
653 Mixin "injection"
654 A mixin defined like this:
655
656 @mixin foo(...) {
657 // ...
658 }
659
660 will accept any keyword arguments, which will be available as variables
661 within the mixin.
662
663 This behavior exists for historical reasons and due to the lack of a
664 **kwargs equivalent within Sass. Its usage makes mixin behavior harder
665 to understand and you should not use it.
666
667 Unsupported Sass features
668 Some Sass features are not supported or have some gaps. Each of these
669 may be considered a bug.
670
671 CLI
672 pyScss's command-line arguments are not entirely compatible with those
673 of the reference compiler.
674
675 Sass 3.3
676 The following Sass 3.3 improvements are not yet implemented, but are
677 planned for the near future:
678
679 • Use of & in expressions.
680
681 • @at-root
682
683 • Source map support.
684
685 • Using ... multiple times in a function call, or passing a map of ar‐
686 guments with .... Likewise, keywords() is not implemented.
687
688 • unique-id(), call(), and the various *-exists() functions are not im‐
689 plemented.
690
692 Reporting bugs
693 If you have any suggestions, bug reports, or minor annoyances, please
694 report them to the issue tracker on GitHub:
695 http://github.com/Kronuz/pyScss/issues
696
697 Contributing
698 Please send us pull requests on GitHub!
699 https://github.com/Kronuz/pyScss
700
701 Running the test suite
702 The test suite is built atop the excellent py.test library, and can be
703 run with:
704
705 py.test
706
707 from the root of a source checkout.
708
709 Most of the tests are pairs of input/output files in scss/tests/files;
710 the test suite scans for these, compiles all the .scss files, and com‐
711 pares the output with the .css file of the same name. To run only par‐
712 ticular tests, you can pass them directly as filenames:
713
714 py.test scss/tests/files/general/000-smoketest.scss
715
716 There are also several tests borrowed from the Ruby and C implementa‐
717 tions. Many of these don't work (due to missing features, different
718 error messages, slightly different formatting, etc.), so to reduce the
719 useless noise produced by a test run, you must explicitly opt into them
720 with --include-ruby, even when using a file filter. These files are in
721 the from-ruby/ and from-sassc/ subdirectories.
722
723 Other than the borrowed tests, the directory names are arbitrary.
724
725 License and copyright
726 Copyright © 2012 German M. Bravo (Kronuz), with additional heavy con‐
727 tributions by Eevee (Lexy Munroe). Licensed under the MIT license.
728
729 pyScss is inspired by and partially derived from various projects:
730
731 • Compass © 2009 Christopher M. Eppstein
732
733 • Sass © 2006-2009 Hampton Catlin and Nathan Weizenbaum
734
735 • xCSS © 2010 Anton Pawlik
736
737 Special thanks to Yelp for allowing Eevee to contribute to pyScss dur‐
738 ing working hours. Yelp does not claim copyright.
739
740 Changelog
741 1.3.5 (June 8, 2016)
742 • The new less2scss module attempts to convert Less syntax to SCSS.
743
744 • The *-exists functions from Sass 3.3 are now supported.
745
746 • The contents of a file @import-ed in the middle of an input file now
747 appears in the expected place, not at the end of the output.
748
749 • Double-slashes within URLs, as often happens with base64-encoded data
750 URLs, are no longer stripped as comments.
751
752 • Nesting selectors that end with a combinator, e.g. div > { p { ... }
753 }, now works correctly.
754
755 • invert() is now left alone when the argument is a number, indicating
756 the CSS filter rather than the Sass function.
757
758 • if() now evaluates its arguments lazily.
759
760 • str-slice() now silently corrects out-of-bounds indices.
761
762 • append() now defaults to returning a space-delimited list, when the
763 given list has fewer than two elements.
764
765 • -moz-calc and -webkit-calc are recognized as variants of the calc()
766 CSS function.
767
768 • Filenames containing dots can now be imported.
769
770 • Properties with a computed value of null are now omitted from the
771 output.
772
773 • The opacity token in IE's strange alpha(opacity=N) construct is now
774 recognized case-insensitively.
775
776 • The Compass gradient functions now recognize currentColor as a color.
777
778 • The fonts extension should now work under Python 3.
779
780 • Escaped astral plane characters no longer crash narrow Python 2
781 builds.
782
783 • The alpha value in rgba(...) is no longer truncated to only two deci‐
784 mal places.
785
786 • Some edge cases with float precision were fixed, so 742px - 40px is
787 no longer 701.99999999px.
788
789 1.3.4 (Dec 15, 2014)
790 • The modulus (%) operator is now supported.
791
792 • / and - inside an expression work correctly; this fixes some cases of
793 using vanilla CSS's / syntax.
794
795 • Relative imports have been more fixed.
796
797 • Line numbers in error messages are... more likely to be correct.
798
799 • Sass at-blocks now parse correctly even when there's no space after
800 the block name, e.g. @if(foo){...}.
801
802 • A few more cases of #{...} being replaced lexically have been
803 switched to real parsing.
804
805 With these changes, pyScss can now successfully compile Zurb Foundation
806 5.
807
808 1.3.3 (Nov 18, 2014)
809 • URLs with quotes now parse as the Url type, not as generic functions.
810 Fixes some uses of @import.
811
812 • A return got lost in the Compass gradient code, which would break
813 some uses of gradients.
814
815 • Some API work in an attempt to get django-pyscss working against 1.3.
816
817 1.3.2 (Oct 17, 2014)
818 • Fix another couple embarrassing bugs, this time with the CLI.
819
820 • Fix the auto behavior of join() to match Ruby.
821
822 • Fully allow arbitrary expressions as map keys; previously, this only
823 worked for the first key. LL(1) is hard.
824
825 • Restore Python 3.2 compatibility.
826
827 • Travis CI and Coveralls are now enabled.
828
829 1.3.1 (Oct 16, 2014)
830 Fixes an embarrassing crash when compiling multiple files together.
831
832 1.3.0 (Oct 15, 2014)
833 This is a somewhat transitional release along the road to 2.0, which
834 will remove a lot of deprecated features.
835
836 Sass/CSS compatibility
837 • Importing files from a parent directory with ../ now works (as long
838 as the imported file is still on the search path).
839
840 • Multiple CSS imports on the same line are now left unchanged. (Pre‐
841 viously, the line would be repeated once for each import.)
842
843 • CSS 3 character set detection is supported.
844
845 • CSS escapes within strings are supported (though, unlike Sass, are
846 usually printed literally rather than escaped).
847
848 • Map keys may now be arbitrary expressions.
849
850 • Slurpy named arguments are now supported.
851
852 • !global on variable assignments is now supported (and does nothing,
853 as in Sass).
854
855 • rebeccapurple is understood as a color name.
856
857 Additionally, a great many more constructs should now parse correctly.
858 By default, when pyScss encounters a parse error, it replaces any in‐
859 terpolations and variables, and treats the result as a single opaque
860 string.
861
862 This was the only way syntax like url(http://foo/bar) was recognized,
863 since a colon is usually not allowed in the middle of a bareword. As a
864 result, code like background: url(...) scale-color(...); didn't work,
865 because the url would fail to parse and so pyScss would never even know
866 that scale-color is supposed to be a function call.
867
868 Now, the parser understands most of the unusual quirks of CSS syntax:
869
870 • () is recognized as an empty list.
871
872 • url() is fully supported.
873
874 • expression(), alpha(opacity=...), and calc() are supported (and left
875 alone, except for interpolation).
876
877 • Interpolation is part of the parser, rather than being applied before
878 parsing, so there should be far fewer bugs with it.
879
880 • CSS escapes within barewords are recognized (and ignored).
881
882 • !important may have whitespace after the !.
883
884 Glossing over a bad parse now spits out a deprecation warning, and will
885 be removed entirely in 2.0.
886
887 Bug fixes
888 • Old-style pseudo-element selectors (:before and friends, written with
889 only one colon) always stay at the end of the selector.
890
891 • The CSS3 grayscale(90%) function is now left alone, rather than being
892 treated as a Sass function. (Previously, only unitless numbers would
893 trigger this behavior.)
894
895 • Placeholder selectors (%foo) no longer end up in the output.
896
897 • Iterating over a list of lists with a single variable works (again).
898
899 • File path handling is much more polite with Windows directory separa‐
900 tors.
901
902 • At-rules broken across several lines are now recognized correctly.
903
904 • @for ... to now excludes the upper bound.
905
906 • @extend no longer shuffles rules around, and should now produce rules
907 in the same order as Ruby Sass. It also produces rules in the cor‐
908 rect order when extending from the same rule more than once. Hope‐
909 fully it's now correct, once and for all.
910
911 • Fixed a couple more Compass gradient bugs. Probably.
912
913 New features
914 • Compatibility with Python 3.2, allegedly.
915
916 • Support for building SVG font sheets from within stylesheets.
917
918 • Error messages have been improved once again: parse errors should be
919 somewhat less cryptic, the source of mixins is included in a trace‐
920 back, and missing closing braces are reported.
921
922 Backwards-incompatible changes
923 • Missing imports are now fatal.
924
925 • Much sloppy behavior or reliance on old xCSS features will now pro‐
926 duce deprecation warnings. All such behaviors will be removed in
927 pyScss 2.0.
928
929 Internals
930 • The C speedups module is now Unicode-aware, and works under CPython
931 3.
932
933 • There's no longer a runtime warning if the speedups module is not
934 found.
935
936 • pyScss is now (a lot more) Unicode-clean; everything internally is
937 treated as text, not bytes.
938
939 • Compiling the grammar is now much less painful, and doesn't require
940 copy-pasting anything.
941
942 • Several large modules have been broken up further. __init__ is, at
943 last, virtually empty.
944
945 • All the built-in functions have been moved into built-in extensions.
946
947 1.2.0 (Oct 8, 2013)
948 This is a significant release that greatly increases compatibility with
949 the reference compiler; in particular, the Sass port of Bootstrap now
950 compiles.
951
952 There are a lot of changes here, so please feel free to report any bugs
953 you see! The goal is 100% compatibility with the Ruby project.
954
955 Missing Sass features
956 • Dashes and underscores are treated as interchangeable in variable,
957 function, and mixin names.
958
959 • Rule blocks in the form background: red { ... } are now supported.
960
961 • Colors are output as their shortest representation, and never as
962 hsl(). The separate compiler options for compressing colors have
963 been removed.
964
965 • The color modification functions (adjust-color, etc.) now work reli‐
966 ably.
967
968 • transparent is recognized as a color.
969
970 • Unrecognized units are now supported and treated as opaque.
971
972 • Arbitrary combinations of units (e.g., px * px) are supported for in‐
973 termediate values. Unit cancellation now works reliably.
974
975 • Comparison and addition are now more in line with the Ruby behavior.
976
977 • / is now left untouched when it appears between literals, as in font:
978 0 / 0.
979
980 • null is supported.
981
982 • zip() is supported.
983
984 • grayscale() now knows it's also a CSS3 filter function, and won't be
985 evaluated if its argument is a number.
986
987 • Slurpy arguments (some-function($args...)) are supported.
988
989 • @extend has been greatly improved: it eliminates common ancestors and
990 works in many complex cases that used to produce strange results.
991
992 • Several Compass functions now adhere more closely to Compass's behav‐
993 ior. linear-gradient() is less likely to wreck valid CSS3 syntax.
994
995 • Compass's e(), pow(), log(), and sqrt() are now supported.
996
997 Bug fixes
998 • Interactive mode works. Again.
999
1000 • Color names in strings and selectors are no longer replaced with hex
1001 equivalents.
1002
1003 • Unrecognized @-rule blocks such as @keyframes are left alone, rather
1004 than being treated like selectors.
1005
1006 • @media blocks aren't repeated for every rule inside.
1007
1008 • Pound-interpolation always drops quotes on strings.
1009
1010 • Single quoted strings no longer lose their quotes when rendered.
1011
1012 • + foo { ... } is now recognized as a nested block, not an include.
1013
1014 • color-stop() and several proposed CSS4 functions no longer produce
1015 "unrecognized function" warnings.
1016
1017 • Several obscure bugs with variable scoping have been fixed, though a
1018 couple others remain.
1019
1020 • Several bugfixes to the C speedups module to bring it in line with
1021 the behavior of the pure-Python scanner.
1022
1023 New features
1024 • Python 3 support. As a result, Python 2.5 no longer works; whether
1025 this is a bug or a feature is not yet clear.
1026
1027 • It's possible to write custom Sass functions in Python, though the
1028 API for this is not final.
1029
1030 • Experimental support for the map type and destructuring @each, both
1031 unreleased additions to the Ruby project.
1032
1033 • Support for the new string and list functions in Sass 3.3.
1034
1035 • Added background-brushed.
1036
1037 Backwards-incompatible changes
1038 • Configuration via monkeypatching the scss module no longer works.
1039 Monkeypatch scss.config instead.
1040
1041 • em and px are no longer compatible.
1042
1043 • Unrecognized variable names are now a fatal error.
1044
1045 Internals
1046 • No longer a single 5000-line file!
1047
1048 • Vastly expanded test suite, including some experimental tests bor‐
1049 rowed from the Ruby and C implementations.
1050
1051 • Parser now produces an AST rather than evaluating expressions during
1052 the parse, which allows for heavier caching and fixes some existing
1053 cache bugs.
1054
1055 • The type system has been virtually rewritten; types now act much less
1056 like Python types, and compilation uses Sass types throughout rather
1057 than mixing Python types with Sass types.
1058
1059 1.1.5 (Feb 15, 2013)
1060 • debug_info now properly produces rules that can be used by FireSass
1061 and Google Chrome SASS Source Maps.
1062
1063 • Improved memory usage for large sets of files to be used as sprites.
1064
1065 • Warns about IE 4095 maximum number of selectors.
1066
1067 • debug_info prints info as comments if specified as comments.
1068
1069 • Better handling of undefined variables.
1070
1071 • Added CSS filter functions and skewX skewY.
1072
1073 • Command line tool and entry point fixed.
1074
1075 • Fix cache buster URLs when paths already include queries or frag‐
1076 ments.
1077
1078 • Hashable Values.
1079
1080 1.1.4 (Aug 8, 2012)
1081 • Added --debug-info command line option (for FireSass output).
1082
1083 • Added compass helper function reject().
1084
1085 • Added undefined keyword for undefined variables.
1086
1087 1.1.3 (Jan 9, 2012)
1088 • Support for the new Sass 3.2.0 features (@content and placeholder se‐
1089 lectors)
1090
1091 • Fixed bug with line numbers throwing an exception.
1092
1093 1.1.2 (Jan 3, 2012)
1094 • Regression bug fixed from 1.1.1
1095
1096 1.1.1 (Jan 2, 2012)
1097 • Added optional C speedup module for an amazing boost in scanning
1098 speed!
1099
1100 • Added headings, stylesheet-url, font-url, font-files, in‐
1101 line-font-files and sprite-names.
1102
1103 1.1.0 (Dec 22, 2011)
1104 • Added min() and max() for lists.
1105
1106 • Removed exception raise.
1107
1108 1.0.9 (Dec 22, 2011)
1109 • Optimizations in the scanner.
1110
1111 • Added background-noise() for compass-recipes support.
1112
1113 • enumerate() and range() can go backwards. Ex.: range(3, 0) goes from
1114 3 to 0.
1115
1116 • Added line numbers and files for errors.
1117
1118 • Added support for Firebug with FireSass.
1119
1120 • nth(n) is round (returns the nth mod len item of the list).
1121
1122 • --watch added to the command line.
1123
1124 • Several bugs fixed.
1125
1126 1.0.8 (May 13, 2011)
1127 • Changed source color ($src-color) default to black.
1128
1129 • Moved the module filename to __init__.py and module renamed back to
1130 scss.
1131
1132 • Index
1133
1134 • Module Index
1135
1136 • Search Page
1137
1139 German M. Bravo (Kronuz)
1140
1142 2023, German M. Bravo (Kronuz)
1143
1144
1145
1146
11471.3 Jul 21, 2023 PYSCSS(1)